diff options
Diffstat (limited to 'arch/arm/mach-imx/generic.c')
-rw-r--r-- | arch/arm/mach-imx/generic.c | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c new file mode 100644 index 000000000000..54377d0f578c --- /dev/null +++ b/arch/arm/mach-imx/generic.c | |||
@@ -0,0 +1,274 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-imx/generic.c | ||
3 | * | ||
4 | * author: Sascha Hauer | ||
5 | * Created: april 20th, 2004 | ||
6 | * Copyright: Synertronixx GmbH | ||
7 | * | ||
8 | * Common code for i.MX 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 as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | * | ||
24 | */ | ||
25 | #include <linux/device.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <asm/hardware.h> | ||
30 | |||
31 | #include <asm/mach/map.h> | ||
32 | |||
33 | void imx_gpio_mode(int gpio_mode) | ||
34 | { | ||
35 | unsigned int pin = gpio_mode & GPIO_PIN_MASK; | ||
36 | unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> 5; | ||
37 | unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> 10; | ||
38 | unsigned int tmp; | ||
39 | |||
40 | /* Pullup enable */ | ||
41 | if(gpio_mode & GPIO_PUEN) | ||
42 | PUEN(port) |= (1<<pin); | ||
43 | else | ||
44 | PUEN(port) &= ~(1<<pin); | ||
45 | |||
46 | /* Data direction */ | ||
47 | if(gpio_mode & GPIO_OUT) | ||
48 | DDIR(port) |= 1<<pin; | ||
49 | else | ||
50 | DDIR(port) &= ~(1<<pin); | ||
51 | |||
52 | /* Primary / alternate function */ | ||
53 | if(gpio_mode & GPIO_AF) | ||
54 | GPR(port) |= (1<<pin); | ||
55 | else | ||
56 | GPR(port) &= ~(1<<pin); | ||
57 | |||
58 | /* use as gpio? */ | ||
59 | if( ocr == 3 ) | ||
60 | GIUS(port) |= (1<<pin); | ||
61 | else | ||
62 | GIUS(port) &= ~(1<<pin); | ||
63 | |||
64 | /* Output / input configuration */ | ||
65 | /* FIXME: I'm not very sure about OCR and ICONF, someone | ||
66 | * should have a look over it | ||
67 | */ | ||
68 | if(pin<16) { | ||
69 | tmp = OCR1(port); | ||
70 | tmp &= ~( 3<<(pin*2)); | ||
71 | tmp |= (ocr << (pin*2)); | ||
72 | OCR1(port) = tmp; | ||
73 | |||
74 | if( gpio_mode & GPIO_AOUT ) | ||
75 | ICONFA1(port) &= ~( 3<<(pin*2)); | ||
76 | if( gpio_mode & GPIO_BOUT ) | ||
77 | ICONFB1(port) &= ~( 3<<(pin*2)); | ||
78 | } else { | ||
79 | tmp = OCR2(port); | ||
80 | tmp &= ~( 3<<((pin-16)*2)); | ||
81 | tmp |= (ocr << ((pin-16)*2)); | ||
82 | OCR2(port) = tmp; | ||
83 | |||
84 | if( gpio_mode & GPIO_AOUT ) | ||
85 | ICONFA2(port) &= ~( 3<<((pin-16)*2)); | ||
86 | if( gpio_mode & GPIO_BOUT ) | ||
87 | ICONFB2(port) &= ~( 3<<((pin-16)*2)); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | EXPORT_SYMBOL(imx_gpio_mode); | ||
92 | |||
93 | /* | ||
94 | * get the system pll clock in Hz | ||
95 | * | ||
96 | * mfi + mfn / (mfd +1) | ||
97 | * f = 2 * f_ref * -------------------- | ||
98 | * pd + 1 | ||
99 | */ | ||
100 | static unsigned int imx_decode_pll(unsigned int pll) | ||
101 | { | ||
102 | u32 mfi = (pll >> 10) & 0xf; | ||
103 | u32 mfn = pll & 0x3ff; | ||
104 | u32 mfd = (pll >> 16) & 0x3ff; | ||
105 | u32 pd = (pll >> 26) & 0xf; | ||
106 | u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512); | ||
107 | |||
108 | mfi = mfi <= 5 ? 5 : mfi; | ||
109 | |||
110 | return (2 * (f_ref>>10) * ( (mfi<<10) + (mfn<<10) / (mfd+1) )) / (pd+1); | ||
111 | } | ||
112 | |||
113 | unsigned int imx_get_system_clk(void) | ||
114 | { | ||
115 | return imx_decode_pll(SPCTL0); | ||
116 | } | ||
117 | EXPORT_SYMBOL(imx_get_system_clk); | ||
118 | |||
119 | unsigned int imx_get_mcu_clk(void) | ||
120 | { | ||
121 | return imx_decode_pll(MPCTL0); | ||
122 | } | ||
123 | EXPORT_SYMBOL(imx_get_mcu_clk); | ||
124 | |||
125 | /* | ||
126 | * get peripheral clock 1 ( UART[12], Timer[12], PWM ) | ||
127 | */ | ||
128 | unsigned int imx_get_perclk1(void) | ||
129 | { | ||
130 | return imx_get_system_clk() / (((PCDR) & 0xf)+1); | ||
131 | } | ||
132 | EXPORT_SYMBOL(imx_get_perclk1); | ||
133 | |||
134 | /* | ||
135 | * get peripheral clock 2 ( LCD, SD, SPI[12] ) | ||
136 | */ | ||
137 | unsigned int imx_get_perclk2(void) | ||
138 | { | ||
139 | return imx_get_system_clk() / (((PCDR>>4) & 0xf)+1); | ||
140 | } | ||
141 | EXPORT_SYMBOL(imx_get_perclk2); | ||
142 | |||
143 | /* | ||
144 | * get peripheral clock 3 ( SSI ) | ||
145 | */ | ||
146 | unsigned int imx_get_perclk3(void) | ||
147 | { | ||
148 | return imx_get_system_clk() / (((PCDR>>16) & 0x7f)+1); | ||
149 | } | ||
150 | EXPORT_SYMBOL(imx_get_perclk3); | ||
151 | |||
152 | /* | ||
153 | * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA ) | ||
154 | */ | ||
155 | unsigned int imx_get_hclk(void) | ||
156 | { | ||
157 | return imx_get_system_clk() / (((CSCR>>10) & 0xf)+1); | ||
158 | } | ||
159 | EXPORT_SYMBOL(imx_get_hclk); | ||
160 | |||
161 | static struct resource imx_mmc_resources[] = { | ||
162 | [0] = { | ||
163 | .start = 0x00214000, | ||
164 | .end = 0x002140FF, | ||
165 | .flags = IORESOURCE_MEM, | ||
166 | }, | ||
167 | [1] = { | ||
168 | .start = (SDHC_INT), | ||
169 | .end = (SDHC_INT), | ||
170 | .flags = IORESOURCE_IRQ, | ||
171 | }, | ||
172 | }; | ||
173 | |||
174 | static struct platform_device imx_mmc_device = { | ||
175 | .name = "imx-mmc", | ||
176 | .id = 0, | ||
177 | .num_resources = ARRAY_SIZE(imx_mmc_resources), | ||
178 | .resource = imx_mmc_resources, | ||
179 | }; | ||
180 | |||
181 | static struct resource imx_uart1_resources[] = { | ||
182 | [0] = { | ||
183 | .start = 0x00206000, | ||
184 | .end = 0x002060FF, | ||
185 | .flags = IORESOURCE_MEM, | ||
186 | }, | ||
187 | [1] = { | ||
188 | .start = (UART1_MINT_RX), | ||
189 | .end = (UART1_MINT_RX), | ||
190 | .flags = IORESOURCE_IRQ, | ||
191 | }, | ||
192 | [2] = { | ||
193 | .start = (UART1_MINT_TX), | ||
194 | .end = (UART1_MINT_TX), | ||
195 | .flags = IORESOURCE_IRQ, | ||
196 | }, | ||
197 | }; | ||
198 | |||
199 | static struct platform_device imx_uart1_device = { | ||
200 | .name = "imx-uart", | ||
201 | .id = 0, | ||
202 | .num_resources = ARRAY_SIZE(imx_uart1_resources), | ||
203 | .resource = imx_uart1_resources, | ||
204 | }; | ||
205 | |||
206 | static struct resource imx_uart2_resources[] = { | ||
207 | [0] = { | ||
208 | .start = 0x00207000, | ||
209 | .end = 0x002070FF, | ||
210 | .flags = IORESOURCE_MEM, | ||
211 | }, | ||
212 | [1] = { | ||
213 | .start = (UART2_MINT_RX), | ||
214 | .end = (UART2_MINT_RX), | ||
215 | .flags = IORESOURCE_IRQ, | ||
216 | }, | ||
217 | [2] = { | ||
218 | .start = (UART2_MINT_TX), | ||
219 | .end = (UART2_MINT_TX), | ||
220 | .flags = IORESOURCE_IRQ, | ||
221 | }, | ||
222 | }; | ||
223 | |||
224 | static struct platform_device imx_uart2_device = { | ||
225 | .name = "imx-uart", | ||
226 | .id = 1, | ||
227 | .num_resources = ARRAY_SIZE(imx_uart2_resources), | ||
228 | .resource = imx_uart2_resources, | ||
229 | }; | ||
230 | |||
231 | static struct resource imxfb_resources[] = { | ||
232 | [0] = { | ||
233 | .start = 0x00205000, | ||
234 | .end = 0x002050FF, | ||
235 | .flags = IORESOURCE_MEM, | ||
236 | }, | ||
237 | [1] = { | ||
238 | .start = LCDC_INT, | ||
239 | .end = LCDC_INT, | ||
240 | .flags = IORESOURCE_IRQ, | ||
241 | }, | ||
242 | }; | ||
243 | |||
244 | static struct platform_device imxfb_device = { | ||
245 | .name = "imx-fb", | ||
246 | .id = 0, | ||
247 | .num_resources = ARRAY_SIZE(imxfb_resources), | ||
248 | .resource = imxfb_resources, | ||
249 | }; | ||
250 | |||
251 | static struct platform_device *devices[] __initdata = { | ||
252 | &imx_mmc_device, | ||
253 | &imxfb_device, | ||
254 | &imx_uart1_device, | ||
255 | &imx_uart2_device, | ||
256 | }; | ||
257 | |||
258 | static struct map_desc imx_io_desc[] __initdata = { | ||
259 | /* virtual physical length type */ | ||
260 | {IMX_IO_BASE, IMX_IO_PHYS, IMX_IO_SIZE, MT_DEVICE}, | ||
261 | }; | ||
262 | |||
263 | void __init | ||
264 | imx_map_io(void) | ||
265 | { | ||
266 | iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc)); | ||
267 | } | ||
268 | |||
269 | static int __init imx_init(void) | ||
270 | { | ||
271 | return platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
272 | } | ||
273 | |||
274 | subsys_initcall(imx_init); | ||