ARM: 6483/1: arm & sh: factorised duplicated clkdev.c
[linux-2.6-block.git] / arch / arm / mach-vexpress / v2m.c
1 /*
2  * Versatile Express V2M Motherboard Support
3  */
4 #include <linux/device.h>
5 #include <linux/amba/bus.h>
6 #include <linux/amba/mmci.h>
7 #include <linux/io.h>
8 #include <linux/init.h>
9 #include <linux/platform_device.h>
10 #include <linux/smsc911x.h>
11 #include <linux/spinlock.h>
12 #include <linux/sysdev.h>
13 #include <linux/usb/isp1760.h>
14 #include <linux/clkdev.h>
15
16 #include <asm/sizes.h>
17 #include <asm/mach/flash.h>
18 #include <asm/mach/map.h>
19 #include <asm/mach/time.h>
20 #include <asm/hardware/arm_timer.h>
21
22 #include <mach/motherboard.h>
23
24 #include <plat/timer-sp.h>
25
26 #include "core.h"
27
28 #define V2M_PA_CS0      0x40000000
29 #define V2M_PA_CS1      0x44000000
30 #define V2M_PA_CS2      0x48000000
31 #define V2M_PA_CS3      0x4c000000
32 #define V2M_PA_CS7      0x10000000
33
34 static struct map_desc v2m_io_desc[] __initdata = {
35         {
36                 .virtual        = __MMIO_P2V(V2M_PA_CS7),
37                 .pfn            = __phys_to_pfn(V2M_PA_CS7),
38                 .length         = SZ_128K,
39                 .type           = MT_DEVICE,
40         },
41 };
42
43 void __init v2m_map_io(struct map_desc *tile, size_t num)
44 {
45         iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
46         iotable_init(tile, num);
47 }
48
49
50 static void __init v2m_timer_init(void)
51 {
52         writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
53         writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL);
54
55         sp804_clocksource_init(MMIO_P2V(V2M_TIMER1));
56         sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0);
57 }
58
59 struct sys_timer v2m_timer = {
60         .init   = v2m_timer_init,
61 };
62
63
64 static DEFINE_SPINLOCK(v2m_cfg_lock);
65
66 int v2m_cfg_write(u32 devfn, u32 data)
67 {
68         /* Configuration interface broken? */
69         u32 val;
70
71         printk("%s: writing %08x to %08x\n", __func__, data, devfn);
72
73         devfn |= SYS_CFG_START | SYS_CFG_WRITE;
74
75         spin_lock(&v2m_cfg_lock);
76         val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
77         writel(val & ~SYS_CFG_COMPLETE, MMIO_P2V(V2M_SYS_CFGSTAT));
78
79         writel(data, MMIO_P2V(V2M_SYS_CFGDATA));
80         writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL));
81
82         do {
83                 val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
84         } while (val == 0);
85         spin_unlock(&v2m_cfg_lock);
86
87         return !!(val & SYS_CFG_ERR);
88 }
89
90 int v2m_cfg_read(u32 devfn, u32 *data)
91 {
92         u32 val;
93
94         devfn |= SYS_CFG_START;
95
96         spin_lock(&v2m_cfg_lock);
97         writel(0, MMIO_P2V(V2M_SYS_CFGSTAT));
98         writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL));
99
100         mb();
101
102         do {
103                 cpu_relax();
104                 val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
105         } while (val == 0);
106
107         *data = readl(MMIO_P2V(V2M_SYS_CFGDATA));
108         spin_unlock(&v2m_cfg_lock);
109
110         return !!(val & SYS_CFG_ERR);
111 }
112
113
114 static struct resource v2m_pcie_i2c_resource = {
115         .start  = V2M_SERIAL_BUS_PCI,
116         .end    = V2M_SERIAL_BUS_PCI + SZ_4K - 1,
117         .flags  = IORESOURCE_MEM,
118 };
119
120 static struct platform_device v2m_pcie_i2c_device = {
121         .name           = "versatile-i2c",
122         .id             = 0,
123         .num_resources  = 1,
124         .resource       = &v2m_pcie_i2c_resource,
125 };
126
127 static struct resource v2m_ddc_i2c_resource = {
128         .start  = V2M_SERIAL_BUS_DVI,
129         .end    = V2M_SERIAL_BUS_DVI + SZ_4K - 1,
130         .flags  = IORESOURCE_MEM,
131 };
132
133 static struct platform_device v2m_ddc_i2c_device = {
134         .name           = "versatile-i2c",
135         .id             = 1,
136         .num_resources  = 1,
137         .resource       = &v2m_ddc_i2c_resource,
138 };
139
140 static struct resource v2m_eth_resources[] = {
141         {
142                 .start  = V2M_LAN9118,
143                 .end    = V2M_LAN9118 + SZ_64K - 1,
144                 .flags  = IORESOURCE_MEM,
145         }, {
146                 .start  = IRQ_V2M_LAN9118,
147                 .end    = IRQ_V2M_LAN9118,
148                 .flags  = IORESOURCE_IRQ,
149         },
150 };
151
152 static struct smsc911x_platform_config v2m_eth_config = {
153         .flags          = SMSC911X_USE_32BIT,
154         .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
155         .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
156         .phy_interface  = PHY_INTERFACE_MODE_MII,
157 };
158
159 static struct platform_device v2m_eth_device = {
160         .name           = "smsc911x",
161         .id             = -1,
162         .resource       = v2m_eth_resources,
163         .num_resources  = ARRAY_SIZE(v2m_eth_resources),
164         .dev.platform_data = &v2m_eth_config,
165 };
166
167 static struct resource v2m_usb_resources[] = {
168         {
169                 .start  = V2M_ISP1761,
170                 .end    = V2M_ISP1761 + SZ_128K - 1,
171                 .flags  = IORESOURCE_MEM,
172         }, {
173                 .start  = IRQ_V2M_ISP1761,
174                 .end    = IRQ_V2M_ISP1761,
175                 .flags  = IORESOURCE_IRQ,
176         },
177 };
178
179 static struct isp1760_platform_data v2m_usb_config = {
180         .is_isp1761             = true,
181         .bus_width_16           = false,
182         .port1_otg              = true,
183         .analog_oc              = false,
184         .dack_polarity_high     = false,
185         .dreq_polarity_high     = false,
186 };
187
188 static struct platform_device v2m_usb_device = {
189         .name           = "isp1760",
190         .id             = -1,
191         .resource       = v2m_usb_resources,
192         .num_resources  = ARRAY_SIZE(v2m_usb_resources),
193         .dev.platform_data = &v2m_usb_config,
194 };
195
196 static int v2m_flash_init(void)
197 {
198         writel(0, MMIO_P2V(V2M_SYS_FLASH));
199         return 0;
200 }
201
202 static void v2m_flash_exit(void)
203 {
204         writel(0, MMIO_P2V(V2M_SYS_FLASH));
205 }
206
207 static void v2m_flash_set_vpp(int on)
208 {
209         writel(on != 0, MMIO_P2V(V2M_SYS_FLASH));
210 }
211
212 static struct flash_platform_data v2m_flash_data = {
213         .map_name       = "cfi_probe",
214         .width          = 4,
215         .init           = v2m_flash_init,
216         .exit           = v2m_flash_exit,
217         .set_vpp        = v2m_flash_set_vpp,
218 };
219
220 static struct resource v2m_flash_resources[] = {
221         {
222                 .start  = V2M_NOR0,
223                 .end    = V2M_NOR0 + SZ_64M - 1,
224                 .flags  = IORESOURCE_MEM,
225         }, {
226                 .start  = V2M_NOR1,
227                 .end    = V2M_NOR1 + SZ_64M - 1,
228                 .flags  = IORESOURCE_MEM,
229         },
230 };
231
232 static struct platform_device v2m_flash_device = {
233         .name           = "armflash",
234         .id             = -1,
235         .resource       = v2m_flash_resources,
236         .num_resources  = ARRAY_SIZE(v2m_flash_resources),
237         .dev.platform_data = &v2m_flash_data,
238 };
239
240
241 static unsigned int v2m_mmci_status(struct device *dev)
242 {
243         return readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0);
244 }
245
246 static struct mmci_platform_data v2m_mmci_data = {
247         .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
248         .status         = v2m_mmci_status,
249 };
250
251 static AMBA_DEVICE(aaci,  "mb:aaci",  V2M_AACI, NULL);
252 static AMBA_DEVICE(mmci,  "mb:mmci",  V2M_MMCI, &v2m_mmci_data);
253 static AMBA_DEVICE(kmi0,  "mb:kmi0",  V2M_KMI0, NULL);
254 static AMBA_DEVICE(kmi1,  "mb:kmi1",  V2M_KMI1, NULL);
255 static AMBA_DEVICE(uart0, "mb:uart0", V2M_UART0, NULL);
256 static AMBA_DEVICE(uart1, "mb:uart1", V2M_UART1, NULL);
257 static AMBA_DEVICE(uart2, "mb:uart2", V2M_UART2, NULL);
258 static AMBA_DEVICE(uart3, "mb:uart3", V2M_UART3, NULL);
259 static AMBA_DEVICE(wdt,   "mb:wdt",   V2M_WDT, NULL);
260 static AMBA_DEVICE(rtc,   "mb:rtc",   V2M_RTC, NULL);
261
262 static struct amba_device *v2m_amba_devs[] __initdata = {
263         &aaci_device,
264         &mmci_device,
265         &kmi0_device,
266         &kmi1_device,
267         &uart0_device,
268         &uart1_device,
269         &uart2_device,
270         &uart3_device,
271         &wdt_device,
272         &rtc_device,
273 };
274
275
276 static long v2m_osc_round(struct clk *clk, unsigned long rate)
277 {
278         return rate;
279 }
280
281 static int v2m_osc1_set(struct clk *clk, unsigned long rate)
282 {
283         return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_MB | 1, rate);
284 }
285
286 static const struct clk_ops osc1_clk_ops = {
287         .round  = v2m_osc_round,
288         .set    = v2m_osc1_set,
289 };
290
291 static struct clk osc1_clk = {
292         .ops    = &osc1_clk_ops,
293         .rate   = 24000000,
294 };
295
296 static struct clk osc2_clk = {
297         .rate   = 24000000,
298 };
299
300 static struct clk dummy_apb_pclk;
301
302 static struct clk_lookup v2m_lookups[] = {
303         {       /* AMBA bus clock */
304                 .con_id         = "apb_pclk",
305                 .clk            = &dummy_apb_pclk,
306         }, {    /* UART0 */
307                 .dev_id         = "mb:uart0",
308                 .clk            = &osc2_clk,
309         }, {    /* UART1 */
310                 .dev_id         = "mb:uart1",
311                 .clk            = &osc2_clk,
312         }, {    /* UART2 */
313                 .dev_id         = "mb:uart2",
314                 .clk            = &osc2_clk,
315         }, {    /* UART3 */
316                 .dev_id         = "mb:uart3",
317                 .clk            = &osc2_clk,
318         }, {    /* KMI0 */
319                 .dev_id         = "mb:kmi0",
320                 .clk            = &osc2_clk,
321         }, {    /* KMI1 */
322                 .dev_id         = "mb:kmi1",
323                 .clk            = &osc2_clk,
324         }, {    /* MMC0 */
325                 .dev_id         = "mb:mmci",
326                 .clk            = &osc2_clk,
327         }, {    /* CLCD */
328                 .dev_id         = "mb:clcd",
329                 .clk            = &osc1_clk,
330         },
331 };
332
333 static void v2m_power_off(void)
334 {
335         if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE_MB, 0))
336                 printk(KERN_EMERG "Unable to shutdown\n");
337 }
338
339 static void v2m_restart(char str, const char *cmd)
340 {
341         if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0))
342                 printk(KERN_EMERG "Unable to reboot\n");
343 }
344
345 static int __init v2m_init(void)
346 {
347         int i;
348
349         clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
350
351         platform_device_register(&v2m_pcie_i2c_device);
352         platform_device_register(&v2m_ddc_i2c_device);
353         platform_device_register(&v2m_flash_device);
354         platform_device_register(&v2m_eth_device);
355         platform_device_register(&v2m_usb_device);
356
357         for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++)
358                 amba_device_register(v2m_amba_devs[i], &iomem_resource);
359
360         pm_power_off = v2m_power_off;
361         arm_pm_restart = v2m_restart;
362
363         return 0;
364 }
365 arch_initcall(v2m_init);