aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa/generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-pxa/generic.c')
-rw-r--r--arch/arm/mach-pxa/generic.c184
1 files changed, 125 insertions, 59 deletions
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 5510f6fdce55..1c34946ee16e 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -25,10 +25,6 @@
25#include <linux/pm.h> 25#include <linux/pm.h>
26#include <linux/string.h> 26#include <linux/string.h>
27 27
28#include <linux/sched.h>
29#include <asm/cnt32_to_63.h>
30#include <asm/div64.h>
31
32#include <asm/hardware.h> 28#include <asm/hardware.h>
33#include <asm/irq.h> 29#include <asm/irq.h>
34#include <asm/system.h> 30#include <asm/system.h>
@@ -47,66 +43,39 @@
47#include "generic.h" 43#include "generic.h"
48 44
49/* 45/*
50 * This is the PXA2xx sched_clock implementation. This has a resolution 46 * Get the clock frequency as reflected by CCCR and the turbo flag.
51 * of at least 308ns and a maximum value that depends on the value of 47 * We assume these values have been applied via a fcs.
52 * CLOCK_TICK_RATE. 48 * If info is not 0 we also display the current settings.
53 *
54 * The return value is guaranteed to be monotonic in that range as
55 * long as there is always less than 582 seconds between successive
56 * calls to this function.
57 */ 49 */
58unsigned long long sched_clock(void) 50unsigned int get_clk_frequency_khz(int info)
59{ 51{
60 unsigned long long v = cnt32_to_63(OSCR); 52 if (cpu_is_pxa21x() || cpu_is_pxa25x())
61 /* Note: top bit ov v needs cleared unless multiplier is even. */ 53 return pxa25x_get_clk_frequency_khz(info);
62 54 else if (cpu_is_pxa27x())
63#if CLOCK_TICK_RATE == 3686400 55 return pxa27x_get_clk_frequency_khz(info);
64 /* 1E9 / 3686400 => 78125 / 288, max value = 32025597s (370 days). */ 56 else
65 /* The <<1 is used to get rid of tick.hi top bit */ 57 return pxa3xx_get_clk_frequency_khz(info);
66 v *= 78125<<1; 58}
67 do_div(v, 288<<1); 59EXPORT_SYMBOL(get_clk_frequency_khz);
68#elif CLOCK_TICK_RATE == 3250000
69 /* 1E9 / 3250000 => 4000 / 13, max value = 709490156s (8211 days) */
70 v *= 4000;
71 do_div(v, 13);
72#elif CLOCK_TICK_RATE == 3249600
73 /* 1E9 / 3249600 => 625000 / 2031, max value = 4541295s (52 days) */
74 v *= 625000;
75 do_div(v, 2031);
76#else
77#warning "consider fixing sched_clock for your value of CLOCK_TICK_RATE"
78 /*
79 * 96-bit math to perform tick * NSEC_PER_SEC / CLOCK_TICK_RATE for
80 * any value of CLOCK_TICK_RATE. Max value is in the 80 thousand
81 * years range and truncation to unsigned long long limits it to
82 * sched_clock's max range of ~584 years. This is nice but with
83 * higher computation cost.
84 */
85 {
86 union {
87 unsigned long long val;
88 struct { unsigned long lo, hi; };
89 } x;
90 unsigned long long y;
91
92 x.val = v;
93 x.hi &= 0x7fffffff;
94 y = (unsigned long long)x.lo * NSEC_PER_SEC;
95 x.lo = y;
96 y = (y >> 32) + (unsigned long long)x.hi * NSEC_PER_SEC;
97 x.hi = do_div(y, CLOCK_TICK_RATE);
98 do_div(x.val, CLOCK_TICK_RATE);
99 x.hi += y;
100 v = x.val;
101 }
102#endif
103 60
104 return v; 61/*
62 * Return the current memory clock frequency in units of 10kHz
63 */
64unsigned int get_memclk_frequency_10khz(void)
65{
66 if (cpu_is_pxa21x() || cpu_is_pxa25x())
67 return pxa25x_get_memclk_frequency_10khz();
68 else if (cpu_is_pxa27x())
69 return pxa27x_get_memclk_frequency_10khz();
70 else
71 return pxa3xx_get_memclk_frequency_10khz();
105} 72}
73EXPORT_SYMBOL(get_memclk_frequency_10khz);
106 74
107/* 75/*
108 * Handy function to set GPIO alternate functions 76 * Handy function to set GPIO alternate functions
109 */ 77 */
78int pxa_last_gpio;
110 79
111int pxa_gpio_mode(int gpio_mode) 80int pxa_gpio_mode(int gpio_mode)
112{ 81{
@@ -115,7 +84,7 @@ int pxa_gpio_mode(int gpio_mode)
115 int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; 84 int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
116 int gafr; 85 int gafr;
117 86
118 if (gpio > PXA_LAST_GPIO) 87 if (gpio > pxa_last_gpio)
119 return -EINVAL; 88 return -EINVAL;
120 89
121 local_irq_save(flags); 90 local_irq_save(flags);
@@ -136,6 +105,44 @@ int pxa_gpio_mode(int gpio_mode)
136 105
137EXPORT_SYMBOL(pxa_gpio_mode); 106EXPORT_SYMBOL(pxa_gpio_mode);
138 107
108int gpio_direction_input(unsigned gpio)
109{
110 unsigned long flags;
111 u32 mask;
112
113 if (gpio > pxa_last_gpio)
114 return -EINVAL;
115
116 mask = GPIO_bit(gpio);
117 local_irq_save(flags);
118 GPDR(gpio) &= ~mask;
119 local_irq_restore(flags);
120
121 return 0;
122}
123EXPORT_SYMBOL(gpio_direction_input);
124
125int gpio_direction_output(unsigned gpio, int value)
126{
127 unsigned long flags;
128 u32 mask;
129
130 if (gpio > pxa_last_gpio)
131 return -EINVAL;
132
133 mask = GPIO_bit(gpio);
134 local_irq_save(flags);
135 if (value)
136 GPSR(gpio) = mask;
137 else
138 GPCR(gpio) = mask;
139 GPDR(gpio) |= mask;
140 local_irq_restore(flags);
141
142 return 0;
143}
144EXPORT_SYMBOL(gpio_direction_output);
145
139/* 146/*
140 * Return GPIO level 147 * Return GPIO level
141 */ 148 */
@@ -159,7 +166,7 @@ EXPORT_SYMBOL(pxa_gpio_set_value);
159/* 166/*
160 * Routine to safely enable or disable a clock in the CKEN 167 * Routine to safely enable or disable a clock in the CKEN
161 */ 168 */
162void pxa_set_cken(int clock, int enable) 169void __pxa_set_cken(int clock, int enable)
163{ 170{
164 unsigned long flags; 171 unsigned long flags;
165 local_irq_save(flags); 172 local_irq_save(flags);
@@ -172,7 +179,7 @@ void pxa_set_cken(int clock, int enable)
172 local_irq_restore(flags); 179 local_irq_restore(flags);
173} 180}
174 181
175EXPORT_SYMBOL(pxa_set_cken); 182EXPORT_SYMBOL(__pxa_set_cken);
176 183
177/* 184/*
178 * Intel PXA2xx internal register mapping. 185 * Intel PXA2xx internal register mapping.
@@ -329,21 +336,80 @@ void __init set_pxa_fb_parent(struct device *parent_dev)
329 pxa_device_fb.dev.parent = parent_dev; 336 pxa_device_fb.dev.parent = parent_dev;
330} 337}
331 338
339static struct resource pxa_resource_ffuart[] = {
340 {
341 .start = __PREG(FFUART),
342 .end = __PREG(FFUART) + 35,
343 .flags = IORESOURCE_MEM,
344 }, {
345 .start = IRQ_FFUART,
346 .end = IRQ_FFUART,
347 .flags = IORESOURCE_IRQ,
348 }
349};
350
332struct platform_device pxa_device_ffuart= { 351struct platform_device pxa_device_ffuart= {
333 .name = "pxa2xx-uart", 352 .name = "pxa2xx-uart",
334 .id = 0, 353 .id = 0,
354 .resource = pxa_resource_ffuart,
355 .num_resources = ARRAY_SIZE(pxa_resource_ffuart),
335}; 356};
357
358static struct resource pxa_resource_btuart[] = {
359 {
360 .start = __PREG(BTUART),
361 .end = __PREG(BTUART) + 35,
362 .flags = IORESOURCE_MEM,
363 }, {
364 .start = IRQ_BTUART,
365 .end = IRQ_BTUART,
366 .flags = IORESOURCE_IRQ,
367 }
368};
369
336struct platform_device pxa_device_btuart = { 370struct platform_device pxa_device_btuart = {
337 .name = "pxa2xx-uart", 371 .name = "pxa2xx-uart",
338 .id = 1, 372 .id = 1,
373 .resource = pxa_resource_btuart,
374 .num_resources = ARRAY_SIZE(pxa_resource_btuart),
339}; 375};
376
377static struct resource pxa_resource_stuart[] = {
378 {
379 .start = __PREG(STUART),
380 .end = __PREG(STUART) + 35,
381 .flags = IORESOURCE_MEM,
382 }, {
383 .start = IRQ_STUART,
384 .end = IRQ_STUART,
385 .flags = IORESOURCE_IRQ,
386 }
387};
388
340struct platform_device pxa_device_stuart = { 389struct platform_device pxa_device_stuart = {
341 .name = "pxa2xx-uart", 390 .name = "pxa2xx-uart",
342 .id = 2, 391 .id = 2,
392 .resource = pxa_resource_stuart,
393 .num_resources = ARRAY_SIZE(pxa_resource_stuart),
343}; 394};
395
396static struct resource pxa_resource_hwuart[] = {
397 {
398 .start = __PREG(HWUART),
399 .end = __PREG(HWUART) + 47,
400 .flags = IORESOURCE_MEM,
401 }, {
402 .start = IRQ_HWUART,
403 .end = IRQ_HWUART,
404 .flags = IORESOURCE_IRQ,
405 }
406};
407
344struct platform_device pxa_device_hwuart = { 408struct platform_device pxa_device_hwuart = {
345 .name = "pxa2xx-uart", 409 .name = "pxa2xx-uart",
346 .id = 3, 410 .id = 3,
411 .resource = pxa_resource_hwuart,
412 .num_resources = ARRAY_SIZE(pxa_resource_hwuart),
347}; 413};
348 414
349static struct resource pxai2c_resources[] = { 415static struct resource pxai2c_resources[] = {