]> err.no Git - linux-2.6/blob - arch/arm/mach-pxa/generic.c
[ARM] pxa: introduce clk support for PXA SoC clocks
[linux-2.6] / arch / arm / mach-pxa / generic.c
1 /*
2  *  linux/arch/arm/mach-pxa/generic.c
3  *
4  *  Author:     Nicolas Pitre
5  *  Created:    Jun 15, 2001
6  *  Copyright:  MontaVista Software Inc.
7  *
8  * Code common to all PXA machines.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * Since this file should be linked before any other machine specific file,
15  * the __initcall() here will be executed first.  This serves as default
16  * initialization stuff for PXA machines which can be overridden later if
17  * need be.
18  */
19 #include <linux/module.h>
20 #include <linux/kernel.h>
21 #include <linux/init.h>
22 #include <linux/delay.h>
23 #include <linux/platform_device.h>
24 #include <linux/ioport.h>
25 #include <linux/pm.h>
26 #include <linux/string.h>
27
28 #include <asm/hardware.h>
29 #include <asm/irq.h>
30 #include <asm/system.h>
31 #include <asm/pgtable.h>
32 #include <asm/mach/map.h>
33
34 #include <asm/arch/pxa-regs.h>
35 #include <asm/arch/gpio.h>
36 #include <asm/arch/udc.h>
37 #include <asm/arch/pxafb.h>
38 #include <asm/arch/mmc.h>
39 #include <asm/arch/irda.h>
40 #include <asm/arch/i2c.h>
41
42 #include "devices.h"
43 #include "generic.h"
44
45 /*
46  * Get the clock frequency as reflected by CCCR and the turbo flag.
47  * We assume these values have been applied via a fcs.
48  * If info is not 0 we also display the current settings.
49  */
50 unsigned int get_clk_frequency_khz(int info)
51 {
52         if (cpu_is_pxa21x() || cpu_is_pxa25x())
53                 return pxa25x_get_clk_frequency_khz(info);
54         else
55                 return pxa27x_get_clk_frequency_khz(info);
56 }
57 EXPORT_SYMBOL(get_clk_frequency_khz);
58
59 /*
60  * Return the current memory clock frequency in units of 10kHz
61  */
62 unsigned int get_memclk_frequency_10khz(void)
63 {
64         if (cpu_is_pxa21x() || cpu_is_pxa25x())
65                 return pxa25x_get_memclk_frequency_10khz();
66         else
67                 return pxa27x_get_memclk_frequency_10khz();
68 }
69 EXPORT_SYMBOL(get_memclk_frequency_10khz);
70
71 /*
72  * Return the current LCD clock frequency in units of 10kHz
73  */
74 unsigned int get_lcdclk_frequency_10khz(void)
75 {
76         if (cpu_is_pxa21x() || cpu_is_pxa25x())
77                 return pxa25x_get_memclk_frequency_10khz();
78         else
79                 return pxa27x_get_lcdclk_frequency_10khz();
80 }
81 EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
82
83 /*
84  * Handy function to set GPIO alternate functions
85  */
86
87 int pxa_gpio_mode(int gpio_mode)
88 {
89         unsigned long flags;
90         int gpio = gpio_mode & GPIO_MD_MASK_NR;
91         int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
92         int gafr;
93
94         if (gpio > PXA_LAST_GPIO)
95                 return -EINVAL;
96
97         local_irq_save(flags);
98         if (gpio_mode & GPIO_DFLT_LOW)
99                 GPCR(gpio) = GPIO_bit(gpio);
100         else if (gpio_mode & GPIO_DFLT_HIGH)
101                 GPSR(gpio) = GPIO_bit(gpio);
102         if (gpio_mode & GPIO_MD_MASK_DIR)
103                 GPDR(gpio) |= GPIO_bit(gpio);
104         else
105                 GPDR(gpio) &= ~GPIO_bit(gpio);
106         gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
107         GAFR(gpio) = gafr |  (fn  << (((gpio) & 0xf)*2));
108         local_irq_restore(flags);
109
110         return 0;
111 }
112
113 EXPORT_SYMBOL(pxa_gpio_mode);
114
115 /*
116  * Return GPIO level
117  */
118 int pxa_gpio_get_value(unsigned gpio)
119 {
120         return __gpio_get_value(gpio);
121 }
122
123 EXPORT_SYMBOL(pxa_gpio_get_value);
124
125 /*
126  * Set output GPIO level
127  */
128 void pxa_gpio_set_value(unsigned gpio, int value)
129 {
130         __gpio_set_value(gpio, value);
131 }
132
133 EXPORT_SYMBOL(pxa_gpio_set_value);
134
135 /*
136  * Routine to safely enable or disable a clock in the CKEN
137  */
138 void pxa_set_cken(int clock, int enable)
139 {
140         unsigned long flags;
141         local_irq_save(flags);
142
143         if (enable)
144                 CKEN |= (1 << clock);
145         else
146                 CKEN &= ~(1 << clock);
147
148         local_irq_restore(flags);
149 }
150
151 EXPORT_SYMBOL(pxa_set_cken);
152
153 /*
154  * Intel PXA2xx internal register mapping.
155  *
156  * Note 1: not all PXA2xx variants implement all those addresses.
157  *
158  * Note 2: virtual 0xfffe0000-0xffffffff is reserved for the vector table
159  *         and cache flush area.
160  */
161 static struct map_desc standard_io_desc[] __initdata = {
162         {       /* Devs */
163                 .virtual        =  0xf2000000,
164                 .pfn            = __phys_to_pfn(0x40000000),
165                 .length         = 0x02000000,
166                 .type           = MT_DEVICE
167         }, {    /* LCD */
168                 .virtual        =  0xf4000000,
169                 .pfn            = __phys_to_pfn(0x44000000),
170                 .length         = 0x00100000,
171                 .type           = MT_DEVICE
172         }, {    /* Mem Ctl */
173                 .virtual        =  0xf6000000,
174                 .pfn            = __phys_to_pfn(0x48000000),
175                 .length         = 0x00100000,
176                 .type           = MT_DEVICE
177         }, {    /* USB host */
178                 .virtual        =  0xf8000000,
179                 .pfn            = __phys_to_pfn(0x4c000000),
180                 .length         = 0x00100000,
181                 .type           = MT_DEVICE
182         }, {    /* Camera */
183                 .virtual        =  0xfa000000,
184                 .pfn            = __phys_to_pfn(0x50000000),
185                 .length         = 0x00100000,
186                 .type           = MT_DEVICE
187         }, {    /* IMem ctl */
188                 .virtual        =  0xfe000000,
189                 .pfn            = __phys_to_pfn(0x58000000),
190                 .length         = 0x00100000,
191                 .type           = MT_DEVICE
192         }, {    /* UNCACHED_PHYS_0 */
193                 .virtual        = 0xff000000,
194                 .pfn            = __phys_to_pfn(0x00000000),
195                 .length         = 0x00100000,
196                 .type           = MT_DEVICE
197         }
198 };
199
200 void __init pxa_map_io(void)
201 {
202         iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
203         get_clk_frequency_khz(1);
204 }
205
206
207 static struct resource pxamci_resources[] = {
208         [0] = {
209                 .start  = 0x41100000,
210                 .end    = 0x41100fff,
211                 .flags  = IORESOURCE_MEM,
212         },
213         [1] = {
214                 .start  = IRQ_MMC,
215                 .end    = IRQ_MMC,
216                 .flags  = IORESOURCE_IRQ,
217         },
218 };
219
220 static u64 pxamci_dmamask = 0xffffffffUL;
221
222 struct platform_device pxa_device_mci = {
223         .name           = "pxa2xx-mci",
224         .id             = -1,
225         .dev            = {
226                 .dma_mask = &pxamci_dmamask,
227                 .coherent_dma_mask = 0xffffffff,
228         },
229         .num_resources  = ARRAY_SIZE(pxamci_resources),
230         .resource       = pxamci_resources,
231 };
232
233 void __init pxa_set_mci_info(struct pxamci_platform_data *info)
234 {
235         pxa_device_mci.dev.platform_data = info;
236 }
237
238
239 static struct pxa2xx_udc_mach_info pxa_udc_info;
240
241 void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
242 {
243         memcpy(&pxa_udc_info, info, sizeof *info);
244 }
245
246 static struct resource pxa2xx_udc_resources[] = {
247         [0] = {
248                 .start  = 0x40600000,
249                 .end    = 0x4060ffff,
250                 .flags  = IORESOURCE_MEM,
251         },
252         [1] = {
253                 .start  = IRQ_USB,
254                 .end    = IRQ_USB,
255                 .flags  = IORESOURCE_IRQ,
256         },
257 };
258
259 static u64 udc_dma_mask = ~(u32)0;
260
261 struct platform_device pxa_device_udc = {
262         .name           = "pxa2xx-udc",
263         .id             = -1,
264         .resource       = pxa2xx_udc_resources,
265         .num_resources  = ARRAY_SIZE(pxa2xx_udc_resources),
266         .dev            =  {
267                 .platform_data  = &pxa_udc_info,
268                 .dma_mask       = &udc_dma_mask,
269         }
270 };
271
272 static struct resource pxafb_resources[] = {
273         [0] = {
274                 .start  = 0x44000000,
275                 .end    = 0x4400ffff,
276                 .flags  = IORESOURCE_MEM,
277         },
278         [1] = {
279                 .start  = IRQ_LCD,
280                 .end    = IRQ_LCD,
281                 .flags  = IORESOURCE_IRQ,
282         },
283 };
284
285 static u64 fb_dma_mask = ~(u64)0;
286
287 struct platform_device pxa_device_fb = {
288         .name           = "pxa2xx-fb",
289         .id             = -1,
290         .dev            = {
291                 .dma_mask       = &fb_dma_mask,
292                 .coherent_dma_mask = 0xffffffff,
293         },
294         .num_resources  = ARRAY_SIZE(pxafb_resources),
295         .resource       = pxafb_resources,
296 };
297
298 void __init set_pxa_fb_info(struct pxafb_mach_info *info)
299 {
300         pxa_device_fb.dev.platform_data = info;
301 }
302
303 void __init set_pxa_fb_parent(struct device *parent_dev)
304 {
305         pxa_device_fb.dev.parent = parent_dev;
306 }
307
308 static struct resource pxa_resource_ffuart[] = {
309         {
310                 .start  = __PREG(FFUART),
311                 .end    = __PREG(FFUART) + 35,
312                 .flags  = IORESOURCE_MEM,
313         }, {
314                 .start  = IRQ_FFUART,
315                 .end    = IRQ_FFUART,
316                 .flags  = IORESOURCE_IRQ,
317         }
318 };
319
320 struct platform_device pxa_device_ffuart= {
321         .name           = "pxa2xx-uart",
322         .id             = 0,
323         .resource       = pxa_resource_ffuart,
324         .num_resources  = ARRAY_SIZE(pxa_resource_ffuart),
325 };
326
327 static struct resource pxa_resource_btuart[] = {
328         {
329                 .start  = __PREG(BTUART),
330                 .end    = __PREG(BTUART) + 35,
331                 .flags  = IORESOURCE_MEM,
332         }, {
333                 .start  = IRQ_BTUART,
334                 .end    = IRQ_BTUART,
335                 .flags  = IORESOURCE_IRQ,
336         }
337 };
338
339 struct platform_device pxa_device_btuart = {
340         .name           = "pxa2xx-uart",
341         .id             = 1,
342         .resource       = pxa_resource_btuart,
343         .num_resources  = ARRAY_SIZE(pxa_resource_btuart),
344 };
345
346 static struct resource pxa_resource_stuart[] = {
347         {
348                 .start  = __PREG(STUART),
349                 .end    = __PREG(STUART) + 35,
350                 .flags  = IORESOURCE_MEM,
351         }, {
352                 .start  = IRQ_STUART,
353                 .end    = IRQ_STUART,
354                 .flags  = IORESOURCE_IRQ,
355         }
356 };
357
358 struct platform_device pxa_device_stuart = {
359         .name           = "pxa2xx-uart",
360         .id             = 2,
361         .resource       = pxa_resource_stuart,
362         .num_resources  = ARRAY_SIZE(pxa_resource_stuart),
363 };
364
365 static struct resource pxa_resource_hwuart[] = {
366         {
367                 .start  = __PREG(HWUART),
368                 .end    = __PREG(HWUART) + 47,
369                 .flags  = IORESOURCE_MEM,
370         }, {
371                 .start  = IRQ_HWUART,
372                 .end    = IRQ_HWUART,
373                 .flags  = IORESOURCE_IRQ,
374         }
375 };
376
377 struct platform_device pxa_device_hwuart = {
378         .name           = "pxa2xx-uart",
379         .id             = 3,
380         .resource       = pxa_resource_hwuart,
381         .num_resources  = ARRAY_SIZE(pxa_resource_hwuart),
382 };
383
384 static struct resource pxai2c_resources[] = {
385         {
386                 .start  = 0x40301680,
387                 .end    = 0x403016a3,
388                 .flags  = IORESOURCE_MEM,
389         }, {
390                 .start  = IRQ_I2C,
391                 .end    = IRQ_I2C,
392                 .flags  = IORESOURCE_IRQ,
393         },
394 };
395
396 struct platform_device pxa_device_i2c = {
397         .name           = "pxa2xx-i2c",
398         .id             = 0,
399         .resource       = pxai2c_resources,
400         .num_resources  = ARRAY_SIZE(pxai2c_resources),
401 };
402
403 void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
404 {
405         pxa_device_i2c.dev.platform_data = info;
406 }
407
408 static struct resource pxai2s_resources[] = {
409         {
410                 .start  = 0x40400000,
411                 .end    = 0x40400083,
412                 .flags  = IORESOURCE_MEM,
413         }, {
414                 .start  = IRQ_I2S,
415                 .end    = IRQ_I2S,
416                 .flags  = IORESOURCE_IRQ,
417         },
418 };
419
420 struct platform_device pxa_device_i2s = {
421         .name           = "pxa2xx-i2s",
422         .id             = -1,
423         .resource       = pxai2s_resources,
424         .num_resources  = ARRAY_SIZE(pxai2s_resources),
425 };
426
427 static u64 pxaficp_dmamask = ~(u32)0;
428
429 struct platform_device pxa_device_ficp = {
430         .name           = "pxa2xx-ir",
431         .id             = -1,
432         .dev            = {
433                 .dma_mask = &pxaficp_dmamask,
434                 .coherent_dma_mask = 0xffffffff,
435         },
436 };
437
438 void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
439 {
440         pxa_device_ficp.dev.platform_data = info;
441 }
442
443 struct platform_device pxa_device_rtc = {
444         .name           = "sa1100-rtc",
445         .id             = -1,
446 };