Commit | Line | Data |
---|---|---|
fef88f10 RK |
1 | /* |
2 | * Versatile Express Core Tile Cortex A9x4 Support | |
3 | */ | |
4 | #include <linux/init.h> | |
68aaae9e | 5 | #include <linux/gfp.h> |
fef88f10 RK |
6 | #include <linux/device.h> |
7 | #include <linux/dma-mapping.h> | |
f417cbad | 8 | #include <linux/platform_device.h> |
fef88f10 RK |
9 | #include <linux/amba/bus.h> |
10 | #include <linux/amba/clcd.h> | |
6d803ba7 | 11 | #include <linux/clkdev.h> |
fef88f10 | 12 | |
cf0bb91b | 13 | #include <asm/pgtable.h> |
fef88f10 RK |
14 | #include <asm/hardware/arm_timer.h> |
15 | #include <asm/hardware/cache-l2x0.h> | |
16 | #include <asm/hardware/gic.h> | |
17 | #include <asm/mach-types.h> | |
f417cbad | 18 | #include <asm/pmu.h> |
bde28b84 | 19 | #include <asm/smp_twd.h> |
fef88f10 | 20 | |
fef88f10 RK |
21 | #include <mach/ct-ca9x4.h> |
22 | ||
8a9618f5 | 23 | #include <asm/hardware/timer-sp.h> |
fef88f10 RK |
24 | |
25 | #include <asm/mach/arch.h> | |
26 | #include <asm/mach/map.h> | |
27 | #include <asm/mach/time.h> | |
28 | ||
29 | #include "core.h" | |
30 | ||
31 | #include <mach/motherboard.h> | |
32 | ||
0fb44b91 RK |
33 | #include <plat/clcd.h> |
34 | ||
fef88f10 RK |
35 | #define V2M_PA_CS7 0x10000000 |
36 | ||
37 | static struct map_desc ct_ca9x4_io_desc[] __initdata = { | |
38 | { | |
39 | .virtual = __MMIO_P2V(CT_CA9X4_MPIC), | |
40 | .pfn = __phys_to_pfn(CT_CA9X4_MPIC), | |
41 | .length = SZ_16K, | |
42 | .type = MT_DEVICE, | |
43 | }, { | |
44 | .virtual = __MMIO_P2V(CT_CA9X4_SP804_TIMER), | |
45 | .pfn = __phys_to_pfn(CT_CA9X4_SP804_TIMER), | |
46 | .length = SZ_4K, | |
47 | .type = MT_DEVICE, | |
48 | }, { | |
49 | .virtual = __MMIO_P2V(CT_CA9X4_L2CC), | |
50 | .pfn = __phys_to_pfn(CT_CA9X4_L2CC), | |
51 | .length = SZ_4K, | |
52 | .type = MT_DEVICE, | |
53 | }, | |
54 | }; | |
55 | ||
56 | static void __init ct_ca9x4_map_io(void) | |
57 | { | |
e56c010f | 58 | #ifdef CONFIG_LOCAL_TIMERS |
bde28b84 | 59 | twd_base = MMIO_P2V(A9_MPCORE_TWD); |
e56c010f | 60 | #endif |
fef88f10 RK |
61 | v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); |
62 | } | |
63 | ||
fef88f10 RK |
64 | static void __init ct_ca9x4_init_irq(void) |
65 | { | |
ff2e27ae RK |
66 | gic_init(0, 29, MMIO_P2V(A9_MPCORE_GIC_DIST), |
67 | MMIO_P2V(A9_MPCORE_GIC_CPU)); | |
fef88f10 RK |
68 | } |
69 | ||
70 | #if 0 | |
cdaf9a2f | 71 | static void __init ct_ca9x4_timer_init(void) |
fef88f10 RK |
72 | { |
73 | writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL); | |
74 | writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL); | |
75 | ||
76 | sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1)); | |
77 | sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0); | |
78 | } | |
79 | ||
80 | static struct sys_timer ct_ca9x4_timer = { | |
81 | .init = ct_ca9x4_timer_init, | |
82 | }; | |
83 | #endif | |
84 | ||
fef88f10 RK |
85 | static void ct_ca9x4_clcd_enable(struct clcd_fb *fb) |
86 | { | |
87 | v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0); | |
88 | v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE_DB1, 2); | |
89 | } | |
90 | ||
91 | static int ct_ca9x4_clcd_setup(struct clcd_fb *fb) | |
92 | { | |
93 | unsigned long framesize = 1024 * 768 * 2; | |
fef88f10 | 94 | |
0fb44b91 RK |
95 | fb->panel = versatile_clcd_get_panel("XVGA"); |
96 | if (!fb->panel) | |
97 | return -EINVAL; | |
fef88f10 | 98 | |
0fb44b91 | 99 | return versatile_clcd_setup_dma(fb, framesize); |
fef88f10 RK |
100 | } |
101 | ||
102 | static struct clcd_board ct_ca9x4_clcd_data = { | |
103 | .name = "CT-CA9X4", | |
0fb44b91 | 104 | .caps = CLCD_CAP_5551 | CLCD_CAP_565, |
fef88f10 RK |
105 | .check = clcdfb_check, |
106 | .decode = clcdfb_decode, | |
107 | .enable = ct_ca9x4_clcd_enable, | |
108 | .setup = ct_ca9x4_clcd_setup, | |
0fb44b91 RK |
109 | .mmap = versatile_clcd_mmap_dma, |
110 | .remove = versatile_clcd_remove_dma, | |
fef88f10 RK |
111 | }; |
112 | ||
113 | static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data); | |
114 | static AMBA_DEVICE(dmc, "ct:dmc", CT_CA9X4_DMC, NULL); | |
115 | static AMBA_DEVICE(smc, "ct:smc", CT_CA9X4_SMC, NULL); | |
116 | static AMBA_DEVICE(gpio, "ct:gpio", CT_CA9X4_GPIO, NULL); | |
117 | ||
118 | static struct amba_device *ct_ca9x4_amba_devs[] __initdata = { | |
119 | &clcd_device, | |
120 | &dmc_device, | |
121 | &smc_device, | |
122 | &gpio_device, | |
123 | }; | |
124 | ||
125 | ||
126 | static long ct_round(struct clk *clk, unsigned long rate) | |
127 | { | |
128 | return rate; | |
129 | } | |
130 | ||
131 | static int ct_set(struct clk *clk, unsigned long rate) | |
132 | { | |
133 | return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_DB1 | 1, rate); | |
134 | } | |
135 | ||
136 | static const struct clk_ops osc1_clk_ops = { | |
137 | .round = ct_round, | |
138 | .set = ct_set, | |
139 | }; | |
140 | ||
141 | static struct clk osc1_clk = { | |
142 | .ops = &osc1_clk_ops, | |
143 | .rate = 24000000, | |
144 | }; | |
145 | ||
146 | static struct clk_lookup lookups[] = { | |
147 | { /* CLCD */ | |
148 | .dev_id = "ct:clcd", | |
149 | .clk = &osc1_clk, | |
150 | }, | |
151 | }; | |
152 | ||
f417cbad WD |
153 | static struct resource pmu_resources[] = { |
154 | [0] = { | |
155 | .start = IRQ_CT_CA9X4_PMU_CPU0, | |
156 | .end = IRQ_CT_CA9X4_PMU_CPU0, | |
157 | .flags = IORESOURCE_IRQ, | |
158 | }, | |
159 | [1] = { | |
160 | .start = IRQ_CT_CA9X4_PMU_CPU1, | |
161 | .end = IRQ_CT_CA9X4_PMU_CPU1, | |
162 | .flags = IORESOURCE_IRQ, | |
163 | }, | |
164 | [2] = { | |
165 | .start = IRQ_CT_CA9X4_PMU_CPU2, | |
166 | .end = IRQ_CT_CA9X4_PMU_CPU2, | |
167 | .flags = IORESOURCE_IRQ, | |
168 | }, | |
169 | [3] = { | |
170 | .start = IRQ_CT_CA9X4_PMU_CPU3, | |
171 | .end = IRQ_CT_CA9X4_PMU_CPU3, | |
172 | .flags = IORESOURCE_IRQ, | |
173 | }, | |
174 | }; | |
175 | ||
176 | static struct platform_device pmu_device = { | |
177 | .name = "arm-pmu", | |
178 | .id = ARM_PMU_DEVICE_CPU, | |
179 | .num_resources = ARRAY_SIZE(pmu_resources), | |
180 | .resource = pmu_resources, | |
181 | }; | |
182 | ||
493a451b RK |
183 | static void __init ct_ca9x4_init_early(void) |
184 | { | |
185 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | |
186 | ||
187 | v2m_init_early(); | |
188 | } | |
189 | ||
cdaf9a2f | 190 | static void __init ct_ca9x4_init(void) |
fef88f10 RK |
191 | { |
192 | int i; | |
193 | ||
194 | #ifdef CONFIG_CACHE_L2X0 | |
2de59fea WD |
195 | void __iomem *l2x0_base = MMIO_P2V(CT_CA9X4_L2CC); |
196 | ||
197 | /* set RAM latencies to 1 cycle for this core tile. */ | |
198 | writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL); | |
199 | writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL); | |
200 | ||
201 | l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff); | |
fef88f10 RK |
202 | #endif |
203 | ||
fef88f10 RK |
204 | for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++) |
205 | amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource); | |
f417cbad WD |
206 | |
207 | platform_device_register(&pmu_device); | |
fef88f10 RK |
208 | } |
209 | ||
210 | MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4") | |
b75c178a | 211 | .boot_params = PLAT_PHYS_OFFSET + 0x00000100, |
fef88f10 RK |
212 | .map_io = ct_ca9x4_map_io, |
213 | .init_irq = ct_ca9x4_init_irq, | |
493a451b | 214 | .init_early = ct_ca9x4_init_early, |
fef88f10 RK |
215 | #if 0 |
216 | .timer = &ct_ca9x4_timer, | |
217 | #else | |
218 | .timer = &v2m_timer, | |
219 | #endif | |
220 | .init_machine = ct_ca9x4_init, | |
221 | MACHINE_END |