bc4e814e |
1 | /* |
2 | * arch/arm/mach-spear3xx/spear300.c |
3 | * |
4 | * SPEAr300 machine source file |
5 | * |
6 | * Copyright (C) 2009 ST Microelectronics |
7 | * Viresh Kumar<viresh.kumar@st.com> |
8 | * |
9 | * This file is licensed under the terms of the GNU General Public |
10 | * License version 2. This program is licensed "as is" without any |
11 | * warranty of any kind, whether express or implied. |
12 | */ |
13 | |
14 | #include <linux/types.h> |
15 | #include <linux/amba/pl061.h> |
16 | #include <linux/ptrace.h> |
17 | #include <asm/irq.h> |
18 | #include <mach/generic.h> |
19 | #include <mach/spear.h> |
4c18e77f |
20 | #include <plat/shirq.h> |
bc4e814e |
21 | |
70f4c0bf |
22 | /* pad multiplexing support */ |
23 | /* muxing registers */ |
24 | #define PAD_MUX_CONFIG_REG 0x00 |
25 | #define MODE_CONFIG_REG 0x04 |
26 | |
27 | /* modes */ |
28 | #define NAND_MODE (1 << 0) |
29 | #define NOR_MODE (1 << 1) |
30 | #define PHOTO_FRAME_MODE (1 << 2) |
31 | #define LEND_IP_PHONE_MODE (1 << 3) |
32 | #define HEND_IP_PHONE_MODE (1 << 4) |
33 | #define LEND_WIFI_PHONE_MODE (1 << 5) |
34 | #define HEND_WIFI_PHONE_MODE (1 << 6) |
35 | #define ATA_PABX_WI2S_MODE (1 << 7) |
36 | #define ATA_PABX_I2S_MODE (1 << 8) |
37 | #define CAML_LCDW_MODE (1 << 9) |
38 | #define CAMU_LCD_MODE (1 << 10) |
39 | #define CAMU_WLCD_MODE (1 << 11) |
40 | #define CAML_LCD_MODE (1 << 12) |
41 | #define ALL_MODES 0x1FFF |
42 | |
43 | struct pmx_mode nand_mode = { |
44 | .id = NAND_MODE, |
45 | .name = "nand mode", |
46 | .mask = 0x00, |
47 | }; |
48 | |
49 | struct pmx_mode nor_mode = { |
50 | .id = NOR_MODE, |
51 | .name = "nor mode", |
52 | .mask = 0x01, |
53 | }; |
54 | |
55 | struct pmx_mode photo_frame_mode = { |
56 | .id = PHOTO_FRAME_MODE, |
57 | .name = "photo frame mode", |
58 | .mask = 0x02, |
59 | }; |
60 | |
61 | struct pmx_mode lend_ip_phone_mode = { |
62 | .id = LEND_IP_PHONE_MODE, |
63 | .name = "lend ip phone mode", |
64 | .mask = 0x03, |
65 | }; |
66 | |
67 | struct pmx_mode hend_ip_phone_mode = { |
68 | .id = HEND_IP_PHONE_MODE, |
69 | .name = "hend ip phone mode", |
70 | .mask = 0x04, |
71 | }; |
72 | |
73 | struct pmx_mode lend_wifi_phone_mode = { |
74 | .id = LEND_WIFI_PHONE_MODE, |
75 | .name = "lend wifi phone mode", |
76 | .mask = 0x05, |
77 | }; |
78 | |
79 | struct pmx_mode hend_wifi_phone_mode = { |
80 | .id = HEND_WIFI_PHONE_MODE, |
81 | .name = "hend wifi phone mode", |
82 | .mask = 0x06, |
83 | }; |
84 | |
85 | struct pmx_mode ata_pabx_wi2s_mode = { |
86 | .id = ATA_PABX_WI2S_MODE, |
87 | .name = "ata pabx wi2s mode", |
88 | .mask = 0x07, |
89 | }; |
90 | |
91 | struct pmx_mode ata_pabx_i2s_mode = { |
92 | .id = ATA_PABX_I2S_MODE, |
93 | .name = "ata pabx i2s mode", |
94 | .mask = 0x08, |
95 | }; |
96 | |
97 | struct pmx_mode caml_lcdw_mode = { |
98 | .id = CAML_LCDW_MODE, |
99 | .name = "caml lcdw mode", |
100 | .mask = 0x0C, |
101 | }; |
102 | |
103 | struct pmx_mode camu_lcd_mode = { |
104 | .id = CAMU_LCD_MODE, |
105 | .name = "camu lcd mode", |
106 | .mask = 0x0D, |
107 | }; |
108 | |
109 | struct pmx_mode camu_wlcd_mode = { |
110 | .id = CAMU_WLCD_MODE, |
111 | .name = "camu wlcd mode", |
112 | .mask = 0x0E, |
113 | }; |
114 | |
115 | struct pmx_mode caml_lcd_mode = { |
116 | .id = CAML_LCD_MODE, |
117 | .name = "caml lcd mode", |
118 | .mask = 0x0F, |
119 | }; |
120 | |
121 | /* devices */ |
122 | struct pmx_dev_mode pmx_fsmc_2_chips_modes[] = { |
123 | { |
124 | .ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE | |
125 | ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE, |
126 | .mask = PMX_FIRDA_MASK, |
127 | }, |
128 | }; |
129 | |
130 | struct pmx_dev pmx_fsmc_2_chips = { |
131 | .name = "fsmc_2_chips", |
132 | .modes = pmx_fsmc_2_chips_modes, |
133 | .mode_count = ARRAY_SIZE(pmx_fsmc_2_chips_modes), |
134 | .enb_on_reset = 1, |
135 | }; |
136 | |
137 | struct pmx_dev_mode pmx_fsmc_4_chips_modes[] = { |
138 | { |
139 | .ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE | |
140 | ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE, |
141 | .mask = PMX_FIRDA_MASK | PMX_UART0_MASK, |
142 | }, |
143 | }; |
144 | |
145 | struct pmx_dev pmx_fsmc_4_chips = { |
146 | .name = "fsmc_4_chips", |
147 | .modes = pmx_fsmc_4_chips_modes, |
148 | .mode_count = ARRAY_SIZE(pmx_fsmc_4_chips_modes), |
149 | .enb_on_reset = 1, |
150 | }; |
151 | |
152 | struct pmx_dev_mode pmx_keyboard_modes[] = { |
153 | { |
154 | .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE | |
155 | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE | |
156 | CAML_LCDW_MODE | CAMU_LCD_MODE | CAMU_WLCD_MODE | |
157 | CAML_LCD_MODE, |
158 | .mask = 0x0, |
159 | }, |
160 | }; |
161 | |
162 | struct pmx_dev pmx_keyboard = { |
163 | .name = "keyboard", |
164 | .modes = pmx_keyboard_modes, |
165 | .mode_count = ARRAY_SIZE(pmx_keyboard_modes), |
166 | .enb_on_reset = 1, |
167 | }; |
168 | |
169 | struct pmx_dev_mode pmx_clcd_modes[] = { |
170 | { |
171 | .ids = PHOTO_FRAME_MODE, |
172 | .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK , |
173 | }, { |
174 | .ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE | |
175 | CAMU_LCD_MODE | CAML_LCD_MODE, |
176 | .mask = PMX_TIMER_3_4_MASK, |
177 | }, |
178 | }; |
179 | |
180 | struct pmx_dev pmx_clcd = { |
181 | .name = "clcd", |
182 | .modes = pmx_clcd_modes, |
183 | .mode_count = ARRAY_SIZE(pmx_clcd_modes), |
184 | .enb_on_reset = 1, |
185 | }; |
186 | |
187 | struct pmx_dev_mode pmx_telecom_gpio_modes[] = { |
188 | { |
189 | .ids = PHOTO_FRAME_MODE | CAMU_LCD_MODE | CAML_LCD_MODE, |
190 | .mask = PMX_MII_MASK, |
191 | }, { |
192 | .ids = LEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE, |
193 | .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK, |
194 | }, { |
195 | .ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_WLCD_MODE, |
196 | .mask = PMX_MII_MASK | PMX_TIMER_3_4_MASK, |
197 | }, { |
198 | .ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE, |
199 | .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK, |
200 | }, { |
201 | .ids = ATA_PABX_WI2S_MODE, |
202 | .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK |
203 | | PMX_UART0_MODEM_MASK, |
204 | }, |
205 | }; |
206 | |
207 | struct pmx_dev pmx_telecom_gpio = { |
208 | .name = "telecom_gpio", |
209 | .modes = pmx_telecom_gpio_modes, |
210 | .mode_count = ARRAY_SIZE(pmx_telecom_gpio_modes), |
211 | .enb_on_reset = 1, |
212 | }; |
213 | |
214 | struct pmx_dev_mode pmx_telecom_tdm_modes[] = { |
215 | { |
216 | .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | |
217 | HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
218 | | HEND_WIFI_PHONE_MODE | ATA_PABX_WI2S_MODE |
219 | | ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
220 | | CAMU_WLCD_MODE | CAML_LCD_MODE, |
221 | .mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK, |
222 | }, |
223 | }; |
224 | |
225 | struct pmx_dev pmx_telecom_tdm = { |
226 | .name = "telecom_tdm", |
227 | .modes = pmx_telecom_tdm_modes, |
228 | .mode_count = ARRAY_SIZE(pmx_telecom_tdm_modes), |
229 | .enb_on_reset = 1, |
230 | }; |
231 | |
232 | struct pmx_dev_mode pmx_telecom_spi_cs_i2c_clk_modes[] = { |
233 | { |
234 | .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE | |
235 | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
236 | | ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE | |
237 | CAML_LCDW_MODE | CAML_LCD_MODE, |
238 | .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK, |
239 | }, |
240 | }; |
241 | |
242 | struct pmx_dev pmx_telecom_spi_cs_i2c_clk = { |
243 | .name = "telecom_spi_cs_i2c_clk", |
244 | .modes = pmx_telecom_spi_cs_i2c_clk_modes, |
245 | .mode_count = ARRAY_SIZE(pmx_telecom_spi_cs_i2c_clk_modes), |
246 | .enb_on_reset = 1, |
247 | }; |
248 | |
249 | struct pmx_dev_mode pmx_telecom_camera_modes[] = { |
250 | { |
251 | .ids = CAML_LCDW_MODE | CAML_LCD_MODE, |
252 | .mask = PMX_MII_MASK, |
253 | }, { |
254 | .ids = CAMU_LCD_MODE | CAMU_WLCD_MODE, |
255 | .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK | PMX_MII_MASK, |
256 | }, |
257 | }; |
258 | |
259 | struct pmx_dev pmx_telecom_camera = { |
260 | .name = "telecom_camera", |
261 | .modes = pmx_telecom_camera_modes, |
262 | .mode_count = ARRAY_SIZE(pmx_telecom_camera_modes), |
263 | .enb_on_reset = 1, |
264 | }; |
265 | |
266 | struct pmx_dev_mode pmx_telecom_dac_modes[] = { |
267 | { |
268 | .ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
269 | | CAMU_WLCD_MODE | CAML_LCD_MODE, |
270 | .mask = PMX_TIMER_1_2_MASK, |
271 | }, |
272 | }; |
273 | |
274 | struct pmx_dev pmx_telecom_dac = { |
275 | .name = "telecom_dac", |
276 | .modes = pmx_telecom_dac_modes, |
277 | .mode_count = ARRAY_SIZE(pmx_telecom_dac_modes), |
278 | .enb_on_reset = 1, |
279 | }; |
280 | |
281 | struct pmx_dev_mode pmx_telecom_i2s_modes[] = { |
282 | { |
283 | .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
284 | | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE | |
285 | ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
286 | | CAMU_WLCD_MODE | CAML_LCD_MODE, |
287 | .mask = PMX_UART0_MODEM_MASK, |
288 | }, |
289 | }; |
290 | |
291 | struct pmx_dev pmx_telecom_i2s = { |
292 | .name = "telecom_i2s", |
293 | .modes = pmx_telecom_i2s_modes, |
294 | .mode_count = ARRAY_SIZE(pmx_telecom_i2s_modes), |
295 | .enb_on_reset = 1, |
296 | }; |
297 | |
298 | struct pmx_dev_mode pmx_telecom_boot_pins_modes[] = { |
299 | { |
300 | .ids = NAND_MODE | NOR_MODE, |
301 | .mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK | |
302 | PMX_TIMER_3_4_MASK, |
303 | }, |
304 | }; |
305 | |
306 | struct pmx_dev pmx_telecom_boot_pins = { |
307 | .name = "telecom_boot_pins", |
308 | .modes = pmx_telecom_boot_pins_modes, |
309 | .mode_count = ARRAY_SIZE(pmx_telecom_boot_pins_modes), |
310 | .enb_on_reset = 1, |
311 | }; |
312 | |
313 | struct pmx_dev_mode pmx_telecom_sdio_4bit_modes[] = { |
314 | { |
315 | .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | |
316 | HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE | |
317 | HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE | |
318 | CAMU_WLCD_MODE | CAML_LCD_MODE | ATA_PABX_WI2S_MODE | |
319 | ATA_PABX_I2S_MODE, |
320 | .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK | |
321 | PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK | |
322 | PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK, |
323 | }, |
324 | }; |
325 | |
326 | struct pmx_dev pmx_telecom_sdio_4bit = { |
327 | .name = "telecom_sdio_4bit", |
328 | .modes = pmx_telecom_sdio_4bit_modes, |
329 | .mode_count = ARRAY_SIZE(pmx_telecom_sdio_4bit_modes), |
330 | .enb_on_reset = 1, |
331 | }; |
332 | |
333 | struct pmx_dev_mode pmx_telecom_sdio_8bit_modes[] = { |
334 | { |
335 | .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | |
336 | HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE | |
337 | HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE | |
338 | CAMU_WLCD_MODE | CAML_LCD_MODE, |
339 | .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK | |
340 | PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK | |
341 | PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK, |
342 | }, |
343 | }; |
344 | |
345 | struct pmx_dev pmx_telecom_sdio_8bit = { |
346 | .name = "telecom_sdio_8bit", |
347 | .modes = pmx_telecom_sdio_8bit_modes, |
348 | .mode_count = ARRAY_SIZE(pmx_telecom_sdio_8bit_modes), |
349 | .enb_on_reset = 1, |
350 | }; |
351 | |
352 | struct pmx_dev_mode pmx_gpio1_modes[] = { |
353 | { |
354 | .ids = PHOTO_FRAME_MODE, |
355 | .mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK | |
356 | PMX_TIMER_3_4_MASK, |
357 | }, |
358 | }; |
359 | |
360 | struct pmx_dev pmx_gpio1 = { |
361 | .name = "arm gpio1", |
362 | .modes = pmx_gpio1_modes, |
363 | .mode_count = ARRAY_SIZE(pmx_gpio1_modes), |
364 | .enb_on_reset = 1, |
365 | }; |
366 | |
367 | /* pmx driver structure */ |
368 | struct pmx_driver pmx_driver = { |
369 | .mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x0000000f}, |
370 | .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff}, |
371 | }; |
372 | |
bc4e814e |
373 | /* Add spear300 specific devices here */ |
374 | /* arm gpio1 device registeration */ |
375 | static struct pl061_platform_data gpio1_plat_data = { |
376 | .gpio_base = 8, |
377 | .irq_base = SPEAR_GPIO1_INT_BASE, |
378 | }; |
379 | |
380 | struct amba_device gpio1_device = { |
381 | .dev = { |
382 | .init_name = "gpio1", |
383 | .platform_data = &gpio1_plat_data, |
384 | }, |
385 | .res = { |
386 | .start = SPEAR300_GPIO_BASE, |
387 | .end = SPEAR300_GPIO_BASE + SPEAR300_GPIO_SIZE - 1, |
388 | .flags = IORESOURCE_MEM, |
389 | }, |
4c18e77f |
390 | .irq = {VIRQ_GPIO1, NO_IRQ}, |
391 | }; |
392 | |
393 | /* spear3xx shared irq */ |
394 | struct shirq_dev_config shirq_ras1_config[] = { |
395 | { |
396 | .virq = VIRQ_IT_PERS_S, |
397 | .enb_mask = IT_PERS_S_IRQ_MASK, |
398 | .status_mask = IT_PERS_S_IRQ_MASK, |
399 | }, { |
400 | .virq = VIRQ_IT_CHANGE_S, |
401 | .enb_mask = IT_CHANGE_S_IRQ_MASK, |
402 | .status_mask = IT_CHANGE_S_IRQ_MASK, |
403 | }, { |
404 | .virq = VIRQ_I2S, |
405 | .enb_mask = I2S_IRQ_MASK, |
406 | .status_mask = I2S_IRQ_MASK, |
407 | }, { |
408 | .virq = VIRQ_TDM, |
409 | .enb_mask = TDM_IRQ_MASK, |
410 | .status_mask = TDM_IRQ_MASK, |
411 | }, { |
412 | .virq = VIRQ_CAMERA_L, |
413 | .enb_mask = CAMERA_L_IRQ_MASK, |
414 | .status_mask = CAMERA_L_IRQ_MASK, |
415 | }, { |
416 | .virq = VIRQ_CAMERA_F, |
417 | .enb_mask = CAMERA_F_IRQ_MASK, |
418 | .status_mask = CAMERA_F_IRQ_MASK, |
419 | }, { |
420 | .virq = VIRQ_CAMERA_V, |
421 | .enb_mask = CAMERA_V_IRQ_MASK, |
422 | .status_mask = CAMERA_V_IRQ_MASK, |
423 | }, { |
424 | .virq = VIRQ_KEYBOARD, |
425 | .enb_mask = KEYBOARD_IRQ_MASK, |
426 | .status_mask = KEYBOARD_IRQ_MASK, |
427 | }, { |
428 | .virq = VIRQ_GPIO1, |
429 | .enb_mask = GPIO1_IRQ_MASK, |
430 | .status_mask = GPIO1_IRQ_MASK, |
431 | }, |
432 | }; |
433 | |
434 | struct spear_shirq shirq_ras1 = { |
435 | .irq = IRQ_GEN_RAS_1, |
436 | .dev_config = shirq_ras1_config, |
437 | .dev_count = ARRAY_SIZE(shirq_ras1_config), |
438 | .regs = { |
439 | .enb_reg = INT_ENB_MASK_REG, |
440 | .status_reg = INT_STS_MASK_REG, |
441 | .status_reg_mask = SHIRQ_RAS1_MASK, |
442 | .clear_reg = -1, |
443 | }, |
bc4e814e |
444 | }; |
445 | |
70f4c0bf |
446 | /* spear300 routines */ |
bc4e814e |
447 | void __init spear300_init(void) |
448 | { |
4c18e77f |
449 | int ret = 0; |
450 | |
bc4e814e |
451 | /* call spear3xx family common init function */ |
452 | spear3xx_init(); |
4c18e77f |
453 | |
454 | /* shared irq registeration */ |
455 | shirq_ras1.regs.base = |
456 | ioremap(SPEAR300_TELECOM_BASE, SPEAR300_TELECOM_REG_SIZE); |
457 | if (shirq_ras1.regs.base) { |
458 | ret = spear_shirq_register(&shirq_ras1); |
459 | if (ret) |
460 | printk(KERN_ERR "Error registering Shared IRQ\n"); |
461 | } |
bc4e814e |
462 | } |
70f4c0bf |
463 | |
464 | void spear300_pmx_init(void) |
465 | { |
466 | spear_pmx_init(&pmx_driver, SPEAR300_SOC_CONFIG_BASE, |
467 | SPEAR300_SOC_CONFIG_SIZE); |
468 | } |