diff options
46 files changed, 5602 insertions, 311 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 5fb38d3f1423..0c0d829176a2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -955,8 +955,9 @@ ARM/SHMOBILE ARM ARCHITECTURE | |||
955 | M: Paul Mundt <lethal@linux-sh.org> | 955 | M: Paul Mundt <lethal@linux-sh.org> |
956 | M: Magnus Damm <magnus.damm@gmail.com> | 956 | M: Magnus Damm <magnus.damm@gmail.com> |
957 | L: linux-sh@vger.kernel.org | 957 | L: linux-sh@vger.kernel.org |
958 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/genesis-2.6.git | ||
959 | W: http://oss.renesas.com | 958 | W: http://oss.renesas.com |
959 | Q: http://patchwork.kernel.org/project/linux-sh/list/ | ||
960 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/genesis-2.6.git | ||
960 | S: Supported | 961 | S: Supported |
961 | F: arch/arm/mach-shmobile/ | 962 | F: arch/arm/mach-shmobile/ |
962 | F: drivers/sh/ | 963 | F: drivers/sh/ |
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 4c704b4e8b34..54b479c35ee0 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig | |||
@@ -7,6 +7,7 @@ config ARCH_SH7367 | |||
7 | select CPU_V6 | 7 | select CPU_V6 |
8 | select HAVE_CLK | 8 | select HAVE_CLK |
9 | select COMMON_CLKDEV | 9 | select COMMON_CLKDEV |
10 | select SH_CLK_CPG | ||
10 | select GENERIC_CLOCKEVENTS | 11 | select GENERIC_CLOCKEVENTS |
11 | 12 | ||
12 | config ARCH_SH7377 | 13 | config ARCH_SH7377 |
@@ -14,6 +15,7 @@ config ARCH_SH7377 | |||
14 | select CPU_V7 | 15 | select CPU_V7 |
15 | select HAVE_CLK | 16 | select HAVE_CLK |
16 | select COMMON_CLKDEV | 17 | select COMMON_CLKDEV |
18 | select SH_CLK_CPG | ||
17 | select GENERIC_CLOCKEVENTS | 19 | select GENERIC_CLOCKEVENTS |
18 | 20 | ||
19 | config ARCH_SH7372 | 21 | config ARCH_SH7372 |
@@ -21,6 +23,7 @@ config ARCH_SH7372 | |||
21 | select CPU_V7 | 23 | select CPU_V7 |
22 | select HAVE_CLK | 24 | select HAVE_CLK |
23 | select COMMON_CLKDEV | 25 | select COMMON_CLKDEV |
26 | select SH_CLK_CPG | ||
24 | select GENERIC_CLOCKEVENTS | 27 | select GENERIC_CLOCKEVENTS |
25 | 28 | ||
26 | comment "SH-Mobile Board Type" | 29 | comment "SH-Mobile Board Type" |
@@ -39,6 +42,20 @@ config MACH_AP4EVB | |||
39 | bool "AP4EVB board" | 42 | bool "AP4EVB board" |
40 | depends on ARCH_SH7372 | 43 | depends on ARCH_SH7372 |
41 | select ARCH_REQUIRE_GPIOLIB | 44 | select ARCH_REQUIRE_GPIOLIB |
45 | select SH_LCD_MIPI_DSI | ||
46 | |||
47 | choice | ||
48 | prompt "AP4EVB LCD panel selection" | ||
49 | default AP4EVB_QHD | ||
50 | depends on MACH_AP4EVB | ||
51 | |||
52 | config AP4EVB_QHD | ||
53 | bool "MIPI-DSI QHD (960x540)" | ||
54 | |||
55 | config AP4EVB_WVGA | ||
56 | bool "Parallel WVGA (800x480)" | ||
57 | |||
58 | endchoice | ||
42 | 59 | ||
43 | comment "SH-Mobile System Configuration" | 60 | comment "SH-Mobile System Configuration" |
44 | 61 | ||
@@ -88,6 +105,15 @@ config SH_TIMER_CMT | |||
88 | help | 105 | help |
89 | This enables build of the CMT timer driver. | 106 | This enables build of the CMT timer driver. |
90 | 107 | ||
108 | config SH_TIMER_TMU | ||
109 | bool "TMU timer driver" | ||
110 | default y | ||
111 | help | ||
112 | This enables build of the TMU timer driver. | ||
113 | |||
91 | endmenu | 114 | endmenu |
92 | 115 | ||
116 | config SH_CLK_CPG | ||
117 | bool | ||
118 | |||
93 | endif | 119 | endif |
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 6d385d371c33..5e16b4c69222 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile | |||
@@ -3,12 +3,12 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common objects | 5 | # Common objects |
6 | obj-y := timer.o console.o | 6 | obj-y := timer.o console.o clock.o |
7 | 7 | ||
8 | # CPU objects | 8 | # CPU objects |
9 | obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o | 9 | obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o |
10 | obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7367.o intc-sh7377.o | 10 | obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7377.o intc-sh7377.o |
11 | obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7367.o intc-sh7372.o | 11 | obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o |
12 | 12 | ||
13 | # Pinmux setup | 13 | # Pinmux setup |
14 | pfc-$(CONFIG_ARCH_SH7367) := pfc-sh7367.o | 14 | pfc-$(CONFIG_ARCH_SH7367) := pfc-sh7367.o |
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 1c2ec96ce261..23d472f9525e 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
@@ -17,25 +17,45 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
19 | */ | 19 | */ |
20 | #include <linux/clk.h> | ||
20 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
22 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
23 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
24 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
25 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/mfd/sh_mobile_sdhi.h> | ||
28 | #include <linux/mmc/host.h> | ||
26 | #include <linux/mtd/mtd.h> | 29 | #include <linux/mtd/mtd.h> |
27 | #include <linux/mtd/partitions.h> | 30 | #include <linux/mtd/partitions.h> |
28 | #include <linux/mtd/physmap.h> | 31 | #include <linux/mtd/physmap.h> |
32 | #include <linux/mmc/host.h> | ||
33 | #include <linux/mmc/sh_mmcif.h> | ||
34 | #include <linux/i2c.h> | ||
35 | #include <linux/i2c/tsc2007.h> | ||
29 | #include <linux/io.h> | 36 | #include <linux/io.h> |
30 | #include <linux/smsc911x.h> | 37 | #include <linux/smsc911x.h> |
38 | #include <linux/sh_intc.h> | ||
39 | #include <linux/sh_clk.h> | ||
31 | #include <linux/gpio.h> | 40 | #include <linux/gpio.h> |
32 | #include <linux/input.h> | 41 | #include <linux/input.h> |
33 | #include <linux/input/sh_keysc.h> | 42 | #include <linux/input/sh_keysc.h> |
43 | #include <linux/usb/r8a66597.h> | ||
44 | |||
45 | #include <sound/sh_fsi.h> | ||
46 | |||
47 | #include <video/sh_mobile_hdmi.h> | ||
48 | #include <video/sh_mobile_lcdc.h> | ||
49 | #include <video/sh_mipi_dsi.h> | ||
50 | |||
34 | #include <mach/common.h> | 51 | #include <mach/common.h> |
52 | #include <mach/irqs.h> | ||
35 | #include <mach/sh7372.h> | 53 | #include <mach/sh7372.h> |
54 | |||
36 | #include <asm/mach-types.h> | 55 | #include <asm/mach-types.h> |
37 | #include <asm/mach/arch.h> | 56 | #include <asm/mach/arch.h> |
38 | #include <asm/mach/map.h> | 57 | #include <asm/mach/map.h> |
58 | #include <asm/mach/time.h> | ||
39 | 59 | ||
40 | /* | 60 | /* |
41 | * Address Interface BusWidth note | 61 | * Address Interface BusWidth note |
@@ -80,12 +100,56 @@ | |||
80 | */ | 100 | */ |
81 | 101 | ||
82 | /* | 102 | /* |
83 | * KEYSC | 103 | * LCD / IRQ / KEYSC / IrDA |
104 | * | ||
105 | * IRQ = IRQ26 (TS), IRQ27 (VIO), IRQ28 (QHD-TouchScreen) | ||
106 | * LCD = 2nd LCDC (WVGA) | ||
84 | * | 107 | * |
85 | * SW43 KEYSC | 108 | * | SW43 | |
86 | * ------------------------- | 109 | * SW3 | ON | OFF | |
87 | * ON enable | 110 | * -------------+-----------------------+---------------+ |
88 | * OFF disable | 111 | * ON | KEY / IrDA | LCD | |
112 | * OFF | KEY / IrDA / IRQ | IRQ | | ||
113 | * | ||
114 | * | ||
115 | * QHD / WVGA display | ||
116 | * | ||
117 | * You can choice display type on menuconfig. | ||
118 | * Then, check above dip-switch. | ||
119 | */ | ||
120 | |||
121 | /* | ||
122 | * USB | ||
123 | * | ||
124 | * J7 : 1-2 MAX3355E VBUS | ||
125 | * 2-3 DC 5.0V | ||
126 | * | ||
127 | * S39: bit2: off | ||
128 | */ | ||
129 | |||
130 | /* | ||
131 | * FSI/FSMI | ||
132 | * | ||
133 | * SW41 : ON : SH-Mobile AP4 Audio Mode | ||
134 | * : OFF : Bluetooth Audio Mode | ||
135 | */ | ||
136 | |||
137 | /* | ||
138 | * MMC0/SDHI1 (CN7) | ||
139 | * | ||
140 | * J22 : select card voltage | ||
141 | * 1-2 pin : 1.8v | ||
142 | * 2-3 pin : 3.3v | ||
143 | * | ||
144 | * SW1 | SW33 | ||
145 | * | bit1 | bit2 | bit3 | bit4 | ||
146 | * ------------+------+------+------+------- | ||
147 | * MMC0 OFF | OFF | ON | ON | X | ||
148 | * SDHI1 OFF | ON | X | OFF | ON | ||
149 | * | ||
150 | * voltage lebel | ||
151 | * CN7 : 1.8v | ||
152 | * CN12: 3.3v | ||
89 | */ | 153 | */ |
90 | 154 | ||
91 | /* MTD */ | 155 | /* MTD */ |
@@ -148,7 +212,7 @@ static struct resource smc911x_resources[] = { | |||
148 | .end = 0x16000000 - 1, | 212 | .end = 0x16000000 - 1, |
149 | .flags = IORESOURCE_MEM, | 213 | .flags = IORESOURCE_MEM, |
150 | }, { | 214 | }, { |
151 | .start = 6, | 215 | .start = evt2irq(0x02c0) /* IRQ6A */, |
152 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, | 216 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, |
153 | }, | 217 | }, |
154 | }; | 218 | }; |
@@ -169,6 +233,180 @@ static struct platform_device smc911x_device = { | |||
169 | }, | 233 | }, |
170 | }; | 234 | }; |
171 | 235 | ||
236 | /* SH_MMCIF */ | ||
237 | static struct resource sh_mmcif_resources[] = { | ||
238 | [0] = { | ||
239 | .name = "SH_MMCIF", | ||
240 | .start = 0xE6BD0000, | ||
241 | .end = 0xE6BD00FF, | ||
242 | .flags = IORESOURCE_MEM, | ||
243 | }, | ||
244 | [1] = { | ||
245 | /* MMC ERR */ | ||
246 | .start = evt2irq(0x1ac0), | ||
247 | .flags = IORESOURCE_IRQ, | ||
248 | }, | ||
249 | [2] = { | ||
250 | /* MMC NOR */ | ||
251 | .start = evt2irq(0x1ae0), | ||
252 | .flags = IORESOURCE_IRQ, | ||
253 | }, | ||
254 | }; | ||
255 | |||
256 | static struct sh_mmcif_plat_data sh_mmcif_plat = { | ||
257 | .sup_pclk = 0, | ||
258 | .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, | ||
259 | .caps = MMC_CAP_4_BIT_DATA | | ||
260 | MMC_CAP_8_BIT_DATA | | ||
261 | MMC_CAP_NEEDS_POLL, | ||
262 | }; | ||
263 | |||
264 | static struct platform_device sh_mmcif_device = { | ||
265 | .name = "sh_mmcif", | ||
266 | .id = 0, | ||
267 | .dev = { | ||
268 | .dma_mask = NULL, | ||
269 | .coherent_dma_mask = 0xffffffff, | ||
270 | .platform_data = &sh_mmcif_plat, | ||
271 | }, | ||
272 | .num_resources = ARRAY_SIZE(sh_mmcif_resources), | ||
273 | .resource = sh_mmcif_resources, | ||
274 | }; | ||
275 | |||
276 | /* SDHI0 */ | ||
277 | static struct sh_mobile_sdhi_info sdhi0_info = { | ||
278 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, | ||
279 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, | ||
280 | }; | ||
281 | |||
282 | static struct resource sdhi0_resources[] = { | ||
283 | [0] = { | ||
284 | .name = "SDHI0", | ||
285 | .start = 0xe6850000, | ||
286 | .end = 0xe68501ff, | ||
287 | .flags = IORESOURCE_MEM, | ||
288 | }, | ||
289 | [1] = { | ||
290 | .start = evt2irq(0x0e00) /* SDHI0 */, | ||
291 | .flags = IORESOURCE_IRQ, | ||
292 | }, | ||
293 | }; | ||
294 | |||
295 | static struct platform_device sdhi0_device = { | ||
296 | .name = "sh_mobile_sdhi", | ||
297 | .num_resources = ARRAY_SIZE(sdhi0_resources), | ||
298 | .resource = sdhi0_resources, | ||
299 | .id = 0, | ||
300 | .dev = { | ||
301 | .platform_data = &sdhi0_info, | ||
302 | }, | ||
303 | }; | ||
304 | |||
305 | /* SDHI1 */ | ||
306 | static struct sh_mobile_sdhi_info sdhi1_info = { | ||
307 | .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, | ||
308 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, | ||
309 | .tmio_ocr_mask = MMC_VDD_165_195, | ||
310 | }; | ||
311 | |||
312 | static struct resource sdhi1_resources[] = { | ||
313 | [0] = { | ||
314 | .name = "SDHI1", | ||
315 | .start = 0xe6860000, | ||
316 | .end = 0xe68601ff, | ||
317 | .flags = IORESOURCE_MEM, | ||
318 | }, | ||
319 | [1] = { | ||
320 | .start = evt2irq(0x0e80), | ||
321 | .flags = IORESOURCE_IRQ, | ||
322 | }, | ||
323 | }; | ||
324 | |||
325 | static struct platform_device sdhi1_device = { | ||
326 | .name = "sh_mobile_sdhi", | ||
327 | .num_resources = ARRAY_SIZE(sdhi1_resources), | ||
328 | .resource = sdhi1_resources, | ||
329 | .id = 1, | ||
330 | .dev = { | ||
331 | .platform_data = &sdhi1_info, | ||
332 | }, | ||
333 | }; | ||
334 | |||
335 | /* USB1 */ | ||
336 | static void usb1_host_port_power(int port, int power) | ||
337 | { | ||
338 | if (!power) /* only power-on supported for now */ | ||
339 | return; | ||
340 | |||
341 | /* set VBOUT/PWEN and EXTLP1 in DVSTCTR */ | ||
342 | __raw_writew(__raw_readw(0xE68B0008) | 0x600, 0xE68B0008); | ||
343 | } | ||
344 | |||
345 | static struct r8a66597_platdata usb1_host_data = { | ||
346 | .on_chip = 1, | ||
347 | .port_power = usb1_host_port_power, | ||
348 | }; | ||
349 | |||
350 | static struct resource usb1_host_resources[] = { | ||
351 | [0] = { | ||
352 | .name = "USBHS", | ||
353 | .start = 0xE68B0000, | ||
354 | .end = 0xE68B00E6 - 1, | ||
355 | .flags = IORESOURCE_MEM, | ||
356 | }, | ||
357 | [1] = { | ||
358 | .start = evt2irq(0x1ce0) /* USB1_USB1I0 */, | ||
359 | .flags = IORESOURCE_IRQ, | ||
360 | }, | ||
361 | }; | ||
362 | |||
363 | static struct platform_device usb1_host_device = { | ||
364 | .name = "r8a66597_hcd", | ||
365 | .id = 1, | ||
366 | .dev = { | ||
367 | .dma_mask = NULL, /* not use dma */ | ||
368 | .coherent_dma_mask = 0xffffffff, | ||
369 | .platform_data = &usb1_host_data, | ||
370 | }, | ||
371 | .num_resources = ARRAY_SIZE(usb1_host_resources), | ||
372 | .resource = usb1_host_resources, | ||
373 | }; | ||
374 | |||
375 | static struct sh_mobile_lcdc_info lcdc_info = { | ||
376 | .ch[0] = { | ||
377 | .chan = LCDC_CHAN_MAINLCD, | ||
378 | .bpp = 16, | ||
379 | } | ||
380 | }; | ||
381 | |||
382 | static struct resource lcdc_resources[] = { | ||
383 | [0] = { | ||
384 | .name = "LCDC", | ||
385 | .start = 0xfe940000, /* P4-only space */ | ||
386 | .end = 0xfe943fff, | ||
387 | .flags = IORESOURCE_MEM, | ||
388 | }, | ||
389 | [1] = { | ||
390 | .start = intcs_evt2irq(0x580), | ||
391 | .flags = IORESOURCE_IRQ, | ||
392 | }, | ||
393 | }; | ||
394 | |||
395 | static struct platform_device lcdc_device = { | ||
396 | .name = "sh_mobile_lcdc_fb", | ||
397 | .num_resources = ARRAY_SIZE(lcdc_resources), | ||
398 | .resource = lcdc_resources, | ||
399 | .dev = { | ||
400 | .platform_data = &lcdc_info, | ||
401 | .coherent_dma_mask = ~0, | ||
402 | }, | ||
403 | }; | ||
404 | |||
405 | /* | ||
406 | * QHD display | ||
407 | */ | ||
408 | #ifdef CONFIG_AP4EVB_QHD | ||
409 | |||
172 | /* KEYSC (Needs SW43 set to ON) */ | 410 | /* KEYSC (Needs SW43 set to ON) */ |
173 | static struct sh_keysc_info keysc_info = { | 411 | static struct sh_keysc_info keysc_info = { |
174 | .mode = SH_KEYSC_MODE_1, | 412 | .mode = SH_KEYSC_MODE_1, |
@@ -191,7 +429,7 @@ static struct resource keysc_resources[] = { | |||
191 | .flags = IORESOURCE_MEM, | 429 | .flags = IORESOURCE_MEM, |
192 | }, | 430 | }, |
193 | [1] = { | 431 | [1] = { |
194 | .start = 79, | 432 | .start = evt2irq(0x0be0), /* KEYSC_KEY */ |
195 | .flags = IORESOURCE_IRQ, | 433 | .flags = IORESOURCE_IRQ, |
196 | }, | 434 | }, |
197 | }; | 435 | }; |
@@ -206,32 +444,362 @@ static struct platform_device keysc_device = { | |||
206 | }, | 444 | }, |
207 | }; | 445 | }; |
208 | 446 | ||
209 | /* SDHI0 */ | 447 | /* MIPI-DSI */ |
210 | static struct resource sdhi0_resources[] = { | 448 | static struct resource mipidsi0_resources[] = { |
211 | [0] = { | 449 | [0] = { |
212 | .name = "SDHI0", | 450 | .start = 0xffc60000, |
213 | .start = 0xe6850000, | 451 | .end = 0xffc68fff, |
214 | .end = 0xe68501ff, | ||
215 | .flags = IORESOURCE_MEM, | 452 | .flags = IORESOURCE_MEM, |
216 | }, | 453 | }, |
454 | }; | ||
455 | |||
456 | static struct sh_mipi_dsi_info mipidsi0_info = { | ||
457 | .data_format = MIPI_RGB888, | ||
458 | .lcd_chan = &lcdc_info.ch[0], | ||
459 | }; | ||
460 | |||
461 | static struct platform_device mipidsi0_device = { | ||
462 | .name = "sh-mipi-dsi", | ||
463 | .num_resources = ARRAY_SIZE(mipidsi0_resources), | ||
464 | .resource = mipidsi0_resources, | ||
465 | .id = 0, | ||
466 | .dev = { | ||
467 | .platform_data = &mipidsi0_info, | ||
468 | }, | ||
469 | }; | ||
470 | |||
471 | /* This function will disappear when we switch to (runtime) PM */ | ||
472 | static int __init ap4evb_init_display_clk(void) | ||
473 | { | ||
474 | struct clk *lcdc_clk; | ||
475 | struct clk *dsitx_clk; | ||
476 | int ret; | ||
477 | |||
478 | lcdc_clk = clk_get(&lcdc_device.dev, "sh_mobile_lcdc_fb.0"); | ||
479 | if (IS_ERR(lcdc_clk)) | ||
480 | return PTR_ERR(lcdc_clk); | ||
481 | |||
482 | dsitx_clk = clk_get(&mipidsi0_device.dev, "sh-mipi-dsi.0"); | ||
483 | if (IS_ERR(dsitx_clk)) { | ||
484 | ret = PTR_ERR(dsitx_clk); | ||
485 | goto eclkdsitxget; | ||
486 | } | ||
487 | |||
488 | ret = clk_enable(lcdc_clk); | ||
489 | if (ret < 0) | ||
490 | goto eclklcdcon; | ||
491 | |||
492 | ret = clk_enable(dsitx_clk); | ||
493 | if (ret < 0) | ||
494 | goto eclkdsitxon; | ||
495 | |||
496 | return 0; | ||
497 | |||
498 | eclkdsitxon: | ||
499 | clk_disable(lcdc_clk); | ||
500 | eclklcdcon: | ||
501 | clk_put(dsitx_clk); | ||
502 | eclkdsitxget: | ||
503 | clk_put(lcdc_clk); | ||
504 | |||
505 | return ret; | ||
506 | } | ||
507 | device_initcall(ap4evb_init_display_clk); | ||
508 | |||
509 | static struct platform_device *qhd_devices[] __initdata = { | ||
510 | &mipidsi0_device, | ||
511 | &keysc_device, | ||
512 | }; | ||
513 | #endif /* CONFIG_AP4EVB_QHD */ | ||
514 | |||
515 | /* FSI */ | ||
516 | #define IRQ_FSI evt2irq(0x1840) | ||
517 | #define FSIACKCR 0xE6150018 | ||
518 | static void fsiackcr_init(struct clk *clk) | ||
519 | { | ||
520 | u32 status = __raw_readl(clk->enable_reg); | ||
521 | |||
522 | /* use external clock */ | ||
523 | status &= ~0x000000ff; | ||
524 | status |= 0x00000080; | ||
525 | __raw_writel(status, clk->enable_reg); | ||
526 | } | ||
527 | |||
528 | static struct clk_ops fsiackcr_clk_ops = { | ||
529 | .init = fsiackcr_init, | ||
530 | }; | ||
531 | |||
532 | static struct clk fsiackcr_clk = { | ||
533 | .ops = &fsiackcr_clk_ops, | ||
534 | .enable_reg = (void __iomem *)FSIACKCR, | ||
535 | .rate = 0, /* unknown */ | ||
536 | }; | ||
537 | |||
538 | static struct sh_fsi_platform_info fsi_info = { | ||
539 | .porta_flags = SH_FSI_BRS_INV | | ||
540 | SH_FSI_OUT_SLAVE_MODE | | ||
541 | SH_FSI_IN_SLAVE_MODE | | ||
542 | SH_FSI_OFMT(PCM) | | ||
543 | SH_FSI_IFMT(PCM), | ||
544 | }; | ||
545 | |||
546 | static struct resource fsi_resources[] = { | ||
547 | [0] = { | ||
548 | .name = "FSI", | ||
549 | .start = 0xFE3C0000, | ||
550 | .end = 0xFE3C0400 - 1, | ||
551 | .flags = IORESOURCE_MEM, | ||
552 | }, | ||
217 | [1] = { | 553 | [1] = { |
218 | .start = 96, | 554 | .start = IRQ_FSI, |
219 | .flags = IORESOURCE_IRQ, | 555 | .flags = IORESOURCE_IRQ, |
220 | }, | 556 | }, |
221 | }; | 557 | }; |
222 | 558 | ||
223 | static struct platform_device sdhi0_device = { | 559 | static struct platform_device fsi_device = { |
224 | .name = "sh_mobile_sdhi", | 560 | .name = "sh_fsi2", |
225 | .num_resources = ARRAY_SIZE(sdhi0_resources), | 561 | .id = 0, |
226 | .resource = sdhi0_resources, | 562 | .num_resources = ARRAY_SIZE(fsi_resources), |
227 | .id = 0, | 563 | .resource = fsi_resources, |
564 | .dev = { | ||
565 | .platform_data = &fsi_info, | ||
566 | }, | ||
567 | }; | ||
568 | |||
569 | static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = { | ||
570 | .clock_source = LCDC_CLK_EXTERNAL, | ||
571 | .ch[0] = { | ||
572 | .chan = LCDC_CHAN_MAINLCD, | ||
573 | .bpp = 16, | ||
574 | .interface_type = RGB24, | ||
575 | .clock_divider = 1, | ||
576 | .flags = LCDC_FLAGS_DWPOL, | ||
577 | .lcd_cfg = { | ||
578 | .name = "HDMI", | ||
579 | /* So far only 720p is supported */ | ||
580 | .xres = 1280, | ||
581 | .yres = 720, | ||
582 | /* | ||
583 | * If left and right margins are not multiples of 8, | ||
584 | * LDHAJR will be adjusted accordingly by the LCDC | ||
585 | * driver. Until we start using EDID, these values | ||
586 | * might have to be adjusted for different monitors. | ||
587 | */ | ||
588 | .left_margin = 200, | ||
589 | .right_margin = 88, | ||
590 | .hsync_len = 48, | ||
591 | .upper_margin = 20, | ||
592 | .lower_margin = 5, | ||
593 | .vsync_len = 5, | ||
594 | .pixclock = 13468, | ||
595 | .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, | ||
596 | }, | ||
597 | } | ||
598 | }; | ||
599 | |||
600 | static struct resource lcdc1_resources[] = { | ||
601 | [0] = { | ||
602 | .name = "LCDC1", | ||
603 | .start = 0xfe944000, | ||
604 | .end = 0xfe947fff, | ||
605 | .flags = IORESOURCE_MEM, | ||
606 | }, | ||
607 | [1] = { | ||
608 | .start = intcs_evt2irq(0x17a0), | ||
609 | .flags = IORESOURCE_IRQ, | ||
610 | }, | ||
611 | }; | ||
612 | |||
613 | static struct platform_device lcdc1_device = { | ||
614 | .name = "sh_mobile_lcdc_fb", | ||
615 | .num_resources = ARRAY_SIZE(lcdc1_resources), | ||
616 | .resource = lcdc1_resources, | ||
617 | .id = 1, | ||
618 | .dev = { | ||
619 | .platform_data = &sh_mobile_lcdc1_info, | ||
620 | .coherent_dma_mask = ~0, | ||
621 | }, | ||
622 | }; | ||
623 | |||
624 | static struct sh_mobile_hdmi_info hdmi_info = { | ||
625 | .lcd_chan = &sh_mobile_lcdc1_info.ch[0], | ||
626 | .lcd_dev = &lcdc1_device.dev, | ||
627 | }; | ||
628 | |||
629 | static struct resource hdmi_resources[] = { | ||
630 | [0] = { | ||
631 | .name = "HDMI", | ||
632 | .start = 0xe6be0000, | ||
633 | .end = 0xe6be00ff, | ||
634 | .flags = IORESOURCE_MEM, | ||
635 | }, | ||
636 | [1] = { | ||
637 | /* There's also an HDMI interrupt on INTCS @ 0x18e0 */ | ||
638 | .start = evt2irq(0x17e0), | ||
639 | .flags = IORESOURCE_IRQ, | ||
640 | }, | ||
641 | }; | ||
642 | |||
643 | static struct platform_device hdmi_device = { | ||
644 | .name = "sh-mobile-hdmi", | ||
645 | .num_resources = ARRAY_SIZE(hdmi_resources), | ||
646 | .resource = hdmi_resources, | ||
647 | .id = -1, | ||
648 | .dev = { | ||
649 | .platform_data = &hdmi_info, | ||
650 | }, | ||
228 | }; | 651 | }; |
229 | 652 | ||
230 | static struct platform_device *ap4evb_devices[] __initdata = { | 653 | static struct platform_device *ap4evb_devices[] __initdata = { |
231 | &nor_flash_device, | 654 | &nor_flash_device, |
232 | &smc911x_device, | 655 | &smc911x_device, |
233 | &keysc_device, | ||
234 | &sdhi0_device, | 656 | &sdhi0_device, |
657 | &sdhi1_device, | ||
658 | &usb1_host_device, | ||
659 | &fsi_device, | ||
660 | &sh_mmcif_device, | ||
661 | &lcdc1_device, | ||
662 | &lcdc_device, | ||
663 | &hdmi_device, | ||
664 | }; | ||
665 | |||
666 | static int __init hdmi_init_pm_clock(void) | ||
667 | { | ||
668 | struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick"); | ||
669 | int ret; | ||
670 | long rate; | ||
671 | |||
672 | if (IS_ERR(hdmi_ick)) { | ||
673 | ret = PTR_ERR(hdmi_ick); | ||
674 | pr_err("Cannot get HDMI ICK: %d\n", ret); | ||
675 | goto out; | ||
676 | } | ||
677 | |||
678 | ret = clk_set_parent(&pllc2_clk, &dv_clki_div2_clk); | ||
679 | if (ret < 0) { | ||
680 | pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, pllc2_clk.usecount); | ||
681 | goto out; | ||
682 | } | ||
683 | |||
684 | pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&pllc2_clk)); | ||
685 | |||
686 | rate = clk_round_rate(&pllc2_clk, 594000000); | ||
687 | if (rate < 0) { | ||
688 | pr_err("Cannot get suitable rate: %ld\n", rate); | ||
689 | ret = rate; | ||
690 | goto out; | ||
691 | } | ||
692 | |||
693 | ret = clk_set_rate(&pllc2_clk, rate); | ||
694 | if (ret < 0) { | ||
695 | pr_err("Cannot set rate %ld: %d\n", rate, ret); | ||
696 | goto out; | ||
697 | } | ||
698 | |||
699 | pr_debug("PLLC2 set frequency %lu\n", rate); | ||
700 | |||
701 | ret = clk_set_parent(hdmi_ick, &pllc2_clk); | ||
702 | if (ret < 0) { | ||
703 | pr_err("Cannot set HDMI parent: %d\n", ret); | ||
704 | goto out; | ||
705 | } | ||
706 | |||
707 | out: | ||
708 | if (!IS_ERR(hdmi_ick)) | ||
709 | clk_put(hdmi_ick); | ||
710 | return ret; | ||
711 | } | ||
712 | |||
713 | device_initcall(hdmi_init_pm_clock); | ||
714 | |||
715 | /* | ||
716 | * FIXME !! | ||
717 | * | ||
718 | * gpio_no_direction | ||
719 | * gpio_pull_up | ||
720 | * are quick_hack. | ||
721 | * | ||
722 | * current gpio frame work doesn't have | ||
723 | * the method to control only pull up/down/free. | ||
724 | * this function should be replaced by correct gpio function | ||
725 | */ | ||
726 | static void __init gpio_no_direction(u32 addr) | ||
727 | { | ||
728 | __raw_writeb(0x00, addr); | ||
729 | } | ||
730 | |||
731 | static void __init gpio_pull_up(u32 addr) | ||
732 | { | ||
733 | u8 data = __raw_readb(addr); | ||
734 | |||
735 | data &= 0x0F; | ||
736 | data |= 0xC0; | ||
737 | __raw_writeb(data, addr); | ||
738 | } | ||
739 | |||
740 | /* TouchScreen */ | ||
741 | #define IRQ28 evt2irq(0x3380) /* IRQ28A */ | ||
742 | #define IRQ7 evt2irq(0x02e0) /* IRQ7A */ | ||
743 | static int ts_get_pendown_state(void) | ||
744 | { | ||
745 | int val1, val2; | ||
746 | |||
747 | gpio_free(GPIO_FN_IRQ28_123); | ||
748 | gpio_free(GPIO_FN_IRQ7_40); | ||
749 | |||
750 | gpio_request(GPIO_PORT123, NULL); | ||
751 | gpio_request(GPIO_PORT40, NULL); | ||
752 | |||
753 | gpio_direction_input(GPIO_PORT123); | ||
754 | gpio_direction_input(GPIO_PORT40); | ||
755 | |||
756 | val1 = gpio_get_value(GPIO_PORT123); | ||
757 | val2 = gpio_get_value(GPIO_PORT40); | ||
758 | |||
759 | gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */ | ||
760 | gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */ | ||
761 | |||
762 | return val1 ^ val2; | ||
763 | } | ||
764 | |||
765 | #define PORT40CR 0xE6051028 | ||
766 | #define PORT123CR 0xE605007B | ||
767 | static int ts_init(void) | ||
768 | { | ||
769 | gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */ | ||
770 | gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */ | ||
771 | |||
772 | gpio_pull_up(PORT40CR); | ||
773 | gpio_pull_up(PORT123CR); | ||
774 | |||
775 | return 0; | ||
776 | } | ||
777 | |||
778 | static struct tsc2007_platform_data tsc2007_info = { | ||
779 | .model = 2007, | ||
780 | .x_plate_ohms = 180, | ||
781 | .get_pendown_state = ts_get_pendown_state, | ||
782 | .init_platform_hw = ts_init, | ||
783 | }; | ||
784 | |||
785 | static struct i2c_board_info tsc_device = { | ||
786 | I2C_BOARD_INFO("tsc2007", 0x48), | ||
787 | .type = "tsc2007", | ||
788 | .platform_data = &tsc2007_info, | ||
789 | /*.irq is selected on ap4evb_init */ | ||
790 | }; | ||
791 | |||
792 | /* I2C */ | ||
793 | static struct i2c_board_info i2c0_devices[] = { | ||
794 | { | ||
795 | I2C_BOARD_INFO("ak4643", 0x13), | ||
796 | }, | ||
797 | }; | ||
798 | |||
799 | static struct i2c_board_info i2c1_devices[] = { | ||
800 | { | ||
801 | I2C_BOARD_INFO("r2025sd", 0x32), | ||
802 | }, | ||
235 | }; | 803 | }; |
236 | 804 | ||
237 | static struct map_desc ap4evb_io_desc[] __initdata = { | 805 | static struct map_desc ap4evb_io_desc[] __initdata = { |
@@ -250,14 +818,18 @@ static void __init ap4evb_map_io(void) | |||
250 | { | 818 | { |
251 | iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc)); | 819 | iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc)); |
252 | 820 | ||
253 | /* setup early devices, clocks and console here as well */ | 821 | /* setup early devices and console here as well */ |
254 | sh7372_add_early_devices(); | 822 | sh7372_add_early_devices(); |
255 | sh7367_clock_init(); /* use g3 clocks for now */ | ||
256 | shmobile_setup_console(); | 823 | shmobile_setup_console(); |
257 | } | 824 | } |
258 | 825 | ||
826 | #define GPIO_PORT9CR 0xE6051009 | ||
827 | #define GPIO_PORT10CR 0xE605100A | ||
259 | static void __init ap4evb_init(void) | 828 | static void __init ap4evb_init(void) |
260 | { | 829 | { |
830 | u32 srcr4; | ||
831 | struct clk *clk; | ||
832 | |||
261 | sh7372_pinmux_init(); | 833 | sh7372_pinmux_init(); |
262 | 834 | ||
263 | /* enable SCIFA0 */ | 835 | /* enable SCIFA0 */ |
@@ -296,6 +868,93 @@ static void __init ap4evb_init(void) | |||
296 | gpio_export(GPIO_PORT34, 0); | 868 | gpio_export(GPIO_PORT34, 0); |
297 | gpio_export(GPIO_PORT35, 0); | 869 | gpio_export(GPIO_PORT35, 0); |
298 | 870 | ||
871 | /* SDHI0 */ | ||
872 | gpio_request(GPIO_FN_SDHICD0, NULL); | ||
873 | gpio_request(GPIO_FN_SDHIWP0, NULL); | ||
874 | gpio_request(GPIO_FN_SDHICMD0, NULL); | ||
875 | gpio_request(GPIO_FN_SDHICLK0, NULL); | ||
876 | gpio_request(GPIO_FN_SDHID0_3, NULL); | ||
877 | gpio_request(GPIO_FN_SDHID0_2, NULL); | ||
878 | gpio_request(GPIO_FN_SDHID0_1, NULL); | ||
879 | gpio_request(GPIO_FN_SDHID0_0, NULL); | ||
880 | |||
881 | /* SDHI1 */ | ||
882 | gpio_request(GPIO_FN_SDHICMD1, NULL); | ||
883 | gpio_request(GPIO_FN_SDHICLK1, NULL); | ||
884 | gpio_request(GPIO_FN_SDHID1_3, NULL); | ||
885 | gpio_request(GPIO_FN_SDHID1_2, NULL); | ||
886 | gpio_request(GPIO_FN_SDHID1_1, NULL); | ||
887 | gpio_request(GPIO_FN_SDHID1_0, NULL); | ||
888 | |||
889 | /* MMCIF */ | ||
890 | gpio_request(GPIO_FN_MMCD0_0, NULL); | ||
891 | gpio_request(GPIO_FN_MMCD0_1, NULL); | ||
892 | gpio_request(GPIO_FN_MMCD0_2, NULL); | ||
893 | gpio_request(GPIO_FN_MMCD0_3, NULL); | ||
894 | gpio_request(GPIO_FN_MMCD0_4, NULL); | ||
895 | gpio_request(GPIO_FN_MMCD0_5, NULL); | ||
896 | gpio_request(GPIO_FN_MMCD0_6, NULL); | ||
897 | gpio_request(GPIO_FN_MMCD0_7, NULL); | ||
898 | gpio_request(GPIO_FN_MMCCMD0, NULL); | ||
899 | gpio_request(GPIO_FN_MMCCLK0, NULL); | ||
900 | |||
901 | /* USB enable */ | ||
902 | gpio_request(GPIO_FN_VBUS0_1, NULL); | ||
903 | gpio_request(GPIO_FN_IDIN_1_18, NULL); | ||
904 | gpio_request(GPIO_FN_PWEN_1_115, NULL); | ||
905 | gpio_request(GPIO_FN_OVCN_1_114, NULL); | ||
906 | gpio_request(GPIO_FN_EXTLP_1, NULL); | ||
907 | gpio_request(GPIO_FN_OVCN2_1, NULL); | ||
908 | |||
909 | /* setup USB phy */ | ||
910 | __raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */ | ||
911 | |||
912 | /* enable FSI2 */ | ||
913 | gpio_request(GPIO_FN_FSIAIBT, NULL); | ||
914 | gpio_request(GPIO_FN_FSIAILR, NULL); | ||
915 | gpio_request(GPIO_FN_FSIAISLD, NULL); | ||
916 | gpio_request(GPIO_FN_FSIAOSLD, NULL); | ||
917 | gpio_request(GPIO_PORT161, NULL); | ||
918 | gpio_direction_output(GPIO_PORT161, 0); /* slave */ | ||
919 | |||
920 | gpio_request(GPIO_PORT9, NULL); | ||
921 | gpio_request(GPIO_PORT10, NULL); | ||
922 | gpio_no_direction(GPIO_PORT9CR); /* FSIAOBT needs no direction */ | ||
923 | gpio_no_direction(GPIO_PORT10CR); /* FSIAOLR needs no direction */ | ||
924 | |||
925 | /* set SPU2 clock to 119.6 MHz */ | ||
926 | clk = clk_get(NULL, "spu_clk"); | ||
927 | if (!IS_ERR(clk)) { | ||
928 | clk_set_rate(clk, clk_round_rate(clk, 119600000)); | ||
929 | clk_put(clk); | ||
930 | } | ||
931 | |||
932 | /* change parent of FSI A */ | ||
933 | clk = clk_get(NULL, "fsia_clk"); | ||
934 | if (!IS_ERR(clk)) { | ||
935 | clk_register(&fsiackcr_clk); | ||
936 | clk_set_parent(clk, &fsiackcr_clk); | ||
937 | clk_put(clk); | ||
938 | } | ||
939 | |||
940 | /* | ||
941 | * set irq priority, to avoid sound chopping | ||
942 | * when NFS rootfs is used | ||
943 | * FSI(3) > SMSC911X(2) | ||
944 | */ | ||
945 | intc_set_priority(IRQ_FSI, 3); | ||
946 | |||
947 | i2c_register_board_info(0, i2c0_devices, | ||
948 | ARRAY_SIZE(i2c0_devices)); | ||
949 | |||
950 | i2c_register_board_info(1, i2c1_devices, | ||
951 | ARRAY_SIZE(i2c1_devices)); | ||
952 | |||
953 | #ifdef CONFIG_AP4EVB_QHD | ||
954 | /* | ||
955 | * QHD | ||
956 | */ | ||
957 | |||
299 | /* enable KEYSC */ | 958 | /* enable KEYSC */ |
300 | gpio_request(GPIO_FN_KEYOUT0, NULL); | 959 | gpio_request(GPIO_FN_KEYOUT0, NULL); |
301 | gpio_request(GPIO_FN_KEYOUT1, NULL); | 960 | gpio_request(GPIO_FN_KEYOUT1, NULL); |
@@ -308,26 +967,122 @@ static void __init ap4evb_init(void) | |||
308 | gpio_request(GPIO_FN_KEYIN3_133, NULL); | 967 | gpio_request(GPIO_FN_KEYIN3_133, NULL); |
309 | gpio_request(GPIO_FN_KEYIN4, NULL); | 968 | gpio_request(GPIO_FN_KEYIN4, NULL); |
310 | 969 | ||
311 | /* SDHI0 */ | 970 | /* enable TouchScreen */ |
312 | gpio_request(GPIO_FN_SDHICD0, NULL); | 971 | set_irq_type(IRQ28, IRQ_TYPE_LEVEL_LOW); |
313 | gpio_request(GPIO_FN_SDHIWP0, NULL); | 972 | |
314 | gpio_request(GPIO_FN_SDHICMD0, NULL); | 973 | tsc_device.irq = IRQ28; |
315 | gpio_request(GPIO_FN_SDHICLK0, NULL); | 974 | i2c_register_board_info(1, &tsc_device, 1); |
316 | gpio_request(GPIO_FN_SDHID0_3, NULL); | 975 | |
317 | gpio_request(GPIO_FN_SDHID0_2, NULL); | 976 | /* LCDC0 */ |
318 | gpio_request(GPIO_FN_SDHID0_1, NULL); | 977 | lcdc_info.clock_source = LCDC_CLK_PERIPHERAL; |
319 | gpio_request(GPIO_FN_SDHID0_0, NULL); | 978 | lcdc_info.ch[0].interface_type = RGB24; |
979 | lcdc_info.ch[0].clock_divider = 1; | ||
980 | lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL; | ||
981 | lcdc_info.ch[0].lcd_cfg.name = "R63302(QHD)"; | ||
982 | lcdc_info.ch[0].lcd_cfg.xres = 544; | ||
983 | lcdc_info.ch[0].lcd_cfg.yres = 961; | ||
984 | lcdc_info.ch[0].lcd_cfg.left_margin = 72; | ||
985 | lcdc_info.ch[0].lcd_cfg.right_margin = 600; | ||
986 | lcdc_info.ch[0].lcd_cfg.hsync_len = 16; | ||
987 | lcdc_info.ch[0].lcd_cfg.upper_margin = 8; | ||
988 | lcdc_info.ch[0].lcd_cfg.lower_margin = 8; | ||
989 | lcdc_info.ch[0].lcd_cfg.vsync_len = 2; | ||
990 | lcdc_info.ch[0].lcd_cfg.sync = FB_SYNC_VERT_HIGH_ACT | | ||
991 | FB_SYNC_HOR_HIGH_ACT; | ||
992 | lcdc_info.ch[0].lcd_size_cfg.width = 44; | ||
993 | lcdc_info.ch[0].lcd_size_cfg.height = 79; | ||
994 | |||
995 | platform_add_devices(qhd_devices, ARRAY_SIZE(qhd_devices)); | ||
996 | |||
997 | #else | ||
998 | /* | ||
999 | * WVGA | ||
1000 | */ | ||
1001 | gpio_request(GPIO_FN_LCDD17, NULL); | ||
1002 | gpio_request(GPIO_FN_LCDD16, NULL); | ||
1003 | gpio_request(GPIO_FN_LCDD15, NULL); | ||
1004 | gpio_request(GPIO_FN_LCDD14, NULL); | ||
1005 | gpio_request(GPIO_FN_LCDD13, NULL); | ||
1006 | gpio_request(GPIO_FN_LCDD12, NULL); | ||
1007 | gpio_request(GPIO_FN_LCDD11, NULL); | ||
1008 | gpio_request(GPIO_FN_LCDD10, NULL); | ||
1009 | gpio_request(GPIO_FN_LCDD9, NULL); | ||
1010 | gpio_request(GPIO_FN_LCDD8, NULL); | ||
1011 | gpio_request(GPIO_FN_LCDD7, NULL); | ||
1012 | gpio_request(GPIO_FN_LCDD6, NULL); | ||
1013 | gpio_request(GPIO_FN_LCDD5, NULL); | ||
1014 | gpio_request(GPIO_FN_LCDD4, NULL); | ||
1015 | gpio_request(GPIO_FN_LCDD3, NULL); | ||
1016 | gpio_request(GPIO_FN_LCDD2, NULL); | ||
1017 | gpio_request(GPIO_FN_LCDD1, NULL); | ||
1018 | gpio_request(GPIO_FN_LCDD0, NULL); | ||
1019 | gpio_request(GPIO_FN_LCDDISP, NULL); | ||
1020 | gpio_request(GPIO_FN_LCDDCK, NULL); | ||
1021 | |||
1022 | gpio_request(GPIO_PORT189, NULL); /* backlight */ | ||
1023 | gpio_direction_output(GPIO_PORT189, 1); | ||
1024 | |||
1025 | gpio_request(GPIO_PORT151, NULL); /* LCDDON */ | ||
1026 | gpio_direction_output(GPIO_PORT151, 1); | ||
1027 | |||
1028 | lcdc_info.clock_source = LCDC_CLK_BUS; | ||
1029 | lcdc_info.ch[0].interface_type = RGB18; | ||
1030 | lcdc_info.ch[0].clock_divider = 2; | ||
1031 | lcdc_info.ch[0].flags = 0; | ||
1032 | lcdc_info.ch[0].lcd_cfg.name = "WVGA Panel"; | ||
1033 | lcdc_info.ch[0].lcd_cfg.xres = 800; | ||
1034 | lcdc_info.ch[0].lcd_cfg.yres = 480; | ||
1035 | lcdc_info.ch[0].lcd_cfg.left_margin = 220; | ||
1036 | lcdc_info.ch[0].lcd_cfg.right_margin = 110; | ||
1037 | lcdc_info.ch[0].lcd_cfg.hsync_len = 70; | ||
1038 | lcdc_info.ch[0].lcd_cfg.upper_margin = 20; | ||
1039 | lcdc_info.ch[0].lcd_cfg.lower_margin = 5; | ||
1040 | lcdc_info.ch[0].lcd_cfg.vsync_len = 5; | ||
1041 | lcdc_info.ch[0].lcd_cfg.sync = 0; | ||
1042 | lcdc_info.ch[0].lcd_size_cfg.width = 152; | ||
1043 | lcdc_info.ch[0].lcd_size_cfg.height = 91; | ||
1044 | |||
1045 | /* enable TouchScreen */ | ||
1046 | set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW); | ||
1047 | |||
1048 | tsc_device.irq = IRQ7; | ||
1049 | i2c_register_board_info(0, &tsc_device, 1); | ||
1050 | #endif /* CONFIG_AP4EVB_QHD */ | ||
320 | 1051 | ||
321 | sh7372_add_standard_devices(); | 1052 | sh7372_add_standard_devices(); |
322 | 1053 | ||
1054 | /* HDMI */ | ||
1055 | gpio_request(GPIO_FN_HDMI_HPD, NULL); | ||
1056 | gpio_request(GPIO_FN_HDMI_CEC, NULL); | ||
1057 | |||
1058 | /* Reset HDMI, must be held at least one EXTALR (32768Hz) period */ | ||
1059 | #define SRCR4 0xe61580bc | ||
1060 | srcr4 = __raw_readl(SRCR4); | ||
1061 | __raw_writel(srcr4 | (1 << 13), SRCR4); | ||
1062 | udelay(50); | ||
1063 | __raw_writel(srcr4 & ~(1 << 13), SRCR4); | ||
1064 | |||
323 | platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); | 1065 | platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); |
324 | } | 1066 | } |
325 | 1067 | ||
1068 | static void __init ap4evb_timer_init(void) | ||
1069 | { | ||
1070 | sh7372_clock_init(); | ||
1071 | shmobile_timer.init(); | ||
1072 | |||
1073 | /* External clock source */ | ||
1074 | clk_set_rate(&dv_clki_clk, 27000000); | ||
1075 | } | ||
1076 | |||
1077 | static struct sys_timer ap4evb_timer = { | ||
1078 | .init = ap4evb_timer_init, | ||
1079 | }; | ||
1080 | |||
326 | MACHINE_START(AP4EVB, "ap4evb") | 1081 | MACHINE_START(AP4EVB, "ap4evb") |
327 | .phys_io = 0xe6000000, | 1082 | .phys_io = 0xe6000000, |
328 | .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, | 1083 | .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, |
329 | .map_io = ap4evb_map_io, | 1084 | .map_io = ap4evb_map_io, |
330 | .init_irq = sh7372_init_irq, | 1085 | .init_irq = sh7372_init_irq, |
331 | .init_machine = ap4evb_init, | 1086 | .init_machine = ap4evb_init, |
332 | .timer = &shmobile_timer, | 1087 | .timer = &ap4evb_timer, |
333 | MACHINE_END | 1088 | MACHINE_END |
diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c index 9247503296c4..a5525901e91f 100644 --- a/arch/arm/mach-shmobile/board-g3evm.c +++ b/arch/arm/mach-shmobile/board-g3evm.c | |||
@@ -37,6 +37,15 @@ | |||
37 | #include <asm/mach-types.h> | 37 | #include <asm/mach-types.h> |
38 | #include <asm/mach/arch.h> | 38 | #include <asm/mach/arch.h> |
39 | #include <asm/mach/map.h> | 39 | #include <asm/mach/map.h> |
40 | #include <asm/mach/time.h> | ||
41 | |||
42 | /* | ||
43 | * IrDA | ||
44 | * | ||
45 | * S67: 5bit : ON power | ||
46 | * : 6bit : ON remote control | ||
47 | * OFF IrDA | ||
48 | */ | ||
40 | 49 | ||
41 | static struct mtd_partition nor_flash_partitions[] = { | 50 | static struct mtd_partition nor_flash_partitions[] = { |
42 | { | 51 | { |
@@ -91,7 +100,7 @@ static struct platform_device nor_flash_device = { | |||
91 | }; | 100 | }; |
92 | 101 | ||
93 | /* USBHS */ | 102 | /* USBHS */ |
94 | void usb_host_port_power(int port, int power) | 103 | static void usb_host_port_power(int port, int power) |
95 | { | 104 | { |
96 | if (!power) /* only power-on supported for now */ | 105 | if (!power) /* only power-on supported for now */ |
97 | return; | 106 | return; |
@@ -113,7 +122,7 @@ static struct resource usb_host_resources[] = { | |||
113 | .flags = IORESOURCE_MEM, | 122 | .flags = IORESOURCE_MEM, |
114 | }, | 123 | }, |
115 | [1] = { | 124 | [1] = { |
116 | .start = 65, | 125 | .start = evt2irq(0xa20), /* USBHS_USHI0 */ |
117 | .flags = IORESOURCE_IRQ, | 126 | .flags = IORESOURCE_IRQ, |
118 | }, | 127 | }, |
119 | }; | 128 | }; |
@@ -153,7 +162,7 @@ static struct resource keysc_resources[] = { | |||
153 | .flags = IORESOURCE_MEM, | 162 | .flags = IORESOURCE_MEM, |
154 | }, | 163 | }, |
155 | [1] = { | 164 | [1] = { |
156 | .start = 79, | 165 | .start = evt2irq(0xbe0), /* KEYSC_KEY */ |
157 | .flags = IORESOURCE_IRQ, | 166 | .flags = IORESOURCE_IRQ, |
158 | }, | 167 | }, |
159 | }; | 168 | }; |
@@ -209,11 +218,31 @@ static struct platform_device nand_flash_device = { | |||
209 | }, | 218 | }, |
210 | }; | 219 | }; |
211 | 220 | ||
221 | static struct resource irda_resources[] = { | ||
222 | [0] = { | ||
223 | .start = 0xE6D00000, | ||
224 | .end = 0xE6D01FD4 - 1, | ||
225 | .flags = IORESOURCE_MEM, | ||
226 | }, | ||
227 | [1] = { | ||
228 | .start = evt2irq(0x480), /* IRDA */ | ||
229 | .flags = IORESOURCE_IRQ, | ||
230 | }, | ||
231 | }; | ||
232 | |||
233 | static struct platform_device irda_device = { | ||
234 | .name = "sh_irda", | ||
235 | .id = -1, | ||
236 | .resource = irda_resources, | ||
237 | .num_resources = ARRAY_SIZE(irda_resources), | ||
238 | }; | ||
239 | |||
212 | static struct platform_device *g3evm_devices[] __initdata = { | 240 | static struct platform_device *g3evm_devices[] __initdata = { |
213 | &nor_flash_device, | 241 | &nor_flash_device, |
214 | &usb_host_device, | 242 | &usb_host_device, |
215 | &keysc_device, | 243 | &keysc_device, |
216 | &nand_flash_device, | 244 | &nand_flash_device, |
245 | &irda_device, | ||
217 | }; | 246 | }; |
218 | 247 | ||
219 | static struct map_desc g3evm_io_desc[] __initdata = { | 248 | static struct map_desc g3evm_io_desc[] __initdata = { |
@@ -232,9 +261,8 @@ static void __init g3evm_map_io(void) | |||
232 | { | 261 | { |
233 | iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc)); | 262 | iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc)); |
234 | 263 | ||
235 | /* setup early devices, clocks and console here as well */ | 264 | /* setup early devices and console here as well */ |
236 | sh7367_add_early_devices(); | 265 | sh7367_add_early_devices(); |
237 | sh7367_clock_init(); | ||
238 | shmobile_setup_console(); | 266 | shmobile_setup_console(); |
239 | } | 267 | } |
240 | 268 | ||
@@ -271,9 +299,6 @@ static void __init g3evm_init(void) | |||
271 | gpio_request(GPIO_FN_EXTLP, NULL); | 299 | gpio_request(GPIO_FN_EXTLP, NULL); |
272 | gpio_request(GPIO_FN_IDIN, NULL); | 300 | gpio_request(GPIO_FN_IDIN, NULL); |
273 | 301 | ||
274 | /* enable clock in SYMSTPCR2 */ | ||
275 | __raw_writel(__raw_readl(0xe6158048) & ~(1 << 22), 0xe6158048); | ||
276 | |||
277 | /* setup USB phy */ | 302 | /* setup USB phy */ |
278 | __raw_writew(0x0300, 0xe605810a); /* USBCR1 */ | 303 | __raw_writew(0x0300, 0xe605810a); /* USBCR1 */ |
279 | __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */ | 304 | __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */ |
@@ -318,16 +343,32 @@ static void __init g3evm_init(void) | |||
318 | /* FOE, FCDE, FSC on dedicated pins */ | 343 | /* FOE, FCDE, FSC on dedicated pins */ |
319 | __raw_writel(__raw_readl(0xe6158048) & ~(1 << 15), 0xe6158048); | 344 | __raw_writel(__raw_readl(0xe6158048) & ~(1 << 15), 0xe6158048); |
320 | 345 | ||
346 | /* IrDA */ | ||
347 | gpio_request(GPIO_FN_IRDA_OUT, NULL); | ||
348 | gpio_request(GPIO_FN_IRDA_IN, NULL); | ||
349 | gpio_request(GPIO_FN_IRDA_FIRSEL, NULL); | ||
350 | set_irq_type(evt2irq(0x480), IRQ_TYPE_LEVEL_LOW); | ||
351 | |||
321 | sh7367_add_standard_devices(); | 352 | sh7367_add_standard_devices(); |
322 | 353 | ||
323 | platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices)); | 354 | platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices)); |
324 | } | 355 | } |
325 | 356 | ||
357 | static void __init g3evm_timer_init(void) | ||
358 | { | ||
359 | sh7367_clock_init(); | ||
360 | shmobile_timer.init(); | ||
361 | } | ||
362 | |||
363 | static struct sys_timer g3evm_timer = { | ||
364 | .init = g3evm_timer_init, | ||
365 | }; | ||
366 | |||
326 | MACHINE_START(G3EVM, "g3evm") | 367 | MACHINE_START(G3EVM, "g3evm") |
327 | .phys_io = 0xe6000000, | 368 | .phys_io = 0xe6000000, |
328 | .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, | 369 | .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, |
329 | .map_io = g3evm_map_io, | 370 | .map_io = g3evm_map_io, |
330 | .init_irq = sh7367_init_irq, | 371 | .init_irq = sh7367_init_irq, |
331 | .init_machine = g3evm_init, | 372 | .init_machine = g3evm_init, |
332 | .timer = &shmobile_timer, | 373 | .timer = &g3evm_timer, |
333 | MACHINE_END | 374 | MACHINE_END |
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c index 10673a90be52..2c3ff6f7f34c 100644 --- a/arch/arm/mach-shmobile/board-g4evm.c +++ b/arch/arm/mach-shmobile/board-g4evm.c | |||
@@ -30,12 +30,39 @@ | |||
30 | #include <linux/io.h> | 30 | #include <linux/io.h> |
31 | #include <linux/input.h> | 31 | #include <linux/input.h> |
32 | #include <linux/input/sh_keysc.h> | 32 | #include <linux/input/sh_keysc.h> |
33 | #include <linux/mfd/sh_mobile_sdhi.h> | ||
33 | #include <linux/gpio.h> | 34 | #include <linux/gpio.h> |
34 | #include <mach/sh7377.h> | 35 | #include <mach/sh7377.h> |
35 | #include <mach/common.h> | 36 | #include <mach/common.h> |
36 | #include <asm/mach-types.h> | 37 | #include <asm/mach-types.h> |
37 | #include <asm/mach/arch.h> | 38 | #include <asm/mach/arch.h> |
38 | #include <asm/mach/map.h> | 39 | #include <asm/mach/map.h> |
40 | #include <asm/mach/time.h> | ||
41 | |||
42 | /* | ||
43 | * SDHI | ||
44 | * | ||
45 | * SDHI0 : card detection is possible | ||
46 | * SDHI1 : card detection is impossible | ||
47 | * | ||
48 | * [G4-MAIN-BOARD] | ||
49 | * JP74 : short # DBG_2V8A for SDHI0 | ||
50 | * JP75 : NC # DBG_3V3A for SDHI0 | ||
51 | * JP76 : NC # DBG_3V3A_SD for SDHI0 | ||
52 | * JP77 : NC # 3V3A_SDIO for SDHI1 | ||
53 | * JP78 : short # DBG_2V8A for SDHI1 | ||
54 | * JP79 : NC # DBG_3V3A for SDHI1 | ||
55 | * JP80 : NC # DBG_3V3A_SD for SDHI1 | ||
56 | * | ||
57 | * [G4-CORE-BOARD] | ||
58 | * S32 : all off # to dissever from G3-CORE_DBG board | ||
59 | * S33 : all off # to dissever from G3-CORE_DBG board | ||
60 | * | ||
61 | * [G3-CORE_DBG-BOARD] | ||
62 | * S1 : all off # to dissever from G3-CORE_DBG board | ||
63 | * S3 : all off # to dissever from G3-CORE_DBG board | ||
64 | * S4 : all off # to dissever from G3-CORE_DBG board | ||
65 | */ | ||
39 | 66 | ||
40 | static struct mtd_partition nor_flash_partitions[] = { | 67 | static struct mtd_partition nor_flash_partitions[] = { |
41 | { | 68 | { |
@@ -90,7 +117,7 @@ static struct platform_device nor_flash_device = { | |||
90 | }; | 117 | }; |
91 | 118 | ||
92 | /* USBHS */ | 119 | /* USBHS */ |
93 | void usb_host_port_power(int port, int power) | 120 | static void usb_host_port_power(int port, int power) |
94 | { | 121 | { |
95 | if (!power) /* only power-on supported for now */ | 122 | if (!power) /* only power-on supported for now */ |
96 | return; | 123 | return; |
@@ -112,8 +139,7 @@ static struct resource usb_host_resources[] = { | |||
112 | .flags = IORESOURCE_MEM, | 139 | .flags = IORESOURCE_MEM, |
113 | }, | 140 | }, |
114 | [1] = { | 141 | [1] = { |
115 | .start = 65, | 142 | .start = evt2irq(0x0a20), /* USBHS_USHI0 */ |
116 | .end = 65, | ||
117 | .flags = IORESOURCE_IRQ, | 143 | .flags = IORESOURCE_IRQ, |
118 | }, | 144 | }, |
119 | }; | 145 | }; |
@@ -154,7 +180,7 @@ static struct resource keysc_resources[] = { | |||
154 | .flags = IORESOURCE_MEM, | 180 | .flags = IORESOURCE_MEM, |
155 | }, | 181 | }, |
156 | [1] = { | 182 | [1] = { |
157 | .start = 79, | 183 | .start = evt2irq(0x0be0), /* KEYSC_KEY */ |
158 | .flags = IORESOURCE_IRQ, | 184 | .flags = IORESOURCE_IRQ, |
159 | }, | 185 | }, |
160 | }; | 186 | }; |
@@ -169,10 +195,53 @@ static struct platform_device keysc_device = { | |||
169 | }, | 195 | }, |
170 | }; | 196 | }; |
171 | 197 | ||
198 | /* SDHI */ | ||
199 | static struct resource sdhi0_resources[] = { | ||
200 | [0] = { | ||
201 | .name = "SDHI0", | ||
202 | .start = 0xe6d50000, | ||
203 | .end = 0xe6d501ff, | ||
204 | .flags = IORESOURCE_MEM, | ||
205 | }, | ||
206 | [1] = { | ||
207 | .start = evt2irq(0x0e00), /* SDHI0 */ | ||
208 | .flags = IORESOURCE_IRQ, | ||
209 | }, | ||
210 | }; | ||
211 | |||
212 | static struct platform_device sdhi0_device = { | ||
213 | .name = "sh_mobile_sdhi", | ||
214 | .num_resources = ARRAY_SIZE(sdhi0_resources), | ||
215 | .resource = sdhi0_resources, | ||
216 | .id = 0, | ||
217 | }; | ||
218 | |||
219 | static struct resource sdhi1_resources[] = { | ||
220 | [0] = { | ||
221 | .name = "SDHI1", | ||
222 | .start = 0xe6d60000, | ||
223 | .end = 0xe6d601ff, | ||
224 | .flags = IORESOURCE_MEM, | ||
225 | }, | ||
226 | [1] = { | ||
227 | .start = evt2irq(0x0e80), /* SDHI1 */ | ||
228 | .flags = IORESOURCE_IRQ, | ||
229 | }, | ||
230 | }; | ||
231 | |||
232 | static struct platform_device sdhi1_device = { | ||
233 | .name = "sh_mobile_sdhi", | ||
234 | .num_resources = ARRAY_SIZE(sdhi1_resources), | ||
235 | .resource = sdhi1_resources, | ||
236 | .id = 1, | ||
237 | }; | ||
238 | |||
172 | static struct platform_device *g4evm_devices[] __initdata = { | 239 | static struct platform_device *g4evm_devices[] __initdata = { |
173 | &nor_flash_device, | 240 | &nor_flash_device, |
174 | &usb_host_device, | 241 | &usb_host_device, |
175 | &keysc_device, | 242 | &keysc_device, |
243 | &sdhi0_device, | ||
244 | &sdhi1_device, | ||
176 | }; | 245 | }; |
177 | 246 | ||
178 | static struct map_desc g4evm_io_desc[] __initdata = { | 247 | static struct map_desc g4evm_io_desc[] __initdata = { |
@@ -191,12 +260,41 @@ static void __init g4evm_map_io(void) | |||
191 | { | 260 | { |
192 | iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc)); | 261 | iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc)); |
193 | 262 | ||
194 | /* setup early devices, clocks and console here as well */ | 263 | /* setup early devices and console here as well */ |
195 | sh7377_add_early_devices(); | 264 | sh7377_add_early_devices(); |
196 | sh7367_clock_init(); /* use g3 clocks for now */ | ||
197 | shmobile_setup_console(); | 265 | shmobile_setup_console(); |
198 | } | 266 | } |
199 | 267 | ||
268 | #define GPIO_SDHID0_D0 0xe60520fc | ||
269 | #define GPIO_SDHID0_D1 0xe60520fd | ||
270 | #define GPIO_SDHID0_D2 0xe60520fe | ||
271 | #define GPIO_SDHID0_D3 0xe60520ff | ||
272 | #define GPIO_SDHICMD0 0xe6052100 | ||
273 | |||
274 | #define GPIO_SDHID1_D0 0xe6052103 | ||
275 | #define GPIO_SDHID1_D1 0xe6052104 | ||
276 | #define GPIO_SDHID1_D2 0xe6052105 | ||
277 | #define GPIO_SDHID1_D3 0xe6052106 | ||
278 | #define GPIO_SDHICMD1 0xe6052107 | ||
279 | |||
280 | /* | ||
281 | * FIXME !! | ||
282 | * | ||
283 | * gpio_pull_up is quick_hack. | ||
284 | * | ||
285 | * current gpio frame work doesn't have | ||
286 | * the method to control only pull up/down/free. | ||
287 | * this function should be replaced by correct gpio function | ||
288 | */ | ||
289 | static void __init gpio_pull_up(u32 addr) | ||
290 | { | ||
291 | u8 data = __raw_readb(addr); | ||
292 | |||
293 | data &= 0x0F; | ||
294 | data |= 0xC0; | ||
295 | __raw_writeb(data, addr); | ||
296 | } | ||
297 | |||
200 | static void __init g4evm_init(void) | 298 | static void __init g4evm_init(void) |
201 | { | 299 | { |
202 | sh7377_pinmux_init(); | 300 | sh7377_pinmux_init(); |
@@ -229,9 +327,6 @@ static void __init g4evm_init(void) | |||
229 | gpio_request(GPIO_FN_EXTLP, NULL); | 327 | gpio_request(GPIO_FN_EXTLP, NULL); |
230 | gpio_request(GPIO_FN_IDIN, NULL); | 328 | gpio_request(GPIO_FN_IDIN, NULL); |
231 | 329 | ||
232 | /* enable clock in SMSTPCR3 */ | ||
233 | __raw_writel(__raw_readl(0xe615013c) & ~(1 << 22), 0xe615013c); | ||
234 | |||
235 | /* setup USB phy */ | 330 | /* setup USB phy */ |
236 | __raw_writew(0x0200, 0xe605810a); /* USBCR1 */ | 331 | __raw_writew(0x0200, 0xe605810a); /* USBCR1 */ |
237 | __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */ | 332 | __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */ |
@@ -253,16 +348,54 @@ static void __init g4evm_init(void) | |||
253 | gpio_request(GPIO_FN_PORT71_KEYIN5_PU, NULL); | 348 | gpio_request(GPIO_FN_PORT71_KEYIN5_PU, NULL); |
254 | gpio_request(GPIO_FN_PORT72_KEYIN6_PU, NULL); | 349 | gpio_request(GPIO_FN_PORT72_KEYIN6_PU, NULL); |
255 | 350 | ||
351 | /* SDHI0 */ | ||
352 | gpio_request(GPIO_FN_SDHICLK0, NULL); | ||
353 | gpio_request(GPIO_FN_SDHICD0, NULL); | ||
354 | gpio_request(GPIO_FN_SDHID0_0, NULL); | ||
355 | gpio_request(GPIO_FN_SDHID0_1, NULL); | ||
356 | gpio_request(GPIO_FN_SDHID0_2, NULL); | ||
357 | gpio_request(GPIO_FN_SDHID0_3, NULL); | ||
358 | gpio_request(GPIO_FN_SDHICMD0, NULL); | ||
359 | gpio_request(GPIO_FN_SDHIWP0, NULL); | ||
360 | gpio_pull_up(GPIO_SDHID0_D0); | ||
361 | gpio_pull_up(GPIO_SDHID0_D1); | ||
362 | gpio_pull_up(GPIO_SDHID0_D2); | ||
363 | gpio_pull_up(GPIO_SDHID0_D3); | ||
364 | gpio_pull_up(GPIO_SDHICMD0); | ||
365 | |||
366 | /* SDHI1 */ | ||
367 | gpio_request(GPIO_FN_SDHICLK1, NULL); | ||
368 | gpio_request(GPIO_FN_SDHID1_0, NULL); | ||
369 | gpio_request(GPIO_FN_SDHID1_1, NULL); | ||
370 | gpio_request(GPIO_FN_SDHID1_2, NULL); | ||
371 | gpio_request(GPIO_FN_SDHID1_3, NULL); | ||
372 | gpio_request(GPIO_FN_SDHICMD1, NULL); | ||
373 | gpio_pull_up(GPIO_SDHID1_D0); | ||
374 | gpio_pull_up(GPIO_SDHID1_D1); | ||
375 | gpio_pull_up(GPIO_SDHID1_D2); | ||
376 | gpio_pull_up(GPIO_SDHID1_D3); | ||
377 | gpio_pull_up(GPIO_SDHICMD1); | ||
378 | |||
256 | sh7377_add_standard_devices(); | 379 | sh7377_add_standard_devices(); |
257 | 380 | ||
258 | platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices)); | 381 | platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices)); |
259 | } | 382 | } |
260 | 383 | ||
384 | static void __init g4evm_timer_init(void) | ||
385 | { | ||
386 | sh7377_clock_init(); | ||
387 | shmobile_timer.init(); | ||
388 | } | ||
389 | |||
390 | static struct sys_timer g4evm_timer = { | ||
391 | .init = g4evm_timer_init, | ||
392 | }; | ||
393 | |||
261 | MACHINE_START(G4EVM, "g4evm") | 394 | MACHINE_START(G4EVM, "g4evm") |
262 | .phys_io = 0xe6000000, | 395 | .phys_io = 0xe6000000, |
263 | .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, | 396 | .io_pg_offst = ((0xe6000000) >> 18) & 0xfffc, |
264 | .map_io = g4evm_map_io, | 397 | .map_io = g4evm_map_io, |
265 | .init_irq = sh7377_init_irq, | 398 | .init_irq = sh7377_init_irq, |
266 | .init_machine = g4evm_init, | 399 | .init_machine = g4evm_init, |
267 | .timer = &shmobile_timer, | 400 | .timer = &g4evm_timer, |
268 | MACHINE_END | 401 | MACHINE_END |
diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c index bb940c6e4e6c..b6454c9f2abb 100644 --- a/arch/arm/mach-shmobile/clock-sh7367.c +++ b/arch/arm/mach-shmobile/clock-sh7367.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Preliminary clock framework support for sh7367 | 2 | * SH7367 clock framework support |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Magnus Damm | 4 | * Copyright (C) 2010 Magnus Damm |
5 | * | 5 | * |
@@ -17,87 +17,342 @@ | |||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
18 | */ | 18 | */ |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/module.h> | ||
21 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
22 | #include <linux/list.h> | 21 | #include <linux/io.h> |
23 | #include <linux/clk.h> | 22 | #include <linux/sh_clk.h> |
23 | #include <mach/common.h> | ||
24 | #include <asm/clkdev.h> | ||
25 | |||
26 | /* SH7367 registers */ | ||
27 | #define RTFRQCR 0xe6150000 | ||
28 | #define SYFRQCR 0xe6150004 | ||
29 | #define CMFRQCR 0xe61500E0 | ||
30 | #define VCLKCR1 0xe6150008 | ||
31 | #define VCLKCR2 0xe615000C | ||
32 | #define VCLKCR3 0xe615001C | ||
33 | #define SCLKACR 0xe6150010 | ||
34 | #define SCLKBCR 0xe6150014 | ||
35 | #define SUBUSBCKCR 0xe6158080 | ||
36 | #define SPUCKCR 0xe6150084 | ||
37 | #define MSUCKCR 0xe6150088 | ||
38 | #define MVI3CKCR 0xe6150090 | ||
39 | #define VOUCKCR 0xe6150094 | ||
40 | #define MFCK1CR 0xe6150098 | ||
41 | #define MFCK2CR 0xe615009C | ||
42 | #define PLLC1CR 0xe6150028 | ||
43 | #define PLLC2CR 0xe615002C | ||
44 | #define RTMSTPCR0 0xe6158030 | ||
45 | #define RTMSTPCR2 0xe6158038 | ||
46 | #define SYMSTPCR0 0xe6158040 | ||
47 | #define SYMSTPCR2 0xe6158048 | ||
48 | #define CMMSTPCR0 0xe615804c | ||
24 | 49 | ||
25 | struct clk { | 50 | /* Fixed 32 KHz root clock from EXTALR pin */ |
26 | const char *name; | 51 | static struct clk r_clk = { |
27 | unsigned long rate; | 52 | .rate = 32768, |
28 | }; | 53 | }; |
29 | 54 | ||
30 | #include <asm/clkdev.h> | 55 | /* |
56 | * 26MHz default rate for the EXTALB1 root input clock. | ||
57 | * If needed, reset this with clk_set_rate() from the platform code. | ||
58 | */ | ||
59 | struct clk sh7367_extalb1_clk = { | ||
60 | .rate = 26666666, | ||
61 | }; | ||
31 | 62 | ||
32 | int __clk_get(struct clk *clk) | 63 | /* |
33 | { | 64 | * 48MHz default rate for the EXTAL2 root input clock. |
34 | return 1; | 65 | * If needed, reset this with clk_set_rate() from the platform code. |
35 | } | 66 | */ |
36 | EXPORT_SYMBOL(__clk_get); | 67 | struct clk sh7367_extal2_clk = { |
68 | .rate = 48000000, | ||
69 | }; | ||
37 | 70 | ||
38 | void __clk_put(struct clk *clk) | 71 | /* A fixed divide-by-2 block */ |
72 | static unsigned long div2_recalc(struct clk *clk) | ||
39 | { | 73 | { |
74 | return clk->parent->rate / 2; | ||
40 | } | 75 | } |
41 | EXPORT_SYMBOL(__clk_put); | ||
42 | 76 | ||
77 | static struct clk_ops div2_clk_ops = { | ||
78 | .recalc = div2_recalc, | ||
79 | }; | ||
80 | |||
81 | /* Divide extalb1 by two */ | ||
82 | static struct clk extalb1_div2_clk = { | ||
83 | .ops = &div2_clk_ops, | ||
84 | .parent = &sh7367_extalb1_clk, | ||
85 | }; | ||
86 | |||
87 | /* Divide extal2 by two */ | ||
88 | static struct clk extal2_div2_clk = { | ||
89 | .ops = &div2_clk_ops, | ||
90 | .parent = &sh7367_extal2_clk, | ||
91 | }; | ||
43 | 92 | ||
44 | int clk_enable(struct clk *clk) | 93 | /* PLLC1 */ |
94 | static unsigned long pllc1_recalc(struct clk *clk) | ||
45 | { | 95 | { |
46 | return 0; | 96 | unsigned long mult = 1; |
97 | |||
98 | if (__raw_readl(PLLC1CR) & (1 << 14)) | ||
99 | mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2; | ||
100 | |||
101 | return clk->parent->rate * mult; | ||
47 | } | 102 | } |
48 | EXPORT_SYMBOL(clk_enable); | ||
49 | 103 | ||
50 | void clk_disable(struct clk *clk) | 104 | static struct clk_ops pllc1_clk_ops = { |
105 | .recalc = pllc1_recalc, | ||
106 | }; | ||
107 | |||
108 | static struct clk pllc1_clk = { | ||
109 | .ops = &pllc1_clk_ops, | ||
110 | .flags = CLK_ENABLE_ON_INIT, | ||
111 | .parent = &extalb1_div2_clk, | ||
112 | }; | ||
113 | |||
114 | /* Divide PLLC1 by two */ | ||
115 | static struct clk pllc1_div2_clk = { | ||
116 | .ops = &div2_clk_ops, | ||
117 | .parent = &pllc1_clk, | ||
118 | }; | ||
119 | |||
120 | /* PLLC2 */ | ||
121 | static unsigned long pllc2_recalc(struct clk *clk) | ||
51 | { | 122 | { |
123 | unsigned long mult = 1; | ||
124 | |||
125 | if (__raw_readl(PLLC2CR) & (1 << 31)) | ||
126 | mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2; | ||
127 | |||
128 | return clk->parent->rate * mult; | ||
52 | } | 129 | } |
53 | EXPORT_SYMBOL(clk_disable); | ||
54 | 130 | ||
55 | unsigned long clk_get_rate(struct clk *clk) | 131 | static struct clk_ops pllc2_clk_ops = { |
132 | .recalc = pllc2_recalc, | ||
133 | }; | ||
134 | |||
135 | static struct clk pllc2_clk = { | ||
136 | .ops = &pllc2_clk_ops, | ||
137 | .flags = CLK_ENABLE_ON_INIT, | ||
138 | .parent = &extalb1_div2_clk, | ||
139 | }; | ||
140 | |||
141 | static struct clk *main_clks[] = { | ||
142 | &r_clk, | ||
143 | &sh7367_extalb1_clk, | ||
144 | &sh7367_extal2_clk, | ||
145 | &extalb1_div2_clk, | ||
146 | &extal2_div2_clk, | ||
147 | &pllc1_clk, | ||
148 | &pllc1_div2_clk, | ||
149 | &pllc2_clk, | ||
150 | }; | ||
151 | |||
152 | static void div4_kick(struct clk *clk) | ||
56 | { | 153 | { |
57 | return clk ? clk->rate : 0; | 154 | unsigned long value; |
155 | |||
156 | /* set KICK bit in SYFRQCR to update hardware setting */ | ||
157 | value = __raw_readl(SYFRQCR); | ||
158 | value |= (1 << 31); | ||
159 | __raw_writel(value, SYFRQCR); | ||
58 | } | 160 | } |
59 | EXPORT_SYMBOL(clk_get_rate); | ||
60 | 161 | ||
61 | /* a static peripheral clock for now - enough to get sh-sci working */ | 162 | static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, |
62 | static struct clk peripheral_clk = { | 163 | 24, 32, 36, 48, 0, 72, 0, 0 }; |
63 | .name = "peripheral_clk", | 164 | |
64 | .rate = 48000000, | 165 | static struct clk_div_mult_table div4_div_mult_table = { |
166 | .divisors = divisors, | ||
167 | .nr_divisors = ARRAY_SIZE(divisors), | ||
65 | }; | 168 | }; |
66 | 169 | ||
67 | /* a static rclk for now - enough to get sh_cmt working */ | 170 | static struct clk_div4_table div4_table = { |
68 | static struct clk r_clk = { | 171 | .div_mult_table = &div4_div_mult_table, |
69 | .name = "r_clk", | 172 | .kick = div4_kick, |
70 | .rate = 32768, | 173 | }; |
174 | |||
175 | enum { DIV4_I, DIV4_G, DIV4_S, DIV4_B, | ||
176 | DIV4_ZX, DIV4_ZT, DIV4_Z, DIV4_ZD, DIV4_HP, | ||
177 | DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR }; | ||
178 | |||
179 | #define DIV4(_reg, _bit, _mask, _flags) \ | ||
180 | SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags) | ||
181 | |||
182 | static struct clk div4_clks[DIV4_NR] = { | ||
183 | [DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT), | ||
184 | [DIV4_G] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT), | ||
185 | [DIV4_S] = DIV4(RTFRQCR, 12, 0x6fff, CLK_ENABLE_ON_INIT), | ||
186 | [DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT), | ||
187 | [DIV4_ZX] = DIV4(SYFRQCR, 20, 0x6fff, 0), | ||
188 | [DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0), | ||
189 | [DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0), | ||
190 | [DIV4_ZD] = DIV4(SYFRQCR, 8, 0x6fff, 0), | ||
191 | [DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0), | ||
192 | [DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0), | ||
193 | [DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0), | ||
194 | [DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0), | ||
195 | [DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0), | ||
71 | }; | 196 | }; |
72 | 197 | ||
73 | /* a static usb0 for now - enough to get r8a66597 working */ | 198 | enum { DIV6_SUB, DIV6_SIUA, DIV6_SIUB, DIV6_MSU, DIV6_SPU, |
74 | static struct clk usb0_clk = { | 199 | DIV6_MVI3, DIV6_MF1, DIV6_MF2, |
75 | .name = "usb0", | 200 | DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_VOU, |
201 | DIV6_NR }; | ||
202 | |||
203 | static struct clk div6_clks[DIV6_NR] = { | ||
204 | [DIV6_SUB] = SH_CLK_DIV6(&sh7367_extal2_clk, SUBUSBCKCR, 0), | ||
205 | [DIV6_SIUA] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKACR, 0), | ||
206 | [DIV6_SIUB] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKBCR, 0), | ||
207 | [DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0), | ||
208 | [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0), | ||
209 | [DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0), | ||
210 | [DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0), | ||
211 | [DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0), | ||
212 | [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0), | ||
213 | [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0), | ||
214 | [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0), | ||
215 | [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0), | ||
76 | }; | 216 | }; |
77 | 217 | ||
78 | /* a static keysc0 clk for now - enough to get sh_keysc working */ | 218 | enum { RTMSTP001, |
79 | static struct clk keysc0_clk = { | 219 | RTMSTP231, RTMSTP230, RTMSTP229, RTMSTP228, RTMSTP226, |
80 | .name = "keysc0", | 220 | RTMSTP216, RTMSTP206, RTMSTP205, RTMSTP201, |
221 | SYMSTP023, SYMSTP007, SYMSTP006, SYMSTP004, | ||
222 | SYMSTP003, SYMSTP002, SYMSTP001, SYMSTP000, | ||
223 | SYMSTP231, SYMSTP229, SYMSTP225, SYMSTP223, SYMSTP222, | ||
224 | SYMSTP215, SYMSTP214, SYMSTP213, SYMSTP211, | ||
225 | CMMSTP003, | ||
226 | MSTP_NR }; | ||
227 | |||
228 | #define MSTP(_parent, _reg, _bit, _flags) \ | ||
229 | SH_CLK_MSTP32(_parent, _reg, _bit, _flags) | ||
230 | |||
231 | static struct clk mstp_clks[MSTP_NR] = { | ||
232 | [RTMSTP001] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR0, 1, 0), /* IIC2 */ | ||
233 | [RTMSTP231] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 31, 0), /* VEU3 */ | ||
234 | [RTMSTP230] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 30, 0), /* VEU2 */ | ||
235 | [RTMSTP229] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 29, 0), /* VEU1 */ | ||
236 | [RTMSTP228] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 28, 0), /* VEU0 */ | ||
237 | [RTMSTP226] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 26, 0), /* VEU2H */ | ||
238 | [RTMSTP216] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR2, 16, 0), /* IIC0 */ | ||
239 | [RTMSTP206] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 6, 0), /* JPU */ | ||
240 | [RTMSTP205] = MSTP(&div6_clks[DIV6_VOU], RTMSTPCR2, 5, 0), /* VOU */ | ||
241 | [RTMSTP201] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 1, 0), /* VPU */ | ||
242 | [SYMSTP023] = MSTP(&div6_clks[DIV6_SPU], SYMSTPCR0, 23, 0), /* SPU1 */ | ||
243 | [SYMSTP007] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 7, 0), /* SCIFA5 */ | ||
244 | [SYMSTP006] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 6, 0), /* SCIFB */ | ||
245 | [SYMSTP004] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 4, 0), /* SCIFA0 */ | ||
246 | [SYMSTP003] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 3, 0), /* SCIFA1 */ | ||
247 | [SYMSTP002] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 2, 0), /* SCIFA2 */ | ||
248 | [SYMSTP001] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 1, 0), /* SCIFA3 */ | ||
249 | [SYMSTP000] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 0, 0), /* SCIFA4 */ | ||
250 | [SYMSTP231] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 31, 0), /* SIU */ | ||
251 | [SYMSTP229] = MSTP(&r_clk, SYMSTPCR2, 29, 0), /* CMT10 */ | ||
252 | [SYMSTP225] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 25, 0), /* IRDA */ | ||
253 | [SYMSTP223] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 23, 0), /* IIC1 */ | ||
254 | [SYMSTP222] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 22, 0), /* USBHS */ | ||
255 | [SYMSTP215] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 15, 0), /* FLCTL */ | ||
256 | [SYMSTP214] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 14, 0), /* SDHI0 */ | ||
257 | [SYMSTP213] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 13, 0), /* SDHI1 */ | ||
258 | [SYMSTP211] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 11, 0), /* SDHI2 */ | ||
259 | [CMMSTP003] = MSTP(&r_clk, CMMSTPCR0, 3, 0), /* KEYSC */ | ||
81 | }; | 260 | }; |
82 | 261 | ||
262 | #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } | ||
263 | #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } | ||
264 | |||
83 | static struct clk_lookup lookups[] = { | 265 | static struct clk_lookup lookups[] = { |
84 | { | 266 | /* main clocks */ |
85 | .clk = &peripheral_clk, | 267 | CLKDEV_CON_ID("r_clk", &r_clk), |
86 | }, { | 268 | CLKDEV_CON_ID("extalb1", &sh7367_extalb1_clk), |
87 | .clk = &r_clk, | 269 | CLKDEV_CON_ID("extal2", &sh7367_extal2_clk), |
88 | }, { | 270 | CLKDEV_CON_ID("extalb1_div2_clk", &extalb1_div2_clk), |
89 | .clk = &usb0_clk, | 271 | CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk), |
90 | }, { | 272 | CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), |
91 | .clk = &keysc0_clk, | 273 | CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), |
92 | } | 274 | CLKDEV_CON_ID("pllc2_clk", &pllc2_clk), |
275 | |||
276 | /* DIV4 clocks */ | ||
277 | CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), | ||
278 | CLKDEV_CON_ID("g_clk", &div4_clks[DIV4_G]), | ||
279 | CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]), | ||
280 | CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]), | ||
281 | CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]), | ||
282 | CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]), | ||
283 | CLKDEV_CON_ID("zd_clk", &div4_clks[DIV4_ZD]), | ||
284 | CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]), | ||
285 | CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]), | ||
286 | CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]), | ||
287 | CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]), | ||
288 | CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]), | ||
289 | |||
290 | /* DIV6 clocks */ | ||
291 | CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), | ||
292 | CLKDEV_CON_ID("siua_clk", &div6_clks[DIV6_SIUA]), | ||
293 | CLKDEV_CON_ID("siub_clk", &div6_clks[DIV6_SIUB]), | ||
294 | CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]), | ||
295 | CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), | ||
296 | CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]), | ||
297 | CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]), | ||
298 | CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]), | ||
299 | CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]), | ||
300 | CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]), | ||
301 | CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), | ||
302 | CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), | ||
303 | |||
304 | /* MSTP32 clocks */ | ||
305 | CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[RTMSTP001]), /* IIC2 */ | ||
306 | CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[RTMSTP231]), /* VEU3 */ | ||
307 | CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[RTMSTP230]), /* VEU2 */ | ||
308 | CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[RTMSTP229]), /* VEU1 */ | ||
309 | CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[RTMSTP228]), /* VEU0 */ | ||
310 | CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[RTMSTP226]), /* VEU2H */ | ||
311 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[RTMSTP216]), /* IIC0 */ | ||
312 | CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[RTMSTP206]), /* JPU */ | ||
313 | CLKDEV_DEV_ID("sh-vou", &mstp_clks[RTMSTP205]), /* VOU */ | ||
314 | CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[RTMSTP201]), /* VPU */ | ||
315 | CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[SYMSTP023]), /* SPU1 */ | ||
316 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[SYMSTP007]), /* SCIFA5 */ | ||
317 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[SYMSTP006]), /* SCIFB */ | ||
318 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[SYMSTP004]), /* SCIFA0 */ | ||
319 | CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[SYMSTP003]), /* SCIFA1 */ | ||
320 | CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[SYMSTP002]), /* SCIFA2 */ | ||
321 | CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[SYMSTP001]), /* SCIFA3 */ | ||
322 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[SYMSTP000]), /* SCIFA4 */ | ||
323 | CLKDEV_DEV_ID("sh_siu", &mstp_clks[SYMSTP231]), /* SIU */ | ||
324 | CLKDEV_CON_ID("cmt1", &mstp_clks[SYMSTP229]), /* CMT10 */ | ||
325 | CLKDEV_DEV_ID("sh_irda", &mstp_clks[SYMSTP225]), /* IRDA */ | ||
326 | CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[SYMSTP223]), /* IIC1 */ | ||
327 | CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[SYMSTP222]), /* USBHS */ | ||
328 | CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[SYMSTP222]), /* USBHS */ | ||
329 | CLKDEV_DEV_ID("sh_flctl", &mstp_clks[SYMSTP215]), /* FLCTL */ | ||
330 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[SYMSTP214]), /* SDHI0 */ | ||
331 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[SYMSTP213]), /* SDHI1 */ | ||
332 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[SYMSTP211]), /* SDHI2 */ | ||
333 | CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[CMMSTP003]), /* KEYSC */ | ||
93 | }; | 334 | }; |
94 | 335 | ||
95 | void __init sh7367_clock_init(void) | 336 | void __init sh7367_clock_init(void) |
96 | { | 337 | { |
97 | int i; | 338 | int k, ret = 0; |
339 | |||
340 | for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) | ||
341 | ret = clk_register(main_clks[k]); | ||
342 | |||
343 | if (!ret) | ||
344 | ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); | ||
345 | |||
346 | if (!ret) | ||
347 | ret = sh_clk_div6_register(div6_clks, DIV6_NR); | ||
348 | |||
349 | if (!ret) | ||
350 | ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); | ||
351 | |||
352 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
98 | 353 | ||
99 | for (i = 0; i < ARRAY_SIZE(lookups); i++) { | 354 | if (!ret) |
100 | lookups[i].con_id = lookups[i].clk->name; | 355 | clk_init(); |
101 | clkdev_add(&lookups[i]); | 356 | else |
102 | } | 357 | panic("failed to setup sh7367 clocks\n"); |
103 | } | 358 | } |
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c new file mode 100644 index 000000000000..fb4e9b1d788e --- /dev/null +++ b/arch/arm/mach-shmobile/clock-sh7372.c | |||
@@ -0,0 +1,560 @@ | |||
1 | /* | ||
2 | * SH7372 clock framework support | ||
3 | * | ||
4 | * Copyright (C) 2010 Magnus Damm | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/sh_clk.h> | ||
23 | #include <mach/common.h> | ||
24 | #include <asm/clkdev.h> | ||
25 | |||
26 | /* SH7372 registers */ | ||
27 | #define FRQCRA 0xe6150000 | ||
28 | #define FRQCRB 0xe6150004 | ||
29 | #define FRQCRC 0xe61500e0 | ||
30 | #define FRQCRD 0xe61500e4 | ||
31 | #define VCLKCR1 0xe6150008 | ||
32 | #define VCLKCR2 0xe615000c | ||
33 | #define VCLKCR3 0xe615001c | ||
34 | #define FMSICKCR 0xe6150010 | ||
35 | #define FMSOCKCR 0xe6150014 | ||
36 | #define FSIACKCR 0xe6150018 | ||
37 | #define FSIBCKCR 0xe6150090 | ||
38 | #define SUBCKCR 0xe6150080 | ||
39 | #define SPUCKCR 0xe6150084 | ||
40 | #define VOUCKCR 0xe6150088 | ||
41 | #define HDMICKCR 0xe6150094 | ||
42 | #define DSITCKCR 0xe6150060 | ||
43 | #define DSI0PCKCR 0xe6150064 | ||
44 | #define DSI1PCKCR 0xe6150098 | ||
45 | #define PLLC01CR 0xe6150028 | ||
46 | #define PLLC2CR 0xe615002c | ||
47 | #define SMSTPCR0 0xe6150130 | ||
48 | #define SMSTPCR1 0xe6150134 | ||
49 | #define SMSTPCR2 0xe6150138 | ||
50 | #define SMSTPCR3 0xe615013c | ||
51 | #define SMSTPCR4 0xe6150140 | ||
52 | |||
53 | /* Platforms must set frequency on their DV_CLKI pin */ | ||
54 | struct clk dv_clki_clk = { | ||
55 | }; | ||
56 | |||
57 | /* Fixed 32 KHz root clock from EXTALR pin */ | ||
58 | static struct clk r_clk = { | ||
59 | .rate = 32768, | ||
60 | }; | ||
61 | |||
62 | /* | ||
63 | * 26MHz default rate for the EXTAL1 root input clock. | ||
64 | * If needed, reset this with clk_set_rate() from the platform code. | ||
65 | */ | ||
66 | struct clk sh7372_extal1_clk = { | ||
67 | .rate = 26000000, | ||
68 | }; | ||
69 | |||
70 | /* | ||
71 | * 48MHz default rate for the EXTAL2 root input clock. | ||
72 | * If needed, reset this with clk_set_rate() from the platform code. | ||
73 | */ | ||
74 | struct clk sh7372_extal2_clk = { | ||
75 | .rate = 48000000, | ||
76 | }; | ||
77 | |||
78 | /* A fixed divide-by-2 block */ | ||
79 | static unsigned long div2_recalc(struct clk *clk) | ||
80 | { | ||
81 | return clk->parent->rate / 2; | ||
82 | } | ||
83 | |||
84 | static struct clk_ops div2_clk_ops = { | ||
85 | .recalc = div2_recalc, | ||
86 | }; | ||
87 | |||
88 | /* Divide dv_clki by two */ | ||
89 | struct clk dv_clki_div2_clk = { | ||
90 | .ops = &div2_clk_ops, | ||
91 | .parent = &dv_clki_clk, | ||
92 | }; | ||
93 | |||
94 | /* Divide extal1 by two */ | ||
95 | static struct clk extal1_div2_clk = { | ||
96 | .ops = &div2_clk_ops, | ||
97 | .parent = &sh7372_extal1_clk, | ||
98 | }; | ||
99 | |||
100 | /* Divide extal2 by two */ | ||
101 | static struct clk extal2_div2_clk = { | ||
102 | .ops = &div2_clk_ops, | ||
103 | .parent = &sh7372_extal2_clk, | ||
104 | }; | ||
105 | |||
106 | /* Divide extal2 by four */ | ||
107 | static struct clk extal2_div4_clk = { | ||
108 | .ops = &div2_clk_ops, | ||
109 | .parent = &extal2_div2_clk, | ||
110 | }; | ||
111 | |||
112 | /* PLLC0 and PLLC1 */ | ||
113 | static unsigned long pllc01_recalc(struct clk *clk) | ||
114 | { | ||
115 | unsigned long mult = 1; | ||
116 | |||
117 | if (__raw_readl(PLLC01CR) & (1 << 14)) | ||
118 | mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1) * 2; | ||
119 | |||
120 | return clk->parent->rate * mult; | ||
121 | } | ||
122 | |||
123 | static struct clk_ops pllc01_clk_ops = { | ||
124 | .recalc = pllc01_recalc, | ||
125 | }; | ||
126 | |||
127 | static struct clk pllc0_clk = { | ||
128 | .ops = &pllc01_clk_ops, | ||
129 | .flags = CLK_ENABLE_ON_INIT, | ||
130 | .parent = &extal1_div2_clk, | ||
131 | .enable_reg = (void __iomem *)FRQCRC, | ||
132 | }; | ||
133 | |||
134 | static struct clk pllc1_clk = { | ||
135 | .ops = &pllc01_clk_ops, | ||
136 | .flags = CLK_ENABLE_ON_INIT, | ||
137 | .parent = &extal1_div2_clk, | ||
138 | .enable_reg = (void __iomem *)FRQCRA, | ||
139 | }; | ||
140 | |||
141 | /* Divide PLLC1 by two */ | ||
142 | static struct clk pllc1_div2_clk = { | ||
143 | .ops = &div2_clk_ops, | ||
144 | .parent = &pllc1_clk, | ||
145 | }; | ||
146 | |||
147 | /* PLLC2 */ | ||
148 | |||
149 | /* Indices are important - they are the actual src selecting values */ | ||
150 | static struct clk *pllc2_parent[] = { | ||
151 | [0] = &extal1_div2_clk, | ||
152 | [1] = &extal2_div2_clk, | ||
153 | [2] = &dv_clki_div2_clk, | ||
154 | }; | ||
155 | |||
156 | /* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */ | ||
157 | static struct cpufreq_frequency_table pllc2_freq_table[29]; | ||
158 | |||
159 | static void pllc2_table_rebuild(struct clk *clk) | ||
160 | { | ||
161 | int i; | ||
162 | |||
163 | /* Initialise PLLC2 frequency table */ | ||
164 | for (i = 0; i < ARRAY_SIZE(pllc2_freq_table) - 2; i++) { | ||
165 | pllc2_freq_table[i].frequency = clk->parent->rate * (i + 20) * 2; | ||
166 | pllc2_freq_table[i].index = i; | ||
167 | } | ||
168 | |||
169 | /* This is a special entry - switching PLL off makes it a repeater */ | ||
170 | pllc2_freq_table[i].frequency = clk->parent->rate; | ||
171 | pllc2_freq_table[i].index = i; | ||
172 | |||
173 | pllc2_freq_table[++i].frequency = CPUFREQ_TABLE_END; | ||
174 | pllc2_freq_table[i].index = i; | ||
175 | } | ||
176 | |||
177 | static unsigned long pllc2_recalc(struct clk *clk) | ||
178 | { | ||
179 | unsigned long mult = 1; | ||
180 | |||
181 | pllc2_table_rebuild(clk); | ||
182 | |||
183 | /* | ||
184 | * If the PLL is off, mult == 1, clk->rate will be updated in | ||
185 | * pllc2_enable(). | ||
186 | */ | ||
187 | if (__raw_readl(PLLC2CR) & (1 << 31)) | ||
188 | mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2; | ||
189 | |||
190 | return clk->parent->rate * mult; | ||
191 | } | ||
192 | |||
193 | static long pllc2_round_rate(struct clk *clk, unsigned long rate) | ||
194 | { | ||
195 | return clk_rate_table_round(clk, clk->freq_table, rate); | ||
196 | } | ||
197 | |||
198 | static int pllc2_enable(struct clk *clk) | ||
199 | { | ||
200 | int i; | ||
201 | |||
202 | __raw_writel(__raw_readl(PLLC2CR) | 0x80000000, PLLC2CR); | ||
203 | |||
204 | for (i = 0; i < 100; i++) | ||
205 | if (__raw_readl(PLLC2CR) & 0x80000000) { | ||
206 | clk->rate = pllc2_recalc(clk); | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | pr_err("%s(): timeout!\n", __func__); | ||
211 | |||
212 | return -ETIMEDOUT; | ||
213 | } | ||
214 | |||
215 | static void pllc2_disable(struct clk *clk) | ||
216 | { | ||
217 | __raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR); | ||
218 | } | ||
219 | |||
220 | static int pllc2_set_rate(struct clk *clk, | ||
221 | unsigned long rate, int algo_id) | ||
222 | { | ||
223 | unsigned long value; | ||
224 | int idx; | ||
225 | |||
226 | idx = clk_rate_table_find(clk, clk->freq_table, rate); | ||
227 | if (idx < 0) | ||
228 | return idx; | ||
229 | |||
230 | if (rate == clk->parent->rate) { | ||
231 | pllc2_disable(clk); | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | value = __raw_readl(PLLC2CR) & ~(0x3f << 24); | ||
236 | |||
237 | if (value & 0x80000000) | ||
238 | pllc2_disable(clk); | ||
239 | |||
240 | __raw_writel((value & ~0x80000000) | ((idx + 19) << 24), PLLC2CR); | ||
241 | |||
242 | if (value & 0x80000000) | ||
243 | return pllc2_enable(clk); | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static int pllc2_set_parent(struct clk *clk, struct clk *parent) | ||
249 | { | ||
250 | u32 value; | ||
251 | int ret, i; | ||
252 | |||
253 | if (!clk->parent_table || !clk->parent_num) | ||
254 | return -EINVAL; | ||
255 | |||
256 | /* Search the parent */ | ||
257 | for (i = 0; i < clk->parent_num; i++) | ||
258 | if (clk->parent_table[i] == parent) | ||
259 | break; | ||
260 | |||
261 | if (i == clk->parent_num) | ||
262 | return -ENODEV; | ||
263 | |||
264 | ret = clk_reparent(clk, parent); | ||
265 | if (ret < 0) | ||
266 | return ret; | ||
267 | |||
268 | value = __raw_readl(PLLC2CR) & ~(3 << 6); | ||
269 | |||
270 | __raw_writel(value | (i << 6), PLLC2CR); | ||
271 | |||
272 | /* Rebiuld the frequency table */ | ||
273 | pllc2_table_rebuild(clk); | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static struct clk_ops pllc2_clk_ops = { | ||
279 | .recalc = pllc2_recalc, | ||
280 | .round_rate = pllc2_round_rate, | ||
281 | .set_rate = pllc2_set_rate, | ||
282 | .enable = pllc2_enable, | ||
283 | .disable = pllc2_disable, | ||
284 | .set_parent = pllc2_set_parent, | ||
285 | }; | ||
286 | |||
287 | struct clk pllc2_clk = { | ||
288 | .ops = &pllc2_clk_ops, | ||
289 | .flags = CLK_ENABLE_ON_INIT, | ||
290 | .parent = &extal1_div2_clk, | ||
291 | .freq_table = pllc2_freq_table, | ||
292 | .parent_table = pllc2_parent, | ||
293 | .parent_num = ARRAY_SIZE(pllc2_parent), | ||
294 | }; | ||
295 | |||
296 | static struct clk *main_clks[] = { | ||
297 | &dv_clki_clk, | ||
298 | &r_clk, | ||
299 | &sh7372_extal1_clk, | ||
300 | &sh7372_extal2_clk, | ||
301 | &dv_clki_div2_clk, | ||
302 | &extal1_div2_clk, | ||
303 | &extal2_div2_clk, | ||
304 | &extal2_div4_clk, | ||
305 | &pllc0_clk, | ||
306 | &pllc1_clk, | ||
307 | &pllc1_div2_clk, | ||
308 | &pllc2_clk, | ||
309 | }; | ||
310 | |||
311 | static void div4_kick(struct clk *clk) | ||
312 | { | ||
313 | unsigned long value; | ||
314 | |||
315 | /* set KICK bit in FRQCRB to update hardware setting */ | ||
316 | value = __raw_readl(FRQCRB); | ||
317 | value |= (1 << 31); | ||
318 | __raw_writel(value, FRQCRB); | ||
319 | } | ||
320 | |||
321 | static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, | ||
322 | 24, 32, 36, 48, 0, 72, 96, 0 }; | ||
323 | |||
324 | static struct clk_div_mult_table div4_div_mult_table = { | ||
325 | .divisors = divisors, | ||
326 | .nr_divisors = ARRAY_SIZE(divisors), | ||
327 | }; | ||
328 | |||
329 | static struct clk_div4_table div4_table = { | ||
330 | .div_mult_table = &div4_div_mult_table, | ||
331 | .kick = div4_kick, | ||
332 | }; | ||
333 | |||
334 | enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR, | ||
335 | DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP, | ||
336 | DIV4_ISPB, DIV4_S, DIV4_ZB, DIV4_ZB3, DIV4_CP, | ||
337 | DIV4_DDRP, DIV4_NR }; | ||
338 | |||
339 | #define DIV4(_reg, _bit, _mask, _flags) \ | ||
340 | SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags) | ||
341 | |||
342 | static struct clk div4_clks[DIV4_NR] = { | ||
343 | [DIV4_I] = DIV4(FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT), | ||
344 | [DIV4_ZG] = DIV4(FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT), | ||
345 | [DIV4_B] = DIV4(FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT), | ||
346 | [DIV4_M1] = DIV4(FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT), | ||
347 | [DIV4_CSIR] = DIV4(FRQCRA, 0, 0x6fff, 0), | ||
348 | [DIV4_ZTR] = DIV4(FRQCRB, 20, 0x6fff, 0), | ||
349 | [DIV4_ZT] = DIV4(FRQCRB, 16, 0x6fff, 0), | ||
350 | [DIV4_ZX] = DIV4(FRQCRB, 12, 0x6fff, 0), | ||
351 | [DIV4_HP] = DIV4(FRQCRB, 4, 0x6fff, 0), | ||
352 | [DIV4_ISPB] = DIV4(FRQCRC, 20, 0x6fff, 0), | ||
353 | [DIV4_S] = DIV4(FRQCRC, 12, 0x6fff, 0), | ||
354 | [DIV4_ZB] = DIV4(FRQCRC, 8, 0x6fff, 0), | ||
355 | [DIV4_ZB3] = DIV4(FRQCRC, 4, 0x6fff, 0), | ||
356 | [DIV4_CP] = DIV4(FRQCRC, 0, 0x6fff, 0), | ||
357 | [DIV4_DDRP] = DIV4(FRQCRD, 0, 0x677c, 0), | ||
358 | }; | ||
359 | |||
360 | enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO, | ||
361 | DIV6_FSIA, DIV6_FSIB, DIV6_SUB, DIV6_SPU, | ||
362 | DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P, | ||
363 | DIV6_NR }; | ||
364 | |||
365 | static struct clk div6_clks[DIV6_NR] = { | ||
366 | [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0), | ||
367 | [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0), | ||
368 | [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0), | ||
369 | [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0), | ||
370 | [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0), | ||
371 | [DIV6_FSIA] = SH_CLK_DIV6(&pllc1_div2_clk, FSIACKCR, 0), | ||
372 | [DIV6_FSIB] = SH_CLK_DIV6(&pllc1_div2_clk, FSIBCKCR, 0), | ||
373 | [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0), | ||
374 | [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0), | ||
375 | [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0), | ||
376 | [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0), | ||
377 | [DIV6_DSI0P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI0PCKCR, 0), | ||
378 | [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0), | ||
379 | }; | ||
380 | |||
381 | enum { DIV6_HDMI, DIV6_REPARENT_NR }; | ||
382 | |||
383 | /* Indices are important - they are the actual src selecting values */ | ||
384 | static struct clk *hdmi_parent[] = { | ||
385 | [0] = &pllc1_div2_clk, | ||
386 | [1] = &pllc2_clk, | ||
387 | [2] = &dv_clki_clk, | ||
388 | [3] = NULL, /* pllc2_div4 not implemented yet */ | ||
389 | }; | ||
390 | |||
391 | static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { | ||
392 | [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0, | ||
393 | hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2), | ||
394 | }; | ||
395 | |||
396 | enum { MSTP001, | ||
397 | MSTP131, MSTP130, | ||
398 | MSTP129, MSTP128, | ||
399 | MSTP118, MSTP117, MSTP116, | ||
400 | MSTP106, MSTP101, MSTP100, | ||
401 | MSTP223, | ||
402 | MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, | ||
403 | MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, | ||
404 | MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403, | ||
405 | MSTP_NR }; | ||
406 | |||
407 | #define MSTP(_parent, _reg, _bit, _flags) \ | ||
408 | SH_CLK_MSTP32(_parent, _reg, _bit, _flags) | ||
409 | |||
410 | static struct clk mstp_clks[MSTP_NR] = { | ||
411 | [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */ | ||
412 | [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */ | ||
413 | [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */ | ||
414 | [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */ | ||
415 | [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */ | ||
416 | [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */ | ||
417 | [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ | ||
418 | [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ | ||
419 | [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */ | ||
420 | [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */ | ||
421 | [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */ | ||
422 | [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */ | ||
423 | [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ | ||
424 | [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ | ||
425 | [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ | ||
426 | [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */ | ||
427 | [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */ | ||
428 | [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ | ||
429 | [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ | ||
430 | [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ | ||
431 | [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, CLK_ENABLE_ON_INIT), /* FSIA */ | ||
432 | [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ | ||
433 | [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ | ||
434 | [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ | ||
435 | [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */ | ||
436 | [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */ | ||
437 | [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */ | ||
438 | [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */ | ||
439 | [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */ | ||
440 | [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */ | ||
441 | [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */ | ||
442 | [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ | ||
443 | }; | ||
444 | |||
445 | #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } | ||
446 | #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } | ||
447 | |||
448 | static struct clk_lookup lookups[] = { | ||
449 | /* main clocks */ | ||
450 | CLKDEV_CON_ID("dv_clki_div2_clk", &dv_clki_div2_clk), | ||
451 | CLKDEV_CON_ID("r_clk", &r_clk), | ||
452 | CLKDEV_CON_ID("extal1", &sh7372_extal1_clk), | ||
453 | CLKDEV_CON_ID("extal2", &sh7372_extal2_clk), | ||
454 | CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk), | ||
455 | CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk), | ||
456 | CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk), | ||
457 | CLKDEV_CON_ID("pllc0_clk", &pllc0_clk), | ||
458 | CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), | ||
459 | CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), | ||
460 | CLKDEV_CON_ID("pllc2_clk", &pllc2_clk), | ||
461 | |||
462 | /* DIV4 clocks */ | ||
463 | CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), | ||
464 | CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]), | ||
465 | CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]), | ||
466 | CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]), | ||
467 | CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]), | ||
468 | CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]), | ||
469 | CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]), | ||
470 | CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]), | ||
471 | CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]), | ||
472 | CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]), | ||
473 | CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]), | ||
474 | CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]), | ||
475 | CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]), | ||
476 | CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]), | ||
477 | CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]), | ||
478 | |||
479 | /* DIV6 clocks */ | ||
480 | CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]), | ||
481 | CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]), | ||
482 | CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), | ||
483 | CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]), | ||
484 | CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]), | ||
485 | CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FSIA]), | ||
486 | CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FSIB]), | ||
487 | CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), | ||
488 | CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), | ||
489 | CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), | ||
490 | CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]), | ||
491 | CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]), | ||
492 | CLKDEV_CON_ID("dsi0p_clk", &div6_clks[DIV6_DSI0P]), | ||
493 | CLKDEV_CON_ID("dsi1p_clk", &div6_clks[DIV6_DSI1P]), | ||
494 | |||
495 | /* MSTP32 clocks */ | ||
496 | CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ | ||
497 | CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */ | ||
498 | CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ | ||
499 | CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */ | ||
500 | CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */ | ||
501 | CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */ | ||
502 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ | ||
503 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ | ||
504 | CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */ | ||
505 | CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */ | ||
506 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ | ||
507 | CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */ | ||
508 | CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */ | ||
509 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ | ||
510 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */ | ||
511 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ | ||
512 | CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ | ||
513 | CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */ | ||
514 | CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ | ||
515 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ | ||
516 | CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */ | ||
517 | CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */ | ||
518 | CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ | ||
519 | CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */ | ||
520 | CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP323]), /* USB0 */ | ||
521 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ | ||
522 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ | ||
523 | CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */ | ||
524 | CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */ | ||
525 | CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */ | ||
526 | CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */ | ||
527 | CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */ | ||
528 | CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ | ||
529 | CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ | ||
530 | CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ | ||
531 | {.con_id = "ick", .dev_id = "sh-mobile-hdmi", .clk = &div6_reparent_clks[DIV6_HDMI]}, | ||
532 | }; | ||
533 | |||
534 | void __init sh7372_clock_init(void) | ||
535 | { | ||
536 | int k, ret = 0; | ||
537 | |||
538 | for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) | ||
539 | ret = clk_register(main_clks[k]); | ||
540 | |||
541 | if (!ret) | ||
542 | ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); | ||
543 | |||
544 | if (!ret) | ||
545 | ret = sh_clk_div6_register(div6_clks, DIV6_NR); | ||
546 | |||
547 | if (!ret) | ||
548 | ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_NR); | ||
549 | |||
550 | if (!ret) | ||
551 | ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); | ||
552 | |||
553 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
554 | |||
555 | if (!ret) | ||
556 | clk_init(); | ||
557 | else | ||
558 | panic("failed to setup sh7372 clocks\n"); | ||
559 | |||
560 | } | ||
diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c new file mode 100644 index 000000000000..e007c28cf0a8 --- /dev/null +++ b/arch/arm/mach-shmobile/clock-sh7377.c | |||
@@ -0,0 +1,369 @@ | |||
1 | /* | ||
2 | * SH7377 clock framework support | ||
3 | * | ||
4 | * Copyright (C) 2010 Magnus Damm | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/sh_clk.h> | ||
23 | #include <mach/common.h> | ||
24 | #include <asm/clkdev.h> | ||
25 | |||
26 | /* SH7377 registers */ | ||
27 | #define RTFRQCR 0xe6150000 | ||
28 | #define SYFRQCR 0xe6150004 | ||
29 | #define CMFRQCR 0xe61500E0 | ||
30 | #define VCLKCR1 0xe6150008 | ||
31 | #define VCLKCR2 0xe615000C | ||
32 | #define VCLKCR3 0xe615001C | ||
33 | #define FMSICKCR 0xe6150010 | ||
34 | #define FMSOCKCR 0xe6150014 | ||
35 | #define FSICKCR 0xe6150018 | ||
36 | #define PLLC1CR 0xe6150028 | ||
37 | #define PLLC2CR 0xe615002C | ||
38 | #define SUBUSBCKCR 0xe6150080 | ||
39 | #define SPUCKCR 0xe6150084 | ||
40 | #define MSUCKCR 0xe6150088 | ||
41 | #define MVI3CKCR 0xe6150090 | ||
42 | #define HDMICKCR 0xe6150094 | ||
43 | #define MFCK1CR 0xe6150098 | ||
44 | #define MFCK2CR 0xe615009C | ||
45 | #define DSITCKCR 0xe6150060 | ||
46 | #define DSIPCKCR 0xe6150064 | ||
47 | #define SMSTPCR0 0xe6150130 | ||
48 | #define SMSTPCR1 0xe6150134 | ||
49 | #define SMSTPCR2 0xe6150138 | ||
50 | #define SMSTPCR3 0xe615013C | ||
51 | #define SMSTPCR4 0xe6150140 | ||
52 | |||
53 | /* Fixed 32 KHz root clock from EXTALR pin */ | ||
54 | static struct clk r_clk = { | ||
55 | .rate = 32768, | ||
56 | }; | ||
57 | |||
58 | /* | ||
59 | * 26MHz default rate for the EXTALC1 root input clock. | ||
60 | * If needed, reset this with clk_set_rate() from the platform code. | ||
61 | */ | ||
62 | struct clk sh7377_extalc1_clk = { | ||
63 | .rate = 26666666, | ||
64 | }; | ||
65 | |||
66 | /* | ||
67 | * 48MHz default rate for the EXTAL2 root input clock. | ||
68 | * If needed, reset this with clk_set_rate() from the platform code. | ||
69 | */ | ||
70 | struct clk sh7377_extal2_clk = { | ||
71 | .rate = 48000000, | ||
72 | }; | ||
73 | |||
74 | /* A fixed divide-by-2 block */ | ||
75 | static unsigned long div2_recalc(struct clk *clk) | ||
76 | { | ||
77 | return clk->parent->rate / 2; | ||
78 | } | ||
79 | |||
80 | static struct clk_ops div2_clk_ops = { | ||
81 | .recalc = div2_recalc, | ||
82 | }; | ||
83 | |||
84 | /* Divide extalc1 by two */ | ||
85 | static struct clk extalc1_div2_clk = { | ||
86 | .ops = &div2_clk_ops, | ||
87 | .parent = &sh7377_extalc1_clk, | ||
88 | }; | ||
89 | |||
90 | /* Divide extal2 by two */ | ||
91 | static struct clk extal2_div2_clk = { | ||
92 | .ops = &div2_clk_ops, | ||
93 | .parent = &sh7377_extal2_clk, | ||
94 | }; | ||
95 | |||
96 | /* Divide extal2 by four */ | ||
97 | static struct clk extal2_div4_clk = { | ||
98 | .ops = &div2_clk_ops, | ||
99 | .parent = &extal2_div2_clk, | ||
100 | }; | ||
101 | |||
102 | /* PLLC1 */ | ||
103 | static unsigned long pllc1_recalc(struct clk *clk) | ||
104 | { | ||
105 | unsigned long mult = 1; | ||
106 | |||
107 | if (__raw_readl(PLLC1CR) & (1 << 14)) | ||
108 | mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2; | ||
109 | |||
110 | return clk->parent->rate * mult; | ||
111 | } | ||
112 | |||
113 | static struct clk_ops pllc1_clk_ops = { | ||
114 | .recalc = pllc1_recalc, | ||
115 | }; | ||
116 | |||
117 | static struct clk pllc1_clk = { | ||
118 | .ops = &pllc1_clk_ops, | ||
119 | .flags = CLK_ENABLE_ON_INIT, | ||
120 | .parent = &extalc1_div2_clk, | ||
121 | }; | ||
122 | |||
123 | /* Divide PLLC1 by two */ | ||
124 | static struct clk pllc1_div2_clk = { | ||
125 | .ops = &div2_clk_ops, | ||
126 | .parent = &pllc1_clk, | ||
127 | }; | ||
128 | |||
129 | /* PLLC2 */ | ||
130 | static unsigned long pllc2_recalc(struct clk *clk) | ||
131 | { | ||
132 | unsigned long mult = 1; | ||
133 | |||
134 | if (__raw_readl(PLLC2CR) & (1 << 31)) | ||
135 | mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2; | ||
136 | |||
137 | return clk->parent->rate * mult; | ||
138 | } | ||
139 | |||
140 | static struct clk_ops pllc2_clk_ops = { | ||
141 | .recalc = pllc2_recalc, | ||
142 | }; | ||
143 | |||
144 | static struct clk pllc2_clk = { | ||
145 | .ops = &pllc2_clk_ops, | ||
146 | .flags = CLK_ENABLE_ON_INIT, | ||
147 | .parent = &extalc1_div2_clk, | ||
148 | }; | ||
149 | |||
150 | static struct clk *main_clks[] = { | ||
151 | &r_clk, | ||
152 | &sh7377_extalc1_clk, | ||
153 | &sh7377_extal2_clk, | ||
154 | &extalc1_div2_clk, | ||
155 | &extal2_div2_clk, | ||
156 | &extal2_div4_clk, | ||
157 | &pllc1_clk, | ||
158 | &pllc1_div2_clk, | ||
159 | &pllc2_clk, | ||
160 | }; | ||
161 | |||
162 | static void div4_kick(struct clk *clk) | ||
163 | { | ||
164 | unsigned long value; | ||
165 | |||
166 | /* set KICK bit in SYFRQCR to update hardware setting */ | ||
167 | value = __raw_readl(SYFRQCR); | ||
168 | value |= (1 << 31); | ||
169 | __raw_writel(value, SYFRQCR); | ||
170 | } | ||
171 | |||
172 | static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, | ||
173 | 24, 32, 36, 48, 0, 72, 96, 0 }; | ||
174 | |||
175 | static struct clk_div_mult_table div4_div_mult_table = { | ||
176 | .divisors = divisors, | ||
177 | .nr_divisors = ARRAY_SIZE(divisors), | ||
178 | }; | ||
179 | |||
180 | static struct clk_div4_table div4_table = { | ||
181 | .div_mult_table = &div4_div_mult_table, | ||
182 | .kick = div4_kick, | ||
183 | }; | ||
184 | |||
185 | enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR, | ||
186 | DIV4_ZTR, DIV4_ZT, DIV4_Z, DIV4_HP, | ||
187 | DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR }; | ||
188 | |||
189 | #define DIV4(_reg, _bit, _mask, _flags) \ | ||
190 | SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags) | ||
191 | |||
192 | static struct clk div4_clks[DIV4_NR] = { | ||
193 | [DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT), | ||
194 | [DIV4_ZG] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT), | ||
195 | [DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT), | ||
196 | [DIV4_M1] = DIV4(RTFRQCR, 4, 0x6fff, CLK_ENABLE_ON_INIT), | ||
197 | [DIV4_CSIR] = DIV4(RTFRQCR, 0, 0x6fff, 0), | ||
198 | [DIV4_ZTR] = DIV4(SYFRQCR, 20, 0x6fff, 0), | ||
199 | [DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0), | ||
200 | [DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0), | ||
201 | [DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0), | ||
202 | [DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0), | ||
203 | [DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0), | ||
204 | [DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0), | ||
205 | [DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0), | ||
206 | }; | ||
207 | |||
208 | enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO, | ||
209 | DIV6_FSI, DIV6_SUB, DIV6_SPU, DIV6_MSU, DIV6_MVI3, DIV6_HDMI, | ||
210 | DIV6_MF1, DIV6_MF2, DIV6_DSIT, DIV6_DSIP, | ||
211 | DIV6_NR }; | ||
212 | |||
213 | static struct clk div6_clks[] = { | ||
214 | [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0), | ||
215 | [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0), | ||
216 | [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0), | ||
217 | [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0), | ||
218 | [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0), | ||
219 | [DIV6_FSI] = SH_CLK_DIV6(&pllc1_div2_clk, FSICKCR, 0), | ||
220 | [DIV6_SUB] = SH_CLK_DIV6(&sh7377_extal2_clk, SUBUSBCKCR, 0), | ||
221 | [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0), | ||
222 | [DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0), | ||
223 | [DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0), | ||
224 | [DIV6_HDMI] = SH_CLK_DIV6(&pllc1_div2_clk, HDMICKCR, 0), | ||
225 | [DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0), | ||
226 | [DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0), | ||
227 | [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0), | ||
228 | [DIV6_DSIP] = SH_CLK_DIV6(&pllc1_div2_clk, DSIPCKCR, 0), | ||
229 | }; | ||
230 | |||
231 | enum { MSTP001, | ||
232 | MSTP131, MSTP130, MSTP129, MSTP128, MSTP116, MSTP106, MSTP101, | ||
233 | MSTP223, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, | ||
234 | MSTP331, MSTP329, MSTP325, MSTP323, MSTP322, | ||
235 | MSTP315, MSTP314, MSTP313, | ||
236 | MSTP403, | ||
237 | MSTP_NR }; | ||
238 | |||
239 | #define MSTP(_parent, _reg, _bit, _flags) \ | ||
240 | SH_CLK_MSTP32(_parent, _reg, _bit, _flags) | ||
241 | |||
242 | static struct clk mstp_clks[] = { | ||
243 | [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */ | ||
244 | [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */ | ||
245 | [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */ | ||
246 | [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */ | ||
247 | [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */ | ||
248 | [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ | ||
249 | [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */ | ||
250 | [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */ | ||
251 | [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */ | ||
252 | [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ | ||
253 | [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ | ||
254 | [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ | ||
255 | [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */ | ||
256 | [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */ | ||
257 | [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ | ||
258 | [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ | ||
259 | [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */ | ||
260 | [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ | ||
261 | [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IRDA */ | ||
262 | [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ | ||
263 | [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ | ||
264 | [MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL */ | ||
265 | [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ | ||
266 | [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */ | ||
267 | [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ | ||
268 | }; | ||
269 | |||
270 | #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } | ||
271 | #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } | ||
272 | |||
273 | static struct clk_lookup lookups[] = { | ||
274 | /* main clocks */ | ||
275 | CLKDEV_CON_ID("r_clk", &r_clk), | ||
276 | CLKDEV_CON_ID("extalc1", &sh7377_extalc1_clk), | ||
277 | CLKDEV_CON_ID("extal2", &sh7377_extal2_clk), | ||
278 | CLKDEV_CON_ID("extalc1_div2_clk", &extalc1_div2_clk), | ||
279 | CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk), | ||
280 | CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk), | ||
281 | CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), | ||
282 | CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), | ||
283 | CLKDEV_CON_ID("pllc2_clk", &pllc2_clk), | ||
284 | |||
285 | /* DIV4 clocks */ | ||
286 | CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), | ||
287 | CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]), | ||
288 | CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]), | ||
289 | CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]), | ||
290 | CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]), | ||
291 | CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]), | ||
292 | CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]), | ||
293 | CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]), | ||
294 | CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]), | ||
295 | CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]), | ||
296 | CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]), | ||
297 | CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]), | ||
298 | CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]), | ||
299 | |||
300 | /* DIV6 clocks */ | ||
301 | CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]), | ||
302 | CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]), | ||
303 | CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), | ||
304 | CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]), | ||
305 | CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]), | ||
306 | CLKDEV_CON_ID("fsi_clk", &div6_clks[DIV6_FSI]), | ||
307 | CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), | ||
308 | CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), | ||
309 | CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]), | ||
310 | CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]), | ||
311 | CLKDEV_CON_ID("hdmi_clk", &div6_clks[DIV6_HDMI]), | ||
312 | CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]), | ||
313 | CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]), | ||
314 | CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]), | ||
315 | CLKDEV_CON_ID("dsip_clk", &div6_clks[DIV6_DSIP]), | ||
316 | |||
317 | /* MSTP32 clocks */ | ||
318 | CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */ | ||
319 | CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */ | ||
320 | CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ | ||
321 | CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */ | ||
322 | CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */ | ||
323 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ | ||
324 | CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */ | ||
325 | CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */ | ||
326 | CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */ | ||
327 | CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */ | ||
328 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ | ||
329 | CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP206]), /* SCIFB */ | ||
330 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ | ||
331 | CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ | ||
332 | CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */ | ||
333 | CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ | ||
334 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ | ||
335 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */ | ||
336 | CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */ | ||
337 | CLKDEV_DEV_ID("sh_irda", &mstp_clks[MSTP325]), /* IRDA */ | ||
338 | CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ | ||
339 | CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USBHS */ | ||
340 | CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USBHS */ | ||
341 | CLKDEV_DEV_ID("sh_flctl", &mstp_clks[MSTP315]), /* FLCTL */ | ||
342 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ | ||
343 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ | ||
344 | CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ | ||
345 | }; | ||
346 | |||
347 | void __init sh7377_clock_init(void) | ||
348 | { | ||
349 | int k, ret = 0; | ||
350 | |||
351 | for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) | ||
352 | ret = clk_register(main_clks[k]); | ||
353 | |||
354 | if (!ret) | ||
355 | ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); | ||
356 | |||
357 | if (!ret) | ||
358 | ret = sh_clk_div6_register(div6_clks, DIV6_NR); | ||
359 | |||
360 | if (!ret) | ||
361 | ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); | ||
362 | |||
363 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
364 | |||
365 | if (!ret) | ||
366 | clk_init(); | ||
367 | else | ||
368 | panic("failed to setup sh7377 clocks\n"); | ||
369 | } | ||
diff --git a/arch/arm/mach-shmobile/clock.c b/arch/arm/mach-shmobile/clock.c new file mode 100644 index 000000000000..b7c705a213a2 --- /dev/null +++ b/arch/arm/mach-shmobile/clock.c | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * SH-Mobile Timer | ||
3 | * | ||
4 | * Copyright (C) 2010 Magnus Damm | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | * | ||
19 | */ | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/sh_clk.h> | ||
23 | |||
24 | int __init clk_init(void) | ||
25 | { | ||
26 | /* Kick the child clocks.. */ | ||
27 | recalculate_root_clocks(); | ||
28 | |||
29 | /* Enable the necessary init clocks */ | ||
30 | clk_enable_init_clocks(); | ||
31 | |||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | int __clk_get(struct clk *clk) | ||
36 | { | ||
37 | return 1; | ||
38 | } | ||
39 | EXPORT_SYMBOL(__clk_get); | ||
40 | |||
41 | void __clk_put(struct clk *clk) | ||
42 | { | ||
43 | } | ||
44 | EXPORT_SYMBOL(__clk_put); | ||
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 57903605cc51..efeef778a875 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h | |||
@@ -3,21 +3,31 @@ | |||
3 | 3 | ||
4 | extern struct sys_timer shmobile_timer; | 4 | extern struct sys_timer shmobile_timer; |
5 | extern void shmobile_setup_console(void); | 5 | extern void shmobile_setup_console(void); |
6 | struct clk; | ||
7 | extern int clk_init(void); | ||
6 | 8 | ||
7 | extern void sh7367_init_irq(void); | 9 | extern void sh7367_init_irq(void); |
8 | extern void sh7367_add_early_devices(void); | 10 | extern void sh7367_add_early_devices(void); |
9 | extern void sh7367_add_standard_devices(void); | 11 | extern void sh7367_add_standard_devices(void); |
10 | extern void sh7367_clock_init(void); | 12 | extern void sh7367_clock_init(void); |
11 | extern void sh7367_pinmux_init(void); | 13 | extern void sh7367_pinmux_init(void); |
14 | extern struct clk sh7367_extalb1_clk; | ||
15 | extern struct clk sh7367_extal2_clk; | ||
12 | 16 | ||
13 | extern void sh7377_init_irq(void); | 17 | extern void sh7377_init_irq(void); |
14 | extern void sh7377_add_early_devices(void); | 18 | extern void sh7377_add_early_devices(void); |
15 | extern void sh7377_add_standard_devices(void); | 19 | extern void sh7377_add_standard_devices(void); |
20 | extern void sh7377_clock_init(void); | ||
16 | extern void sh7377_pinmux_init(void); | 21 | extern void sh7377_pinmux_init(void); |
22 | extern struct clk sh7377_extalc1_clk; | ||
23 | extern struct clk sh7377_extal2_clk; | ||
17 | 24 | ||
18 | extern void sh7372_init_irq(void); | 25 | extern void sh7372_init_irq(void); |
19 | extern void sh7372_add_early_devices(void); | 26 | extern void sh7372_add_early_devices(void); |
20 | extern void sh7372_add_standard_devices(void); | 27 | extern void sh7372_add_standard_devices(void); |
28 | extern void sh7372_clock_init(void); | ||
21 | extern void sh7372_pinmux_init(void); | 29 | extern void sh7372_pinmux_init(void); |
30 | extern struct clk sh7372_extal1_clk; | ||
31 | extern struct clk sh7372_extal2_clk; | ||
22 | 32 | ||
23 | #endif /* __ARCH_MACH_COMMON_H */ | 33 | #endif /* __ARCH_MACH_COMMON_H */ |
diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h index 132256bb8c81..fa15b5f8a001 100644 --- a/arch/arm/mach-shmobile/include/mach/irqs.h +++ b/arch/arm/mach-shmobile/include/mach/irqs.h | |||
@@ -3,7 +3,13 @@ | |||
3 | 3 | ||
4 | #define NR_IRQS 512 | 4 | #define NR_IRQS 512 |
5 | 5 | ||
6 | /* INTCA */ | ||
6 | #define evt2irq(evt) (((evt) >> 5) - 16) | 7 | #define evt2irq(evt) (((evt) >> 5) - 16) |
7 | #define irq2evt(irq) (((irq) + 16) << 5) | 8 | #define irq2evt(irq) (((irq) + 16) << 5) |
8 | 9 | ||
10 | /* INTCS */ | ||
11 | #define INTCS_VECT_BASE 0x2200 | ||
12 | #define INTCS_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect)) | ||
13 | #define intcs_evt2irq(evt) evt2irq(INTCS_VECT_BASE + (evt)) | ||
14 | |||
9 | #endif /* __ASM_MACH_IRQS_H */ | 15 | #endif /* __ASM_MACH_IRQS_H */ |
diff --git a/arch/arm/mach-shmobile/include/mach/memory.h b/arch/arm/mach-shmobile/include/mach/memory.h index e188183f4dce..377584e57e03 100644 --- a/arch/arm/mach-shmobile/include/mach/memory.h +++ b/arch/arm/mach-shmobile/include/mach/memory.h | |||
@@ -4,4 +4,7 @@ | |||
4 | #define PHYS_OFFSET UL(CONFIG_MEMORY_START) | 4 | #define PHYS_OFFSET UL(CONFIG_MEMORY_START) |
5 | #define MEM_SIZE UL(CONFIG_MEMORY_SIZE) | 5 | #define MEM_SIZE UL(CONFIG_MEMORY_SIZE) |
6 | 6 | ||
7 | /* DMA memory at 0xf6000000 - 0xffdfffff */ | ||
8 | #define CONSISTENT_DMA_SIZE (158 << 20) | ||
9 | |||
7 | #endif /* __ASM_MACH_MEMORY_H */ | 10 | #endif /* __ASM_MACH_MEMORY_H */ |
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index dc34f00c56b8..33e9700ded7e 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h | |||
@@ -11,6 +11,8 @@ | |||
11 | #ifndef __ASM_SH7372_H__ | 11 | #ifndef __ASM_SH7372_H__ |
12 | #define __ASM_SH7372_H__ | 12 | #define __ASM_SH7372_H__ |
13 | 13 | ||
14 | #include <linux/sh_clk.h> | ||
15 | |||
14 | /* | 16 | /* |
15 | * Pin Function Controller: | 17 | * Pin Function Controller: |
16 | * GPIO_FN_xx - GPIO used to select pin function | 18 | * GPIO_FN_xx - GPIO used to select pin function |
@@ -431,4 +433,32 @@ enum { | |||
431 | GPIO_FN_SDENC_DV_CLKI, | 433 | GPIO_FN_SDENC_DV_CLKI, |
432 | }; | 434 | }; |
433 | 435 | ||
436 | /* DMA slave IDs */ | ||
437 | enum { | ||
438 | SHDMA_SLAVE_SCIF0_TX, | ||
439 | SHDMA_SLAVE_SCIF0_RX, | ||
440 | SHDMA_SLAVE_SCIF1_TX, | ||
441 | SHDMA_SLAVE_SCIF1_RX, | ||
442 | SHDMA_SLAVE_SCIF2_TX, | ||
443 | SHDMA_SLAVE_SCIF2_RX, | ||
444 | SHDMA_SLAVE_SCIF3_TX, | ||
445 | SHDMA_SLAVE_SCIF3_RX, | ||
446 | SHDMA_SLAVE_SCIF4_TX, | ||
447 | SHDMA_SLAVE_SCIF4_RX, | ||
448 | SHDMA_SLAVE_SCIF5_TX, | ||
449 | SHDMA_SLAVE_SCIF5_RX, | ||
450 | SHDMA_SLAVE_SCIF6_TX, | ||
451 | SHDMA_SLAVE_SCIF6_RX, | ||
452 | SHDMA_SLAVE_SDHI0_RX, | ||
453 | SHDMA_SLAVE_SDHI0_TX, | ||
454 | SHDMA_SLAVE_SDHI1_RX, | ||
455 | SHDMA_SLAVE_SDHI1_TX, | ||
456 | SHDMA_SLAVE_SDHI2_RX, | ||
457 | SHDMA_SLAVE_SDHI2_TX, | ||
458 | }; | ||
459 | |||
460 | extern struct clk dv_clki_clk; | ||
461 | extern struct clk dv_clki_div2_clk; | ||
462 | extern struct clk pllc2_clk; | ||
463 | |||
434 | #endif /* __ASM_SH7372_H__ */ | 464 | #endif /* __ASM_SH7372_H__ */ |
diff --git a/arch/arm/mach-shmobile/include/mach/vmalloc.h b/arch/arm/mach-shmobile/include/mach/vmalloc.h index fb3c4f1ab252..4aecf6e3a859 100644 --- a/arch/arm/mach-shmobile/include/mach/vmalloc.h +++ b/arch/arm/mach-shmobile/include/mach/vmalloc.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef __ASM_MACH_VMALLOC_H | 1 | #ifndef __ASM_MACH_VMALLOC_H |
2 | #define __ASM_MACH_VMALLOC_H | 2 | #define __ASM_MACH_VMALLOC_H |
3 | 3 | ||
4 | #define VMALLOC_END (PAGE_OFFSET + 0x24000000) | 4 | /* Vmalloc at ... - 0xe5ffffff */ |
5 | #define VMALLOC_END 0xe6000000 | ||
5 | 6 | ||
6 | #endif /* __ASM_MACH_VMALLOC_H */ | 7 | #endif /* __ASM_MACH_VMALLOC_H */ |
diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c index 5ff70cadfc32..1a20c489b20d 100644 --- a/arch/arm/mach-shmobile/intc-sh7367.c +++ b/arch/arm/mach-shmobile/intc-sh7367.c | |||
@@ -75,7 +75,7 @@ enum { | |||
75 | ETM11, ARM11, USBHS, FLCTL, IIC1 | 75 | ETM11, ARM11, USBHS, FLCTL, IIC1 |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static struct intc_vect intca_vectors[] = { | 78 | static struct intc_vect intca_vectors[] __initdata = { |
79 | INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220), | 79 | INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220), |
80 | INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260), | 80 | INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260), |
81 | INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0), | 81 | INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0), |
@@ -162,7 +162,7 @@ static struct intc_group intca_groups[] __initdata = { | |||
162 | INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1), | 162 | INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1), |
163 | }; | 163 | }; |
164 | 164 | ||
165 | static struct intc_mask_reg intca_mask_registers[] = { | 165 | static struct intc_mask_reg intca_mask_registers[] __initdata = { |
166 | { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */ | 166 | { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */ |
167 | { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, | 167 | { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, |
168 | { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */ | 168 | { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */ |
@@ -211,7 +211,7 @@ static struct intc_mask_reg intca_mask_registers[] = { | |||
211 | MISTY, CMT3, RWDT1, RWDT0 } }, | 211 | MISTY, CMT3, RWDT1, RWDT0 } }, |
212 | }; | 212 | }; |
213 | 213 | ||
214 | static struct intc_prio_reg intca_prio_registers[] = { | 214 | static struct intc_prio_reg intca_prio_registers[] __initdata = { |
215 | { 0xe6900010, 0, 32, 4, /* INTPRI00A */ | 215 | { 0xe6900010, 0, 32, 4, /* INTPRI00A */ |
216 | { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, | 216 | { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, |
217 | { 0xe6900014, 0, 32, 4, /* INTPRI10A */ | 217 | { 0xe6900014, 0, 32, 4, /* INTPRI10A */ |
@@ -263,8 +263,178 @@ static struct intc_desc intca_desc __initdata = { | |||
263 | intca_sense_registers, intca_ack_registers), | 263 | intca_sense_registers, intca_ack_registers), |
264 | }; | 264 | }; |
265 | 265 | ||
266 | enum { | ||
267 | UNUSED_INTCS = 0, | ||
268 | |||
269 | INTCS, | ||
270 | |||
271 | /* interrupt sources INTCS */ | ||
272 | VIO2_VEU0, VIO2_VEU1, VIO2_VEU2, VIO2_VEU3, | ||
273 | VIO3_VOU, | ||
274 | RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3, | ||
275 | VIO1_CEU, VIO1_BEU0, VIO1_BEU1, VIO1_BEU2, | ||
276 | VPU, | ||
277 | SGX530, | ||
278 | _2DDMAC_2DDM0, _2DDMAC_2DDM1, _2DDMAC_2DDM2, _2DDMAC_2DDM3, | ||
279 | IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, | ||
280 | IPMMU_IPMMUB, IPMMU_IPMMUS, | ||
281 | RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR, | ||
282 | MSIOF, | ||
283 | IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0, | ||
284 | TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, | ||
285 | CMT, | ||
286 | TSIF, | ||
287 | IPMMUI, | ||
288 | MVI3, | ||
289 | ICB, | ||
290 | PEP, | ||
291 | ASA, | ||
292 | BEM, | ||
293 | VE2HO, | ||
294 | HQE, | ||
295 | JPEG, | ||
296 | LCDC, | ||
297 | |||
298 | /* interrupt groups INTCS */ | ||
299 | _2DDMAC, RTDMAC_1, RTDMAC_2, VEU, BEU, IIC0, IPMMU, IIC2, | ||
300 | }; | ||
301 | |||
302 | static struct intc_vect intcs_vectors[] = { | ||
303 | INTCS_VECT(VIO2_VEU0, 0x700), INTCS_VECT(VIO2_VEU1, 0x720), | ||
304 | INTCS_VECT(VIO2_VEU2, 0x740), INTCS_VECT(VIO2_VEU3, 0x760), | ||
305 | INTCS_VECT(VIO3_VOU, 0x780), | ||
306 | INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820), | ||
307 | INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860), | ||
308 | INTCS_VECT(VIO1_CEU, 0x880), INTCS_VECT(VIO1_BEU0, 0x8a0), | ||
309 | INTCS_VECT(VIO1_BEU1, 0x8c0), INTCS_VECT(VIO1_BEU2, 0x8e0), | ||
310 | INTCS_VECT(VPU, 0x980), | ||
311 | INTCS_VECT(SGX530, 0x9e0), | ||
312 | INTCS_VECT(_2DDMAC_2DDM0, 0xa00), INTCS_VECT(_2DDMAC_2DDM1, 0xa20), | ||
313 | INTCS_VECT(_2DDMAC_2DDM2, 0xa40), INTCS_VECT(_2DDMAC_2DDM3, 0xa60), | ||
314 | INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0), | ||
315 | INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0), | ||
316 | INTCS_VECT(IPMMU_IPMMUB, 0xb20), INTCS_VECT(IPMMU_IPMMUS, 0xb60), | ||
317 | INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0), | ||
318 | INTCS_VECT(RTDMAC_2_DADERR, 0xbc0), | ||
319 | INTCS_VECT(MSIOF, 0xd20), | ||
320 | INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20), | ||
321 | INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60), | ||
322 | INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0), | ||
323 | INTCS_VECT(TMU_TUNI2, 0xec0), | ||
324 | INTCS_VECT(CMT, 0xf00), | ||
325 | INTCS_VECT(TSIF, 0xf20), | ||
326 | INTCS_VECT(IPMMUI, 0xf60), | ||
327 | INTCS_VECT(MVI3, 0x420), | ||
328 | INTCS_VECT(ICB, 0x480), | ||
329 | INTCS_VECT(PEP, 0x4a0), | ||
330 | INTCS_VECT(ASA, 0x4c0), | ||
331 | INTCS_VECT(BEM, 0x4e0), | ||
332 | INTCS_VECT(VE2HO, 0x520), | ||
333 | INTCS_VECT(HQE, 0x540), | ||
334 | INTCS_VECT(JPEG, 0x560), | ||
335 | INTCS_VECT(LCDC, 0x580), | ||
336 | |||
337 | INTC_VECT(INTCS, 0xf80), | ||
338 | }; | ||
339 | |||
340 | static struct intc_group intcs_groups[] __initdata = { | ||
341 | INTC_GROUP(_2DDMAC, _2DDMAC_2DDM0, _2DDMAC_2DDM1, | ||
342 | _2DDMAC_2DDM2, _2DDMAC_2DDM3), | ||
343 | INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI0, RTDMAC_1_DEI1, | ||
344 | RTDMAC_1_DEI2, RTDMAC_1_DEI3), | ||
345 | INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR), | ||
346 | INTC_GROUP(VEU, VIO2_VEU0, VIO2_VEU1, VIO2_VEU2, VIO2_VEU3), | ||
347 | INTC_GROUP(BEU, VIO1_BEU0, VIO1_BEU1, VIO1_BEU2), | ||
348 | INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0), | ||
349 | INTC_GROUP(IPMMU, IPMMU_IPMMUS, IPMMU_IPMMUB), | ||
350 | INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2), | ||
351 | }; | ||
352 | |||
353 | static struct intc_mask_reg intcs_mask_registers[] = { | ||
354 | { 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */ | ||
355 | { VIO1_BEU2, VIO1_BEU1, VIO1_BEU0, VIO1_CEU, | ||
356 | VIO2_VEU3, VIO2_VEU2, VIO2_VEU1, VIO2_VEU0 } }, | ||
357 | { 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */ | ||
358 | { VIO3_VOU, 0, VE2HO, VPU, | ||
359 | 0, 0, 0, 0 } }, | ||
360 | { 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */ | ||
361 | { _2DDMAC_2DDM3, _2DDMAC_2DDM2, _2DDMAC_2DDM1, _2DDMAC_2DDM0, | ||
362 | BEM, ASA, PEP, ICB } }, | ||
363 | { 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */ | ||
364 | { 0, 0, MVI3, 0, | ||
365 | JPEG, HQE, 0, LCDC } }, | ||
366 | { 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */ | ||
367 | { 0, RTDMAC_2_DADERR, RTDMAC_2_DEI5, RTDMAC_2_DEI4, | ||
368 | RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } }, | ||
369 | { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */ | ||
370 | { 0, 0, MSIOF, 0, | ||
371 | SGX530, 0, 0, 0 } }, | ||
372 | { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */ | ||
373 | { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0, | ||
374 | 0, 0, 0, 0 } }, | ||
375 | { 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */ | ||
376 | { 0, 0, 0, CMT, | ||
377 | IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } }, | ||
378 | { 0xffd201a8, 0xffd201e8, 8, /* IMR10SA / IMCR10SA */ | ||
379 | { IPMMU_IPMMUS, 0, IPMMU_IPMMUB, 0, | ||
380 | 0, 0, 0, 0 } }, | ||
381 | { 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */ | ||
382 | { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0, | ||
383 | 0, 0, IPMMUI, TSIF } }, | ||
384 | { 0xffd20104, 0, 16, /* INTAMASK */ | ||
385 | { 0, 0, 0, 0, 0, 0, 0, 0, | ||
386 | 0, 0, 0, 0, 0, 0, 0, INTCS } }, | ||
387 | }; | ||
388 | |||
389 | /* Priority is needed for INTCA to receive the INTCS interrupt */ | ||
390 | static struct intc_prio_reg intcs_prio_registers[] = { | ||
391 | { 0xffd20000, 0, 16, 4, /* IPRAS */ { 0, MVI3, _2DDMAC, ICB } }, | ||
392 | { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPEG, LCDC, 0, 0 } }, | ||
393 | { 0xffd20008, 0, 16, 4, /* IPRCS */ { BBIF2, 0, 0, 0 } }, | ||
394 | { 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_1, VIO1_CEU, 0, VPU } }, | ||
395 | { 0xffd20014, 0, 16, 4, /* IPRFS */ { 0, RTDMAC_2, 0, CMT } }, | ||
396 | { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU_TUNI0, TMU_TUNI1, | ||
397 | TMU_TUNI2, 0 } }, | ||
398 | { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, VIO3_VOU, VEU, BEU } }, | ||
399 | { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF, IIC0 } }, | ||
400 | { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, SGX530, 0, 0 } }, | ||
401 | { 0xffd20028, 0, 16, 4, /* IPRKS */ { BEM, ASA, IPMMUI, PEP } }, | ||
402 | { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, VE2HO, HQE } }, | ||
403 | { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } }, | ||
404 | }; | ||
405 | |||
406 | static struct resource intcs_resources[] __initdata = { | ||
407 | [0] = { | ||
408 | .start = 0xffd20000, | ||
409 | .end = 0xffd2ffff, | ||
410 | .flags = IORESOURCE_MEM, | ||
411 | } | ||
412 | }; | ||
413 | |||
414 | static struct intc_desc intcs_desc __initdata = { | ||
415 | .name = "sh7367-intcs", | ||
416 | .resource = intcs_resources, | ||
417 | .num_resources = ARRAY_SIZE(intcs_resources), | ||
418 | .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers, | ||
419 | intcs_prio_registers, NULL, NULL), | ||
420 | }; | ||
421 | |||
422 | static void intcs_demux(unsigned int irq, struct irq_desc *desc) | ||
423 | { | ||
424 | void __iomem *reg = (void *)get_irq_data(irq); | ||
425 | unsigned int evtcodeas = ioread32(reg); | ||
426 | |||
427 | generic_handle_irq(intcs_evt2irq(evtcodeas)); | ||
428 | } | ||
429 | |||
266 | void __init sh7367_init_irq(void) | 430 | void __init sh7367_init_irq(void) |
267 | { | 431 | { |
268 | /* INTCA */ | 432 | void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE); |
433 | |||
269 | register_intc_controller(&intca_desc); | 434 | register_intc_controller(&intca_desc); |
435 | register_intc_controller(&intcs_desc); | ||
436 | |||
437 | /* demux using INTEVTSA */ | ||
438 | set_irq_data(evt2irq(0xf80), (void *)intevtsa); | ||
439 | set_irq_chained_handler(evt2irq(0xf80), intcs_demux); | ||
270 | } | 440 | } |
diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c index 3ce9d9bd5899..e3551b56cd03 100644 --- a/arch/arm/mach-shmobile/intc-sh7372.c +++ b/arch/arm/mach-shmobile/intc-sh7372.c | |||
@@ -319,17 +319,17 @@ static struct intc_prio_reg intca_prio_registers[] __initdata = { | |||
319 | { 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } }, | 319 | { 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } }, |
320 | { 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S, | 320 | { 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S, |
321 | CMT14, CMT15 } }, | 321 | CMT14, CMT15 } }, |
322 | { 0xe694003c, 0, 16, 4, /* IPRPA3 */ { 0, 0, | 322 | { 0xe695003c, 0, 16, 4, /* IPRPA3 */ { 0, 0, |
323 | MMC_MMC_ERR, MMC_MMC_NOR } }, | 323 | MMC_MMC_ERR, MMC_MMC_NOR } }, |
324 | { 0xe6940040, 0, 16, 4, /* IPRQA3 */ { IIC4_ALI4, IIC4_TACKI4, | 324 | { 0xe6950040, 0, 16, 4, /* IPRQA3 */ { IIC4_ALI4, IIC4_TACKI4, |
325 | IIC4_WAITI4, IIC4_DTEI4 } }, | 325 | IIC4_WAITI4, IIC4_DTEI4 } }, |
326 | { 0xe6940044, 0, 16, 4, /* IPRRA3 */ { IIC3_ALI3, IIC3_TACKI3, | 326 | { 0xe6950044, 0, 16, 4, /* IPRRA3 */ { IIC3_ALI3, IIC3_TACKI3, |
327 | IIC3_WAITI3, IIC3_DTEI3 } }, | 327 | IIC3_WAITI3, IIC3_DTEI3 } }, |
328 | { 0xe6940048, 0, 16, 4, /* IPRSA3 */ { 0/*ERI*/, 0/*RXI*/, | 328 | { 0xe6950048, 0, 16, 4, /* IPRSA3 */ { 0/*ERI*/, 0/*RXI*/, |
329 | 0/*TXI*/, 0/*TEI*/} }, | 329 | 0/*TXI*/, 0/*TEI*/} }, |
330 | { 0xe694004c, 0, 16, 4, /* IPRTA3 */ { USB0_USB0I1, USB0_USB0I0, | 330 | { 0xe695004c, 0, 16, 4, /* IPRTA3 */ { USB0_USB0I1, USB0_USB0I0, |
331 | USB1_USB1I1, USB1_USB1I0 } }, | 331 | USB1_USB1I1, USB1_USB1I0 } }, |
332 | { 0xe6940050, 0, 16, 4, /* IPRUA3 */ { USBHSDMAC1_USHDMI, 0, 0, 0 } }, | 332 | { 0xe6950050, 0, 16, 4, /* IPRUA3 */ { USBHSDMAC1_USHDMI, 0, 0, 0 } }, |
333 | }; | 333 | }; |
334 | 334 | ||
335 | static struct intc_sense_reg intca_sense_registers[] __initdata = { | 335 | static struct intc_sense_reg intca_sense_registers[] __initdata = { |
@@ -363,7 +363,227 @@ static struct intc_desc intca_desc __initdata = { | |||
363 | intca_sense_registers, intca_ack_registers), | 363 | intca_sense_registers, intca_ack_registers), |
364 | }; | 364 | }; |
365 | 365 | ||
366 | enum { | ||
367 | UNUSED_INTCS = 0, | ||
368 | |||
369 | INTCS, | ||
370 | |||
371 | /* interrupt sources INTCS */ | ||
372 | VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3, | ||
373 | RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3, | ||
374 | CEU, BEU_BEU0, BEU_BEU1, BEU_BEU2, | ||
375 | VPU, | ||
376 | TSIF1, | ||
377 | _3DG_SGX530, | ||
378 | _2DDMAC, | ||
379 | IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, | ||
380 | IPMMU_IPMMUR, IPMMU_IPMMUR2, | ||
381 | RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR, | ||
382 | MSIOF, | ||
383 | IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0, | ||
384 | TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, | ||
385 | CMT0, | ||
386 | TSIF0, | ||
387 | LMB, | ||
388 | CTI, | ||
389 | ICB, | ||
390 | JPU_JPEG, | ||
391 | LCDC, | ||
392 | LCRC, | ||
393 | RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3, | ||
394 | RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR, | ||
395 | ISP, | ||
396 | LCDC1, | ||
397 | CSIRX, | ||
398 | DSITX_DSITX0, | ||
399 | DSITX_DSITX1, | ||
400 | TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2, | ||
401 | CMT4, | ||
402 | DSITX1_DSITX1_0, | ||
403 | DSITX1_DSITX1_1, | ||
404 | CPORTS2R, | ||
405 | JPU6E, | ||
406 | |||
407 | /* interrupt groups INTCS */ | ||
408 | RTDMAC_1, RTDMAC_2, VEU, BEU, IIC0, IPMMU, IIC2, | ||
409 | RTDMAC2_1, RTDMAC2_2, TMU1, DSITX, | ||
410 | }; | ||
411 | |||
412 | static struct intc_vect intcs_vectors[] = { | ||
413 | INTCS_VECT(VEU_VEU0, 0x700), INTCS_VECT(VEU_VEU1, 0x720), | ||
414 | INTCS_VECT(VEU_VEU2, 0x740), INTCS_VECT(VEU_VEU3, 0x760), | ||
415 | INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820), | ||
416 | INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860), | ||
417 | INTCS_VECT(CEU, 0x880), INTCS_VECT(BEU_BEU0, 0x8a0), | ||
418 | INTCS_VECT(BEU_BEU1, 0x8c0), INTCS_VECT(BEU_BEU2, 0x8e0), | ||
419 | INTCS_VECT(VPU, 0x980), | ||
420 | INTCS_VECT(TSIF1, 0x9a0), | ||
421 | INTCS_VECT(_3DG_SGX530, 0x9e0), | ||
422 | INTCS_VECT(_2DDMAC, 0xa00), | ||
423 | INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0), | ||
424 | INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0), | ||
425 | INTCS_VECT(IPMMU_IPMMUR, 0xb00), INTCS_VECT(IPMMU_IPMMUR2, 0xb20), | ||
426 | INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0), | ||
427 | INTCS_VECT(RTDMAC_2_DADERR, 0xbc0), | ||
428 | INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20), | ||
429 | INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60), | ||
430 | INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0), | ||
431 | INTCS_VECT(TMU_TUNI2, 0xec0), | ||
432 | INTCS_VECT(CMT0, 0xf00), | ||
433 | INTCS_VECT(TSIF0, 0xf20), | ||
434 | INTCS_VECT(LMB, 0xf60), | ||
435 | INTCS_VECT(CTI, 0x400), | ||
436 | INTCS_VECT(ICB, 0x480), | ||
437 | INTCS_VECT(JPU_JPEG, 0x560), | ||
438 | INTCS_VECT(LCDC, 0x580), | ||
439 | INTCS_VECT(LCRC, 0x5a0), | ||
440 | INTCS_VECT(RTDMAC2_1_DEI0, 0x1300), INTCS_VECT(RTDMAC2_1_DEI1, 0x1320), | ||
441 | INTCS_VECT(RTDMAC2_1_DEI2, 0x1340), INTCS_VECT(RTDMAC2_1_DEI3, 0x1360), | ||
442 | INTCS_VECT(RTDMAC2_2_DEI4, 0x1380), INTCS_VECT(RTDMAC2_2_DEI5, 0x13a0), | ||
443 | INTCS_VECT(RTDMAC2_2_DADERR, 0x13c0), | ||
444 | INTCS_VECT(ISP, 0x1720), | ||
445 | INTCS_VECT(LCDC1, 0x1780), | ||
446 | INTCS_VECT(CSIRX, 0x17a0), | ||
447 | INTCS_VECT(DSITX_DSITX0, 0x17c0), | ||
448 | INTCS_VECT(DSITX_DSITX1, 0x17e0), | ||
449 | INTCS_VECT(TMU1_TUNI0, 0x1900), INTCS_VECT(TMU1_TUNI1, 0x1920), | ||
450 | INTCS_VECT(TMU1_TUNI2, 0x1940), | ||
451 | INTCS_VECT(CMT4, 0x1980), | ||
452 | INTCS_VECT(DSITX1_DSITX1_0, 0x19a0), | ||
453 | INTCS_VECT(DSITX1_DSITX1_1, 0x19c0), | ||
454 | INTCS_VECT(CPORTS2R, 0x1a20), | ||
455 | INTCS_VECT(JPU6E, 0x1a80), | ||
456 | |||
457 | INTC_VECT(INTCS, 0xf80), | ||
458 | }; | ||
459 | |||
460 | static struct intc_group intcs_groups[] __initdata = { | ||
461 | INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI0, RTDMAC_1_DEI1, | ||
462 | RTDMAC_1_DEI2, RTDMAC_1_DEI3), | ||
463 | INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR), | ||
464 | INTC_GROUP(VEU, VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3), | ||
465 | INTC_GROUP(BEU, BEU_BEU0, BEU_BEU1, BEU_BEU2), | ||
466 | INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0), | ||
467 | INTC_GROUP(IPMMU, IPMMU_IPMMUR, IPMMU_IPMMUR2), | ||
468 | INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2), | ||
469 | INTC_GROUP(RTDMAC2_1, RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, | ||
470 | RTDMAC2_1_DEI2, RTDMAC2_1_DEI3), | ||
471 | INTC_GROUP(RTDMAC2_2, RTDMAC2_2_DEI4, | ||
472 | RTDMAC2_2_DEI5, RTDMAC2_2_DADERR), | ||
473 | INTC_GROUP(TMU1, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0), | ||
474 | INTC_GROUP(DSITX, DSITX_DSITX0, DSITX_DSITX1), | ||
475 | }; | ||
476 | |||
477 | static struct intc_mask_reg intcs_mask_registers[] = { | ||
478 | { 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */ | ||
479 | { BEU_BEU2, BEU_BEU1, BEU_BEU0, CEU, | ||
480 | VEU_VEU3, VEU_VEU2, VEU_VEU1, VEU_VEU0 } }, | ||
481 | { 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */ | ||
482 | { 0, 0, 0, VPU, | ||
483 | 0, 0, 0, 0 } }, | ||
484 | { 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */ | ||
485 | { 0, 0, 0, _2DDMAC, | ||
486 | 0, 0, 0, ICB } }, | ||
487 | { 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */ | ||
488 | { 0, 0, 0, CTI, | ||
489 | JPU_JPEG, 0, LCRC, LCDC } }, | ||
490 | { 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */ | ||
491 | { 0, RTDMAC_2_DADERR, RTDMAC_2_DEI5, RTDMAC_2_DEI4, | ||
492 | RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } }, | ||
493 | { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */ | ||
494 | { 0, 0, MSIOF, 0, | ||
495 | _3DG_SGX530, 0, 0, 0 } }, | ||
496 | { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */ | ||
497 | { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0, | ||
498 | 0, 0, 0, 0 } }, | ||
499 | { 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */ | ||
500 | { 0, 0, 0, CMT0, | ||
501 | IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } }, | ||
502 | { 0xffd201a8, 0xffd201e8, 8, /* IMR10SA / IMCR10SA */ | ||
503 | { 0, 0, IPMMU_IPMMUR2, IPMMU_IPMMUR, | ||
504 | 0, 0, 0, 0 } }, | ||
505 | { 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */ | ||
506 | { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0, | ||
507 | 0, TSIF1, LMB, TSIF0 } }, | ||
508 | { 0xffd50180, 0xffd501c0, 8, /* IMR0SA3 / IMCR0SA3 */ | ||
509 | { 0, RTDMAC2_2_DADERR, RTDMAC2_2_DEI5, RTDMAC2_2_DEI4, | ||
510 | RTDMAC2_1_DEI3, RTDMAC2_1_DEI2, RTDMAC2_1_DEI1, RTDMAC2_1_DEI0 } }, | ||
511 | { 0xffd50190, 0xffd501d0, 8, /* IMR4SA3 / IMCR4SA3 */ | ||
512 | { 0, ISP, 0, 0, | ||
513 | LCDC1, CSIRX, DSITX_DSITX0, DSITX_DSITX1 } }, | ||
514 | { 0xffd50198, 0xffd501d8, 8, /* IMR6SA3 / IMCR6SA3 */ | ||
515 | { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0, | ||
516 | CMT4, DSITX1_DSITX1_0, DSITX1_DSITX1_1, 0 } }, | ||
517 | { 0xffd5019c, 0xffd501dc, 8, /* IMR7SA3 / IMCR7SA3 */ | ||
518 | { 0, CPORTS2R, 0, 0, | ||
519 | JPU6E, 0, 0, 0 } }, | ||
520 | { 0xffd20104, 0, 16, /* INTAMASK */ | ||
521 | { 0, 0, 0, 0, 0, 0, 0, 0, | ||
522 | 0, 0, 0, 0, 0, 0, 0, INTCS } }, | ||
523 | }; | ||
524 | |||
525 | /* Priority is needed for INTCA to receive the INTCS interrupt */ | ||
526 | static struct intc_prio_reg intcs_prio_registers[] = { | ||
527 | { 0xffd20000, 0, 16, 4, /* IPRAS */ { CTI, 0, _2DDMAC, ICB } }, | ||
528 | { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPU_JPEG, LCDC, 0, LCRC } }, | ||
529 | { 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_1, CEU, 0, VPU } }, | ||
530 | { 0xffd20014, 0, 16, 4, /* IPRFS */ { 0, RTDMAC_2, 0, CMT0 } }, | ||
531 | { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU_TUNI0, TMU_TUNI1, | ||
532 | TMU_TUNI2, TSIF1 } }, | ||
533 | { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, 0, VEU, BEU } }, | ||
534 | { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF0, IIC0 } }, | ||
535 | { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, _3DG_SGX530, 0, 0 } }, | ||
536 | { 0xffd20028, 0, 16, 4, /* IPRKS */ { 0, 0, LMB, 0 } }, | ||
537 | { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, 0, 0 } }, | ||
538 | { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } }, | ||
539 | { 0xffd50000, 0, 16, 4, /* IPRAS3 */ { RTDMAC2_1, 0, 0, 0 } }, | ||
540 | { 0xffd50004, 0, 16, 4, /* IPRBS3 */ { RTDMAC2_2, 0, 0, 0 } }, | ||
541 | { 0xffd50020, 0, 16, 4, /* IPRIS3 */ { 0, ISP, 0, 0 } }, | ||
542 | { 0xffd50024, 0, 16, 4, /* IPRJS3 */ { LCDC1, CSIRX, DSITX, 0 } }, | ||
543 | { 0xffd50030, 0, 16, 4, /* IPRMS3 */ { TMU1, 0, 0, 0 } }, | ||
544 | { 0xffd50034, 0, 16, 4, /* IPRNS3 */ { CMT4, DSITX1_DSITX1_0, | ||
545 | DSITX1_DSITX1_1, 0 } }, | ||
546 | { 0xffd50038, 0, 16, 4, /* IPROS3 */ { 0, CPORTS2R, 0, 0 } }, | ||
547 | { 0xffd5003c, 0, 16, 4, /* IPRPS3 */ { JPU6E, 0, 0, 0 } }, | ||
548 | }; | ||
549 | |||
550 | static struct resource intcs_resources[] __initdata = { | ||
551 | [0] = { | ||
552 | .start = 0xffd20000, | ||
553 | .end = 0xffd201ff, | ||
554 | .flags = IORESOURCE_MEM, | ||
555 | }, | ||
556 | [1] = { | ||
557 | .start = 0xffd50000, | ||
558 | .end = 0xffd501ff, | ||
559 | .flags = IORESOURCE_MEM, | ||
560 | } | ||
561 | }; | ||
562 | |||
563 | static struct intc_desc intcs_desc __initdata = { | ||
564 | .name = "sh7372-intcs", | ||
565 | .resource = intcs_resources, | ||
566 | .num_resources = ARRAY_SIZE(intcs_resources), | ||
567 | .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers, | ||
568 | intcs_prio_registers, NULL, NULL), | ||
569 | }; | ||
570 | |||
571 | static void intcs_demux(unsigned int irq, struct irq_desc *desc) | ||
572 | { | ||
573 | void __iomem *reg = (void *)get_irq_data(irq); | ||
574 | unsigned int evtcodeas = ioread32(reg); | ||
575 | |||
576 | generic_handle_irq(intcs_evt2irq(evtcodeas)); | ||
577 | } | ||
578 | |||
366 | void __init sh7372_init_irq(void) | 579 | void __init sh7372_init_irq(void) |
367 | { | 580 | { |
581 | void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE); | ||
582 | |||
368 | register_intc_controller(&intca_desc); | 583 | register_intc_controller(&intca_desc); |
584 | register_intc_controller(&intcs_desc); | ||
585 | |||
586 | /* demux using INTEVTSA */ | ||
587 | set_irq_data(evt2irq(0xf80), (void *)intevtsa); | ||
588 | set_irq_chained_handler(evt2irq(0xf80), intcs_demux); | ||
369 | } | 589 | } |
diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c index 5c781e2d1897..2cdeb8ccd821 100644 --- a/arch/arm/mach-shmobile/intc-sh7377.c +++ b/arch/arm/mach-shmobile/intc-sh7377.c | |||
@@ -90,7 +90,7 @@ enum { | |||
90 | ICUSB, ICUDMC | 90 | ICUSB, ICUDMC |
91 | }; | 91 | }; |
92 | 92 | ||
93 | static struct intc_vect intca_vectors[] = { | 93 | static struct intc_vect intca_vectors[] __initdata = { |
94 | INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220), | 94 | INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220), |
95 | INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260), | 95 | INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260), |
96 | INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0), | 96 | INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0), |
@@ -202,7 +202,7 @@ static struct intc_group intca_groups[] __initdata = { | |||
202 | INTC_GROUP(ICUDMC, ICUDMC_ICUDMC1, ICUDMC_ICUDMC2), | 202 | INTC_GROUP(ICUDMC, ICUDMC_ICUDMC1, ICUDMC_ICUDMC2), |
203 | }; | 203 | }; |
204 | 204 | ||
205 | static struct intc_mask_reg intca_mask_registers[] = { | 205 | static struct intc_mask_reg intca_mask_registers[] __initdata = { |
206 | { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */ | 206 | { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */ |
207 | { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, | 207 | { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, |
208 | { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */ | 208 | { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */ |
@@ -272,7 +272,7 @@ static struct intc_mask_reg intca_mask_registers[] = { | |||
272 | SCIFA6, 0, 0, 0 } }, | 272 | SCIFA6, 0, 0, 0 } }, |
273 | }; | 273 | }; |
274 | 274 | ||
275 | static struct intc_prio_reg intca_prio_registers[] = { | 275 | static struct intc_prio_reg intca_prio_registers[] __initdata = { |
276 | { 0xe6900010, 0, 32, 4, /* INTPRI00A */ | 276 | { 0xe6900010, 0, 32, 4, /* INTPRI00A */ |
277 | { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, | 277 | { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } }, |
278 | { 0xe6900014, 0, 32, 4, /* INTPRI10A */ | 278 | { 0xe6900014, 0, 32, 4, /* INTPRI10A */ |
@@ -346,7 +346,301 @@ static struct intc_desc intca_desc __initdata = { | |||
346 | intca_sense_registers, intca_ack_registers), | 346 | intca_sense_registers, intca_ack_registers), |
347 | }; | 347 | }; |
348 | 348 | ||
349 | /* this macro ignore entry which is also in INTCA */ | ||
350 | #define __IGNORE(a...) | ||
351 | #define __IGNORE0(a...) 0 | ||
352 | |||
353 | enum { | ||
354 | UNUSED_INTCS = 0, | ||
355 | |||
356 | INTCS, | ||
357 | |||
358 | /* interrupt sources INTCS */ | ||
359 | VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3, | ||
360 | RTDMAC1_1_DEI0, RTDMAC1_1_DEI1, RTDMAC1_1_DEI2, RTDMAC1_1_DEI3, | ||
361 | CEU, | ||
362 | BEU_BEU0, BEU_BEU1, BEU_BEU2, | ||
363 | __IGNORE(MFI) | ||
364 | __IGNORE(BBIF2) | ||
365 | VPU, | ||
366 | TSIF1, | ||
367 | __IGNORE(SGX540) | ||
368 | _2DDMAC, | ||
369 | IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, | ||
370 | IPMMU_IPMMUR, IPMMU_IPMMUR2, | ||
371 | RTDMAC1_2_DEI4, RTDMAC1_2_DEI5, RTDMAC1_2_DADERR, | ||
372 | __IGNORE(KEYSC) | ||
373 | __IGNORE(TTI20) | ||
374 | __IGNORE(MSIOF) | ||
375 | IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0, | ||
376 | TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, | ||
377 | CMT0, | ||
378 | TSIF0, | ||
379 | __IGNORE(CMT2) | ||
380 | LMB, | ||
381 | __IGNORE(MSUG) | ||
382 | __IGNORE(MSU_MSU, MSU_MSU2) | ||
383 | __IGNORE(CTI) | ||
384 | MVI3, | ||
385 | __IGNORE(RWDT0) | ||
386 | __IGNORE(RWDT1) | ||
387 | ICB, | ||
388 | PEP, | ||
389 | ASA, | ||
390 | __IGNORE(_2DG) | ||
391 | HQE, | ||
392 | JPU, | ||
393 | LCDC0, | ||
394 | __IGNORE(LCRC) | ||
395 | RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3, | ||
396 | RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR, | ||
397 | FRC, | ||
398 | LCDC1, | ||
399 | CSIRX, | ||
400 | DSITX_DSITX0, DSITX_DSITX1, | ||
401 | __IGNORE(SPU2_SPU0, SPU2_SPU1) | ||
402 | __IGNORE(FSI) | ||
403 | __IGNORE(FMSI) | ||
404 | __IGNORE(SCUV) | ||
405 | TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12, | ||
406 | TSIF2, | ||
407 | CMT4, | ||
408 | __IGNORE(MFIS2) | ||
409 | CPORTS2R, | ||
410 | |||
411 | /* interrupt groups INTCS */ | ||
412 | RTDMAC1_1, RTDMAC1_2, VEU, BEU, IIC0, __IGNORE(MSU) IPMMU, | ||
413 | IIC2, RTDMAC2_1, RTDMAC2_2, DSITX, __IGNORE(SPU2) TMU1, | ||
414 | }; | ||
415 | |||
416 | #define INTCS_INTVECT 0x0F80 | ||
417 | static struct intc_vect intcs_vectors[] __initdata = { | ||
418 | INTCS_VECT(VEU_VEU0, 0x0700), INTCS_VECT(VEU_VEU1, 0x0720), | ||
419 | INTCS_VECT(VEU_VEU2, 0x0740), INTCS_VECT(VEU_VEU3, 0x0760), | ||
420 | INTCS_VECT(RTDMAC1_1_DEI0, 0x0800), INTCS_VECT(RTDMAC1_1_DEI1, 0x0820), | ||
421 | INTCS_VECT(RTDMAC1_1_DEI2, 0x0840), INTCS_VECT(RTDMAC1_1_DEI3, 0x0860), | ||
422 | INTCS_VECT(CEU, 0x0880), | ||
423 | INTCS_VECT(BEU_BEU0, 0x08A0), | ||
424 | INTCS_VECT(BEU_BEU1, 0x08C0), | ||
425 | INTCS_VECT(BEU_BEU2, 0x08E0), | ||
426 | __IGNORE(INTCS_VECT(MFI, 0x0900)) | ||
427 | __IGNORE(INTCS_VECT(BBIF2, 0x0960)) | ||
428 | INTCS_VECT(VPU, 0x0980), | ||
429 | INTCS_VECT(TSIF1, 0x09A0), | ||
430 | __IGNORE(INTCS_VECT(SGX540, 0x09E0)) | ||
431 | INTCS_VECT(_2DDMAC, 0x0A00), | ||
432 | INTCS_VECT(IIC2_ALI2, 0x0A80), INTCS_VECT(IIC2_TACKI2, 0x0AA0), | ||
433 | INTCS_VECT(IIC2_WAITI2, 0x0AC0), INTCS_VECT(IIC2_DTEI2, 0x0AE0), | ||
434 | INTCS_VECT(IPMMU_IPMMUR, 0x0B00), INTCS_VECT(IPMMU_IPMMUR2, 0x0B20), | ||
435 | INTCS_VECT(RTDMAC1_2_DEI4, 0x0B80), | ||
436 | INTCS_VECT(RTDMAC1_2_DEI5, 0x0BA0), | ||
437 | INTCS_VECT(RTDMAC1_2_DADERR, 0x0BC0), | ||
438 | __IGNORE(INTCS_VECT(KEYSC 0x0BE0)) | ||
439 | __IGNORE(INTCS_VECT(TTI20, 0x0C80)) | ||
440 | __IGNORE(INTCS_VECT(MSIOF, 0x0D20)) | ||
441 | INTCS_VECT(IIC0_ALI0, 0x0E00), INTCS_VECT(IIC0_TACKI0, 0x0E20), | ||
442 | INTCS_VECT(IIC0_WAITI0, 0x0E40), INTCS_VECT(IIC0_DTEI0, 0x0E60), | ||
443 | INTCS_VECT(TMU_TUNI0, 0x0E80), | ||
444 | INTCS_VECT(TMU_TUNI1, 0x0EA0), | ||
445 | INTCS_VECT(TMU_TUNI2, 0x0EC0), | ||
446 | INTCS_VECT(CMT0, 0x0F00), | ||
447 | INTCS_VECT(TSIF0, 0x0F20), | ||
448 | __IGNORE(INTCS_VECT(CMT2, 0x0F40)) | ||
449 | INTCS_VECT(LMB, 0x0F60), | ||
450 | __IGNORE(INTCS_VECT(MSUG, 0x0F80)) | ||
451 | __IGNORE(INTCS_VECT(MSU_MSU, 0x0FA0)) | ||
452 | __IGNORE(INTCS_VECT(MSU_MSU2, 0x0FC0)) | ||
453 | __IGNORE(INTCS_VECT(CTI, 0x0400)) | ||
454 | INTCS_VECT(MVI3, 0x0420), | ||
455 | __IGNORE(INTCS_VECT(RWDT0, 0x0440)) | ||
456 | __IGNORE(INTCS_VECT(RWDT1, 0x0460)) | ||
457 | INTCS_VECT(ICB, 0x0480), | ||
458 | INTCS_VECT(PEP, 0x04A0), | ||
459 | INTCS_VECT(ASA, 0x04C0), | ||
460 | __IGNORE(INTCS_VECT(_2DG, 0x04E0)) | ||
461 | INTCS_VECT(HQE, 0x0540), | ||
462 | INTCS_VECT(JPU, 0x0560), | ||
463 | INTCS_VECT(LCDC0, 0x0580), | ||
464 | __IGNORE(INTCS_VECT(LCRC, 0x05A0)) | ||
465 | INTCS_VECT(RTDMAC2_1_DEI0, 0x1300), INTCS_VECT(RTDMAC2_1_DEI1, 0x1320), | ||
466 | INTCS_VECT(RTDMAC2_1_DEI2, 0x1340), INTCS_VECT(RTDMAC2_1_DEI3, 0x1360), | ||
467 | INTCS_VECT(RTDMAC2_2_DEI4, 0x1380), INTCS_VECT(RTDMAC2_2_DEI5, 0x13A0), | ||
468 | INTCS_VECT(RTDMAC2_2_DADERR, 0x13C0), | ||
469 | INTCS_VECT(FRC, 0x1700), | ||
470 | INTCS_VECT(LCDC1, 0x1780), | ||
471 | INTCS_VECT(CSIRX, 0x17A0), | ||
472 | INTCS_VECT(DSITX_DSITX0, 0x17C0), INTCS_VECT(DSITX_DSITX1, 0x17E0), | ||
473 | __IGNORE(INTCS_VECT(SPU2_SPU0, 0x1800)) | ||
474 | __IGNORE(INTCS_VECT(SPU2_SPU1, 0x1820)) | ||
475 | __IGNORE(INTCS_VECT(FSI, 0x1840)) | ||
476 | __IGNORE(INTCS_VECT(FMSI, 0x1860)) | ||
477 | __IGNORE(INTCS_VECT(SCUV, 0x1880)) | ||
478 | INTCS_VECT(TMU1_TUNI10, 0x1900), INTCS_VECT(TMU1_TUNI11, 0x1920), | ||
479 | INTCS_VECT(TMU1_TUNI12, 0x1940), | ||
480 | INTCS_VECT(TSIF2, 0x1960), | ||
481 | INTCS_VECT(CMT4, 0x1980), | ||
482 | __IGNORE(INTCS_VECT(MFIS2, 0x1A00)) | ||
483 | INTCS_VECT(CPORTS2R, 0x1A20), | ||
484 | |||
485 | INTC_VECT(INTCS, INTCS_INTVECT), | ||
486 | }; | ||
487 | |||
488 | static struct intc_group intcs_groups[] __initdata = { | ||
489 | INTC_GROUP(RTDMAC1_1, | ||
490 | RTDMAC1_1_DEI0, RTDMAC1_1_DEI1, | ||
491 | RTDMAC1_1_DEI2, RTDMAC1_1_DEI3), | ||
492 | INTC_GROUP(RTDMAC1_2, | ||
493 | RTDMAC1_2_DEI4, RTDMAC1_2_DEI5, RTDMAC1_2_DADERR), | ||
494 | INTC_GROUP(VEU, VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3), | ||
495 | INTC_GROUP(BEU, BEU_BEU0, BEU_BEU1, BEU_BEU2), | ||
496 | INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0), | ||
497 | __IGNORE(INTC_GROUP(MSU, MSU_MSU, MSU_MSU2)) | ||
498 | INTC_GROUP(IPMMU, IPMMU_IPMMUR, IPMMU_IPMMUR2), | ||
499 | INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2), | ||
500 | INTC_GROUP(RTDMAC2_1, | ||
501 | RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, | ||
502 | RTDMAC2_1_DEI2, RTDMAC2_1_DEI3), | ||
503 | INTC_GROUP(RTDMAC2_2, RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR), | ||
504 | INTC_GROUP(DSITX, DSITX_DSITX0, DSITX_DSITX1), | ||
505 | __IGNORE(INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1)) | ||
506 | INTC_GROUP(TMU1, TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12), | ||
507 | }; | ||
508 | |||
509 | static struct intc_mask_reg intcs_mask_registers[] __initdata = { | ||
510 | { 0xE6940184, 0xE69401C4, 8, /* IMR1AS / IMCR1AS */ | ||
511 | { BEU_BEU2, BEU_BEU1, BEU_BEU0, CEU, | ||
512 | VEU_VEU3, VEU_VEU2, VEU_VEU1, VEU_VEU0 } }, | ||
513 | { 0xE6940188, 0xE69401C8, 8, /* IMR2AS / IMCR2AS */ | ||
514 | { 0, 0, 0, VPU, | ||
515 | __IGNORE0(BBIF2), 0, 0, __IGNORE0(MFI) } }, | ||
516 | { 0xE694018C, 0xE69401CC, 8, /* IMR3AS / IMCR3AS */ | ||
517 | { 0, 0, 0, _2DDMAC, | ||
518 | __IGNORE0(_2DG), ASA, PEP, ICB } }, | ||
519 | { 0xE6940190, 0xE69401D0, 8, /* IMR4AS / IMCR4AS */ | ||
520 | { 0, 0, MVI3, __IGNORE0(CTI), | ||
521 | JPU, HQE, __IGNORE0(LCRC), LCDC0 } }, | ||
522 | { 0xE6940194, 0xE69401D4, 8, /* IMR5AS / IMCR5AS */ | ||
523 | { __IGNORE0(KEYSC), RTDMAC1_2_DADERR, RTDMAC1_2_DEI5, RTDMAC1_2_DEI4, | ||
524 | RTDMAC1_1_DEI3, RTDMAC1_1_DEI2, RTDMAC1_1_DEI1, RTDMAC1_1_DEI0 } }, | ||
525 | __IGNORE({ 0xE6940198, 0xE69401D8, 8, /* IMR6AS / IMCR6AS */ | ||
526 | { 0, 0, MSIOF, 0, | ||
527 | SGX540, 0, TTI20, 0 } }) | ||
528 | { 0xE694019C, 0xE69401DC, 8, /* IMR7AS / IMCR7AS */ | ||
529 | { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0, | ||
530 | 0, 0, 0, 0 } }, | ||
531 | __IGNORE({ 0xE69401A0, 0xE69401E0, 8, /* IMR8AS / IMCR8AS */ | ||
532 | { 0, 0, 0, 0, | ||
533 | 0, MSU_MSU, MSU_MSU2, MSUG } }) | ||
534 | { 0xE69401A4, 0xE69401E4, 8, /* IMR9AS / IMCR9AS */ | ||
535 | { __IGNORE0(RWDT1), __IGNORE0(RWDT0), __IGNORE0(CMT2), CMT0, | ||
536 | IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } }, | ||
537 | { 0xE69401A8, 0xE69401E8, 8, /* IMR10AS / IMCR10AS */ | ||
538 | { 0, 0, IPMMU_IPMMUR, IPMMU_IPMMUR2, | ||
539 | 0, 0, 0, 0 } }, | ||
540 | { 0xE69401AC, 0xE69401EC, 8, /* IMR11AS / IMCR11AS */ | ||
541 | { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0, | ||
542 | 0, TSIF1, LMB, TSIF0 } }, | ||
543 | { 0xE6950180, 0xE69501C0, 8, /* IMR0AS3 / IMCR0AS3 */ | ||
544 | { RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3, | ||
545 | RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR, 0 } }, | ||
546 | { 0xE6950190, 0xE69501D0, 8, /* IMR4AS3 / IMCR4AS3 */ | ||
547 | { FRC, 0, 0, 0, | ||
548 | LCDC1, CSIRX, DSITX_DSITX0, DSITX_DSITX1 } }, | ||
549 | __IGNORE({ 0xE6950194, 0xE69501D4, 8, /* IMR5AS3 / IMCR5AS3 */ | ||
550 | {SPU2_SPU0, SPU2_SPU1, FSI, FMSI, | ||
551 | SCUV, 0, 0, 0 } }) | ||
552 | { 0xE6950198, 0xE69501D8, 8, /* IMR6AS3 / IMCR6AS3 */ | ||
553 | { TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12, TSIF2, | ||
554 | CMT4, 0, 0, 0 } }, | ||
555 | { 0xE695019C, 0xE69501DC, 8, /* IMR7AS3 / IMCR7AS3 */ | ||
556 | { __IGNORE0(MFIS2), CPORTS2R, 0, 0, | ||
557 | 0, 0, 0, 0 } }, | ||
558 | { 0xFFD20104, 0, 16, /* INTAMASK */ | ||
559 | { 0, 0, 0, 0, 0, 0, 0, 0, | ||
560 | 0, 0, 0, 0, 0, 0, 0, INTCS } } | ||
561 | }; | ||
562 | |||
563 | static struct intc_prio_reg intcs_prio_registers[] __initdata = { | ||
564 | /* IPRAS */ | ||
565 | { 0xFFD20000, 0, 16, 4, { __IGNORE0(CTI), MVI3, _2DDMAC, ICB } }, | ||
566 | /* IPRBS */ | ||
567 | { 0xFFD20004, 0, 16, 4, { JPU, LCDC0, 0, __IGNORE0(LCRC) } }, | ||
568 | /* IPRCS */ | ||
569 | __IGNORE({ 0xFFD20008, 0, 16, 4, { BBIF2, 0, 0, 0 } }) | ||
570 | /* IPRES */ | ||
571 | { 0xFFD20010, 0, 16, 4, { RTDMAC1_1, CEU, __IGNORE0(MFI), VPU } }, | ||
572 | /* IPRFS */ | ||
573 | { 0xFFD20014, 0, 16, 4, | ||
574 | { __IGNORE0(KEYSC), RTDMAC1_2, __IGNORE0(CMT2), CMT0 } }, | ||
575 | /* IPRGS */ | ||
576 | { 0xFFD20018, 0, 16, 4, { TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, TSIF1 } }, | ||
577 | /* IPRHS */ | ||
578 | { 0xFFD2001C, 0, 16, 4, { __IGNORE0(TTI20), 0, VEU, BEU } }, | ||
579 | /* IPRIS */ | ||
580 | { 0xFFD20020, 0, 16, 4, { 0, __IGNORE0(MSIOF), TSIF0, IIC0 } }, | ||
581 | /* IPRJS */ | ||
582 | __IGNORE({ 0xFFD20024, 0, 16, 4, { 0, SGX540, MSUG, MSU } }) | ||
583 | /* IPRKS */ | ||
584 | { 0xFFD20028, 0, 16, 4, { __IGNORE0(_2DG), ASA, LMB, PEP } }, | ||
585 | /* IPRLS */ | ||
586 | { 0xFFD2002C, 0, 16, 4, { IPMMU, 0, 0, HQE } }, | ||
587 | /* IPRMS */ | ||
588 | { 0xFFD20030, 0, 16, 4, | ||
589 | { IIC2, 0, __IGNORE0(RWDT1), __IGNORE0(RWDT0) } }, | ||
590 | /* IPRAS3 */ | ||
591 | { 0xFFD50000, 0, 16, 4, { RTDMAC2_1, 0, 0, 0 } }, | ||
592 | /* IPRBS3 */ | ||
593 | { 0xFFD50004, 0, 16, 4, { RTDMAC2_2, 0, 0, 0 } }, | ||
594 | /* IPRIS3 */ | ||
595 | { 0xFFD50020, 0, 16, 4, { FRC, 0, 0, 0 } }, | ||
596 | /* IPRJS3 */ | ||
597 | { 0xFFD50024, 0, 16, 4, { LCDC1, CSIRX, DSITX, 0 } }, | ||
598 | /* IPRKS3 */ | ||
599 | __IGNORE({ 0xFFD50028, 0, 16, 4, { SPU2, 0, FSI, FMSI } }) | ||
600 | /* IPRLS3 */ | ||
601 | __IGNORE({ 0xFFD5002C, 0, 16, 4, { SCUV, 0, 0, 0 } }) | ||
602 | /* IPRMS3 */ | ||
603 | { 0xFFD50030, 0, 16, 4, { TMU1, 0, 0, TSIF2 } }, | ||
604 | /* IPRNS3 */ | ||
605 | { 0xFFD50034, 0, 16, 4, { CMT4, 0, 0, 0 } }, | ||
606 | /* IPROS3 */ | ||
607 | { 0xFFD50038, 0, 16, 4, { __IGNORE0(MFIS2), CPORTS2R, 0, 0 } }, | ||
608 | }; | ||
609 | |||
610 | static struct resource intcs_resources[] __initdata = { | ||
611 | [0] = { | ||
612 | .start = 0xffd20000, | ||
613 | .end = 0xffd500ff, | ||
614 | .flags = IORESOURCE_MEM, | ||
615 | } | ||
616 | }; | ||
617 | |||
618 | static struct intc_desc intcs_desc __initdata = { | ||
619 | .name = "sh7377-intcs", | ||
620 | .resource = intcs_resources, | ||
621 | .num_resources = ARRAY_SIZE(intcs_resources), | ||
622 | .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, | ||
623 | intcs_mask_registers, intcs_prio_registers, | ||
624 | NULL, NULL), | ||
625 | }; | ||
626 | |||
627 | static void intcs_demux(unsigned int irq, struct irq_desc *desc) | ||
628 | { | ||
629 | void __iomem *reg = (void *)get_irq_data(irq); | ||
630 | unsigned int evtcodeas = ioread32(reg); | ||
631 | |||
632 | generic_handle_irq(intcs_evt2irq(evtcodeas)); | ||
633 | } | ||
634 | |||
635 | #define INTEVTSA 0xFFD20100 | ||
349 | void __init sh7377_init_irq(void) | 636 | void __init sh7377_init_irq(void) |
350 | { | 637 | { |
638 | void __iomem *intevtsa = ioremap_nocache(INTEVTSA, PAGE_SIZE); | ||
639 | |||
351 | register_intc_controller(&intca_desc); | 640 | register_intc_controller(&intca_desc); |
641 | register_intc_controller(&intcs_desc); | ||
642 | |||
643 | /* demux using INTEVTSA */ | ||
644 | set_irq_data(evt2irq(INTCS_INTVECT), (void *)intevtsa); | ||
645 | set_irq_chained_handler(evt2irq(INTCS_INTVECT), intcs_demux); | ||
352 | } | 646 | } |
diff --git a/arch/arm/mach-shmobile/pfc-sh7372.c b/arch/arm/mach-shmobile/pfc-sh7372.c index 9557d0964d73..ec420353f8e3 100644 --- a/arch/arm/mach-shmobile/pfc-sh7372.c +++ b/arch/arm/mach-shmobile/pfc-sh7372.c | |||
@@ -1160,6 +1160,9 @@ static struct pinmux_gpio pinmux_gpios[] = { | |||
1160 | GPIO_FN(LCDD18), GPIO_FN(LCDD19), GPIO_FN(LCDD20), | 1160 | GPIO_FN(LCDD18), GPIO_FN(LCDD19), GPIO_FN(LCDD20), |
1161 | GPIO_FN(LCDD21), GPIO_FN(LCDD22), GPIO_FN(LCDD23), | 1161 | GPIO_FN(LCDD21), GPIO_FN(LCDD22), GPIO_FN(LCDD23), |
1162 | 1162 | ||
1163 | GPIO_FN(LCDC0_SELECT), | ||
1164 | GPIO_FN(LCDC1_SELECT), | ||
1165 | |||
1163 | /* IRDA */ | 1166 | /* IRDA */ |
1164 | GPIO_FN(IRDA_OUT), GPIO_FN(IRDA_IN), GPIO_FN(IRDA_FIRSEL), | 1167 | GPIO_FN(IRDA_OUT), GPIO_FN(IRDA_IN), GPIO_FN(IRDA_FIRSEL), |
1165 | GPIO_FN(IROUT_139), GPIO_FN(IROUT_140), | 1168 | GPIO_FN(IROUT_139), GPIO_FN(IROUT_140), |
diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c index eca90716140e..3148c11a550e 100644 --- a/arch/arm/mach-shmobile/setup-sh7367.c +++ b/arch/arm/mach-shmobile/setup-sh7367.c | |||
@@ -31,11 +31,13 @@ | |||
31 | #include <asm/mach-types.h> | 31 | #include <asm/mach-types.h> |
32 | #include <asm/mach/arch.h> | 32 | #include <asm/mach/arch.h> |
33 | 33 | ||
34 | /* SCIFA0 */ | ||
34 | static struct plat_sci_port scif0_platform_data = { | 35 | static struct plat_sci_port scif0_platform_data = { |
35 | .mapbase = 0xe6c40000, | 36 | .mapbase = 0xe6c40000, |
36 | .flags = UPF_BOOT_AUTOCONF, | 37 | .flags = UPF_BOOT_AUTOCONF, |
37 | .type = PORT_SCIF, | 38 | .type = PORT_SCIF, |
38 | .irqs = { 80, 80, 80, 80 }, | 39 | .irqs = { evt2irq(0xc00), evt2irq(0xc00), |
40 | evt2irq(0xc00), evt2irq(0xc00) }, | ||
39 | }; | 41 | }; |
40 | 42 | ||
41 | static struct platform_device scif0_device = { | 43 | static struct platform_device scif0_device = { |
@@ -46,11 +48,13 @@ static struct platform_device scif0_device = { | |||
46 | }, | 48 | }, |
47 | }; | 49 | }; |
48 | 50 | ||
51 | /* SCIFA1 */ | ||
49 | static struct plat_sci_port scif1_platform_data = { | 52 | static struct plat_sci_port scif1_platform_data = { |
50 | .mapbase = 0xe6c50000, | 53 | .mapbase = 0xe6c50000, |
51 | .flags = UPF_BOOT_AUTOCONF, | 54 | .flags = UPF_BOOT_AUTOCONF, |
52 | .type = PORT_SCIF, | 55 | .type = PORT_SCIF, |
53 | .irqs = { 81, 81, 81, 81 }, | 56 | .irqs = { evt2irq(0xc20), evt2irq(0xc20), |
57 | evt2irq(0xc20), evt2irq(0xc20) }, | ||
54 | }; | 58 | }; |
55 | 59 | ||
56 | static struct platform_device scif1_device = { | 60 | static struct platform_device scif1_device = { |
@@ -61,11 +65,13 @@ static struct platform_device scif1_device = { | |||
61 | }, | 65 | }, |
62 | }; | 66 | }; |
63 | 67 | ||
68 | /* SCIFA2 */ | ||
64 | static struct plat_sci_port scif2_platform_data = { | 69 | static struct plat_sci_port scif2_platform_data = { |
65 | .mapbase = 0xe6c60000, | 70 | .mapbase = 0xe6c60000, |
66 | .flags = UPF_BOOT_AUTOCONF, | 71 | .flags = UPF_BOOT_AUTOCONF, |
67 | .type = PORT_SCIF, | 72 | .type = PORT_SCIF, |
68 | .irqs = { 82, 82, 82, 82 }, | 73 | .irqs = { evt2irq(0xc40), evt2irq(0xc40), |
74 | evt2irq(0xc40), evt2irq(0xc40) }, | ||
69 | }; | 75 | }; |
70 | 76 | ||
71 | static struct platform_device scif2_device = { | 77 | static struct platform_device scif2_device = { |
@@ -76,11 +82,13 @@ static struct platform_device scif2_device = { | |||
76 | }, | 82 | }, |
77 | }; | 83 | }; |
78 | 84 | ||
85 | /* SCIFA3 */ | ||
79 | static struct plat_sci_port scif3_platform_data = { | 86 | static struct plat_sci_port scif3_platform_data = { |
80 | .mapbase = 0xe6c70000, | 87 | .mapbase = 0xe6c70000, |
81 | .flags = UPF_BOOT_AUTOCONF, | 88 | .flags = UPF_BOOT_AUTOCONF, |
82 | .type = PORT_SCIF, | 89 | .type = PORT_SCIF, |
83 | .irqs = { 83, 83, 83, 83 }, | 90 | .irqs = { evt2irq(0xc60), evt2irq(0xc60), |
91 | evt2irq(0xc60), evt2irq(0xc60) }, | ||
84 | }; | 92 | }; |
85 | 93 | ||
86 | static struct platform_device scif3_device = { | 94 | static struct platform_device scif3_device = { |
@@ -91,11 +99,13 @@ static struct platform_device scif3_device = { | |||
91 | }, | 99 | }, |
92 | }; | 100 | }; |
93 | 101 | ||
102 | /* SCIFA4 */ | ||
94 | static struct plat_sci_port scif4_platform_data = { | 103 | static struct plat_sci_port scif4_platform_data = { |
95 | .mapbase = 0xe6c80000, | 104 | .mapbase = 0xe6c80000, |
96 | .flags = UPF_BOOT_AUTOCONF, | 105 | .flags = UPF_BOOT_AUTOCONF, |
97 | .type = PORT_SCIF, | 106 | .type = PORT_SCIF, |
98 | .irqs = { 89, 89, 89, 89 }, | 107 | .irqs = { evt2irq(0xd20), evt2irq(0xd20), |
108 | evt2irq(0xd20), evt2irq(0xd20) }, | ||
99 | }; | 109 | }; |
100 | 110 | ||
101 | static struct platform_device scif4_device = { | 111 | static struct platform_device scif4_device = { |
@@ -106,11 +116,13 @@ static struct platform_device scif4_device = { | |||
106 | }, | 116 | }, |
107 | }; | 117 | }; |
108 | 118 | ||
119 | /* SCIFA5 */ | ||
109 | static struct plat_sci_port scif5_platform_data = { | 120 | static struct plat_sci_port scif5_platform_data = { |
110 | .mapbase = 0xe6cb0000, | 121 | .mapbase = 0xe6cb0000, |
111 | .flags = UPF_BOOT_AUTOCONF, | 122 | .flags = UPF_BOOT_AUTOCONF, |
112 | .type = PORT_SCIF, | 123 | .type = PORT_SCIF, |
113 | .irqs = { 90, 90, 90, 90 }, | 124 | .irqs = { evt2irq(0xd40), evt2irq(0xd40), |
125 | evt2irq(0xd40), evt2irq(0xd40) }, | ||
114 | }; | 126 | }; |
115 | 127 | ||
116 | static struct platform_device scif5_device = { | 128 | static struct platform_device scif5_device = { |
@@ -121,11 +133,13 @@ static struct platform_device scif5_device = { | |||
121 | }, | 133 | }, |
122 | }; | 134 | }; |
123 | 135 | ||
136 | /* SCIFB */ | ||
124 | static struct plat_sci_port scif6_platform_data = { | 137 | static struct plat_sci_port scif6_platform_data = { |
125 | .mapbase = 0xe6c30000, | 138 | .mapbase = 0xe6c30000, |
126 | .flags = UPF_BOOT_AUTOCONF, | 139 | .flags = UPF_BOOT_AUTOCONF, |
127 | .type = PORT_SCIF, | 140 | .type = PORT_SCIF, |
128 | .irqs = { 91, 91, 91, 91 }, | 141 | .irqs = { evt2irq(0xd60), evt2irq(0xd60), |
142 | evt2irq(0xd60), evt2irq(0xd60) }, | ||
129 | }; | 143 | }; |
130 | 144 | ||
131 | static struct platform_device scif6_device = { | 145 | static struct platform_device scif6_device = { |
@@ -153,7 +167,7 @@ static struct resource cmt10_resources[] = { | |||
153 | .flags = IORESOURCE_MEM, | 167 | .flags = IORESOURCE_MEM, |
154 | }, | 168 | }, |
155 | [1] = { | 169 | [1] = { |
156 | .start = 72, | 170 | .start = evt2irq(0xb00), /* CMT1_CMT10 */ |
157 | .flags = IORESOURCE_IRQ, | 171 | .flags = IORESOURCE_IRQ, |
158 | }, | 172 | }, |
159 | }; | 173 | }; |
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 1d1153290f59..e26686c9d0b6 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c | |||
@@ -26,17 +26,21 @@ | |||
26 | #include <linux/input.h> | 26 | #include <linux/input.h> |
27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
28 | #include <linux/serial_sci.h> | 28 | #include <linux/serial_sci.h> |
29 | #include <linux/sh_dma.h> | ||
29 | #include <linux/sh_intc.h> | 30 | #include <linux/sh_intc.h> |
30 | #include <linux/sh_timer.h> | 31 | #include <linux/sh_timer.h> |
31 | #include <mach/hardware.h> | 32 | #include <mach/hardware.h> |
33 | #include <mach/sh7372.h> | ||
32 | #include <asm/mach-types.h> | 34 | #include <asm/mach-types.h> |
33 | #include <asm/mach/arch.h> | 35 | #include <asm/mach/arch.h> |
34 | 36 | ||
37 | /* SCIFA0 */ | ||
35 | static struct plat_sci_port scif0_platform_data = { | 38 | static struct plat_sci_port scif0_platform_data = { |
36 | .mapbase = 0xe6c40000, | 39 | .mapbase = 0xe6c40000, |
37 | .flags = UPF_BOOT_AUTOCONF, | 40 | .flags = UPF_BOOT_AUTOCONF, |
38 | .type = PORT_SCIF, | 41 | .type = PORT_SCIFA, |
39 | .irqs = { 80, 80, 80, 80 }, | 42 | .irqs = { evt2irq(0x0c00), evt2irq(0x0c00), |
43 | evt2irq(0x0c00), evt2irq(0x0c00) }, | ||
40 | }; | 44 | }; |
41 | 45 | ||
42 | static struct platform_device scif0_device = { | 46 | static struct platform_device scif0_device = { |
@@ -47,11 +51,13 @@ static struct platform_device scif0_device = { | |||
47 | }, | 51 | }, |
48 | }; | 52 | }; |
49 | 53 | ||
54 | /* SCIFA1 */ | ||
50 | static struct plat_sci_port scif1_platform_data = { | 55 | static struct plat_sci_port scif1_platform_data = { |
51 | .mapbase = 0xe6c50000, | 56 | .mapbase = 0xe6c50000, |
52 | .flags = UPF_BOOT_AUTOCONF, | 57 | .flags = UPF_BOOT_AUTOCONF, |
53 | .type = PORT_SCIF, | 58 | .type = PORT_SCIFA, |
54 | .irqs = { 81, 81, 81, 81 }, | 59 | .irqs = { evt2irq(0x0c20), evt2irq(0x0c20), |
60 | evt2irq(0x0c20), evt2irq(0x0c20) }, | ||
55 | }; | 61 | }; |
56 | 62 | ||
57 | static struct platform_device scif1_device = { | 63 | static struct platform_device scif1_device = { |
@@ -62,11 +68,13 @@ static struct platform_device scif1_device = { | |||
62 | }, | 68 | }, |
63 | }; | 69 | }; |
64 | 70 | ||
71 | /* SCIFA2 */ | ||
65 | static struct plat_sci_port scif2_platform_data = { | 72 | static struct plat_sci_port scif2_platform_data = { |
66 | .mapbase = 0xe6c60000, | 73 | .mapbase = 0xe6c60000, |
67 | .flags = UPF_BOOT_AUTOCONF, | 74 | .flags = UPF_BOOT_AUTOCONF, |
68 | .type = PORT_SCIF, | 75 | .type = PORT_SCIFA, |
69 | .irqs = { 82, 82, 82, 82 }, | 76 | .irqs = { evt2irq(0x0c40), evt2irq(0x0c40), |
77 | evt2irq(0x0c40), evt2irq(0x0c40) }, | ||
70 | }; | 78 | }; |
71 | 79 | ||
72 | static struct platform_device scif2_device = { | 80 | static struct platform_device scif2_device = { |
@@ -77,11 +85,13 @@ static struct platform_device scif2_device = { | |||
77 | }, | 85 | }, |
78 | }; | 86 | }; |
79 | 87 | ||
88 | /* SCIFA3 */ | ||
80 | static struct plat_sci_port scif3_platform_data = { | 89 | static struct plat_sci_port scif3_platform_data = { |
81 | .mapbase = 0xe6c70000, | 90 | .mapbase = 0xe6c70000, |
82 | .flags = UPF_BOOT_AUTOCONF, | 91 | .flags = UPF_BOOT_AUTOCONF, |
83 | .type = PORT_SCIF, | 92 | .type = PORT_SCIFA, |
84 | .irqs = { 83, 83, 83, 83 }, | 93 | .irqs = { evt2irq(0x0c60), evt2irq(0x0c60), |
94 | evt2irq(0x0c60), evt2irq(0x0c60) }, | ||
85 | }; | 95 | }; |
86 | 96 | ||
87 | static struct platform_device scif3_device = { | 97 | static struct platform_device scif3_device = { |
@@ -92,11 +102,13 @@ static struct platform_device scif3_device = { | |||
92 | }, | 102 | }, |
93 | }; | 103 | }; |
94 | 104 | ||
105 | /* SCIFA4 */ | ||
95 | static struct plat_sci_port scif4_platform_data = { | 106 | static struct plat_sci_port scif4_platform_data = { |
96 | .mapbase = 0xe6c80000, | 107 | .mapbase = 0xe6c80000, |
97 | .flags = UPF_BOOT_AUTOCONF, | 108 | .flags = UPF_BOOT_AUTOCONF, |
98 | .type = PORT_SCIF, | 109 | .type = PORT_SCIFA, |
99 | .irqs = { 89, 89, 89, 89 }, | 110 | .irqs = { evt2irq(0x0d20), evt2irq(0x0d20), |
111 | evt2irq(0x0d20), evt2irq(0x0d20) }, | ||
100 | }; | 112 | }; |
101 | 113 | ||
102 | static struct platform_device scif4_device = { | 114 | static struct platform_device scif4_device = { |
@@ -107,11 +119,13 @@ static struct platform_device scif4_device = { | |||
107 | }, | 119 | }, |
108 | }; | 120 | }; |
109 | 121 | ||
122 | /* SCIFA5 */ | ||
110 | static struct plat_sci_port scif5_platform_data = { | 123 | static struct plat_sci_port scif5_platform_data = { |
111 | .mapbase = 0xe6cb0000, | 124 | .mapbase = 0xe6cb0000, |
112 | .flags = UPF_BOOT_AUTOCONF, | 125 | .flags = UPF_BOOT_AUTOCONF, |
113 | .type = PORT_SCIF, | 126 | .type = PORT_SCIFA, |
114 | .irqs = { 90, 90, 90, 90 }, | 127 | .irqs = { evt2irq(0x0d40), evt2irq(0x0d40), |
128 | evt2irq(0x0d40), evt2irq(0x0d40) }, | ||
115 | }; | 129 | }; |
116 | 130 | ||
117 | static struct platform_device scif5_device = { | 131 | static struct platform_device scif5_device = { |
@@ -122,11 +136,13 @@ static struct platform_device scif5_device = { | |||
122 | }, | 136 | }, |
123 | }; | 137 | }; |
124 | 138 | ||
139 | /* SCIFB */ | ||
125 | static struct plat_sci_port scif6_platform_data = { | 140 | static struct plat_sci_port scif6_platform_data = { |
126 | .mapbase = 0xe6c30000, | 141 | .mapbase = 0xe6c30000, |
127 | .flags = UPF_BOOT_AUTOCONF, | 142 | .flags = UPF_BOOT_AUTOCONF, |
128 | .type = PORT_SCIF, | 143 | .type = PORT_SCIFB, |
129 | .irqs = { 91, 91, 91, 91 }, | 144 | .irqs = { evt2irq(0x0d60), evt2irq(0x0d60), |
145 | evt2irq(0x0d60), evt2irq(0x0d60) }, | ||
130 | }; | 146 | }; |
131 | 147 | ||
132 | static struct platform_device scif6_device = { | 148 | static struct platform_device scif6_device = { |
@@ -137,11 +153,12 @@ static struct platform_device scif6_device = { | |||
137 | }, | 153 | }, |
138 | }; | 154 | }; |
139 | 155 | ||
156 | /* CMT */ | ||
140 | static struct sh_timer_config cmt10_platform_data = { | 157 | static struct sh_timer_config cmt10_platform_data = { |
141 | .name = "CMT10", | 158 | .name = "CMT10", |
142 | .channel_offset = 0x10, | 159 | .channel_offset = 0x10, |
143 | .timer_bit = 0, | 160 | .timer_bit = 0, |
144 | .clk = "r_clk", | 161 | .clk = "cmt1", |
145 | .clockevent_rating = 125, | 162 | .clockevent_rating = 125, |
146 | .clocksource_rating = 125, | 163 | .clocksource_rating = 125, |
147 | }; | 164 | }; |
@@ -154,7 +171,7 @@ static struct resource cmt10_resources[] = { | |||
154 | .flags = IORESOURCE_MEM, | 171 | .flags = IORESOURCE_MEM, |
155 | }, | 172 | }, |
156 | [1] = { | 173 | [1] = { |
157 | .start = 72, | 174 | .start = evt2irq(0x0b00), /* CMT1_CMT10 */ |
158 | .flags = IORESOURCE_IRQ, | 175 | .flags = IORESOURCE_IRQ, |
159 | }, | 176 | }, |
160 | }; | 177 | }; |
@@ -169,6 +186,337 @@ static struct platform_device cmt10_device = { | |||
169 | .num_resources = ARRAY_SIZE(cmt10_resources), | 186 | .num_resources = ARRAY_SIZE(cmt10_resources), |
170 | }; | 187 | }; |
171 | 188 | ||
189 | /* I2C */ | ||
190 | static struct resource iic0_resources[] = { | ||
191 | [0] = { | ||
192 | .name = "IIC0", | ||
193 | .start = 0xFFF20000, | ||
194 | .end = 0xFFF20425 - 1, | ||
195 | .flags = IORESOURCE_MEM, | ||
196 | }, | ||
197 | [1] = { | ||
198 | .start = intcs_evt2irq(0xe00), /* IIC0_ALI0 */ | ||
199 | .end = intcs_evt2irq(0xe60), /* IIC0_DTEI0 */ | ||
200 | .flags = IORESOURCE_IRQ, | ||
201 | }, | ||
202 | }; | ||
203 | |||
204 | static struct platform_device iic0_device = { | ||
205 | .name = "i2c-sh_mobile", | ||
206 | .id = 0, /* "i2c0" clock */ | ||
207 | .num_resources = ARRAY_SIZE(iic0_resources), | ||
208 | .resource = iic0_resources, | ||
209 | }; | ||
210 | |||
211 | static struct resource iic1_resources[] = { | ||
212 | [0] = { | ||
213 | .name = "IIC1", | ||
214 | .start = 0xE6C20000, | ||
215 | .end = 0xE6C20425 - 1, | ||
216 | .flags = IORESOURCE_MEM, | ||
217 | }, | ||
218 | [1] = { | ||
219 | .start = evt2irq(0x780), /* IIC1_ALI1 */ | ||
220 | .end = evt2irq(0x7e0), /* IIC1_DTEI1 */ | ||
221 | .flags = IORESOURCE_IRQ, | ||
222 | }, | ||
223 | }; | ||
224 | |||
225 | static struct platform_device iic1_device = { | ||
226 | .name = "i2c-sh_mobile", | ||
227 | .id = 1, /* "i2c1" clock */ | ||
228 | .num_resources = ARRAY_SIZE(iic1_resources), | ||
229 | .resource = iic1_resources, | ||
230 | }; | ||
231 | |||
232 | /* DMA */ | ||
233 | /* Transmit sizes and respective CHCR register values */ | ||
234 | enum { | ||
235 | XMIT_SZ_8BIT = 0, | ||
236 | XMIT_SZ_16BIT = 1, | ||
237 | XMIT_SZ_32BIT = 2, | ||
238 | XMIT_SZ_64BIT = 7, | ||
239 | XMIT_SZ_128BIT = 3, | ||
240 | XMIT_SZ_256BIT = 4, | ||
241 | XMIT_SZ_512BIT = 5, | ||
242 | }; | ||
243 | |||
244 | /* log2(size / 8) - used to calculate number of transfers */ | ||
245 | #define TS_SHIFT { \ | ||
246 | [XMIT_SZ_8BIT] = 0, \ | ||
247 | [XMIT_SZ_16BIT] = 1, \ | ||
248 | [XMIT_SZ_32BIT] = 2, \ | ||
249 | [XMIT_SZ_64BIT] = 3, \ | ||
250 | [XMIT_SZ_128BIT] = 4, \ | ||
251 | [XMIT_SZ_256BIT] = 5, \ | ||
252 | [XMIT_SZ_512BIT] = 6, \ | ||
253 | } | ||
254 | |||
255 | #define TS_INDEX2VAL(i) ((((i) & 3) << 3) | \ | ||
256 | (((i) & 0xc) << (20 - 2))) | ||
257 | |||
258 | static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = { | ||
259 | { | ||
260 | .slave_id = SHDMA_SLAVE_SCIF0_TX, | ||
261 | .addr = 0xe6c40020, | ||
262 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
263 | .mid_rid = 0x21, | ||
264 | }, { | ||
265 | .slave_id = SHDMA_SLAVE_SCIF0_RX, | ||
266 | .addr = 0xe6c40024, | ||
267 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
268 | .mid_rid = 0x22, | ||
269 | }, { | ||
270 | .slave_id = SHDMA_SLAVE_SCIF1_TX, | ||
271 | .addr = 0xe6c50020, | ||
272 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
273 | .mid_rid = 0x25, | ||
274 | }, { | ||
275 | .slave_id = SHDMA_SLAVE_SCIF1_RX, | ||
276 | .addr = 0xe6c50024, | ||
277 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
278 | .mid_rid = 0x26, | ||
279 | }, { | ||
280 | .slave_id = SHDMA_SLAVE_SCIF2_TX, | ||
281 | .addr = 0xe6c60020, | ||
282 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
283 | .mid_rid = 0x29, | ||
284 | }, { | ||
285 | .slave_id = SHDMA_SLAVE_SCIF2_RX, | ||
286 | .addr = 0xe6c60024, | ||
287 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
288 | .mid_rid = 0x2a, | ||
289 | }, { | ||
290 | .slave_id = SHDMA_SLAVE_SCIF3_TX, | ||
291 | .addr = 0xe6c70020, | ||
292 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
293 | .mid_rid = 0x2d, | ||
294 | }, { | ||
295 | .slave_id = SHDMA_SLAVE_SCIF3_RX, | ||
296 | .addr = 0xe6c70024, | ||
297 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
298 | .mid_rid = 0x2e, | ||
299 | }, { | ||
300 | .slave_id = SHDMA_SLAVE_SCIF4_TX, | ||
301 | .addr = 0xe6c80020, | ||
302 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
303 | .mid_rid = 0x39, | ||
304 | }, { | ||
305 | .slave_id = SHDMA_SLAVE_SCIF4_RX, | ||
306 | .addr = 0xe6c80024, | ||
307 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
308 | .mid_rid = 0x3a, | ||
309 | }, { | ||
310 | .slave_id = SHDMA_SLAVE_SCIF5_TX, | ||
311 | .addr = 0xe6cb0020, | ||
312 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
313 | .mid_rid = 0x35, | ||
314 | }, { | ||
315 | .slave_id = SHDMA_SLAVE_SCIF5_RX, | ||
316 | .addr = 0xe6cb0024, | ||
317 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
318 | .mid_rid = 0x36, | ||
319 | }, { | ||
320 | .slave_id = SHDMA_SLAVE_SCIF6_TX, | ||
321 | .addr = 0xe6c30040, | ||
322 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
323 | .mid_rid = 0x3d, | ||
324 | }, { | ||
325 | .slave_id = SHDMA_SLAVE_SCIF6_RX, | ||
326 | .addr = 0xe6c30060, | ||
327 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT), | ||
328 | .mid_rid = 0x3e, | ||
329 | }, { | ||
330 | .slave_id = SHDMA_SLAVE_SDHI0_TX, | ||
331 | .addr = 0xe6850030, | ||
332 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), | ||
333 | .mid_rid = 0xc1, | ||
334 | }, { | ||
335 | .slave_id = SHDMA_SLAVE_SDHI0_RX, | ||
336 | .addr = 0xe6850030, | ||
337 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), | ||
338 | .mid_rid = 0xc2, | ||
339 | }, { | ||
340 | .slave_id = SHDMA_SLAVE_SDHI1_TX, | ||
341 | .addr = 0xe6860030, | ||
342 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), | ||
343 | .mid_rid = 0xc9, | ||
344 | }, { | ||
345 | .slave_id = SHDMA_SLAVE_SDHI1_RX, | ||
346 | .addr = 0xe6860030, | ||
347 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), | ||
348 | .mid_rid = 0xca, | ||
349 | }, { | ||
350 | .slave_id = SHDMA_SLAVE_SDHI2_TX, | ||
351 | .addr = 0xe6870030, | ||
352 | .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), | ||
353 | .mid_rid = 0xcd, | ||
354 | }, { | ||
355 | .slave_id = SHDMA_SLAVE_SDHI2_RX, | ||
356 | .addr = 0xe6870030, | ||
357 | .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT), | ||
358 | .mid_rid = 0xce, | ||
359 | }, | ||
360 | }; | ||
361 | |||
362 | static const struct sh_dmae_channel sh7372_dmae_channels[] = { | ||
363 | { | ||
364 | .offset = 0, | ||
365 | .dmars = 0, | ||
366 | .dmars_bit = 0, | ||
367 | }, { | ||
368 | .offset = 0x10, | ||
369 | .dmars = 0, | ||
370 | .dmars_bit = 8, | ||
371 | }, { | ||
372 | .offset = 0x20, | ||
373 | .dmars = 4, | ||
374 | .dmars_bit = 0, | ||
375 | }, { | ||
376 | .offset = 0x30, | ||
377 | .dmars = 4, | ||
378 | .dmars_bit = 8, | ||
379 | }, { | ||
380 | .offset = 0x50, | ||
381 | .dmars = 8, | ||
382 | .dmars_bit = 0, | ||
383 | }, { | ||
384 | .offset = 0x60, | ||
385 | .dmars = 8, | ||
386 | .dmars_bit = 8, | ||
387 | } | ||
388 | }; | ||
389 | |||
390 | static const unsigned int ts_shift[] = TS_SHIFT; | ||
391 | |||
392 | static struct sh_dmae_pdata dma_platform_data = { | ||
393 | .slave = sh7372_dmae_slaves, | ||
394 | .slave_num = ARRAY_SIZE(sh7372_dmae_slaves), | ||
395 | .channel = sh7372_dmae_channels, | ||
396 | .channel_num = ARRAY_SIZE(sh7372_dmae_channels), | ||
397 | .ts_low_shift = 3, | ||
398 | .ts_low_mask = 0x18, | ||
399 | .ts_high_shift = (20 - 2), /* 2 bits for shifted low TS */ | ||
400 | .ts_high_mask = 0x00300000, | ||
401 | .ts_shift = ts_shift, | ||
402 | .ts_shift_num = ARRAY_SIZE(ts_shift), | ||
403 | .dmaor_init = DMAOR_DME, | ||
404 | }; | ||
405 | |||
406 | /* Resource order important! */ | ||
407 | static struct resource sh7372_dmae0_resources[] = { | ||
408 | { | ||
409 | /* Channel registers and DMAOR */ | ||
410 | .start = 0xfe008020, | ||
411 | .end = 0xfe00808f, | ||
412 | .flags = IORESOURCE_MEM, | ||
413 | }, | ||
414 | { | ||
415 | /* DMARSx */ | ||
416 | .start = 0xfe009000, | ||
417 | .end = 0xfe00900b, | ||
418 | .flags = IORESOURCE_MEM, | ||
419 | }, | ||
420 | { | ||
421 | /* DMA error IRQ */ | ||
422 | .start = 246, | ||
423 | .end = 246, | ||
424 | .flags = IORESOURCE_IRQ, | ||
425 | }, | ||
426 | { | ||
427 | /* IRQ for channels 0-5 */ | ||
428 | .start = 240, | ||
429 | .end = 245, | ||
430 | .flags = IORESOURCE_IRQ, | ||
431 | }, | ||
432 | }; | ||
433 | |||
434 | /* Resource order important! */ | ||
435 | static struct resource sh7372_dmae1_resources[] = { | ||
436 | { | ||
437 | /* Channel registers and DMAOR */ | ||
438 | .start = 0xfe018020, | ||
439 | .end = 0xfe01808f, | ||
440 | .flags = IORESOURCE_MEM, | ||
441 | }, | ||
442 | { | ||
443 | /* DMARSx */ | ||
444 | .start = 0xfe019000, | ||
445 | .end = 0xfe01900b, | ||
446 | .flags = IORESOURCE_MEM, | ||
447 | }, | ||
448 | { | ||
449 | /* DMA error IRQ */ | ||
450 | .start = 254, | ||
451 | .end = 254, | ||
452 | .flags = IORESOURCE_IRQ, | ||
453 | }, | ||
454 | { | ||
455 | /* IRQ for channels 0-5 */ | ||
456 | .start = 248, | ||
457 | .end = 253, | ||
458 | .flags = IORESOURCE_IRQ, | ||
459 | }, | ||
460 | }; | ||
461 | |||
462 | /* Resource order important! */ | ||
463 | static struct resource sh7372_dmae2_resources[] = { | ||
464 | { | ||
465 | /* Channel registers and DMAOR */ | ||
466 | .start = 0xfe028020, | ||
467 | .end = 0xfe02808f, | ||
468 | .flags = IORESOURCE_MEM, | ||
469 | }, | ||
470 | { | ||
471 | /* DMARSx */ | ||
472 | .start = 0xfe029000, | ||
473 | .end = 0xfe02900b, | ||
474 | .flags = IORESOURCE_MEM, | ||
475 | }, | ||
476 | { | ||
477 | /* DMA error IRQ */ | ||
478 | .start = 262, | ||
479 | .end = 262, | ||
480 | .flags = IORESOURCE_IRQ, | ||
481 | }, | ||
482 | { | ||
483 | /* IRQ for channels 0-5 */ | ||
484 | .start = 256, | ||
485 | .end = 261, | ||
486 | .flags = IORESOURCE_IRQ, | ||
487 | }, | ||
488 | }; | ||
489 | |||
490 | static struct platform_device dma0_device = { | ||
491 | .name = "sh-dma-engine", | ||
492 | .id = 0, | ||
493 | .resource = sh7372_dmae0_resources, | ||
494 | .num_resources = ARRAY_SIZE(sh7372_dmae0_resources), | ||
495 | .dev = { | ||
496 | .platform_data = &dma_platform_data, | ||
497 | }, | ||
498 | }; | ||
499 | |||
500 | static struct platform_device dma1_device = { | ||
501 | .name = "sh-dma-engine", | ||
502 | .id = 1, | ||
503 | .resource = sh7372_dmae1_resources, | ||
504 | .num_resources = ARRAY_SIZE(sh7372_dmae1_resources), | ||
505 | .dev = { | ||
506 | .platform_data = &dma_platform_data, | ||
507 | }, | ||
508 | }; | ||
509 | |||
510 | static struct platform_device dma2_device = { | ||
511 | .name = "sh-dma-engine", | ||
512 | .id = 2, | ||
513 | .resource = sh7372_dmae2_resources, | ||
514 | .num_resources = ARRAY_SIZE(sh7372_dmae2_resources), | ||
515 | .dev = { | ||
516 | .platform_data = &dma_platform_data, | ||
517 | }, | ||
518 | }; | ||
519 | |||
172 | static struct platform_device *sh7372_early_devices[] __initdata = { | 520 | static struct platform_device *sh7372_early_devices[] __initdata = { |
173 | &scif0_device, | 521 | &scif0_device, |
174 | &scif1_device, | 522 | &scif1_device, |
@@ -178,6 +526,11 @@ static struct platform_device *sh7372_early_devices[] __initdata = { | |||
178 | &scif5_device, | 526 | &scif5_device, |
179 | &scif6_device, | 527 | &scif6_device, |
180 | &cmt10_device, | 528 | &cmt10_device, |
529 | &iic0_device, | ||
530 | &iic1_device, | ||
531 | &dma0_device, | ||
532 | &dma1_device, | ||
533 | &dma2_device, | ||
181 | }; | 534 | }; |
182 | 535 | ||
183 | void __init sh7372_add_standard_devices(void) | 536 | void __init sh7372_add_standard_devices(void) |
@@ -186,14 +539,8 @@ void __init sh7372_add_standard_devices(void) | |||
186 | ARRAY_SIZE(sh7372_early_devices)); | 539 | ARRAY_SIZE(sh7372_early_devices)); |
187 | } | 540 | } |
188 | 541 | ||
189 | #define SMSTPCR3 0xe615013c | ||
190 | #define SMSTPCR3_CMT1 (1 << 29) | ||
191 | |||
192 | void __init sh7372_add_early_devices(void) | 542 | void __init sh7372_add_early_devices(void) |
193 | { | 543 | { |
194 | /* enable clock to CMT1 */ | ||
195 | __raw_writel(__raw_readl(SMSTPCR3) & ~SMSTPCR3_CMT1, SMSTPCR3); | ||
196 | |||
197 | early_platform_add_devices(sh7372_early_devices, | 544 | early_platform_add_devices(sh7372_early_devices, |
198 | ARRAY_SIZE(sh7372_early_devices)); | 545 | ARRAY_SIZE(sh7372_early_devices)); |
199 | } | 546 | } |
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c index 60e37774c35c..bb4adf17dbf4 100644 --- a/arch/arm/mach-shmobile/setup-sh7377.c +++ b/arch/arm/mach-shmobile/setup-sh7377.c | |||
@@ -32,11 +32,13 @@ | |||
32 | #include <asm/mach-types.h> | 32 | #include <asm/mach-types.h> |
33 | #include <asm/mach/arch.h> | 33 | #include <asm/mach/arch.h> |
34 | 34 | ||
35 | /* SCIFA0 */ | ||
35 | static struct plat_sci_port scif0_platform_data = { | 36 | static struct plat_sci_port scif0_platform_data = { |
36 | .mapbase = 0xe6c40000, | 37 | .mapbase = 0xe6c40000, |
37 | .flags = UPF_BOOT_AUTOCONF, | 38 | .flags = UPF_BOOT_AUTOCONF, |
38 | .type = PORT_SCIF, | 39 | .type = PORT_SCIF, |
39 | .irqs = { 80, 80, 80, 80 }, | 40 | .irqs = { evt2irq(0xc00), evt2irq(0xc00), |
41 | evt2irq(0xc00), evt2irq(0xc00) }, | ||
40 | }; | 42 | }; |
41 | 43 | ||
42 | static struct platform_device scif0_device = { | 44 | static struct platform_device scif0_device = { |
@@ -47,11 +49,13 @@ static struct platform_device scif0_device = { | |||
47 | }, | 49 | }, |
48 | }; | 50 | }; |
49 | 51 | ||
52 | /* SCIFA1 */ | ||
50 | static struct plat_sci_port scif1_platform_data = { | 53 | static struct plat_sci_port scif1_platform_data = { |
51 | .mapbase = 0xe6c50000, | 54 | .mapbase = 0xe6c50000, |
52 | .flags = UPF_BOOT_AUTOCONF, | 55 | .flags = UPF_BOOT_AUTOCONF, |
53 | .type = PORT_SCIF, | 56 | .type = PORT_SCIF, |
54 | .irqs = { 81, 81, 81, 81 }, | 57 | .irqs = { evt2irq(0xc20), evt2irq(0xc20), |
58 | evt2irq(0xc20), evt2irq(0xc20) }, | ||
55 | }; | 59 | }; |
56 | 60 | ||
57 | static struct platform_device scif1_device = { | 61 | static struct platform_device scif1_device = { |
@@ -62,11 +66,13 @@ static struct platform_device scif1_device = { | |||
62 | }, | 66 | }, |
63 | }; | 67 | }; |
64 | 68 | ||
69 | /* SCIFA2 */ | ||
65 | static struct plat_sci_port scif2_platform_data = { | 70 | static struct plat_sci_port scif2_platform_data = { |
66 | .mapbase = 0xe6c60000, | 71 | .mapbase = 0xe6c60000, |
67 | .flags = UPF_BOOT_AUTOCONF, | 72 | .flags = UPF_BOOT_AUTOCONF, |
68 | .type = PORT_SCIF, | 73 | .type = PORT_SCIF, |
69 | .irqs = { 82, 82, 82, 82 }, | 74 | .irqs = { evt2irq(0xc40), evt2irq(0xc40), |
75 | evt2irq(0xc40), evt2irq(0xc40) }, | ||
70 | }; | 76 | }; |
71 | 77 | ||
72 | static struct platform_device scif2_device = { | 78 | static struct platform_device scif2_device = { |
@@ -77,11 +83,13 @@ static struct platform_device scif2_device = { | |||
77 | }, | 83 | }, |
78 | }; | 84 | }; |
79 | 85 | ||
86 | /* SCIFA3 */ | ||
80 | static struct plat_sci_port scif3_platform_data = { | 87 | static struct plat_sci_port scif3_platform_data = { |
81 | .mapbase = 0xe6c70000, | 88 | .mapbase = 0xe6c70000, |
82 | .flags = UPF_BOOT_AUTOCONF, | 89 | .flags = UPF_BOOT_AUTOCONF, |
83 | .type = PORT_SCIF, | 90 | .type = PORT_SCIF, |
84 | .irqs = { 83, 83, 83, 83 }, | 91 | .irqs = { evt2irq(0xc60), evt2irq(0xc60), |
92 | evt2irq(0xc60), evt2irq(0xc60) }, | ||
85 | }; | 93 | }; |
86 | 94 | ||
87 | static struct platform_device scif3_device = { | 95 | static struct platform_device scif3_device = { |
@@ -92,11 +100,13 @@ static struct platform_device scif3_device = { | |||
92 | }, | 100 | }, |
93 | }; | 101 | }; |
94 | 102 | ||
103 | /* SCIFA4 */ | ||
95 | static struct plat_sci_port scif4_platform_data = { | 104 | static struct plat_sci_port scif4_platform_data = { |
96 | .mapbase = 0xe6c80000, | 105 | .mapbase = 0xe6c80000, |
97 | .flags = UPF_BOOT_AUTOCONF, | 106 | .flags = UPF_BOOT_AUTOCONF, |
98 | .type = PORT_SCIF, | 107 | .type = PORT_SCIF, |
99 | .irqs = { 89, 89, 89, 89 }, | 108 | .irqs = { evt2irq(0xd20), evt2irq(0xd20), |
109 | evt2irq(0xd20), evt2irq(0xd20) }, | ||
100 | }; | 110 | }; |
101 | 111 | ||
102 | static struct platform_device scif4_device = { | 112 | static struct platform_device scif4_device = { |
@@ -107,11 +117,13 @@ static struct platform_device scif4_device = { | |||
107 | }, | 117 | }, |
108 | }; | 118 | }; |
109 | 119 | ||
120 | /* SCIFA5 */ | ||
110 | static struct plat_sci_port scif5_platform_data = { | 121 | static struct plat_sci_port scif5_platform_data = { |
111 | .mapbase = 0xe6cb0000, | 122 | .mapbase = 0xe6cb0000, |
112 | .flags = UPF_BOOT_AUTOCONF, | 123 | .flags = UPF_BOOT_AUTOCONF, |
113 | .type = PORT_SCIF, | 124 | .type = PORT_SCIF, |
114 | .irqs = { 90, 90, 90, 90 }, | 125 | .irqs = { evt2irq(0xd40), evt2irq(0xd40), |
126 | evt2irq(0xd40), evt2irq(0xd40) }, | ||
115 | }; | 127 | }; |
116 | 128 | ||
117 | static struct platform_device scif5_device = { | 129 | static struct platform_device scif5_device = { |
@@ -122,11 +134,13 @@ static struct platform_device scif5_device = { | |||
122 | }, | 134 | }, |
123 | }; | 135 | }; |
124 | 136 | ||
137 | /* SCIFA6 */ | ||
125 | static struct plat_sci_port scif6_platform_data = { | 138 | static struct plat_sci_port scif6_platform_data = { |
126 | .mapbase = 0xe6cc0000, | 139 | .mapbase = 0xe6cc0000, |
127 | .flags = UPF_BOOT_AUTOCONF, | 140 | .flags = UPF_BOOT_AUTOCONF, |
128 | .type = PORT_SCIF, | 141 | .type = PORT_SCIF, |
129 | .irqs = { 196, 196, 196, 196 }, | 142 | .irqs = { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80), |
143 | intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) }, | ||
130 | }; | 144 | }; |
131 | 145 | ||
132 | static struct platform_device scif6_device = { | 146 | static struct platform_device scif6_device = { |
@@ -137,11 +151,13 @@ static struct platform_device scif6_device = { | |||
137 | }, | 151 | }, |
138 | }; | 152 | }; |
139 | 153 | ||
154 | /* SCIFB */ | ||
140 | static struct plat_sci_port scif7_platform_data = { | 155 | static struct plat_sci_port scif7_platform_data = { |
141 | .mapbase = 0xe6c30000, | 156 | .mapbase = 0xe6c30000, |
142 | .flags = UPF_BOOT_AUTOCONF, | 157 | .flags = UPF_BOOT_AUTOCONF, |
143 | .type = PORT_SCIF, | 158 | .type = PORT_SCIF, |
144 | .irqs = { 91, 91, 91, 91 }, | 159 | .irqs = { evt2irq(0xd60), evt2irq(0xd60), |
160 | evt2irq(0xd60), evt2irq(0xd60) }, | ||
145 | }; | 161 | }; |
146 | 162 | ||
147 | static struct platform_device scif7_device = { | 163 | static struct platform_device scif7_device = { |
@@ -169,7 +185,7 @@ static struct resource cmt10_resources[] = { | |||
169 | .flags = IORESOURCE_MEM, | 185 | .flags = IORESOURCE_MEM, |
170 | }, | 186 | }, |
171 | [1] = { | 187 | [1] = { |
172 | .start = 72, | 188 | .start = evt2irq(0xb00), /* CMT1_CMT10 */ |
173 | .flags = IORESOURCE_IRQ, | 189 | .flags = IORESOURCE_IRQ, |
174 | }, | 190 | }, |
175 | }; | 191 | }; |
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index de375b64e410..3da116f47f01 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c | |||
@@ -154,7 +154,7 @@ static struct platform_device nand_flash_device = { | |||
154 | #define PORT_DRVCRA 0xA405018A | 154 | #define PORT_DRVCRA 0xA405018A |
155 | #define PORT_DRVCRB 0xA405018C | 155 | #define PORT_DRVCRB 0xA405018C |
156 | 156 | ||
157 | static void ap320_wvga_power_on(void *board_data) | 157 | static void ap320_wvga_power_on(void *board_data, struct fb_info *info) |
158 | { | 158 | { |
159 | msleep(100); | 159 | msleep(100); |
160 | 160 | ||
diff --git a/arch/sh/boards/mach-kfr2r09/Makefile b/arch/sh/boards/mach-kfr2r09/Makefile index 4e577a3bf658..60dd63f4a427 100644 --- a/arch/sh/boards/mach-kfr2r09/Makefile +++ b/arch/sh/boards/mach-kfr2r09/Makefile | |||
@@ -1,2 +1,4 @@ | |||
1 | obj-y := setup.o sdram.o | 1 | obj-y := setup.o sdram.o |
2 | obj-$(CONFIG_FB_SH_MOBILE_LCDC) += lcd_wqvga.o | 2 | ifneq ($(CONFIG_FB_SH_MOBILE_LCDC),) |
3 | obj-y += lcd_wqvga.o | ||
4 | endif | ||
diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c index e9b970846c41..25e145fb7087 100644 --- a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c +++ b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c | |||
@@ -327,7 +327,7 @@ static int kfr2r09_lcd_backlight(int on) | |||
327 | return 0; | 327 | return 0; |
328 | } | 328 | } |
329 | 329 | ||
330 | void kfr2r09_lcd_on(void *board_data) | 330 | void kfr2r09_lcd_on(void *board_data, struct fb_info *info) |
331 | { | 331 | { |
332 | kfr2r09_lcd_backlight(1); | 332 | kfr2r09_lcd_backlight(1); |
333 | } | 333 | } |
diff --git a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h index 484ef42c2fb5..07e635b0e04c 100644 --- a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h +++ b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h | |||
@@ -3,23 +3,23 @@ | |||
3 | 3 | ||
4 | #include <video/sh_mobile_lcdc.h> | 4 | #include <video/sh_mobile_lcdc.h> |
5 | 5 | ||
6 | #ifdef CONFIG_FB_SH_MOBILE_LCDC | 6 | #if defined(CONFIG_FB_SH_MOBILE_LCDC) || defined(CONFIG_FB_SH_MOBILE_LCDC_MODULE) |
7 | void kfr2r09_lcd_on(void *board_data); | 7 | void kfr2r09_lcd_on(void *board_data, struct fb_info *info); |
8 | void kfr2r09_lcd_off(void *board_data); | 8 | void kfr2r09_lcd_off(void *board_data); |
9 | int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle, | 9 | int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle, |
10 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops); | 10 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops); |
11 | void kfr2r09_lcd_start(void *board_data, void *sys_ops_handle, | 11 | void kfr2r09_lcd_start(void *board_data, void *sys_ops_handle, |
12 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops); | 12 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops); |
13 | #else | 13 | #else |
14 | static inline void kfr2r09_lcd_on(void *board_data) {} | 14 | static void kfr2r09_lcd_on(void *board_data) {} |
15 | static inline void kfr2r09_lcd_off(void *board_data) {} | 15 | static void kfr2r09_lcd_off(void *board_data) {} |
16 | static inline int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle, | 16 | static int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle, |
17 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops) | 17 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops) |
18 | { | 18 | { |
19 | return -ENODEV; | 19 | return -ENODEV; |
20 | } | 20 | } |
21 | static inline void kfr2r09_lcd_start(void *board_data, void *sys_ops_handle, | 21 | static void kfr2r09_lcd_start(void *board_data, void *sys_ops_handle, |
22 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops) | 22 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops) |
23 | { | 23 | { |
24 | } | 24 | } |
25 | #endif | 25 | #endif |
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 9e01e96fee94..8344375dc015 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
@@ -128,7 +128,7 @@ config TXX9_DMAC | |||
128 | 128 | ||
129 | config SH_DMAE | 129 | config SH_DMAE |
130 | tristate "Renesas SuperH DMAC support" | 130 | tristate "Renesas SuperH DMAC support" |
131 | depends on SUPERH && SH_DMA | 131 | depends on (SUPERH && SH_DMA) || (ARM && ARCH_SHMOBILE) |
132 | depends on !SH_DMA_API | 132 | depends on !SH_DMA_API |
133 | select DMA_ENGINE | 133 | select DMA_ENGINE |
134 | help | 134 | help |
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index a2a519fd2a24..fb64cf36ba61 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
@@ -816,7 +816,7 @@ static irqreturn_t sh_dmae_interrupt(int irq, void *data) | |||
816 | return ret; | 816 | return ret; |
817 | } | 817 | } |
818 | 818 | ||
819 | #if defined(CONFIG_CPU_SH4) | 819 | #if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) |
820 | static irqreturn_t sh_dmae_err(int irq, void *data) | 820 | static irqreturn_t sh_dmae_err(int irq, void *data) |
821 | { | 821 | { |
822 | struct sh_dmae_device *shdev = (struct sh_dmae_device *)data; | 822 | struct sh_dmae_device *shdev = (struct sh_dmae_device *)data; |
@@ -1057,7 +1057,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
1057 | /* Default transfer size of 32 bytes requires 32-byte alignment */ | 1057 | /* Default transfer size of 32 bytes requires 32-byte alignment */ |
1058 | shdev->common.copy_align = LOG2_DEFAULT_XFER_SIZE; | 1058 | shdev->common.copy_align = LOG2_DEFAULT_XFER_SIZE; |
1059 | 1059 | ||
1060 | #if defined(CONFIG_CPU_SH4) | 1060 | #if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) |
1061 | chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1); | 1061 | chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1); |
1062 | 1062 | ||
1063 | if (!chanirq_res) | 1063 | if (!chanirq_res) |
@@ -1082,7 +1082,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
1082 | 1082 | ||
1083 | #else | 1083 | #else |
1084 | chanirq_res = errirq_res; | 1084 | chanirq_res = errirq_res; |
1085 | #endif /* CONFIG_CPU_SH4 */ | 1085 | #endif /* CONFIG_CPU_SH4 || CONFIG_ARCH_SHMOBILE */ |
1086 | 1086 | ||
1087 | if (chanirq_res->start == chanirq_res->end && | 1087 | if (chanirq_res->start == chanirq_res->end && |
1088 | !platform_get_resource(pdev, IORESOURCE_IRQ, 1)) { | 1088 | !platform_get_resource(pdev, IORESOURCE_IRQ, 1)) { |
@@ -1129,7 +1129,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
1129 | chan_probe_err: | 1129 | chan_probe_err: |
1130 | sh_dmae_chan_remove(shdev); | 1130 | sh_dmae_chan_remove(shdev); |
1131 | eirqres: | 1131 | eirqres: |
1132 | #if defined(CONFIG_CPU_SH4) | 1132 | #if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) |
1133 | free_irq(errirq, shdev); | 1133 | free_irq(errirq, shdev); |
1134 | eirq_err: | 1134 | eirq_err: |
1135 | #endif | 1135 | #endif |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index bceafbfa7268..29e01f6238a7 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -549,7 +549,7 @@ config I2C_SH7760 | |||
549 | 549 | ||
550 | config I2C_SH_MOBILE | 550 | config I2C_SH_MOBILE |
551 | tristate "SuperH Mobile I2C Controller" | 551 | tristate "SuperH Mobile I2C Controller" |
552 | depends on SUPERH | 552 | depends on SUPERH || ARCH_SHMOBILE |
553 | help | 553 | help |
554 | If you say yes to this option, support will be included for the | 554 | If you say yes to this option, support will be included for the |
555 | built-in I2C interface on the Renesas SH-Mobile processor. | 555 | built-in I2C interface on the Renesas SH-Mobile processor. |
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index ffb405d7c6f2..598c49acaeb5 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c | |||
@@ -119,8 +119,10 @@ struct sh_mobile_i2c_data { | |||
119 | struct i2c_adapter adap; | 119 | struct i2c_adapter adap; |
120 | 120 | ||
121 | struct clk *clk; | 121 | struct clk *clk; |
122 | u_int8_t icic; | ||
122 | u_int8_t iccl; | 123 | u_int8_t iccl; |
123 | u_int8_t icch; | 124 | u_int8_t icch; |
125 | u_int8_t flags; | ||
124 | 126 | ||
125 | spinlock_t lock; | 127 | spinlock_t lock; |
126 | wait_queue_head_t wait; | 128 | wait_queue_head_t wait; |
@@ -129,15 +131,17 @@ struct sh_mobile_i2c_data { | |||
129 | int sr; | 131 | int sr; |
130 | }; | 132 | }; |
131 | 133 | ||
134 | #define IIC_FLAG_HAS_ICIC67 (1 << 0) | ||
135 | |||
132 | #define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */ | 136 | #define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */ |
133 | 137 | ||
134 | /* Register offsets */ | 138 | /* Register offsets */ |
135 | #define ICDR(pd) (pd->reg + 0x00) | 139 | #define ICDR 0x00 |
136 | #define ICCR(pd) (pd->reg + 0x04) | 140 | #define ICCR 0x04 |
137 | #define ICSR(pd) (pd->reg + 0x08) | 141 | #define ICSR 0x08 |
138 | #define ICIC(pd) (pd->reg + 0x0c) | 142 | #define ICIC 0x0c |
139 | #define ICCL(pd) (pd->reg + 0x10) | 143 | #define ICCL 0x10 |
140 | #define ICCH(pd) (pd->reg + 0x14) | 144 | #define ICCH 0x14 |
141 | 145 | ||
142 | /* Register bits */ | 146 | /* Register bits */ |
143 | #define ICCR_ICE 0x80 | 147 | #define ICCR_ICE 0x80 |
@@ -155,11 +159,32 @@ struct sh_mobile_i2c_data { | |||
155 | #define ICSR_WAIT 0x02 | 159 | #define ICSR_WAIT 0x02 |
156 | #define ICSR_DTE 0x01 | 160 | #define ICSR_DTE 0x01 |
157 | 161 | ||
162 | #define ICIC_ICCLB8 0x80 | ||
163 | #define ICIC_ICCHB8 0x40 | ||
158 | #define ICIC_ALE 0x08 | 164 | #define ICIC_ALE 0x08 |
159 | #define ICIC_TACKE 0x04 | 165 | #define ICIC_TACKE 0x04 |
160 | #define ICIC_WAITE 0x02 | 166 | #define ICIC_WAITE 0x02 |
161 | #define ICIC_DTEE 0x01 | 167 | #define ICIC_DTEE 0x01 |
162 | 168 | ||
169 | static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data) | ||
170 | { | ||
171 | if (offs == ICIC) | ||
172 | data |= pd->icic; | ||
173 | |||
174 | iowrite8(data, pd->reg + offs); | ||
175 | } | ||
176 | |||
177 | static unsigned char iic_rd(struct sh_mobile_i2c_data *pd, int offs) | ||
178 | { | ||
179 | return ioread8(pd->reg + offs); | ||
180 | } | ||
181 | |||
182 | static void iic_set_clr(struct sh_mobile_i2c_data *pd, int offs, | ||
183 | unsigned char set, unsigned char clr) | ||
184 | { | ||
185 | iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr); | ||
186 | } | ||
187 | |||
163 | static void activate_ch(struct sh_mobile_i2c_data *pd) | 188 | static void activate_ch(struct sh_mobile_i2c_data *pd) |
164 | { | 189 | { |
165 | unsigned long i2c_clk; | 190 | unsigned long i2c_clk; |
@@ -187,6 +212,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd) | |||
187 | else | 212 | else |
188 | pd->iccl = (u_int8_t)(num/denom); | 213 | pd->iccl = (u_int8_t)(num/denom); |
189 | 214 | ||
215 | /* one more bit of ICCL in ICIC */ | ||
216 | if (pd->flags & IIC_FLAG_HAS_ICIC67) { | ||
217 | if ((num/denom) > 0xff) | ||
218 | pd->icic |= ICIC_ICCLB8; | ||
219 | else | ||
220 | pd->icic &= ~ICIC_ICCLB8; | ||
221 | } | ||
222 | |||
190 | /* Calculate the value for icch. From the data sheet: | 223 | /* Calculate the value for icch. From the data sheet: |
191 | icch = (p clock / transfer rate) * (H / (L + H)) */ | 224 | icch = (p clock / transfer rate) * (H / (L + H)) */ |
192 | num = i2c_clk * 4; | 225 | num = i2c_clk * 4; |
@@ -196,25 +229,33 @@ static void activate_ch(struct sh_mobile_i2c_data *pd) | |||
196 | else | 229 | else |
197 | pd->icch = (u_int8_t)(num/denom); | 230 | pd->icch = (u_int8_t)(num/denom); |
198 | 231 | ||
232 | /* one more bit of ICCH in ICIC */ | ||
233 | if (pd->flags & IIC_FLAG_HAS_ICIC67) { | ||
234 | if ((num/denom) > 0xff) | ||
235 | pd->icic |= ICIC_ICCHB8; | ||
236 | else | ||
237 | pd->icic &= ~ICIC_ICCHB8; | ||
238 | } | ||
239 | |||
199 | /* Enable channel and configure rx ack */ | 240 | /* Enable channel and configure rx ack */ |
200 | iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); | 241 | iic_set_clr(pd, ICCR, ICCR_ICE, 0); |
201 | 242 | ||
202 | /* Mask all interrupts */ | 243 | /* Mask all interrupts */ |
203 | iowrite8(0, ICIC(pd)); | 244 | iic_wr(pd, ICIC, 0); |
204 | 245 | ||
205 | /* Set the clock */ | 246 | /* Set the clock */ |
206 | iowrite8(pd->iccl, ICCL(pd)); | 247 | iic_wr(pd, ICCL, pd->iccl); |
207 | iowrite8(pd->icch, ICCH(pd)); | 248 | iic_wr(pd, ICCH, pd->icch); |
208 | } | 249 | } |
209 | 250 | ||
210 | static void deactivate_ch(struct sh_mobile_i2c_data *pd) | 251 | static void deactivate_ch(struct sh_mobile_i2c_data *pd) |
211 | { | 252 | { |
212 | /* Clear/disable interrupts */ | 253 | /* Clear/disable interrupts */ |
213 | iowrite8(0, ICSR(pd)); | 254 | iic_wr(pd, ICSR, 0); |
214 | iowrite8(0, ICIC(pd)); | 255 | iic_wr(pd, ICIC, 0); |
215 | 256 | ||
216 | /* Disable channel */ | 257 | /* Disable channel */ |
217 | iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); | 258 | iic_set_clr(pd, ICCR, 0, ICCR_ICE); |
218 | 259 | ||
219 | /* Disable clock and mark device as idle */ | 260 | /* Disable clock and mark device as idle */ |
220 | clk_disable(pd->clk); | 261 | clk_disable(pd->clk); |
@@ -233,35 +274,35 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd, | |||
233 | 274 | ||
234 | switch (op) { | 275 | switch (op) { |
235 | case OP_START: /* issue start and trigger DTE interrupt */ | 276 | case OP_START: /* issue start and trigger DTE interrupt */ |
236 | iowrite8(0x94, ICCR(pd)); | 277 | iic_wr(pd, ICCR, 0x94); |
237 | break; | 278 | break; |
238 | case OP_TX_FIRST: /* disable DTE interrupt and write data */ | 279 | case OP_TX_FIRST: /* disable DTE interrupt and write data */ |
239 | iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE, ICIC(pd)); | 280 | iic_wr(pd, ICIC, ICIC_WAITE | ICIC_ALE | ICIC_TACKE); |
240 | iowrite8(data, ICDR(pd)); | 281 | iic_wr(pd, ICDR, data); |
241 | break; | 282 | break; |
242 | case OP_TX: /* write data */ | 283 | case OP_TX: /* write data */ |
243 | iowrite8(data, ICDR(pd)); | 284 | iic_wr(pd, ICDR, data); |
244 | break; | 285 | break; |
245 | case OP_TX_STOP: /* write data and issue a stop afterwards */ | 286 | case OP_TX_STOP: /* write data and issue a stop afterwards */ |
246 | iowrite8(data, ICDR(pd)); | 287 | iic_wr(pd, ICDR, data); |
247 | iowrite8(0x90, ICCR(pd)); | 288 | iic_wr(pd, ICCR, 0x90); |
248 | break; | 289 | break; |
249 | case OP_TX_TO_RX: /* select read mode */ | 290 | case OP_TX_TO_RX: /* select read mode */ |
250 | iowrite8(0x81, ICCR(pd)); | 291 | iic_wr(pd, ICCR, 0x81); |
251 | break; | 292 | break; |
252 | case OP_RX: /* just read data */ | 293 | case OP_RX: /* just read data */ |
253 | ret = ioread8(ICDR(pd)); | 294 | ret = iic_rd(pd, ICDR); |
254 | break; | 295 | break; |
255 | case OP_RX_STOP: /* enable DTE interrupt, issue stop */ | 296 | case OP_RX_STOP: /* enable DTE interrupt, issue stop */ |
256 | iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE, | 297 | iic_wr(pd, ICIC, |
257 | ICIC(pd)); | 298 | ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); |
258 | iowrite8(0xc0, ICCR(pd)); | 299 | iic_wr(pd, ICCR, 0xc0); |
259 | break; | 300 | break; |
260 | case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */ | 301 | case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */ |
261 | iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE, | 302 | iic_wr(pd, ICIC, |
262 | ICIC(pd)); | 303 | ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); |
263 | ret = ioread8(ICDR(pd)); | 304 | ret = iic_rd(pd, ICDR); |
264 | iowrite8(0xc0, ICCR(pd)); | 305 | iic_wr(pd, ICCR, 0xc0); |
265 | break; | 306 | break; |
266 | } | 307 | } |
267 | 308 | ||
@@ -367,7 +408,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id) | |||
367 | unsigned char sr; | 408 | unsigned char sr; |
368 | int wakeup; | 409 | int wakeup; |
369 | 410 | ||
370 | sr = ioread8(ICSR(pd)); | 411 | sr = iic_rd(pd, ICSR); |
371 | pd->sr |= sr; /* remember state */ | 412 | pd->sr |= sr; /* remember state */ |
372 | 413 | ||
373 | dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr, | 414 | dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr, |
@@ -376,7 +417,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id) | |||
376 | 417 | ||
377 | if (sr & (ICSR_AL | ICSR_TACK)) { | 418 | if (sr & (ICSR_AL | ICSR_TACK)) { |
378 | /* don't interrupt transaction - continue to issue stop */ | 419 | /* don't interrupt transaction - continue to issue stop */ |
379 | iowrite8(sr & ~(ICSR_AL | ICSR_TACK), ICSR(pd)); | 420 | iic_wr(pd, ICSR, sr & ~(ICSR_AL | ICSR_TACK)); |
380 | wakeup = 0; | 421 | wakeup = 0; |
381 | } else if (pd->msg->flags & I2C_M_RD) | 422 | } else if (pd->msg->flags & I2C_M_RD) |
382 | wakeup = sh_mobile_i2c_isr_rx(pd); | 423 | wakeup = sh_mobile_i2c_isr_rx(pd); |
@@ -384,7 +425,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id) | |||
384 | wakeup = sh_mobile_i2c_isr_tx(pd); | 425 | wakeup = sh_mobile_i2c_isr_tx(pd); |
385 | 426 | ||
386 | if (sr & ICSR_WAIT) /* TODO: add delay here to support slow acks */ | 427 | if (sr & ICSR_WAIT) /* TODO: add delay here to support slow acks */ |
387 | iowrite8(sr & ~ICSR_WAIT, ICSR(pd)); | 428 | iic_wr(pd, ICSR, sr & ~ICSR_WAIT); |
388 | 429 | ||
389 | if (wakeup) { | 430 | if (wakeup) { |
390 | pd->sr |= SW_DONE; | 431 | pd->sr |= SW_DONE; |
@@ -402,21 +443,21 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg) | |||
402 | } | 443 | } |
403 | 444 | ||
404 | /* Initialize channel registers */ | 445 | /* Initialize channel registers */ |
405 | iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); | 446 | iic_set_clr(pd, ICCR, 0, ICCR_ICE); |
406 | 447 | ||
407 | /* Enable channel and configure rx ack */ | 448 | /* Enable channel and configure rx ack */ |
408 | iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); | 449 | iic_set_clr(pd, ICCR, ICCR_ICE, 0); |
409 | 450 | ||
410 | /* Set the clock */ | 451 | /* Set the clock */ |
411 | iowrite8(pd->iccl, ICCL(pd)); | 452 | iic_wr(pd, ICCL, pd->iccl); |
412 | iowrite8(pd->icch, ICCH(pd)); | 453 | iic_wr(pd, ICCH, pd->icch); |
413 | 454 | ||
414 | pd->msg = usr_msg; | 455 | pd->msg = usr_msg; |
415 | pd->pos = -1; | 456 | pd->pos = -1; |
416 | pd->sr = 0; | 457 | pd->sr = 0; |
417 | 458 | ||
418 | /* Enable all interrupts to begin with */ | 459 | /* Enable all interrupts to begin with */ |
419 | iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE | ICIC_DTEE, ICIC(pd)); | 460 | iic_wr(pd, ICIC, ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); |
420 | return 0; | 461 | return 0; |
421 | } | 462 | } |
422 | 463 | ||
@@ -451,7 +492,7 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, | |||
451 | 492 | ||
452 | retry_count = 1000; | 493 | retry_count = 1000; |
453 | again: | 494 | again: |
454 | val = ioread8(ICSR(pd)); | 495 | val = iic_rd(pd, ICSR); |
455 | 496 | ||
456 | dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr); | 497 | dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr); |
457 | 498 | ||
@@ -576,6 +617,12 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) | |||
576 | goto err_irq; | 617 | goto err_irq; |
577 | } | 618 | } |
578 | 619 | ||
620 | /* The IIC blocks on SH-Mobile ARM processors | ||
621 | * come with two new bits in ICIC. | ||
622 | */ | ||
623 | if (size > 0x17) | ||
624 | pd->flags |= IIC_FLAG_HAS_ICIC67; | ||
625 | |||
579 | /* Enable Runtime PM for this device. | 626 | /* Enable Runtime PM for this device. |
580 | * | 627 | * |
581 | * Also tell the Runtime PM core to ignore children | 628 | * Also tell the Runtime PM core to ignore children |
diff --git a/drivers/net/irda/sh_irda.c b/drivers/net/irda/sh_irda.c index edd5666f0ffb..9e3f4f54281d 100644 --- a/drivers/net/irda/sh_irda.c +++ b/drivers/net/irda/sh_irda.c | |||
@@ -748,7 +748,6 @@ static int __devinit sh_irda_probe(struct platform_device *pdev) | |||
748 | struct net_device *ndev; | 748 | struct net_device *ndev; |
749 | struct sh_irda_self *self; | 749 | struct sh_irda_self *self; |
750 | struct resource *res; | 750 | struct resource *res; |
751 | char clk_name[8]; | ||
752 | int irq; | 751 | int irq; |
753 | int err = -ENOMEM; | 752 | int err = -ENOMEM; |
754 | 753 | ||
@@ -775,10 +774,9 @@ static int __devinit sh_irda_probe(struct platform_device *pdev) | |||
775 | if (err) | 774 | if (err) |
776 | goto err_mem_2; | 775 | goto err_mem_2; |
777 | 776 | ||
778 | snprintf(clk_name, sizeof(clk_name), "irda%d", pdev->id); | 777 | self->clk = clk_get(&pdev->dev, NULL); |
779 | self->clk = clk_get(&pdev->dev, clk_name); | ||
780 | if (IS_ERR(self->clk)) { | 778 | if (IS_ERR(self->clk)) { |
781 | dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); | 779 | dev_err(&pdev->dev, "cannot get irda clock\n"); |
782 | goto err_mem_3; | 780 | goto err_mem_3; |
783 | } | 781 | } |
784 | 782 | ||
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 5f90fcd7d107..c291b3add1d2 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -346,6 +346,27 @@ static int scif_rxfill(struct uart_port *port) | |||
346 | return sci_in(port, SCFDR) & SCIF2_RFDC_MASK; | 346 | return sci_in(port, SCFDR) & SCIF2_RFDC_MASK; |
347 | } | 347 | } |
348 | } | 348 | } |
349 | #elif defined(CONFIG_ARCH_SH7372) | ||
350 | static int scif_txfill(struct uart_port *port) | ||
351 | { | ||
352 | if (port->type == PORT_SCIFA) | ||
353 | return sci_in(port, SCFDR) >> 8; | ||
354 | else | ||
355 | return sci_in(port, SCTFDR); | ||
356 | } | ||
357 | |||
358 | static int scif_txroom(struct uart_port *port) | ||
359 | { | ||
360 | return port->fifosize - scif_txfill(port); | ||
361 | } | ||
362 | |||
363 | static int scif_rxfill(struct uart_port *port) | ||
364 | { | ||
365 | if (port->type == PORT_SCIFA) | ||
366 | return sci_in(port, SCFDR) & SCIF_RFDC_MASK; | ||
367 | else | ||
368 | return sci_in(port, SCRFDR); | ||
369 | } | ||
349 | #else | 370 | #else |
350 | static int scif_txfill(struct uart_port *port) | 371 | static int scif_txfill(struct uart_port *port) |
351 | { | 372 | { |
@@ -683,7 +704,7 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr) | |||
683 | u16 ssr = sci_in(port, SCxSR); | 704 | u16 ssr = sci_in(port, SCxSR); |
684 | 705 | ||
685 | /* Disable future Rx interrupts */ | 706 | /* Disable future Rx interrupts */ |
686 | if (port->type == PORT_SCIFA) { | 707 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
687 | disable_irq_nosync(irq); | 708 | disable_irq_nosync(irq); |
688 | scr |= 0x4000; | 709 | scr |= 0x4000; |
689 | } else { | 710 | } else { |
@@ -928,7 +949,7 @@ static void sci_dma_tx_complete(void *arg) | |||
928 | 949 | ||
929 | if (!uart_circ_empty(xmit)) { | 950 | if (!uart_circ_empty(xmit)) { |
930 | schedule_work(&s->work_tx); | 951 | schedule_work(&s->work_tx); |
931 | } else if (port->type == PORT_SCIFA) { | 952 | } else if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
932 | u16 ctrl = sci_in(port, SCSCR); | 953 | u16 ctrl = sci_in(port, SCSCR); |
933 | sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE); | 954 | sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE); |
934 | } | 955 | } |
@@ -1184,7 +1205,7 @@ static void sci_start_tx(struct uart_port *port) | |||
1184 | unsigned short ctrl; | 1205 | unsigned short ctrl; |
1185 | 1206 | ||
1186 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 1207 | #ifdef CONFIG_SERIAL_SH_SCI_DMA |
1187 | if (port->type == PORT_SCIFA) { | 1208 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
1188 | u16 new, scr = sci_in(port, SCSCR); | 1209 | u16 new, scr = sci_in(port, SCSCR); |
1189 | if (s->chan_tx) | 1210 | if (s->chan_tx) |
1190 | new = scr | 0x8000; | 1211 | new = scr | 0x8000; |
@@ -1197,7 +1218,7 @@ static void sci_start_tx(struct uart_port *port) | |||
1197 | s->cookie_tx < 0) | 1218 | s->cookie_tx < 0) |
1198 | schedule_work(&s->work_tx); | 1219 | schedule_work(&s->work_tx); |
1199 | #endif | 1220 | #endif |
1200 | if (!s->chan_tx || port->type == PORT_SCIFA) { | 1221 | if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
1201 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ | 1222 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ |
1202 | ctrl = sci_in(port, SCSCR); | 1223 | ctrl = sci_in(port, SCSCR); |
1203 | sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE); | 1224 | sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE); |
@@ -1210,7 +1231,7 @@ static void sci_stop_tx(struct uart_port *port) | |||
1210 | 1231 | ||
1211 | /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ | 1232 | /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ |
1212 | ctrl = sci_in(port, SCSCR); | 1233 | ctrl = sci_in(port, SCSCR); |
1213 | if (port->type == PORT_SCIFA) | 1234 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) |
1214 | ctrl &= ~0x8000; | 1235 | ctrl &= ~0x8000; |
1215 | ctrl &= ~SCI_CTRL_FLAGS_TIE; | 1236 | ctrl &= ~SCI_CTRL_FLAGS_TIE; |
1216 | sci_out(port, SCSCR, ctrl); | 1237 | sci_out(port, SCSCR, ctrl); |
@@ -1222,7 +1243,7 @@ static void sci_start_rx(struct uart_port *port) | |||
1222 | 1243 | ||
1223 | /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ | 1244 | /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ |
1224 | ctrl |= sci_in(port, SCSCR); | 1245 | ctrl |= sci_in(port, SCSCR); |
1225 | if (port->type == PORT_SCIFA) | 1246 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) |
1226 | ctrl &= ~0x4000; | 1247 | ctrl &= ~0x4000; |
1227 | sci_out(port, SCSCR, ctrl); | 1248 | sci_out(port, SCSCR, ctrl); |
1228 | } | 1249 | } |
@@ -1233,7 +1254,7 @@ static void sci_stop_rx(struct uart_port *port) | |||
1233 | 1254 | ||
1234 | /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ | 1255 | /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ |
1235 | ctrl = sci_in(port, SCSCR); | 1256 | ctrl = sci_in(port, SCSCR); |
1236 | if (port->type == PORT_SCIFA) | 1257 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) |
1237 | ctrl &= ~0x4000; | 1258 | ctrl &= ~0x4000; |
1238 | ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE); | 1259 | ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE); |
1239 | sci_out(port, SCSCR, ctrl); | 1260 | sci_out(port, SCSCR, ctrl); |
@@ -1271,7 +1292,7 @@ static void rx_timer_fn(unsigned long arg) | |||
1271 | struct uart_port *port = &s->port; | 1292 | struct uart_port *port = &s->port; |
1272 | u16 scr = sci_in(port, SCSCR); | 1293 | u16 scr = sci_in(port, SCSCR); |
1273 | 1294 | ||
1274 | if (port->type == PORT_SCIFA) { | 1295 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
1275 | scr &= ~0x4000; | 1296 | scr &= ~0x4000; |
1276 | enable_irq(s->irqs[1]); | 1297 | enable_irq(s->irqs[1]); |
1277 | } | 1298 | } |
@@ -1524,6 +1545,8 @@ static const char *sci_type(struct uart_port *port) | |||
1524 | return "scif"; | 1545 | return "scif"; |
1525 | case PORT_SCIFA: | 1546 | case PORT_SCIFA: |
1526 | return "scifa"; | 1547 | return "scifa"; |
1548 | case PORT_SCIFB: | ||
1549 | return "scifb"; | ||
1527 | } | 1550 | } |
1528 | 1551 | ||
1529 | return NULL; | 1552 | return NULL; |
@@ -1612,6 +1635,9 @@ static int __devinit sci_init_single(struct platform_device *dev, | |||
1612 | port->line = index; | 1635 | port->line = index; |
1613 | 1636 | ||
1614 | switch (p->type) { | 1637 | switch (p->type) { |
1638 | case PORT_SCIFB: | ||
1639 | port->fifosize = 256; | ||
1640 | break; | ||
1615 | case PORT_SCIFA: | 1641 | case PORT_SCIFA: |
1616 | port->fifosize = 64; | 1642 | port->fifosize = 64; |
1617 | break; | 1643 | break; |
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index f70c49f915fa..9b52f77a9305 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h | |||
@@ -322,7 +322,7 @@ | |||
322 | #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ | 322 | #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ |
323 | static inline unsigned int sci_##name##_in(struct uart_port *port) \ | 323 | static inline unsigned int sci_##name##_in(struct uart_port *port) \ |
324 | { \ | 324 | { \ |
325 | if (port->type == PORT_SCIF) { \ | 325 | if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \ |
326 | SCI_IN(scif_size, scif_offset) \ | 326 | SCI_IN(scif_size, scif_offset) \ |
327 | } else { /* PORT_SCI or PORT_SCIFA */ \ | 327 | } else { /* PORT_SCI or PORT_SCIFA */ \ |
328 | SCI_IN(sci_size, sci_offset); \ | 328 | SCI_IN(sci_size, sci_offset); \ |
@@ -330,7 +330,7 @@ | |||
330 | } \ | 330 | } \ |
331 | static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \ | 331 | static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \ |
332 | { \ | 332 | { \ |
333 | if (port->type == PORT_SCIF) { \ | 333 | if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \ |
334 | SCI_OUT(scif_size, scif_offset, value) \ | 334 | SCI_OUT(scif_size, scif_offset, value) \ |
335 | } else { /* PORT_SCI or PORT_SCIFA */ \ | 335 | } else { /* PORT_SCI or PORT_SCIFA */ \ |
336 | SCI_OUT(sci_size, sci_offset, value); \ | 336 | SCI_OUT(sci_size, sci_offset, value); \ |
@@ -384,8 +384,12 @@ | |||
384 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 384 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
385 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | 385 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
386 | defined(CONFIG_ARCH_SH7367) || \ | 386 | defined(CONFIG_ARCH_SH7367) || \ |
387 | defined(CONFIG_ARCH_SH7377) || \ | 387 | defined(CONFIG_ARCH_SH7377) |
388 | defined(CONFIG_ARCH_SH7372) | 388 | #define SCIF_FNS(name, scif_offset, scif_size) \ |
389 | CPU_SCIF_FNS(name, scif_offset, scif_size) | ||
390 | #elif defined(CONFIG_ARCH_SH7372) | ||
391 | #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) \ | ||
392 | CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) | ||
389 | #define SCIF_FNS(name, scif_offset, scif_size) \ | 393 | #define SCIF_FNS(name, scif_offset, scif_size) \ |
390 | CPU_SCIF_FNS(name, scif_offset, scif_size) | 394 | CPU_SCIF_FNS(name, scif_offset, scif_size) |
391 | #else | 395 | #else |
@@ -422,8 +426,7 @@ | |||
422 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 426 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
423 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | 427 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
424 | defined(CONFIG_ARCH_SH7367) || \ | 428 | defined(CONFIG_ARCH_SH7367) || \ |
425 | defined(CONFIG_ARCH_SH7377) || \ | 429 | defined(CONFIG_ARCH_SH7377) |
426 | defined(CONFIG_ARCH_SH7372) | ||
427 | 430 | ||
428 | SCIF_FNS(SCSMR, 0x00, 16) | 431 | SCIF_FNS(SCSMR, 0x00, 16) |
429 | SCIF_FNS(SCBRR, 0x04, 8) | 432 | SCIF_FNS(SCBRR, 0x04, 8) |
@@ -436,6 +439,20 @@ SCIF_FNS(SCFDR, 0x1c, 16) | |||
436 | SCIF_FNS(SCxTDR, 0x20, 8) | 439 | SCIF_FNS(SCxTDR, 0x20, 8) |
437 | SCIF_FNS(SCxRDR, 0x24, 8) | 440 | SCIF_FNS(SCxRDR, 0x24, 8) |
438 | SCIF_FNS(SCLSR, 0x00, 0) | 441 | SCIF_FNS(SCLSR, 0x00, 0) |
442 | #elif defined(CONFIG_ARCH_SH7372) | ||
443 | SCIF_FNS(SCSMR, 0x00, 16) | ||
444 | SCIF_FNS(SCBRR, 0x04, 8) | ||
445 | SCIF_FNS(SCSCR, 0x08, 16) | ||
446 | SCIF_FNS(SCTDSR, 0x0c, 16) | ||
447 | SCIF_FNS(SCFER, 0x10, 16) | ||
448 | SCIF_FNS(SCxSR, 0x14, 16) | ||
449 | SCIF_FNS(SCFCR, 0x18, 16) | ||
450 | SCIF_FNS(SCFDR, 0x1c, 16) | ||
451 | SCIF_FNS(SCTFDR, 0x38, 16) | ||
452 | SCIF_FNS(SCRFDR, 0x3c, 16) | ||
453 | SCIx_FNS(SCxTDR, 0x20, 8, 0x40, 8) | ||
454 | SCIx_FNS(SCxRDR, 0x24, 8, 0x60, 8) | ||
455 | SCIF_FNS(SCLSR, 0x00, 0) | ||
439 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ | 456 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ |
440 | defined(CONFIG_CPU_SUBTYPE_SH7724) | 457 | defined(CONFIG_CPU_SUBTYPE_SH7724) |
441 | SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) | 458 | SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) |
diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile index 78bb5127abd0..08fc653a825c 100644 --- a/drivers/sh/Makefile +++ b/drivers/sh/Makefile | |||
@@ -1,9 +1,10 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the SuperH specific drivers. | 2 | # Makefile for the SuperH specific drivers. |
3 | # | 3 | # |
4 | obj-y := clk.o intc.o | ||
5 | |||
4 | obj-$(CONFIG_SUPERHYWAY) += superhyway/ | 6 | obj-$(CONFIG_SUPERHYWAY) += superhyway/ |
5 | obj-$(CONFIG_MAPLE) += maple/ | 7 | obj-$(CONFIG_MAPLE) += maple/ |
8 | |||
6 | obj-$(CONFIG_GENERIC_GPIO) += pfc.o | 9 | obj-$(CONFIG_GENERIC_GPIO) += pfc.o |
7 | obj-$(CONFIG_SUPERH) += clk.o | ||
8 | obj-$(CONFIG_SH_CLK_CPG) += clk-cpg.o | 10 | obj-$(CONFIG_SH_CLK_CPG) += clk-cpg.o |
9 | obj-y += intc.o | ||
diff --git a/drivers/sh/clk-cpg.c b/drivers/sh/clk-cpg.c index f5c80ba9ab1c..8c024b984ed8 100644 --- a/drivers/sh/clk-cpg.c +++ b/drivers/sh/clk-cpg.c | |||
@@ -68,6 +68,39 @@ static unsigned long sh_clk_div6_recalc(struct clk *clk) | |||
68 | return clk->freq_table[idx].frequency; | 68 | return clk->freq_table[idx].frequency; |
69 | } | 69 | } |
70 | 70 | ||
71 | static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) | ||
72 | { | ||
73 | struct clk_div_mult_table *table = &sh_clk_div6_table; | ||
74 | u32 value; | ||
75 | int ret, i; | ||
76 | |||
77 | if (!clk->parent_table || !clk->parent_num) | ||
78 | return -EINVAL; | ||
79 | |||
80 | /* Search the parent */ | ||
81 | for (i = 0; i < clk->parent_num; i++) | ||
82 | if (clk->parent_table[i] == parent) | ||
83 | break; | ||
84 | |||
85 | if (i == clk->parent_num) | ||
86 | return -ENODEV; | ||
87 | |||
88 | ret = clk_reparent(clk, parent); | ||
89 | if (ret < 0) | ||
90 | return ret; | ||
91 | |||
92 | value = __raw_readl(clk->enable_reg) & | ||
93 | ~(((1 << clk->src_width) - 1) << clk->src_shift); | ||
94 | |||
95 | __raw_writel(value | (i << clk->src_shift), clk->enable_reg); | ||
96 | |||
97 | /* Rebuild the frequency table */ | ||
98 | clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, | ||
99 | table, &clk->arch_flags); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
71 | static int sh_clk_div6_set_rate(struct clk *clk, | 104 | static int sh_clk_div6_set_rate(struct clk *clk, |
72 | unsigned long rate, int algo_id) | 105 | unsigned long rate, int algo_id) |
73 | { | 106 | { |
@@ -117,7 +150,17 @@ static struct clk_ops sh_clk_div6_clk_ops = { | |||
117 | .disable = sh_clk_div6_disable, | 150 | .disable = sh_clk_div6_disable, |
118 | }; | 151 | }; |
119 | 152 | ||
120 | int __init sh_clk_div6_register(struct clk *clks, int nr) | 153 | static struct clk_ops sh_clk_div6_reparent_clk_ops = { |
154 | .recalc = sh_clk_div6_recalc, | ||
155 | .round_rate = sh_clk_div_round_rate, | ||
156 | .set_rate = sh_clk_div6_set_rate, | ||
157 | .enable = sh_clk_div6_enable, | ||
158 | .disable = sh_clk_div6_disable, | ||
159 | .set_parent = sh_clk_div6_set_parent, | ||
160 | }; | ||
161 | |||
162 | static int __init sh_clk_div6_register_ops(struct clk *clks, int nr, | ||
163 | struct clk_ops *ops) | ||
121 | { | 164 | { |
122 | struct clk *clkp; | 165 | struct clk *clkp; |
123 | void *freq_table; | 166 | void *freq_table; |
@@ -136,7 +179,7 @@ int __init sh_clk_div6_register(struct clk *clks, int nr) | |||
136 | for (k = 0; !ret && (k < nr); k++) { | 179 | for (k = 0; !ret && (k < nr); k++) { |
137 | clkp = clks + k; | 180 | clkp = clks + k; |
138 | 181 | ||
139 | clkp->ops = &sh_clk_div6_clk_ops; | 182 | clkp->ops = ops; |
140 | clkp->id = -1; | 183 | clkp->id = -1; |
141 | clkp->freq_table = freq_table + (k * freq_table_size); | 184 | clkp->freq_table = freq_table + (k * freq_table_size); |
142 | clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; | 185 | clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; |
@@ -147,6 +190,17 @@ int __init sh_clk_div6_register(struct clk *clks, int nr) | |||
147 | return ret; | 190 | return ret; |
148 | } | 191 | } |
149 | 192 | ||
193 | int __init sh_clk_div6_register(struct clk *clks, int nr) | ||
194 | { | ||
195 | return sh_clk_div6_register_ops(clks, nr, &sh_clk_div6_clk_ops); | ||
196 | } | ||
197 | |||
198 | int __init sh_clk_div6_reparent_register(struct clk *clks, int nr) | ||
199 | { | ||
200 | return sh_clk_div6_register_ops(clks, nr, | ||
201 | &sh_clk_div6_reparent_clk_ops); | ||
202 | } | ||
203 | |||
150 | static unsigned long sh_clk_div4_recalc(struct clk *clk) | 204 | static unsigned long sh_clk_div4_recalc(struct clk *clk) |
151 | { | 205 | { |
152 | struct clk_div4_table *d4t = clk->priv; | 206 | struct clk_div4_table *d4t = clk->priv; |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 7b11ea68c80e..bbeee4ba2488 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -1896,6 +1896,13 @@ config FB_W100 | |||
1896 | 1896 | ||
1897 | If unsure, say N. | 1897 | If unsure, say N. |
1898 | 1898 | ||
1899 | config SH_MIPI_DSI | ||
1900 | tristate | ||
1901 | depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK | ||
1902 | |||
1903 | config SH_LCD_MIPI_DSI | ||
1904 | bool | ||
1905 | |||
1899 | config FB_SH_MOBILE_LCDC | 1906 | config FB_SH_MOBILE_LCDC |
1900 | tristate "SuperH Mobile LCDC framebuffer support" | 1907 | tristate "SuperH Mobile LCDC framebuffer support" |
1901 | depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK | 1908 | depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK |
@@ -1904,9 +1911,17 @@ config FB_SH_MOBILE_LCDC | |||
1904 | select FB_SYS_IMAGEBLIT | 1911 | select FB_SYS_IMAGEBLIT |
1905 | select FB_SYS_FOPS | 1912 | select FB_SYS_FOPS |
1906 | select FB_DEFERRED_IO | 1913 | select FB_DEFERRED_IO |
1914 | select SH_MIPI_DSI if SH_LCD_MIPI_DSI | ||
1907 | ---help--- | 1915 | ---help--- |
1908 | Frame buffer driver for the on-chip SH-Mobile LCD controller. | 1916 | Frame buffer driver for the on-chip SH-Mobile LCD controller. |
1909 | 1917 | ||
1918 | config FB_SH_MOBILE_HDMI | ||
1919 | tristate "SuperH Mobile HDMI controller support" | ||
1920 | depends on FB_SH_MOBILE_LCDC | ||
1921 | select FB_MODE_HELPERS | ||
1922 | ---help--- | ||
1923 | Driver for the on-chip SH-Mobile HDMI controller. | ||
1924 | |||
1910 | config FB_TMIO | 1925 | config FB_TMIO |
1911 | tristate "Toshiba Mobile IO FrameBuffer support" | 1926 | tristate "Toshiba Mobile IO FrameBuffer support" |
1912 | depends on FB && MFD_CORE | 1927 | depends on FB && MFD_CORE |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index f56a9cae2157..485e8ed1318c 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -123,6 +123,8 @@ obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o | |||
123 | obj-$(CONFIG_FB_PS3) += ps3fb.o | 123 | obj-$(CONFIG_FB_PS3) += ps3fb.o |
124 | obj-$(CONFIG_FB_SM501) += sm501fb.o | 124 | obj-$(CONFIG_FB_SM501) += sm501fb.o |
125 | obj-$(CONFIG_FB_XILINX) += xilinxfb.o | 125 | obj-$(CONFIG_FB_XILINX) += xilinxfb.o |
126 | obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o | ||
127 | obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o | ||
126 | obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o | 128 | obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o |
127 | obj-$(CONFIG_FB_OMAP) += omap/ | 129 | obj-$(CONFIG_FB_OMAP) += omap/ |
128 | obj-y += omap2/ | 130 | obj-y += omap2/ |
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c new file mode 100644 index 000000000000..5699ce0c1780 --- /dev/null +++ b/drivers/video/sh_mipi_dsi.c | |||
@@ -0,0 +1,505 @@ | |||
1 | /* | ||
2 | * Renesas SH-mobile MIPI DSI support | ||
3 | * | ||
4 | * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
5 | * | ||
6 | * This is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of version 2 of the GNU General Public License as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk.h> | ||
12 | #include <linux/delay.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/string.h> | ||
18 | #include <linux/types.h> | ||
19 | |||
20 | #include <video/mipi_display.h> | ||
21 | #include <video/sh_mipi_dsi.h> | ||
22 | #include <video/sh_mobile_lcdc.h> | ||
23 | |||
24 | #define CMTSRTCTR 0x80d0 | ||
25 | #define CMTSRTREQ 0x8070 | ||
26 | |||
27 | #define DSIINTE 0x0060 | ||
28 | |||
29 | /* E.g., sh7372 has 2 MIPI-DSIs - one for each LCDC */ | ||
30 | #define MAX_SH_MIPI_DSI 2 | ||
31 | |||
32 | struct sh_mipi { | ||
33 | void __iomem *base; | ||
34 | struct clk *dsit_clk; | ||
35 | struct clk *dsip_clk; | ||
36 | }; | ||
37 | |||
38 | static struct sh_mipi *mipi_dsi[MAX_SH_MIPI_DSI]; | ||
39 | |||
40 | /* Protect the above array */ | ||
41 | static DEFINE_MUTEX(array_lock); | ||
42 | |||
43 | static struct sh_mipi *sh_mipi_by_handle(int handle) | ||
44 | { | ||
45 | if (handle >= ARRAY_SIZE(mipi_dsi) || handle < 0) | ||
46 | return NULL; | ||
47 | |||
48 | return mipi_dsi[handle]; | ||
49 | } | ||
50 | |||
51 | static int sh_mipi_send_short(struct sh_mipi *mipi, u8 dsi_cmd, | ||
52 | u8 cmd, u8 param) | ||
53 | { | ||
54 | u32 data = (dsi_cmd << 24) | (cmd << 16) | (param << 8); | ||
55 | int cnt = 100; | ||
56 | |||
57 | /* transmit a short packet to LCD panel */ | ||
58 | iowrite32(1 | data, mipi->base + 0x80d0); /* CMTSRTCTR */ | ||
59 | iowrite32(1, mipi->base + 0x8070); /* CMTSRTREQ */ | ||
60 | |||
61 | while ((ioread32(mipi->base + 0x8070) & 1) && --cnt) | ||
62 | udelay(1); | ||
63 | |||
64 | return cnt ? 0 : -ETIMEDOUT; | ||
65 | } | ||
66 | |||
67 | #define LCD_CHAN2MIPI(c) ((c) < LCDC_CHAN_MAINLCD || (c) > LCDC_CHAN_SUBLCD ? \ | ||
68 | -EINVAL : (c) - 1) | ||
69 | |||
70 | static int sh_mipi_dcs(int handle, u8 cmd) | ||
71 | { | ||
72 | struct sh_mipi *mipi = sh_mipi_by_handle(LCD_CHAN2MIPI(handle)); | ||
73 | if (!mipi) | ||
74 | return -ENODEV; | ||
75 | return sh_mipi_send_short(mipi, MIPI_DSI_DCS_SHORT_WRITE, cmd, 0); | ||
76 | } | ||
77 | |||
78 | static int sh_mipi_dcs_param(int handle, u8 cmd, u8 param) | ||
79 | { | ||
80 | struct sh_mipi *mipi = sh_mipi_by_handle(LCD_CHAN2MIPI(handle)); | ||
81 | if (!mipi) | ||
82 | return -ENODEV; | ||
83 | return sh_mipi_send_short(mipi, MIPI_DSI_DCS_SHORT_WRITE_PARAM, cmd, | ||
84 | param); | ||
85 | } | ||
86 | |||
87 | static void sh_mipi_dsi_enable(struct sh_mipi *mipi, bool enable) | ||
88 | { | ||
89 | /* | ||
90 | * enable LCDC data tx, transition to LPS after completion of each HS | ||
91 | * packet | ||
92 | */ | ||
93 | iowrite32(0x00000002 | enable, mipi->base + 0x8000); /* DTCTR */ | ||
94 | } | ||
95 | |||
96 | static void sh_mipi_shutdown(struct platform_device *pdev) | ||
97 | { | ||
98 | struct sh_mipi *mipi = platform_get_drvdata(pdev); | ||
99 | |||
100 | sh_mipi_dsi_enable(mipi, false); | ||
101 | } | ||
102 | |||
103 | static void mipi_display_on(void *arg, struct fb_info *info) | ||
104 | { | ||
105 | struct sh_mipi *mipi = arg; | ||
106 | |||
107 | sh_mipi_dsi_enable(mipi, true); | ||
108 | } | ||
109 | |||
110 | static void mipi_display_off(void *arg) | ||
111 | { | ||
112 | struct sh_mipi *mipi = arg; | ||
113 | |||
114 | sh_mipi_dsi_enable(mipi, false); | ||
115 | } | ||
116 | |||
117 | static int __init sh_mipi_setup(struct sh_mipi *mipi, | ||
118 | struct sh_mipi_dsi_info *pdata) | ||
119 | { | ||
120 | void __iomem *base = mipi->base; | ||
121 | struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan; | ||
122 | u32 pctype, datatype, pixfmt; | ||
123 | u32 linelength; | ||
124 | bool yuv; | ||
125 | |||
126 | /* Select data format */ | ||
127 | switch (pdata->data_format) { | ||
128 | case MIPI_RGB888: | ||
129 | pctype = 0; | ||
130 | datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; | ||
131 | pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; | ||
132 | linelength = ch->lcd_cfg.xres * 3; | ||
133 | yuv = false; | ||
134 | break; | ||
135 | case MIPI_RGB565: | ||
136 | pctype = 1; | ||
137 | datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; | ||
138 | pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; | ||
139 | linelength = ch->lcd_cfg.xres * 2; | ||
140 | yuv = false; | ||
141 | break; | ||
142 | case MIPI_RGB666_LP: | ||
143 | pctype = 2; | ||
144 | datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; | ||
145 | pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; | ||
146 | linelength = ch->lcd_cfg.xres * 3; | ||
147 | yuv = false; | ||
148 | break; | ||
149 | case MIPI_RGB666: | ||
150 | pctype = 3; | ||
151 | datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; | ||
152 | pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; | ||
153 | linelength = (ch->lcd_cfg.xres * 18 + 7) / 8; | ||
154 | yuv = false; | ||
155 | break; | ||
156 | case MIPI_BGR888: | ||
157 | pctype = 8; | ||
158 | datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; | ||
159 | pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; | ||
160 | linelength = ch->lcd_cfg.xres * 3; | ||
161 | yuv = false; | ||
162 | break; | ||
163 | case MIPI_BGR565: | ||
164 | pctype = 9; | ||
165 | datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; | ||
166 | pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; | ||
167 | linelength = ch->lcd_cfg.xres * 2; | ||
168 | yuv = false; | ||
169 | break; | ||
170 | case MIPI_BGR666_LP: | ||
171 | pctype = 0xa; | ||
172 | datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; | ||
173 | pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; | ||
174 | linelength = ch->lcd_cfg.xres * 3; | ||
175 | yuv = false; | ||
176 | break; | ||
177 | case MIPI_BGR666: | ||
178 | pctype = 0xb; | ||
179 | datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; | ||
180 | pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; | ||
181 | linelength = (ch->lcd_cfg.xres * 18 + 7) / 8; | ||
182 | yuv = false; | ||
183 | break; | ||
184 | case MIPI_YUYV: | ||
185 | pctype = 4; | ||
186 | datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; | ||
187 | pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; | ||
188 | linelength = ch->lcd_cfg.xres * 2; | ||
189 | yuv = true; | ||
190 | break; | ||
191 | case MIPI_UYVY: | ||
192 | pctype = 5; | ||
193 | datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; | ||
194 | pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; | ||
195 | linelength = ch->lcd_cfg.xres * 2; | ||
196 | yuv = true; | ||
197 | break; | ||
198 | case MIPI_YUV420_L: | ||
199 | pctype = 6; | ||
200 | datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; | ||
201 | pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; | ||
202 | linelength = (ch->lcd_cfg.xres * 12 + 7) / 8; | ||
203 | yuv = true; | ||
204 | break; | ||
205 | case MIPI_YUV420: | ||
206 | pctype = 7; | ||
207 | datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; | ||
208 | pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; | ||
209 | /* Length of U/V line */ | ||
210 | linelength = (ch->lcd_cfg.xres + 1) / 2; | ||
211 | yuv = true; | ||
212 | break; | ||
213 | default: | ||
214 | return -EINVAL; | ||
215 | } | ||
216 | |||
217 | if ((yuv && ch->interface_type != YUV422) || | ||
218 | (!yuv && ch->interface_type != RGB24)) | ||
219 | return -EINVAL; | ||
220 | |||
221 | /* reset DSI link */ | ||
222 | iowrite32(0x00000001, base); /* SYSCTRL */ | ||
223 | /* Hold reset for 100 cycles of the slowest of bus, HS byte and LP clock */ | ||
224 | udelay(50); | ||
225 | iowrite32(0x00000000, base); /* SYSCTRL */ | ||
226 | |||
227 | /* setup DSI link */ | ||
228 | |||
229 | /* | ||
230 | * Default = ULPS enable | | ||
231 | * Contention detection enabled | | ||
232 | * EoT packet transmission enable | | ||
233 | * CRC check enable | | ||
234 | * ECC check enable | ||
235 | * additionally enable first two lanes | ||
236 | */ | ||
237 | iowrite32(0x00003703, base + 0x04); /* SYSCONF */ | ||
238 | /* | ||
239 | * T_wakeup = 0x7000 | ||
240 | * T_hs-trail = 3 | ||
241 | * T_hs-prepare = 3 | ||
242 | * T_clk-trail = 3 | ||
243 | * T_clk-prepare = 2 | ||
244 | */ | ||
245 | iowrite32(0x70003332, base + 0x08); /* TIMSET */ | ||
246 | /* no responses requested */ | ||
247 | iowrite32(0x00000000, base + 0x18); /* RESREQSET0 */ | ||
248 | /* request response to packets of type 0x28 */ | ||
249 | iowrite32(0x00000100, base + 0x1c); /* RESREQSET1 */ | ||
250 | /* High-speed transmission timeout, default 0xffffffff */ | ||
251 | iowrite32(0x0fffffff, base + 0x20); /* HSTTOVSET */ | ||
252 | /* LP reception timeout, default 0xffffffff */ | ||
253 | iowrite32(0x0fffffff, base + 0x24); /* LPRTOVSET */ | ||
254 | /* Turn-around timeout, default 0xffffffff */ | ||
255 | iowrite32(0x0fffffff, base + 0x28); /* TATOVSET */ | ||
256 | /* Peripheral reset timeout, default 0xffffffff */ | ||
257 | iowrite32(0x0fffffff, base + 0x2c); /* PRTOVSET */ | ||
258 | /* Enable timeout counters */ | ||
259 | iowrite32(0x00000f00, base + 0x30); /* DSICTRL */ | ||
260 | /* Interrupts not used, disable all */ | ||
261 | iowrite32(0, base + DSIINTE); | ||
262 | /* DSI-Tx bias on */ | ||
263 | iowrite32(0x00000001, base + 0x70); /* PHYCTRL */ | ||
264 | udelay(200); | ||
265 | /* Deassert resets, power on, set multiplier */ | ||
266 | iowrite32(0x03070b01, base + 0x70); /* PHYCTRL */ | ||
267 | |||
268 | /* setup l-bridge */ | ||
269 | |||
270 | /* | ||
271 | * Enable transmission of all packets, | ||
272 | * transmit LPS after each HS packet completion | ||
273 | */ | ||
274 | iowrite32(0x00000006, base + 0x8000); /* DTCTR */ | ||
275 | /* VSYNC width = 2 (<< 17) */ | ||
276 | iowrite32(0x00040000 | (pctype << 12) | datatype, base + 0x8020); /* VMCTR1 */ | ||
277 | /* | ||
278 | * Non-burst mode with sync pulses: VSE and HSE are output, | ||
279 | * HSA period allowed, no commands in LP | ||
280 | */ | ||
281 | iowrite32(0x00e00000, base + 0x8024); /* VMCTR2 */ | ||
282 | /* | ||
283 | * 0x660 = 1632 bytes per line (RGB24, 544 pixels: see | ||
284 | * sh_mobile_lcdc_info.ch[0].lcd_cfg.xres), HSALEN = 1 - default | ||
285 | * (unused, since VMCTR2[HSABM] = 0) | ||
286 | */ | ||
287 | iowrite32(1 | (linelength << 16), base + 0x8028); /* VMLEN1 */ | ||
288 | |||
289 | msleep(5); | ||
290 | |||
291 | /* setup LCD panel */ | ||
292 | |||
293 | /* cf. drivers/video/omap/lcd_mipid.c */ | ||
294 | sh_mipi_dcs(ch->chan, MIPI_DCS_EXIT_SLEEP_MODE); | ||
295 | msleep(120); | ||
296 | /* | ||
297 | * [7] - Page Address Mode | ||
298 | * [6] - Column Address Mode | ||
299 | * [5] - Page / Column Address Mode | ||
300 | * [4] - Display Device Line Refresh Order | ||
301 | * [3] - RGB/BGR Order | ||
302 | * [2] - Display Data Latch Data Order | ||
303 | * [1] - Flip Horizontal | ||
304 | * [0] - Flip Vertical | ||
305 | */ | ||
306 | sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_ADDRESS_MODE, 0x00); | ||
307 | /* cf. set_data_lines() */ | ||
308 | sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_PIXEL_FORMAT, | ||
309 | pixfmt << 4); | ||
310 | sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON); | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static int __init sh_mipi_probe(struct platform_device *pdev) | ||
316 | { | ||
317 | struct sh_mipi *mipi; | ||
318 | struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data; | ||
319 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
320 | unsigned long rate, f_current; | ||
321 | int idx = pdev->id, ret; | ||
322 | char dsip_clk[] = "dsi.p_clk"; | ||
323 | |||
324 | if (!res || idx >= ARRAY_SIZE(mipi_dsi) || !pdata) | ||
325 | return -ENODEV; | ||
326 | |||
327 | mutex_lock(&array_lock); | ||
328 | if (idx < 0) | ||
329 | for (idx = 0; idx < ARRAY_SIZE(mipi_dsi) && mipi_dsi[idx]; idx++) | ||
330 | ; | ||
331 | |||
332 | if (idx == ARRAY_SIZE(mipi_dsi)) { | ||
333 | ret = -EBUSY; | ||
334 | goto efindslot; | ||
335 | } | ||
336 | |||
337 | mipi = kzalloc(sizeof(*mipi), GFP_KERNEL); | ||
338 | if (!mipi) { | ||
339 | ret = -ENOMEM; | ||
340 | goto ealloc; | ||
341 | } | ||
342 | |||
343 | if (!request_mem_region(res->start, resource_size(res), pdev->name)) { | ||
344 | dev_err(&pdev->dev, "MIPI register region already claimed\n"); | ||
345 | ret = -EBUSY; | ||
346 | goto ereqreg; | ||
347 | } | ||
348 | |||
349 | mipi->base = ioremap(res->start, resource_size(res)); | ||
350 | if (!mipi->base) { | ||
351 | ret = -ENOMEM; | ||
352 | goto emap; | ||
353 | } | ||
354 | |||
355 | mipi->dsit_clk = clk_get(&pdev->dev, "dsit_clk"); | ||
356 | if (IS_ERR(mipi->dsit_clk)) { | ||
357 | ret = PTR_ERR(mipi->dsit_clk); | ||
358 | goto eclktget; | ||
359 | } | ||
360 | |||
361 | f_current = clk_get_rate(mipi->dsit_clk); | ||
362 | /* 80MHz required by the datasheet */ | ||
363 | rate = clk_round_rate(mipi->dsit_clk, 80000000); | ||
364 | if (rate > 0 && rate != f_current) | ||
365 | ret = clk_set_rate(mipi->dsit_clk, rate); | ||
366 | else | ||
367 | ret = rate; | ||
368 | if (ret < 0) | ||
369 | goto esettrate; | ||
370 | |||
371 | dev_dbg(&pdev->dev, "DSI-T clk %lu -> %lu\n", f_current, rate); | ||
372 | |||
373 | sprintf(dsip_clk, "dsi%1.1dp_clk", idx); | ||
374 | mipi->dsip_clk = clk_get(&pdev->dev, dsip_clk); | ||
375 | if (IS_ERR(mipi->dsip_clk)) { | ||
376 | ret = PTR_ERR(mipi->dsip_clk); | ||
377 | goto eclkpget; | ||
378 | } | ||
379 | |||
380 | f_current = clk_get_rate(mipi->dsip_clk); | ||
381 | /* Between 10 and 50MHz */ | ||
382 | rate = clk_round_rate(mipi->dsip_clk, 24000000); | ||
383 | if (rate > 0 && rate != f_current) | ||
384 | ret = clk_set_rate(mipi->dsip_clk, rate); | ||
385 | else | ||
386 | ret = rate; | ||
387 | if (ret < 0) | ||
388 | goto esetprate; | ||
389 | |||
390 | dev_dbg(&pdev->dev, "DSI-P clk %lu -> %lu\n", f_current, rate); | ||
391 | |||
392 | msleep(10); | ||
393 | |||
394 | ret = clk_enable(mipi->dsit_clk); | ||
395 | if (ret < 0) | ||
396 | goto eclkton; | ||
397 | |||
398 | ret = clk_enable(mipi->dsip_clk); | ||
399 | if (ret < 0) | ||
400 | goto eclkpon; | ||
401 | |||
402 | mipi_dsi[idx] = mipi; | ||
403 | |||
404 | ret = sh_mipi_setup(mipi, pdata); | ||
405 | if (ret < 0) | ||
406 | goto emipisetup; | ||
407 | |||
408 | mutex_unlock(&array_lock); | ||
409 | platform_set_drvdata(pdev, mipi); | ||
410 | |||
411 | /* Set up LCDC callbacks */ | ||
412 | pdata->lcd_chan->board_cfg.board_data = mipi; | ||
413 | pdata->lcd_chan->board_cfg.display_on = mipi_display_on; | ||
414 | pdata->lcd_chan->board_cfg.display_off = mipi_display_off; | ||
415 | |||
416 | return 0; | ||
417 | |||
418 | emipisetup: | ||
419 | mipi_dsi[idx] = NULL; | ||
420 | clk_disable(mipi->dsip_clk); | ||
421 | eclkpon: | ||
422 | clk_disable(mipi->dsit_clk); | ||
423 | eclkton: | ||
424 | esetprate: | ||
425 | clk_put(mipi->dsip_clk); | ||
426 | eclkpget: | ||
427 | esettrate: | ||
428 | clk_put(mipi->dsit_clk); | ||
429 | eclktget: | ||
430 | iounmap(mipi->base); | ||
431 | emap: | ||
432 | release_mem_region(res->start, resource_size(res)); | ||
433 | ereqreg: | ||
434 | kfree(mipi); | ||
435 | ealloc: | ||
436 | efindslot: | ||
437 | mutex_unlock(&array_lock); | ||
438 | |||
439 | return ret; | ||
440 | } | ||
441 | |||
442 | static int __exit sh_mipi_remove(struct platform_device *pdev) | ||
443 | { | ||
444 | struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data; | ||
445 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
446 | struct sh_mipi *mipi = platform_get_drvdata(pdev); | ||
447 | int i, ret; | ||
448 | |||
449 | mutex_lock(&array_lock); | ||
450 | |||
451 | for (i = 0; i < ARRAY_SIZE(mipi_dsi) && mipi_dsi[i] != mipi; i++) | ||
452 | ; | ||
453 | |||
454 | if (i == ARRAY_SIZE(mipi_dsi)) { | ||
455 | ret = -EINVAL; | ||
456 | } else { | ||
457 | ret = 0; | ||
458 | mipi_dsi[i] = NULL; | ||
459 | } | ||
460 | |||
461 | mutex_unlock(&array_lock); | ||
462 | |||
463 | if (ret < 0) | ||
464 | return ret; | ||
465 | |||
466 | pdata->lcd_chan->board_cfg.display_on = NULL; | ||
467 | pdata->lcd_chan->board_cfg.display_off = NULL; | ||
468 | pdata->lcd_chan->board_cfg.board_data = NULL; | ||
469 | |||
470 | clk_disable(mipi->dsip_clk); | ||
471 | clk_disable(mipi->dsit_clk); | ||
472 | clk_put(mipi->dsit_clk); | ||
473 | clk_put(mipi->dsip_clk); | ||
474 | iounmap(mipi->base); | ||
475 | if (res) | ||
476 | release_mem_region(res->start, resource_size(res)); | ||
477 | platform_set_drvdata(pdev, NULL); | ||
478 | kfree(mipi); | ||
479 | |||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | static struct platform_driver sh_mipi_driver = { | ||
484 | .remove = __exit_p(sh_mipi_remove), | ||
485 | .shutdown = sh_mipi_shutdown, | ||
486 | .driver = { | ||
487 | .name = "sh-mipi-dsi", | ||
488 | }, | ||
489 | }; | ||
490 | |||
491 | static int __init sh_mipi_init(void) | ||
492 | { | ||
493 | return platform_driver_probe(&sh_mipi_driver, sh_mipi_probe); | ||
494 | } | ||
495 | module_init(sh_mipi_init); | ||
496 | |||
497 | static void __exit sh_mipi_exit(void) | ||
498 | { | ||
499 | platform_driver_unregister(&sh_mipi_driver); | ||
500 | } | ||
501 | module_exit(sh_mipi_exit); | ||
502 | |||
503 | MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); | ||
504 | MODULE_DESCRIPTION("SuperH / ARM-shmobile MIPI DSI driver"); | ||
505 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c new file mode 100644 index 000000000000..2fde08cc66bf --- /dev/null +++ b/drivers/video/sh_mobile_hdmi.c | |||
@@ -0,0 +1,1028 @@ | |||
1 | /* | ||
2 | * SH-Mobile High-Definition Multimedia Interface (HDMI) driver | ||
3 | * for SLISHDMI13T and SLIPHDMIT IP cores | ||
4 | * | ||
5 | * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk.h> | ||
13 | #include <linux/console.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/pm_runtime.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/workqueue.h> | ||
25 | |||
26 | #include <video/sh_mobile_hdmi.h> | ||
27 | #include <video/sh_mobile_lcdc.h> | ||
28 | |||
29 | #define HDMI_SYSTEM_CTRL 0x00 /* System control */ | ||
30 | #define HDMI_L_R_DATA_SWAP_CTRL_RPKT 0x01 /* L/R data swap control, | ||
31 | bits 19..16 of 20-bit N for Audio Clock Regeneration packet */ | ||
32 | #define HDMI_20_BIT_N_FOR_AUDIO_RPKT_15_8 0x02 /* bits 15..8 of 20-bit N for Audio Clock Regeneration packet */ | ||
33 | #define HDMI_20_BIT_N_FOR_AUDIO_RPKT_7_0 0x03 /* bits 7..0 of 20-bit N for Audio Clock Regeneration packet */ | ||
34 | #define HDMI_SPDIF_AUDIO_SAMP_FREQ_CTS 0x04 /* SPDIF audio sampling frequency, | ||
35 | bits 19..16 of Internal CTS */ | ||
36 | #define HDMI_INTERNAL_CTS_15_8 0x05 /* bits 15..8 of Internal CTS */ | ||
37 | #define HDMI_INTERNAL_CTS_7_0 0x06 /* bits 7..0 of Internal CTS */ | ||
38 | #define HDMI_EXTERNAL_CTS_19_16 0x07 /* External CTS */ | ||
39 | #define HDMI_EXTERNAL_CTS_15_8 0x08 /* External CTS */ | ||
40 | #define HDMI_EXTERNAL_CTS_7_0 0x09 /* External CTS */ | ||
41 | #define HDMI_AUDIO_SETTING_1 0x0A /* Audio setting.1 */ | ||
42 | #define HDMI_AUDIO_SETTING_2 0x0B /* Audio setting.2 */ | ||
43 | #define HDMI_I2S_AUDIO_SET 0x0C /* I2S audio setting */ | ||
44 | #define HDMI_DSD_AUDIO_SET 0x0D /* DSD audio setting */ | ||
45 | #define HDMI_DEBUG_MONITOR_1 0x0E /* Debug monitor.1 */ | ||
46 | #define HDMI_DEBUG_MONITOR_2 0x0F /* Debug monitor.2 */ | ||
47 | #define HDMI_I2S_INPUT_PIN_SWAP 0x10 /* I2S input pin swap */ | ||
48 | #define HDMI_AUDIO_STATUS_BITS_SETTING_1 0x11 /* Audio status bits setting.1 */ | ||
49 | #define HDMI_AUDIO_STATUS_BITS_SETTING_2 0x12 /* Audio status bits setting.2 */ | ||
50 | #define HDMI_CATEGORY_CODE 0x13 /* Category code */ | ||
51 | #define HDMI_SOURCE_NUM_AUDIO_WORD_LEN 0x14 /* Source number/Audio word length */ | ||
52 | #define HDMI_AUDIO_VIDEO_SETTING_1 0x15 /* Audio/Video setting.1 */ | ||
53 | #define HDMI_VIDEO_SETTING_1 0x16 /* Video setting.1 */ | ||
54 | #define HDMI_DEEP_COLOR_MODES 0x17 /* Deep Color Modes */ | ||
55 | |||
56 | /* 12 16- and 10-bit Color space conversion parameters: 0x18..0x2f */ | ||
57 | #define HDMI_COLOR_SPACE_CONVERSION_PARAMETERS 0x18 | ||
58 | |||
59 | #define HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS 0x30 /* External video parameter settings */ | ||
60 | #define HDMI_EXTERNAL_H_TOTAL_7_0 0x31 /* External horizontal total (LSB) */ | ||
61 | #define HDMI_EXTERNAL_H_TOTAL_11_8 0x32 /* External horizontal total (MSB) */ | ||
62 | #define HDMI_EXTERNAL_H_BLANK_7_0 0x33 /* External horizontal blank (LSB) */ | ||
63 | #define HDMI_EXTERNAL_H_BLANK_9_8 0x34 /* External horizontal blank (MSB) */ | ||
64 | #define HDMI_EXTERNAL_H_DELAY_7_0 0x35 /* External horizontal delay (LSB) */ | ||
65 | #define HDMI_EXTERNAL_H_DELAY_9_8 0x36 /* External horizontal delay (MSB) */ | ||
66 | #define HDMI_EXTERNAL_H_DURATION_7_0 0x37 /* External horizontal duration (LSB) */ | ||
67 | #define HDMI_EXTERNAL_H_DURATION_9_8 0x38 /* External horizontal duration (MSB) */ | ||
68 | #define HDMI_EXTERNAL_V_TOTAL_7_0 0x39 /* External vertical total (LSB) */ | ||
69 | #define HDMI_EXTERNAL_V_TOTAL_9_8 0x3A /* External vertical total (MSB) */ | ||
70 | #define HDMI_AUDIO_VIDEO_SETTING_2 0x3B /* Audio/Video setting.2 */ | ||
71 | #define HDMI_EXTERNAL_V_BLANK 0x3D /* External vertical blank */ | ||
72 | #define HDMI_EXTERNAL_V_DELAY 0x3E /* External vertical delay */ | ||
73 | #define HDMI_EXTERNAL_V_DURATION 0x3F /* External vertical duration */ | ||
74 | #define HDMI_CTRL_PKT_MANUAL_SEND_CONTROL 0x40 /* Control packet manual send control */ | ||
75 | #define HDMI_CTRL_PKT_AUTO_SEND 0x41 /* Control packet auto send with VSYNC control */ | ||
76 | #define HDMI_AUTO_CHECKSUM_OPTION 0x42 /* Auto checksum option */ | ||
77 | #define HDMI_VIDEO_SETTING_2 0x45 /* Video setting.2 */ | ||
78 | #define HDMI_OUTPUT_OPTION 0x46 /* Output option */ | ||
79 | #define HDMI_SLIPHDMIT_PARAM_OPTION 0x51 /* SLIPHDMIT parameter option */ | ||
80 | #define HDMI_HSYNC_PMENT_AT_EMB_7_0 0x52 /* HSYNC placement at embedded sync (LSB) */ | ||
81 | #define HDMI_HSYNC_PMENT_AT_EMB_15_8 0x53 /* HSYNC placement at embedded sync (MSB) */ | ||
82 | #define HDMI_VSYNC_PMENT_AT_EMB_7_0 0x54 /* VSYNC placement at embedded sync (LSB) */ | ||
83 | #define HDMI_VSYNC_PMENT_AT_EMB_14_8 0x55 /* VSYNC placement at embedded sync (MSB) */ | ||
84 | #define HDMI_SLIPHDMIT_PARAM_SETTINGS_1 0x56 /* SLIPHDMIT parameter settings.1 */ | ||
85 | #define HDMI_SLIPHDMIT_PARAM_SETTINGS_2 0x57 /* SLIPHDMIT parameter settings.2 */ | ||
86 | #define HDMI_SLIPHDMIT_PARAM_SETTINGS_3 0x58 /* SLIPHDMIT parameter settings.3 */ | ||
87 | #define HDMI_SLIPHDMIT_PARAM_SETTINGS_5 0x59 /* SLIPHDMIT parameter settings.5 */ | ||
88 | #define HDMI_SLIPHDMIT_PARAM_SETTINGS_6 0x5A /* SLIPHDMIT parameter settings.6 */ | ||
89 | #define HDMI_SLIPHDMIT_PARAM_SETTINGS_7 0x5B /* SLIPHDMIT parameter settings.7 */ | ||
90 | #define HDMI_SLIPHDMIT_PARAM_SETTINGS_8 0x5C /* SLIPHDMIT parameter settings.8 */ | ||
91 | #define HDMI_SLIPHDMIT_PARAM_SETTINGS_9 0x5D /* SLIPHDMIT parameter settings.9 */ | ||
92 | #define HDMI_SLIPHDMIT_PARAM_SETTINGS_10 0x5E /* SLIPHDMIT parameter settings.10 */ | ||
93 | #define HDMI_CTRL_PKT_BUF_INDEX 0x5F /* Control packet buffer index */ | ||
94 | #define HDMI_CTRL_PKT_BUF_ACCESS_HB0 0x60 /* Control packet data buffer access window - HB0 */ | ||
95 | #define HDMI_CTRL_PKT_BUF_ACCESS_HB1 0x61 /* Control packet data buffer access window - HB1 */ | ||
96 | #define HDMI_CTRL_PKT_BUF_ACCESS_HB2 0x62 /* Control packet data buffer access window - HB2 */ | ||
97 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB0 0x63 /* Control packet data buffer access window - PB0 */ | ||
98 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB1 0x64 /* Control packet data buffer access window - PB1 */ | ||
99 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB2 0x65 /* Control packet data buffer access window - PB2 */ | ||
100 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB3 0x66 /* Control packet data buffer access window - PB3 */ | ||
101 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB4 0x67 /* Control packet data buffer access window - PB4 */ | ||
102 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB5 0x68 /* Control packet data buffer access window - PB5 */ | ||
103 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB6 0x69 /* Control packet data buffer access window - PB6 */ | ||
104 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB7 0x6A /* Control packet data buffer access window - PB7 */ | ||
105 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB8 0x6B /* Control packet data buffer access window - PB8 */ | ||
106 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB9 0x6C /* Control packet data buffer access window - PB9 */ | ||
107 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB10 0x6D /* Control packet data buffer access window - PB10 */ | ||
108 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB11 0x6E /* Control packet data buffer access window - PB11 */ | ||
109 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB12 0x6F /* Control packet data buffer access window - PB12 */ | ||
110 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB13 0x70 /* Control packet data buffer access window - PB13 */ | ||
111 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB14 0x71 /* Control packet data buffer access window - PB14 */ | ||
112 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB15 0x72 /* Control packet data buffer access window - PB15 */ | ||
113 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB16 0x73 /* Control packet data buffer access window - PB16 */ | ||
114 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB17 0x74 /* Control packet data buffer access window - PB17 */ | ||
115 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB18 0x75 /* Control packet data buffer access window - PB18 */ | ||
116 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB19 0x76 /* Control packet data buffer access window - PB19 */ | ||
117 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB20 0x77 /* Control packet data buffer access window - PB20 */ | ||
118 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB21 0x78 /* Control packet data buffer access window - PB21 */ | ||
119 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB22 0x79 /* Control packet data buffer access window - PB22 */ | ||
120 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB23 0x7A /* Control packet data buffer access window - PB23 */ | ||
121 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB24 0x7B /* Control packet data buffer access window - PB24 */ | ||
122 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB25 0x7C /* Control packet data buffer access window - PB25 */ | ||
123 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB26 0x7D /* Control packet data buffer access window - PB26 */ | ||
124 | #define HDMI_CTRL_PKT_BUF_ACCESS_PB27 0x7E /* Control packet data buffer access window - PB27 */ | ||
125 | #define HDMI_EDID_KSV_FIFO_ACCESS_WINDOW 0x80 /* EDID/KSV FIFO access window */ | ||
126 | #define HDMI_DDC_BUS_ACCESS_FREQ_CTRL_7_0 0x81 /* DDC bus access frequency control (LSB) */ | ||
127 | #define HDMI_DDC_BUS_ACCESS_FREQ_CTRL_15_8 0x82 /* DDC bus access frequency control (MSB) */ | ||
128 | #define HDMI_INTERRUPT_MASK_1 0x92 /* Interrupt mask.1 */ | ||
129 | #define HDMI_INTERRUPT_MASK_2 0x93 /* Interrupt mask.2 */ | ||
130 | #define HDMI_INTERRUPT_STATUS_1 0x94 /* Interrupt status.1 */ | ||
131 | #define HDMI_INTERRUPT_STATUS_2 0x95 /* Interrupt status.2 */ | ||
132 | #define HDMI_INTERRUPT_MASK_3 0x96 /* Interrupt mask.3 */ | ||
133 | #define HDMI_INTERRUPT_MASK_4 0x97 /* Interrupt mask.4 */ | ||
134 | #define HDMI_INTERRUPT_STATUS_3 0x98 /* Interrupt status.3 */ | ||
135 | #define HDMI_INTERRUPT_STATUS_4 0x99 /* Interrupt status.4 */ | ||
136 | #define HDMI_SOFTWARE_HDCP_CONTROL_1 0x9A /* Software HDCP control.1 */ | ||
137 | #define HDMI_FRAME_COUNTER 0x9C /* Frame counter */ | ||
138 | #define HDMI_FRAME_COUNTER_FOR_RI_CHECK 0x9D /* Frame counter for Ri check */ | ||
139 | #define HDMI_HDCP_CONTROL 0xAF /* HDCP control */ | ||
140 | #define HDMI_RI_FRAME_COUNT_REGISTER 0xB2 /* Ri frame count register */ | ||
141 | #define HDMI_DDC_BUS_CONTROL 0xB7 /* DDC bus control */ | ||
142 | #define HDMI_HDCP_STATUS 0xB8 /* HDCP status */ | ||
143 | #define HDMI_SHA0 0xB9 /* sha0 */ | ||
144 | #define HDMI_SHA1 0xBA /* sha1 */ | ||
145 | #define HDMI_SHA2 0xBB /* sha2 */ | ||
146 | #define HDMI_SHA3 0xBC /* sha3 */ | ||
147 | #define HDMI_SHA4 0xBD /* sha4 */ | ||
148 | #define HDMI_BCAPS_READ 0xBE /* BCAPS read / debug */ | ||
149 | #define HDMI_AKSV_BKSV_7_0_MONITOR 0xBF /* AKSV/BKSV[7:0] monitor */ | ||
150 | #define HDMI_AKSV_BKSV_15_8_MONITOR 0xC0 /* AKSV/BKSV[15:8] monitor */ | ||
151 | #define HDMI_AKSV_BKSV_23_16_MONITOR 0xC1 /* AKSV/BKSV[23:16] monitor */ | ||
152 | #define HDMI_AKSV_BKSV_31_24_MONITOR 0xC2 /* AKSV/BKSV[31:24] monitor */ | ||
153 | #define HDMI_AKSV_BKSV_39_32_MONITOR 0xC3 /* AKSV/BKSV[39:32] monitor */ | ||
154 | #define HDMI_EDID_SEGMENT_POINTER 0xC4 /* EDID segment pointer */ | ||
155 | #define HDMI_EDID_WORD_ADDRESS 0xC5 /* EDID word address */ | ||
156 | #define HDMI_EDID_DATA_FIFO_ADDRESS 0xC6 /* EDID data FIFO address */ | ||
157 | #define HDMI_NUM_OF_HDMI_DEVICES 0xC7 /* Number of HDMI devices */ | ||
158 | #define HDMI_HDCP_ERROR_CODE 0xC8 /* HDCP error code */ | ||
159 | #define HDMI_100MS_TIMER_SET 0xC9 /* 100ms timer setting */ | ||
160 | #define HDMI_5SEC_TIMER_SET 0xCA /* 5sec timer setting */ | ||
161 | #define HDMI_RI_READ_COUNT 0xCB /* Ri read count */ | ||
162 | #define HDMI_AN_SEED 0xCC /* An seed */ | ||
163 | #define HDMI_MAX_NUM_OF_RCIVRS_ALLOWED 0xCD /* Maximum number of receivers allowed */ | ||
164 | #define HDMI_HDCP_MEMORY_ACCESS_CONTROL_1 0xCE /* HDCP memory access control.1 */ | ||
165 | #define HDMI_HDCP_MEMORY_ACCESS_CONTROL_2 0xCF /* HDCP memory access control.2 */ | ||
166 | #define HDMI_HDCP_CONTROL_2 0xD0 /* HDCP Control 2 */ | ||
167 | #define HDMI_HDCP_KEY_MEMORY_CONTROL 0xD2 /* HDCP Key Memory Control */ | ||
168 | #define HDMI_COLOR_SPACE_CONV_CONFIG_1 0xD3 /* Color space conversion configuration.1 */ | ||
169 | #define HDMI_VIDEO_SETTING_3 0xD4 /* Video setting.3 */ | ||
170 | #define HDMI_RI_7_0 0xD5 /* Ri[7:0] */ | ||
171 | #define HDMI_RI_15_8 0xD6 /* Ri[15:8] */ | ||
172 | #define HDMI_PJ 0xD7 /* Pj */ | ||
173 | #define HDMI_SHA_RD 0xD8 /* sha_rd */ | ||
174 | #define HDMI_RI_7_0_SAVED 0xD9 /* Ri[7:0] saved */ | ||
175 | #define HDMI_RI_15_8_SAVED 0xDA /* Ri[15:8] saved */ | ||
176 | #define HDMI_PJ_SAVED 0xDB /* Pj saved */ | ||
177 | #define HDMI_NUM_OF_DEVICES 0xDC /* Number of devices */ | ||
178 | #define HDMI_HOT_PLUG_MSENS_STATUS 0xDF /* Hot plug/MSENS status */ | ||
179 | #define HDMI_BCAPS_WRITE 0xE0 /* bcaps */ | ||
180 | #define HDMI_BSTAT_7_0 0xE1 /* bstat[7:0] */ | ||
181 | #define HDMI_BSTAT_15_8 0xE2 /* bstat[15:8] */ | ||
182 | #define HDMI_BKSV_7_0 0xE3 /* bksv[7:0] */ | ||
183 | #define HDMI_BKSV_15_8 0xE4 /* bksv[15:8] */ | ||
184 | #define HDMI_BKSV_23_16 0xE5 /* bksv[23:16] */ | ||
185 | #define HDMI_BKSV_31_24 0xE6 /* bksv[31:24] */ | ||
186 | #define HDMI_BKSV_39_32 0xE7 /* bksv[39:32] */ | ||
187 | #define HDMI_AN_7_0 0xE8 /* An[7:0] */ | ||
188 | #define HDMI_AN_15_8 0xE9 /* An [15:8] */ | ||
189 | #define HDMI_AN_23_16 0xEA /* An [23:16] */ | ||
190 | #define HDMI_AN_31_24 0xEB /* An [31:24] */ | ||
191 | #define HDMI_AN_39_32 0xEC /* An [39:32] */ | ||
192 | #define HDMI_AN_47_40 0xED /* An [47:40] */ | ||
193 | #define HDMI_AN_55_48 0xEE /* An [55:48] */ | ||
194 | #define HDMI_AN_63_56 0xEF /* An [63:56] */ | ||
195 | #define HDMI_PRODUCT_ID 0xF0 /* Product ID */ | ||
196 | #define HDMI_REVISION_ID 0xF1 /* Revision ID */ | ||
197 | #define HDMI_TEST_MODE 0xFE /* Test mode */ | ||
198 | |||
199 | enum hotplug_state { | ||
200 | HDMI_HOTPLUG_DISCONNECTED, | ||
201 | HDMI_HOTPLUG_CONNECTED, | ||
202 | HDMI_HOTPLUG_EDID_DONE, | ||
203 | }; | ||
204 | |||
205 | struct sh_hdmi { | ||
206 | void __iomem *base; | ||
207 | enum hotplug_state hp_state; | ||
208 | struct clk *hdmi_clk; | ||
209 | struct device *dev; | ||
210 | struct fb_info *info; | ||
211 | struct delayed_work edid_work; | ||
212 | struct fb_var_screeninfo var; | ||
213 | }; | ||
214 | |||
215 | static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg) | ||
216 | { | ||
217 | iowrite8(data, hdmi->base + reg); | ||
218 | } | ||
219 | |||
220 | static u8 hdmi_read(struct sh_hdmi *hdmi, u8 reg) | ||
221 | { | ||
222 | return ioread8(hdmi->base + reg); | ||
223 | } | ||
224 | |||
225 | /* External video parameter settings */ | ||
226 | static void hdmi_external_video_param(struct sh_hdmi *hdmi) | ||
227 | { | ||
228 | struct fb_var_screeninfo *var = &hdmi->var; | ||
229 | u16 htotal, hblank, hdelay, vtotal, vblank, vdelay, voffset; | ||
230 | u8 sync = 0; | ||
231 | |||
232 | htotal = var->xres + var->right_margin + var->left_margin + var->hsync_len; | ||
233 | |||
234 | hdelay = var->hsync_len + var->left_margin; | ||
235 | hblank = var->right_margin + hdelay; | ||
236 | |||
237 | /* | ||
238 | * Vertical timing looks a bit different in Figure 18, | ||
239 | * but let's try the same first by setting offset = 0 | ||
240 | */ | ||
241 | vtotal = var->yres + var->upper_margin + var->lower_margin + var->vsync_len; | ||
242 | |||
243 | vdelay = var->vsync_len + var->upper_margin; | ||
244 | vblank = var->lower_margin + vdelay; | ||
245 | voffset = min(var->upper_margin / 2, 6U); | ||
246 | |||
247 | /* | ||
248 | * [3]: VSYNC polarity: Positive | ||
249 | * [2]: HSYNC polarity: Positive | ||
250 | * [1]: Interlace/Progressive: Progressive | ||
251 | * [0]: External video settings enable: used. | ||
252 | */ | ||
253 | if (var->sync & FB_SYNC_HOR_HIGH_ACT) | ||
254 | sync |= 4; | ||
255 | if (var->sync & FB_SYNC_VERT_HIGH_ACT) | ||
256 | sync |= 8; | ||
257 | |||
258 | pr_debug("H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x\n", | ||
259 | htotal, hblank, hdelay, var->hsync_len, | ||
260 | vtotal, vblank, vdelay, var->vsync_len, sync); | ||
261 | |||
262 | hdmi_write(hdmi, sync | (voffset << 4), HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS); | ||
263 | |||
264 | hdmi_write(hdmi, htotal, HDMI_EXTERNAL_H_TOTAL_7_0); | ||
265 | hdmi_write(hdmi, htotal >> 8, HDMI_EXTERNAL_H_TOTAL_11_8); | ||
266 | |||
267 | hdmi_write(hdmi, hblank, HDMI_EXTERNAL_H_BLANK_7_0); | ||
268 | hdmi_write(hdmi, hblank >> 8, HDMI_EXTERNAL_H_BLANK_9_8); | ||
269 | |||
270 | hdmi_write(hdmi, hdelay, HDMI_EXTERNAL_H_DELAY_7_0); | ||
271 | hdmi_write(hdmi, hdelay >> 8, HDMI_EXTERNAL_H_DELAY_9_8); | ||
272 | |||
273 | hdmi_write(hdmi, var->hsync_len, HDMI_EXTERNAL_H_DURATION_7_0); | ||
274 | hdmi_write(hdmi, var->hsync_len >> 8, HDMI_EXTERNAL_H_DURATION_9_8); | ||
275 | |||
276 | hdmi_write(hdmi, vtotal, HDMI_EXTERNAL_V_TOTAL_7_0); | ||
277 | hdmi_write(hdmi, vtotal >> 8, HDMI_EXTERNAL_V_TOTAL_9_8); | ||
278 | |||
279 | hdmi_write(hdmi, vblank, HDMI_EXTERNAL_V_BLANK); | ||
280 | |||
281 | hdmi_write(hdmi, vdelay, HDMI_EXTERNAL_V_DELAY); | ||
282 | |||
283 | hdmi_write(hdmi, var->vsync_len, HDMI_EXTERNAL_V_DURATION); | ||
284 | |||
285 | /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for manual mode */ | ||
286 | } | ||
287 | |||
288 | /** | ||
289 | * sh_hdmi_video_config() | ||
290 | */ | ||
291 | static void sh_hdmi_video_config(struct sh_hdmi *hdmi) | ||
292 | { | ||
293 | /* | ||
294 | * [7:4]: Audio sampling frequency: 48kHz | ||
295 | * [3:1]: Input video format: RGB and YCbCr 4:4:4 (Y on Green) | ||
296 | * [0]: Internal/External DE select: internal | ||
297 | */ | ||
298 | hdmi_write(hdmi, 0x20, HDMI_AUDIO_VIDEO_SETTING_1); | ||
299 | |||
300 | /* | ||
301 | * [7:6]: Video output format: RGB 4:4:4 | ||
302 | * [5:4]: Input video data width: 8 bit | ||
303 | * [3:1]: EAV/SAV location: channel 1 | ||
304 | * [0]: Video input color space: RGB | ||
305 | */ | ||
306 | hdmi_write(hdmi, 0x34, HDMI_VIDEO_SETTING_1); | ||
307 | |||
308 | /* | ||
309 | * [7:6]: Together with bit [6] of HDMI_AUDIO_VIDEO_SETTING_2, which is | ||
310 | * left at 0 by default, this configures 24bpp and sets the Color Depth | ||
311 | * (CD) field in the General Control Packet | ||
312 | */ | ||
313 | hdmi_write(hdmi, 0x20, HDMI_DEEP_COLOR_MODES); | ||
314 | } | ||
315 | |||
316 | /** | ||
317 | * sh_hdmi_audio_config() | ||
318 | */ | ||
319 | static void sh_hdmi_audio_config(struct sh_hdmi *hdmi) | ||
320 | { | ||
321 | /* | ||
322 | * [7:4] L/R data swap control | ||
323 | * [3:0] appropriate N[19:16] | ||
324 | */ | ||
325 | hdmi_write(hdmi, 0x00, HDMI_L_R_DATA_SWAP_CTRL_RPKT); | ||
326 | /* appropriate N[15:8] */ | ||
327 | hdmi_write(hdmi, 0x18, HDMI_20_BIT_N_FOR_AUDIO_RPKT_15_8); | ||
328 | /* appropriate N[7:0] */ | ||
329 | hdmi_write(hdmi, 0x00, HDMI_20_BIT_N_FOR_AUDIO_RPKT_7_0); | ||
330 | |||
331 | /* [7:4] 48 kHz SPDIF not used */ | ||
332 | hdmi_write(hdmi, 0x20, HDMI_SPDIF_AUDIO_SAMP_FREQ_CTS); | ||
333 | |||
334 | /* | ||
335 | * [6:5] set required down sampling rate if required | ||
336 | * [4:3] set required audio source | ||
337 | */ | ||
338 | hdmi_write(hdmi, 0x00, HDMI_AUDIO_SETTING_1); | ||
339 | |||
340 | /* [3:0] set sending channel number for channel status */ | ||
341 | hdmi_write(hdmi, 0x40, HDMI_AUDIO_SETTING_2); | ||
342 | |||
343 | /* | ||
344 | * [5:2] set valid I2S source input pin | ||
345 | * [1:0] set input I2S source mode | ||
346 | */ | ||
347 | hdmi_write(hdmi, 0x04, HDMI_I2S_AUDIO_SET); | ||
348 | |||
349 | /* [7:4] set valid DSD source input pin */ | ||
350 | hdmi_write(hdmi, 0x00, HDMI_DSD_AUDIO_SET); | ||
351 | |||
352 | /* [7:0] set appropriate I2S input pin swap settings if required */ | ||
353 | hdmi_write(hdmi, 0x00, HDMI_I2S_INPUT_PIN_SWAP); | ||
354 | |||
355 | /* | ||
356 | * [7] set validity bit for channel status | ||
357 | * [3:0] set original sample frequency for channel status | ||
358 | */ | ||
359 | hdmi_write(hdmi, 0x00, HDMI_AUDIO_STATUS_BITS_SETTING_1); | ||
360 | |||
361 | /* | ||
362 | * [7] set value for channel status | ||
363 | * [6] set value for channel status | ||
364 | * [5] set copyright bit for channel status | ||
365 | * [4:2] set additional information for channel status | ||
366 | * [1:0] set clock accuracy for channel status | ||
367 | */ | ||
368 | hdmi_write(hdmi, 0x00, HDMI_AUDIO_STATUS_BITS_SETTING_2); | ||
369 | |||
370 | /* [7:0] set category code for channel status */ | ||
371 | hdmi_write(hdmi, 0x00, HDMI_CATEGORY_CODE); | ||
372 | |||
373 | /* | ||
374 | * [7:4] set source number for channel status | ||
375 | * [3:0] set word length for channel status | ||
376 | */ | ||
377 | hdmi_write(hdmi, 0x00, HDMI_SOURCE_NUM_AUDIO_WORD_LEN); | ||
378 | |||
379 | /* [7:4] set sample frequency for channel status */ | ||
380 | hdmi_write(hdmi, 0x20, HDMI_AUDIO_VIDEO_SETTING_1); | ||
381 | } | ||
382 | |||
383 | /** | ||
384 | * sh_hdmi_phy_config() | ||
385 | */ | ||
386 | static void sh_hdmi_phy_config(struct sh_hdmi *hdmi) | ||
387 | { | ||
388 | /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */ | ||
389 | hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1); | ||
390 | hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2); | ||
391 | hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3); | ||
392 | /* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */ | ||
393 | hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5); | ||
394 | hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6); | ||
395 | hdmi_write(hdmi, 0x4A, HDMI_SLIPHDMIT_PARAM_SETTINGS_7); | ||
396 | hdmi_write(hdmi, 0x0E, HDMI_SLIPHDMIT_PARAM_SETTINGS_8); | ||
397 | hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9); | ||
398 | hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10); | ||
399 | } | ||
400 | |||
401 | /** | ||
402 | * sh_hdmi_avi_infoframe_setup() - Auxiliary Video Information InfoFrame CONTROL PACKET | ||
403 | */ | ||
404 | static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi) | ||
405 | { | ||
406 | /* AVI InfoFrame */ | ||
407 | hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_INDEX); | ||
408 | |||
409 | /* Packet Type = 0x82 */ | ||
410 | hdmi_write(hdmi, 0x82, HDMI_CTRL_PKT_BUF_ACCESS_HB0); | ||
411 | |||
412 | /* Version = 0x02 */ | ||
413 | hdmi_write(hdmi, 0x02, HDMI_CTRL_PKT_BUF_ACCESS_HB1); | ||
414 | |||
415 | /* Length = 13 (0x0D) */ | ||
416 | hdmi_write(hdmi, 0x0D, HDMI_CTRL_PKT_BUF_ACCESS_HB2); | ||
417 | |||
418 | /* N. A. Checksum */ | ||
419 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0); | ||
420 | |||
421 | /* | ||
422 | * Y = RGB | ||
423 | * A0 = No Data | ||
424 | * B = Bar Data not valid | ||
425 | * S = No Data | ||
426 | */ | ||
427 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB1); | ||
428 | |||
429 | /* | ||
430 | * C = No Data | ||
431 | * M = 16:9 Picture Aspect Ratio | ||
432 | * R = Same as picture aspect ratio | ||
433 | */ | ||
434 | hdmi_write(hdmi, 0x28, HDMI_CTRL_PKT_BUF_ACCESS_PB2); | ||
435 | |||
436 | /* | ||
437 | * ITC = No Data | ||
438 | * EC = xvYCC601 | ||
439 | * Q = Default (depends on video format) | ||
440 | * SC = No Known non_uniform Scaling | ||
441 | */ | ||
442 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB3); | ||
443 | |||
444 | /* | ||
445 | * VIC = 1280 x 720p: ignored if external config is used | ||
446 | * Send 2 for 720 x 480p, 16 for 1080p | ||
447 | */ | ||
448 | hdmi_write(hdmi, 4, HDMI_CTRL_PKT_BUF_ACCESS_PB4); | ||
449 | |||
450 | /* PR = No Repetition */ | ||
451 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB5); | ||
452 | |||
453 | /* Line Number of End of Top Bar (lower 8 bits) */ | ||
454 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB6); | ||
455 | |||
456 | /* Line Number of End of Top Bar (upper 8 bits) */ | ||
457 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB7); | ||
458 | |||
459 | /* Line Number of Start of Bottom Bar (lower 8 bits) */ | ||
460 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB8); | ||
461 | |||
462 | /* Line Number of Start of Bottom Bar (upper 8 bits) */ | ||
463 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB9); | ||
464 | |||
465 | /* Pixel Number of End of Left Bar (lower 8 bits) */ | ||
466 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB10); | ||
467 | |||
468 | /* Pixel Number of End of Left Bar (upper 8 bits) */ | ||
469 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB11); | ||
470 | |||
471 | /* Pixel Number of Start of Right Bar (lower 8 bits) */ | ||
472 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB12); | ||
473 | |||
474 | /* Pixel Number of Start of Right Bar (upper 8 bits) */ | ||
475 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB13); | ||
476 | } | ||
477 | |||
478 | /** | ||
479 | * sh_hdmi_audio_infoframe_setup() - Audio InfoFrame of CONTROL PACKET | ||
480 | */ | ||
481 | static void sh_hdmi_audio_infoframe_setup(struct sh_hdmi *hdmi) | ||
482 | { | ||
483 | /* Audio InfoFrame */ | ||
484 | hdmi_write(hdmi, 0x08, HDMI_CTRL_PKT_BUF_INDEX); | ||
485 | |||
486 | /* Packet Type = 0x84 */ | ||
487 | hdmi_write(hdmi, 0x84, HDMI_CTRL_PKT_BUF_ACCESS_HB0); | ||
488 | |||
489 | /* Version Number = 0x01 */ | ||
490 | hdmi_write(hdmi, 0x01, HDMI_CTRL_PKT_BUF_ACCESS_HB1); | ||
491 | |||
492 | /* 0 Length = 10 (0x0A) */ | ||
493 | hdmi_write(hdmi, 0x0A, HDMI_CTRL_PKT_BUF_ACCESS_HB2); | ||
494 | |||
495 | /* n. a. Checksum */ | ||
496 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0); | ||
497 | |||
498 | /* Audio Channel Count = Refer to Stream Header */ | ||
499 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB1); | ||
500 | |||
501 | /* Refer to Stream Header */ | ||
502 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB2); | ||
503 | |||
504 | /* Format depends on coding type (i.e. CT0...CT3) */ | ||
505 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB3); | ||
506 | |||
507 | /* Speaker Channel Allocation = Front Right + Front Left */ | ||
508 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB4); | ||
509 | |||
510 | /* Level Shift Value = 0 dB, Down - mix is permitted or no information */ | ||
511 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB5); | ||
512 | |||
513 | /* Reserved (0) */ | ||
514 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB6); | ||
515 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB7); | ||
516 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB8); | ||
517 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB9); | ||
518 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB10); | ||
519 | } | ||
520 | |||
521 | /** | ||
522 | * sh_hdmi_gamut_metadata_setup() - Gamut Metadata Packet of CONTROL PACKET | ||
523 | */ | ||
524 | static void sh_hdmi_gamut_metadata_setup(struct sh_hdmi *hdmi) | ||
525 | { | ||
526 | int i; | ||
527 | |||
528 | /* Gamut Metadata Packet */ | ||
529 | hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_INDEX); | ||
530 | |||
531 | /* Packet Type = 0x0A */ | ||
532 | hdmi_write(hdmi, 0x0A, HDMI_CTRL_PKT_BUF_ACCESS_HB0); | ||
533 | /* Gamut Packet is not used, so default value */ | ||
534 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1); | ||
535 | /* Gamut Packet is not used, so default value */ | ||
536 | hdmi_write(hdmi, 0x10, HDMI_CTRL_PKT_BUF_ACCESS_HB2); | ||
537 | |||
538 | /* GBD bytes 0 through 27 */ | ||
539 | for (i = 0; i <= 27; i++) | ||
540 | /* HDMI_CTRL_PKT_BUF_ACCESS_PB0_63H - PB27_7EH */ | ||
541 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i); | ||
542 | } | ||
543 | |||
544 | /** | ||
545 | * sh_hdmi_acp_setup() - Audio Content Protection Packet (ACP) | ||
546 | */ | ||
547 | static void sh_hdmi_acp_setup(struct sh_hdmi *hdmi) | ||
548 | { | ||
549 | int i; | ||
550 | |||
551 | /* Audio Content Protection Packet (ACP) */ | ||
552 | hdmi_write(hdmi, 0x01, HDMI_CTRL_PKT_BUF_INDEX); | ||
553 | |||
554 | /* Packet Type = 0x04 */ | ||
555 | hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_ACCESS_HB0); | ||
556 | /* ACP_Type */ | ||
557 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1); | ||
558 | /* Reserved (0) */ | ||
559 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2); | ||
560 | |||
561 | /* GBD bytes 0 through 27 */ | ||
562 | for (i = 0; i <= 27; i++) | ||
563 | /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */ | ||
564 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i); | ||
565 | } | ||
566 | |||
567 | /** | ||
568 | * sh_hdmi_isrc1_setup() - ISRC1 Packet | ||
569 | */ | ||
570 | static void sh_hdmi_isrc1_setup(struct sh_hdmi *hdmi) | ||
571 | { | ||
572 | int i; | ||
573 | |||
574 | /* ISRC1 Packet */ | ||
575 | hdmi_write(hdmi, 0x02, HDMI_CTRL_PKT_BUF_INDEX); | ||
576 | |||
577 | /* Packet Type = 0x05 */ | ||
578 | hdmi_write(hdmi, 0x05, HDMI_CTRL_PKT_BUF_ACCESS_HB0); | ||
579 | /* ISRC_Cont, ISRC_Valid, Reserved (0), ISRC_Status */ | ||
580 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1); | ||
581 | /* Reserved (0) */ | ||
582 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2); | ||
583 | |||
584 | /* PB0 UPC_EAN_ISRC_0-15 */ | ||
585 | /* Bytes PB16-PB27 shall be set to a value of 0. */ | ||
586 | for (i = 0; i <= 27; i++) | ||
587 | /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */ | ||
588 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i); | ||
589 | } | ||
590 | |||
591 | /** | ||
592 | * sh_hdmi_isrc2_setup() - ISRC2 Packet | ||
593 | */ | ||
594 | static void sh_hdmi_isrc2_setup(struct sh_hdmi *hdmi) | ||
595 | { | ||
596 | int i; | ||
597 | |||
598 | /* ISRC2 Packet */ | ||
599 | hdmi_write(hdmi, 0x03, HDMI_CTRL_PKT_BUF_INDEX); | ||
600 | |||
601 | /* HB0 Packet Type = 0x06 */ | ||
602 | hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_ACCESS_HB0); | ||
603 | /* Reserved (0) */ | ||
604 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1); | ||
605 | /* Reserved (0) */ | ||
606 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2); | ||
607 | |||
608 | /* PB0 UPC_EAN_ISRC_16-31 */ | ||
609 | /* Bytes PB16-PB27 shall be set to a value of 0. */ | ||
610 | for (i = 0; i <= 27; i++) | ||
611 | /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */ | ||
612 | hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i); | ||
613 | } | ||
614 | |||
615 | /** | ||
616 | * sh_hdmi_configure() - Initialise HDMI for output | ||
617 | */ | ||
618 | static void sh_hdmi_configure(struct sh_hdmi *hdmi) | ||
619 | { | ||
620 | /* Configure video format */ | ||
621 | sh_hdmi_video_config(hdmi); | ||
622 | |||
623 | /* Configure audio format */ | ||
624 | sh_hdmi_audio_config(hdmi); | ||
625 | |||
626 | /* Configure PHY */ | ||
627 | sh_hdmi_phy_config(hdmi); | ||
628 | |||
629 | /* Auxiliary Video Information (AVI) InfoFrame */ | ||
630 | sh_hdmi_avi_infoframe_setup(hdmi); | ||
631 | |||
632 | /* Audio InfoFrame */ | ||
633 | sh_hdmi_audio_infoframe_setup(hdmi); | ||
634 | |||
635 | /* Gamut Metadata packet */ | ||
636 | sh_hdmi_gamut_metadata_setup(hdmi); | ||
637 | |||
638 | /* Audio Content Protection (ACP) Packet */ | ||
639 | sh_hdmi_acp_setup(hdmi); | ||
640 | |||
641 | /* ISRC1 Packet */ | ||
642 | sh_hdmi_isrc1_setup(hdmi); | ||
643 | |||
644 | /* ISRC2 Packet */ | ||
645 | sh_hdmi_isrc2_setup(hdmi); | ||
646 | |||
647 | /* | ||
648 | * Control packet auto send with VSYNC control: auto send | ||
649 | * General control, Gamut metadata, ISRC, and ACP packets | ||
650 | */ | ||
651 | hdmi_write(hdmi, 0x8E, HDMI_CTRL_PKT_AUTO_SEND); | ||
652 | |||
653 | /* FIXME */ | ||
654 | msleep(10); | ||
655 | |||
656 | /* PS mode b->d, reset PLLA and PLLB */ | ||
657 | hdmi_write(hdmi, 0x4C, HDMI_SYSTEM_CTRL); | ||
658 | |||
659 | udelay(10); | ||
660 | |||
661 | hdmi_write(hdmi, 0x40, HDMI_SYSTEM_CTRL); | ||
662 | } | ||
663 | |||
664 | static void sh_hdmi_read_edid(struct sh_hdmi *hdmi) | ||
665 | { | ||
666 | struct fb_var_screeninfo *var = &hdmi->var; | ||
667 | struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; | ||
668 | struct fb_videomode *lcd_cfg = &pdata->lcd_chan->lcd_cfg; | ||
669 | unsigned long height = var->height, width = var->width; | ||
670 | int i; | ||
671 | u8 edid[128]; | ||
672 | |||
673 | /* Read EDID */ | ||
674 | pr_debug("Read back EDID code:"); | ||
675 | for (i = 0; i < 128; i++) { | ||
676 | edid[i] = hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW); | ||
677 | #ifdef DEBUG | ||
678 | if ((i % 16) == 0) { | ||
679 | printk(KERN_CONT "\n"); | ||
680 | printk(KERN_DEBUG "%02X | %02X", i, edid[i]); | ||
681 | } else { | ||
682 | printk(KERN_CONT " %02X", edid[i]); | ||
683 | } | ||
684 | #endif | ||
685 | } | ||
686 | #ifdef DEBUG | ||
687 | printk(KERN_CONT "\n"); | ||
688 | #endif | ||
689 | fb_parse_edid(edid, var); | ||
690 | pr_debug("%u-%u-%u-%u x %u-%u-%u-%u @ %lu kHz monitor detected\n", | ||
691 | var->left_margin, var->xres, var->right_margin, var->hsync_len, | ||
692 | var->upper_margin, var->yres, var->lower_margin, var->vsync_len, | ||
693 | PICOS2KHZ(var->pixclock)); | ||
694 | |||
695 | /* FIXME: Use user-provided configuration instead of EDID */ | ||
696 | var->width = width; | ||
697 | var->xres = lcd_cfg->xres; | ||
698 | var->xres_virtual = lcd_cfg->xres; | ||
699 | var->left_margin = lcd_cfg->left_margin; | ||
700 | var->right_margin = lcd_cfg->right_margin; | ||
701 | var->hsync_len = lcd_cfg->hsync_len; | ||
702 | var->height = height; | ||
703 | var->yres = lcd_cfg->yres; | ||
704 | var->yres_virtual = lcd_cfg->yres * 2; | ||
705 | var->upper_margin = lcd_cfg->upper_margin; | ||
706 | var->lower_margin = lcd_cfg->lower_margin; | ||
707 | var->vsync_len = lcd_cfg->vsync_len; | ||
708 | var->sync = lcd_cfg->sync; | ||
709 | var->pixclock = lcd_cfg->pixclock; | ||
710 | |||
711 | hdmi_external_video_param(hdmi); | ||
712 | } | ||
713 | |||
714 | static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id) | ||
715 | { | ||
716 | struct sh_hdmi *hdmi = dev_id; | ||
717 | u8 status1, status2, mask1, mask2; | ||
718 | |||
719 | /* mode_b and PLLA and PLLB reset */ | ||
720 | hdmi_write(hdmi, 0x2C, HDMI_SYSTEM_CTRL); | ||
721 | |||
722 | /* How long shall reset be held? */ | ||
723 | udelay(10); | ||
724 | |||
725 | /* mode_b and PLLA and PLLB reset release */ | ||
726 | hdmi_write(hdmi, 0x20, HDMI_SYSTEM_CTRL); | ||
727 | |||
728 | status1 = hdmi_read(hdmi, HDMI_INTERRUPT_STATUS_1); | ||
729 | status2 = hdmi_read(hdmi, HDMI_INTERRUPT_STATUS_2); | ||
730 | |||
731 | mask1 = hdmi_read(hdmi, HDMI_INTERRUPT_MASK_1); | ||
732 | mask2 = hdmi_read(hdmi, HDMI_INTERRUPT_MASK_2); | ||
733 | |||
734 | /* Correct would be to ack only set bits, but the datasheet requires 0xff */ | ||
735 | hdmi_write(hdmi, 0xFF, HDMI_INTERRUPT_STATUS_1); | ||
736 | hdmi_write(hdmi, 0xFF, HDMI_INTERRUPT_STATUS_2); | ||
737 | |||
738 | if (printk_ratelimit()) | ||
739 | pr_debug("IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x\n", | ||
740 | irq, status1, mask1, status2, mask2); | ||
741 | |||
742 | if (!((status1 & mask1) | (status2 & mask2))) { | ||
743 | return IRQ_NONE; | ||
744 | } else if (status1 & 0xc0) { | ||
745 | u8 msens; | ||
746 | |||
747 | /* Datasheet specifies 10ms... */ | ||
748 | udelay(500); | ||
749 | |||
750 | msens = hdmi_read(hdmi, HDMI_HOT_PLUG_MSENS_STATUS); | ||
751 | pr_debug("MSENS 0x%x\n", msens); | ||
752 | /* Check, if hot plug & MSENS pin status are both high */ | ||
753 | if ((msens & 0xC0) == 0xC0) { | ||
754 | /* Display plug in */ | ||
755 | hdmi->hp_state = HDMI_HOTPLUG_CONNECTED; | ||
756 | |||
757 | /* Set EDID word address */ | ||
758 | hdmi_write(hdmi, 0x00, HDMI_EDID_WORD_ADDRESS); | ||
759 | /* Set EDID segment pointer */ | ||
760 | hdmi_write(hdmi, 0x00, HDMI_EDID_SEGMENT_POINTER); | ||
761 | /* Enable EDID interrupt */ | ||
762 | hdmi_write(hdmi, 0xC6, HDMI_INTERRUPT_MASK_1); | ||
763 | } else if (!(status1 & 0x80)) { | ||
764 | /* Display unplug, beware multiple interrupts */ | ||
765 | if (hdmi->hp_state != HDMI_HOTPLUG_DISCONNECTED) | ||
766 | schedule_delayed_work(&hdmi->edid_work, 0); | ||
767 | |||
768 | hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED; | ||
769 | /* display_off will switch back to mode_a */ | ||
770 | } | ||
771 | } else if (status1 & 2) { | ||
772 | /* EDID error interrupt: retry */ | ||
773 | /* Set EDID word address */ | ||
774 | hdmi_write(hdmi, 0x00, HDMI_EDID_WORD_ADDRESS); | ||
775 | /* Set EDID segment pointer */ | ||
776 | hdmi_write(hdmi, 0x00, HDMI_EDID_SEGMENT_POINTER); | ||
777 | } else if (status1 & 4) { | ||
778 | /* Disable EDID interrupt */ | ||
779 | hdmi_write(hdmi, 0xC0, HDMI_INTERRUPT_MASK_1); | ||
780 | hdmi->hp_state = HDMI_HOTPLUG_EDID_DONE; | ||
781 | schedule_delayed_work(&hdmi->edid_work, msecs_to_jiffies(10)); | ||
782 | } | ||
783 | |||
784 | return IRQ_HANDLED; | ||
785 | } | ||
786 | |||
787 | static void hdmi_display_on(void *arg, struct fb_info *info) | ||
788 | { | ||
789 | struct sh_hdmi *hdmi = arg; | ||
790 | struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; | ||
791 | |||
792 | if (info->var.xres != 1280 || info->var.yres != 720) { | ||
793 | dev_warn(info->device, "Unsupported framebuffer geometry %ux%u\n", | ||
794 | info->var.xres, info->var.yres); | ||
795 | return; | ||
796 | } | ||
797 | |||
798 | pr_debug("%s(%p): state %x\n", __func__, pdata->lcd_dev, info->state); | ||
799 | /* | ||
800 | * FIXME: not a good place to store fb_info. And we cannot nullify it | ||
801 | * even on monitor disconnect. What should the lifecycle be? | ||
802 | */ | ||
803 | hdmi->info = info; | ||
804 | switch (hdmi->hp_state) { | ||
805 | case HDMI_HOTPLUG_EDID_DONE: | ||
806 | /* PS mode d->e. All functions are active */ | ||
807 | hdmi_write(hdmi, 0x80, HDMI_SYSTEM_CTRL); | ||
808 | pr_debug("HDMI running\n"); | ||
809 | break; | ||
810 | case HDMI_HOTPLUG_DISCONNECTED: | ||
811 | info->state = FBINFO_STATE_SUSPENDED; | ||
812 | default: | ||
813 | hdmi->var = info->var; | ||
814 | } | ||
815 | } | ||
816 | |||
817 | static void hdmi_display_off(void *arg) | ||
818 | { | ||
819 | struct sh_hdmi *hdmi = arg; | ||
820 | struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; | ||
821 | |||
822 | pr_debug("%s(%p)\n", __func__, pdata->lcd_dev); | ||
823 | /* PS mode e->a */ | ||
824 | hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL); | ||
825 | } | ||
826 | |||
827 | /* Hotplug interrupt occurred, read EDID */ | ||
828 | static void edid_work_fn(struct work_struct *work) | ||
829 | { | ||
830 | struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work); | ||
831 | struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; | ||
832 | |||
833 | pr_debug("%s(%p): begin, hotplug status %d\n", __func__, | ||
834 | pdata->lcd_dev, hdmi->hp_state); | ||
835 | |||
836 | if (!pdata->lcd_dev) | ||
837 | return; | ||
838 | |||
839 | if (hdmi->hp_state == HDMI_HOTPLUG_EDID_DONE) { | ||
840 | pm_runtime_get_sync(hdmi->dev); | ||
841 | /* A device has been plugged in */ | ||
842 | sh_hdmi_read_edid(hdmi); | ||
843 | msleep(10); | ||
844 | sh_hdmi_configure(hdmi); | ||
845 | /* Switched to another (d) power-save mode */ | ||
846 | msleep(10); | ||
847 | |||
848 | if (!hdmi->info) | ||
849 | return; | ||
850 | |||
851 | acquire_console_sem(); | ||
852 | |||
853 | /* HDMI plug in */ | ||
854 | hdmi->info->var = hdmi->var; | ||
855 | if (hdmi->info->state != FBINFO_STATE_RUNNING) | ||
856 | fb_set_suspend(hdmi->info, 0); | ||
857 | else | ||
858 | hdmi_display_on(hdmi, hdmi->info); | ||
859 | |||
860 | release_console_sem(); | ||
861 | } else { | ||
862 | if (!hdmi->info) | ||
863 | return; | ||
864 | |||
865 | acquire_console_sem(); | ||
866 | |||
867 | /* HDMI disconnect */ | ||
868 | fb_set_suspend(hdmi->info, 1); | ||
869 | |||
870 | release_console_sem(); | ||
871 | pm_runtime_put(hdmi->dev); | ||
872 | } | ||
873 | |||
874 | pr_debug("%s(%p): end\n", __func__, pdata->lcd_dev); | ||
875 | } | ||
876 | |||
877 | static int __init sh_hdmi_probe(struct platform_device *pdev) | ||
878 | { | ||
879 | struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data; | ||
880 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
881 | int irq = platform_get_irq(pdev, 0), ret; | ||
882 | struct sh_hdmi *hdmi; | ||
883 | long rate; | ||
884 | |||
885 | if (!res || !pdata || irq < 0) | ||
886 | return -ENODEV; | ||
887 | |||
888 | hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL); | ||
889 | if (!hdmi) { | ||
890 | dev_err(&pdev->dev, "Cannot allocate device data\n"); | ||
891 | return -ENOMEM; | ||
892 | } | ||
893 | |||
894 | hdmi->dev = &pdev->dev; | ||
895 | |||
896 | hdmi->hdmi_clk = clk_get(&pdev->dev, "ick"); | ||
897 | if (IS_ERR(hdmi->hdmi_clk)) { | ||
898 | ret = PTR_ERR(hdmi->hdmi_clk); | ||
899 | dev_err(&pdev->dev, "Unable to get clock: %d\n", ret); | ||
900 | goto egetclk; | ||
901 | } | ||
902 | |||
903 | rate = PICOS2KHZ(pdata->lcd_chan->lcd_cfg.pixclock) * 1000; | ||
904 | |||
905 | rate = clk_round_rate(hdmi->hdmi_clk, rate); | ||
906 | if (rate < 0) { | ||
907 | ret = rate; | ||
908 | dev_err(&pdev->dev, "Cannot get suitable rate: %ld\n", rate); | ||
909 | goto erate; | ||
910 | } | ||
911 | |||
912 | ret = clk_set_rate(hdmi->hdmi_clk, rate); | ||
913 | if (ret < 0) { | ||
914 | dev_err(&pdev->dev, "Cannot set rate %ld: %d\n", rate, ret); | ||
915 | goto erate; | ||
916 | } | ||
917 | |||
918 | pr_debug("HDMI set frequency %lu\n", rate); | ||
919 | |||
920 | ret = clk_enable(hdmi->hdmi_clk); | ||
921 | if (ret < 0) { | ||
922 | dev_err(&pdev->dev, "Cannot enable clock: %d\n", ret); | ||
923 | goto eclkenable; | ||
924 | } | ||
925 | |||
926 | dev_info(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate); | ||
927 | |||
928 | if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) { | ||
929 | dev_err(&pdev->dev, "HDMI register region already claimed\n"); | ||
930 | ret = -EBUSY; | ||
931 | goto ereqreg; | ||
932 | } | ||
933 | |||
934 | hdmi->base = ioremap(res->start, resource_size(res)); | ||
935 | if (!hdmi->base) { | ||
936 | dev_err(&pdev->dev, "HDMI register region already claimed\n"); | ||
937 | ret = -ENOMEM; | ||
938 | goto emap; | ||
939 | } | ||
940 | |||
941 | platform_set_drvdata(pdev, hdmi); | ||
942 | |||
943 | #if 1 | ||
944 | /* Product and revision IDs are 0 in sh-mobile version */ | ||
945 | dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n", | ||
946 | hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID)); | ||
947 | #endif | ||
948 | |||
949 | /* Set up LCDC callbacks */ | ||
950 | pdata->lcd_chan->board_cfg.board_data = hdmi; | ||
951 | pdata->lcd_chan->board_cfg.display_on = hdmi_display_on; | ||
952 | pdata->lcd_chan->board_cfg.display_off = hdmi_display_off; | ||
953 | |||
954 | INIT_DELAYED_WORK(&hdmi->edid_work, edid_work_fn); | ||
955 | |||
956 | pm_runtime_enable(&pdev->dev); | ||
957 | pm_runtime_resume(&pdev->dev); | ||
958 | |||
959 | ret = request_irq(irq, sh_hdmi_hotplug, 0, | ||
960 | dev_name(&pdev->dev), hdmi); | ||
961 | if (ret < 0) { | ||
962 | dev_err(&pdev->dev, "Unable to request irq: %d\n", ret); | ||
963 | goto ereqirq; | ||
964 | } | ||
965 | |||
966 | return 0; | ||
967 | |||
968 | ereqirq: | ||
969 | pm_runtime_disable(&pdev->dev); | ||
970 | iounmap(hdmi->base); | ||
971 | emap: | ||
972 | release_mem_region(res->start, resource_size(res)); | ||
973 | ereqreg: | ||
974 | clk_disable(hdmi->hdmi_clk); | ||
975 | eclkenable: | ||
976 | erate: | ||
977 | clk_put(hdmi->hdmi_clk); | ||
978 | egetclk: | ||
979 | kfree(hdmi); | ||
980 | |||
981 | return ret; | ||
982 | } | ||
983 | |||
984 | static int __exit sh_hdmi_remove(struct platform_device *pdev) | ||
985 | { | ||
986 | struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data; | ||
987 | struct sh_hdmi *hdmi = platform_get_drvdata(pdev); | ||
988 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
989 | int irq = platform_get_irq(pdev, 0); | ||
990 | |||
991 | pdata->lcd_chan->board_cfg.display_on = NULL; | ||
992 | pdata->lcd_chan->board_cfg.display_off = NULL; | ||
993 | pdata->lcd_chan->board_cfg.board_data = NULL; | ||
994 | |||
995 | free_irq(irq, hdmi); | ||
996 | pm_runtime_disable(&pdev->dev); | ||
997 | cancel_delayed_work_sync(&hdmi->edid_work); | ||
998 | clk_disable(hdmi->hdmi_clk); | ||
999 | clk_put(hdmi->hdmi_clk); | ||
1000 | iounmap(hdmi->base); | ||
1001 | release_mem_region(res->start, resource_size(res)); | ||
1002 | kfree(hdmi); | ||
1003 | |||
1004 | return 0; | ||
1005 | } | ||
1006 | |||
1007 | static struct platform_driver sh_hdmi_driver = { | ||
1008 | .remove = __exit_p(sh_hdmi_remove), | ||
1009 | .driver = { | ||
1010 | .name = "sh-mobile-hdmi", | ||
1011 | }, | ||
1012 | }; | ||
1013 | |||
1014 | static int __init sh_hdmi_init(void) | ||
1015 | { | ||
1016 | return platform_driver_probe(&sh_hdmi_driver, sh_hdmi_probe); | ||
1017 | } | ||
1018 | module_init(sh_hdmi_init); | ||
1019 | |||
1020 | static void __exit sh_hdmi_exit(void) | ||
1021 | { | ||
1022 | platform_driver_unregister(&sh_hdmi_driver); | ||
1023 | } | ||
1024 | module_exit(sh_hdmi_exit); | ||
1025 | |||
1026 | MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); | ||
1027 | MODULE_DESCRIPTION("SuperH / ARM-shmobile HDMI driver"); | ||
1028 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 12c451a711e9..d72075a9f01c 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -56,6 +56,7 @@ static int lcdc_shared_regs[] = { | |||
56 | /* per-channel registers */ | 56 | /* per-channel registers */ |
57 | enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, | 57 | enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, |
58 | LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR, | 58 | LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR, |
59 | LDHAJR, | ||
59 | NR_CH_REGS }; | 60 | NR_CH_REGS }; |
60 | 61 | ||
61 | static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { | 62 | static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { |
@@ -74,6 +75,7 @@ static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { | |||
74 | [LDVLNR] = 0x450, | 75 | [LDVLNR] = 0x450, |
75 | [LDVSYNR] = 0x454, | 76 | [LDVSYNR] = 0x454, |
76 | [LDPMR] = 0x460, | 77 | [LDPMR] = 0x460, |
78 | [LDHAJR] = 0x4a0, | ||
77 | }; | 79 | }; |
78 | 80 | ||
79 | static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = { | 81 | static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = { |
@@ -137,6 +139,7 @@ struct sh_mobile_lcdc_priv { | |||
137 | struct clk *dot_clk; | 139 | struct clk *dot_clk; |
138 | unsigned long lddckr; | 140 | unsigned long lddckr; |
139 | struct sh_mobile_lcdc_chan ch[2]; | 141 | struct sh_mobile_lcdc_chan ch[2]; |
142 | struct notifier_block notifier; | ||
140 | unsigned long saved_shared_regs[NR_SHARED_REGS]; | 143 | unsigned long saved_shared_regs[NR_SHARED_REGS]; |
141 | int started; | 144 | int started; |
142 | }; | 145 | }; |
@@ -404,6 +407,56 @@ static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv, | |||
404 | lcdc_write(priv, _LDDCKSTPR, 1); /* stop dotclock */ | 407 | lcdc_write(priv, _LDDCKSTPR, 1); /* stop dotclock */ |
405 | } | 408 | } |
406 | 409 | ||
410 | static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch) | ||
411 | { | ||
412 | struct fb_var_screeninfo *var = &ch->info->var; | ||
413 | unsigned long h_total, hsync_pos; | ||
414 | u32 tmp; | ||
415 | |||
416 | tmp = ch->ldmt1r_value; | ||
417 | tmp |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1 << 28; | ||
418 | tmp |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1 << 27; | ||
419 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DWPOL) ? 1 << 26 : 0; | ||
420 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DIPOL) ? 1 << 25 : 0; | ||
421 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DAPOL) ? 1 << 24 : 0; | ||
422 | tmp |= (ch->cfg.flags & LCDC_FLAGS_HSCNT) ? 1 << 17 : 0; | ||
423 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DWCNT) ? 1 << 16 : 0; | ||
424 | lcdc_write_chan(ch, LDMT1R, tmp); | ||
425 | |||
426 | /* setup SYS bus */ | ||
427 | lcdc_write_chan(ch, LDMT2R, ch->cfg.sys_bus_cfg.ldmt2r); | ||
428 | lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r); | ||
429 | |||
430 | /* horizontal configuration */ | ||
431 | h_total = var->xres + var->hsync_len + | ||
432 | var->left_margin + var->right_margin; | ||
433 | tmp = h_total / 8; /* HTCN */ | ||
434 | tmp |= (var->xres / 8) << 16; /* HDCN */ | ||
435 | lcdc_write_chan(ch, LDHCNR, tmp); | ||
436 | |||
437 | hsync_pos = var->xres + var->right_margin; | ||
438 | tmp = hsync_pos / 8; /* HSYNP */ | ||
439 | tmp |= (var->hsync_len / 8) << 16; /* HSYNW */ | ||
440 | lcdc_write_chan(ch, LDHSYNR, tmp); | ||
441 | |||
442 | /* vertical configuration */ | ||
443 | tmp = var->yres + var->vsync_len + | ||
444 | var->upper_margin + var->lower_margin; /* VTLN */ | ||
445 | tmp |= var->yres << 16; /* VDLN */ | ||
446 | lcdc_write_chan(ch, LDVLNR, tmp); | ||
447 | |||
448 | tmp = var->yres + var->lower_margin; /* VSYNP */ | ||
449 | tmp |= var->vsync_len << 16; /* VSYNW */ | ||
450 | lcdc_write_chan(ch, LDVSYNR, tmp); | ||
451 | |||
452 | /* Adjust horizontal synchronisation for HDMI */ | ||
453 | tmp = ((var->xres & 7) << 24) | | ||
454 | ((h_total & 7) << 16) | | ||
455 | ((var->hsync_len & 7) << 8) | | ||
456 | hsync_pos; | ||
457 | lcdc_write_chan(ch, LDHAJR, tmp); | ||
458 | } | ||
459 | |||
407 | static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | 460 | static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) |
408 | { | 461 | { |
409 | struct sh_mobile_lcdc_chan *ch; | 462 | struct sh_mobile_lcdc_chan *ch; |
@@ -470,49 +523,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
470 | if (!ch->enabled) | 523 | if (!ch->enabled) |
471 | continue; | 524 | continue; |
472 | 525 | ||
473 | tmp = ch->ldmt1r_value; | 526 | sh_mobile_lcdc_geometry(ch); |
474 | tmp |= (lcd_cfg->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1 << 28; | ||
475 | tmp |= (lcd_cfg->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1 << 27; | ||
476 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DWPOL) ? 1 << 26 : 0; | ||
477 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DIPOL) ? 1 << 25 : 0; | ||
478 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DAPOL) ? 1 << 24 : 0; | ||
479 | tmp |= (ch->cfg.flags & LCDC_FLAGS_HSCNT) ? 1 << 17 : 0; | ||
480 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DWCNT) ? 1 << 16 : 0; | ||
481 | lcdc_write_chan(ch, LDMT1R, tmp); | ||
482 | |||
483 | /* setup SYS bus */ | ||
484 | lcdc_write_chan(ch, LDMT2R, ch->cfg.sys_bus_cfg.ldmt2r); | ||
485 | lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r); | ||
486 | |||
487 | /* horizontal configuration */ | ||
488 | tmp = lcd_cfg->xres + lcd_cfg->hsync_len; | ||
489 | tmp += lcd_cfg->left_margin; | ||
490 | tmp += lcd_cfg->right_margin; | ||
491 | tmp /= 8; /* HTCN */ | ||
492 | tmp |= (lcd_cfg->xres / 8) << 16; /* HDCN */ | ||
493 | lcdc_write_chan(ch, LDHCNR, tmp); | ||
494 | |||
495 | tmp = lcd_cfg->xres; | ||
496 | tmp += lcd_cfg->right_margin; | ||
497 | tmp /= 8; /* HSYNP */ | ||
498 | tmp |= (lcd_cfg->hsync_len / 8) << 16; /* HSYNW */ | ||
499 | lcdc_write_chan(ch, LDHSYNR, tmp); | ||
500 | 527 | ||
501 | /* power supply */ | 528 | /* power supply */ |
502 | lcdc_write_chan(ch, LDPMR, 0); | 529 | lcdc_write_chan(ch, LDPMR, 0); |
503 | 530 | ||
504 | /* vertical configuration */ | ||
505 | tmp = lcd_cfg->yres + lcd_cfg->vsync_len; | ||
506 | tmp += lcd_cfg->upper_margin; | ||
507 | tmp += lcd_cfg->lower_margin; /* VTLN */ | ||
508 | tmp |= lcd_cfg->yres << 16; /* VDLN */ | ||
509 | lcdc_write_chan(ch, LDVLNR, tmp); | ||
510 | |||
511 | tmp = lcd_cfg->yres; | ||
512 | tmp += lcd_cfg->lower_margin; /* VSYNP */ | ||
513 | tmp |= lcd_cfg->vsync_len << 16; /* VSYNW */ | ||
514 | lcdc_write_chan(ch, LDVSYNR, tmp); | ||
515 | |||
516 | board_cfg = &ch->cfg.board_cfg; | 531 | board_cfg = &ch->cfg.board_cfg; |
517 | if (board_cfg->setup_sys) | 532 | if (board_cfg->setup_sys) |
518 | ret = board_cfg->setup_sys(board_cfg->board_data, ch, | 533 | ret = board_cfg->setup_sys(board_cfg->board_data, ch, |
@@ -577,7 +592,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
577 | 592 | ||
578 | board_cfg = &ch->cfg.board_cfg; | 593 | board_cfg = &ch->cfg.board_cfg; |
579 | if (board_cfg->display_on) | 594 | if (board_cfg->display_on) |
580 | board_cfg->display_on(board_cfg->board_data); | 595 | board_cfg->display_on(board_cfg->board_data, ch->info); |
581 | } | 596 | } |
582 | 597 | ||
583 | return 0; | 598 | return 0; |
@@ -943,6 +958,62 @@ static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { | |||
943 | .runtime_resume = sh_mobile_lcdc_runtime_resume, | 958 | .runtime_resume = sh_mobile_lcdc_runtime_resume, |
944 | }; | 959 | }; |
945 | 960 | ||
961 | static int sh_mobile_lcdc_notify(struct notifier_block *nb, | ||
962 | unsigned long action, void *data) | ||
963 | { | ||
964 | struct fb_event *event = data; | ||
965 | struct fb_info *info = event->info; | ||
966 | struct sh_mobile_lcdc_chan *ch = info->par; | ||
967 | struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg; | ||
968 | struct fb_var_screeninfo *var; | ||
969 | |||
970 | if (&ch->lcdc->notifier != nb) | ||
971 | return 0; | ||
972 | |||
973 | dev_dbg(info->dev, "%s(): action = %lu, data = %p\n", | ||
974 | __func__, action, event->data); | ||
975 | |||
976 | switch(action) { | ||
977 | case FB_EVENT_SUSPEND: | ||
978 | if (board_cfg->display_off) | ||
979 | board_cfg->display_off(board_cfg->board_data); | ||
980 | pm_runtime_put(info->device); | ||
981 | break; | ||
982 | case FB_EVENT_RESUME: | ||
983 | var = &info->var; | ||
984 | |||
985 | /* HDMI must be enabled before LCDC configuration */ | ||
986 | if (board_cfg->display_on) | ||
987 | board_cfg->display_on(board_cfg->board_data, ch->info); | ||
988 | |||
989 | /* Check if the new display is not in our modelist */ | ||
990 | if (ch->info->modelist.next && | ||
991 | !fb_match_mode(var, &ch->info->modelist)) { | ||
992 | struct fb_videomode mode; | ||
993 | int ret; | ||
994 | |||
995 | /* Can we handle this display? */ | ||
996 | if (var->xres > ch->cfg.lcd_cfg.xres || | ||
997 | var->yres > ch->cfg.lcd_cfg.yres) | ||
998 | return -ENOMEM; | ||
999 | |||
1000 | /* Add to the modelist */ | ||
1001 | fb_var_to_videomode(&mode, var); | ||
1002 | ret = fb_add_videomode(&mode, &ch->info->modelist); | ||
1003 | if (ret < 0) | ||
1004 | return ret; | ||
1005 | } | ||
1006 | |||
1007 | pm_runtime_get_sync(info->device); | ||
1008 | |||
1009 | sh_mobile_lcdc_geometry(ch); | ||
1010 | |||
1011 | break; | ||
1012 | } | ||
1013 | |||
1014 | return 0; | ||
1015 | } | ||
1016 | |||
946 | static int sh_mobile_lcdc_remove(struct platform_device *pdev); | 1017 | static int sh_mobile_lcdc_remove(struct platform_device *pdev); |
947 | 1018 | ||
948 | static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | 1019 | static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) |
@@ -1020,15 +1091,19 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
1020 | goto err1; | 1091 | goto err1; |
1021 | } | 1092 | } |
1022 | 1093 | ||
1094 | priv->base = ioremap_nocache(res->start, resource_size(res)); | ||
1095 | if (!priv->base) | ||
1096 | goto err1; | ||
1097 | |||
1023 | error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv); | 1098 | error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv); |
1024 | if (error) { | 1099 | if (error) { |
1025 | dev_err(&pdev->dev, "unable to setup clocks\n"); | 1100 | dev_err(&pdev->dev, "unable to setup clocks\n"); |
1026 | goto err1; | 1101 | goto err1; |
1027 | } | 1102 | } |
1028 | 1103 | ||
1029 | priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1); | ||
1030 | |||
1031 | for (i = 0; i < j; i++) { | 1104 | for (i = 0; i < j; i++) { |
1105 | struct fb_var_screeninfo *var; | ||
1106 | struct fb_videomode *lcd_cfg; | ||
1032 | cfg = &priv->ch[i].cfg; | 1107 | cfg = &priv->ch[i].cfg; |
1033 | 1108 | ||
1034 | priv->ch[i].info = framebuffer_alloc(0, &pdev->dev); | 1109 | priv->ch[i].info = framebuffer_alloc(0, &pdev->dev); |
@@ -1039,22 +1114,33 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
1039 | } | 1114 | } |
1040 | 1115 | ||
1041 | info = priv->ch[i].info; | 1116 | info = priv->ch[i].info; |
1117 | var = &info->var; | ||
1118 | lcd_cfg = &cfg->lcd_cfg; | ||
1042 | info->fbops = &sh_mobile_lcdc_ops; | 1119 | info->fbops = &sh_mobile_lcdc_ops; |
1043 | info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres; | 1120 | var->xres = var->xres_virtual = lcd_cfg->xres; |
1044 | info->var.yres = cfg->lcd_cfg.yres; | 1121 | var->yres = lcd_cfg->yres; |
1045 | /* Default Y virtual resolution is 2x panel size */ | 1122 | /* Default Y virtual resolution is 2x panel size */ |
1046 | info->var.yres_virtual = info->var.yres * 2; | 1123 | var->yres_virtual = var->yres * 2; |
1047 | info->var.width = cfg->lcd_size_cfg.width; | 1124 | var->width = cfg->lcd_size_cfg.width; |
1048 | info->var.height = cfg->lcd_size_cfg.height; | 1125 | var->height = cfg->lcd_size_cfg.height; |
1049 | info->var.activate = FB_ACTIVATE_NOW; | 1126 | var->activate = FB_ACTIVATE_NOW; |
1050 | error = sh_mobile_lcdc_set_bpp(&info->var, cfg->bpp); | 1127 | var->left_margin = lcd_cfg->left_margin; |
1128 | var->right_margin = lcd_cfg->right_margin; | ||
1129 | var->upper_margin = lcd_cfg->upper_margin; | ||
1130 | var->lower_margin = lcd_cfg->lower_margin; | ||
1131 | var->hsync_len = lcd_cfg->hsync_len; | ||
1132 | var->vsync_len = lcd_cfg->vsync_len; | ||
1133 | var->sync = lcd_cfg->sync; | ||
1134 | var->pixclock = lcd_cfg->pixclock; | ||
1135 | |||
1136 | error = sh_mobile_lcdc_set_bpp(var, cfg->bpp); | ||
1051 | if (error) | 1137 | if (error) |
1052 | break; | 1138 | break; |
1053 | 1139 | ||
1054 | info->fix = sh_mobile_lcdc_fix; | 1140 | info->fix = sh_mobile_lcdc_fix; |
1055 | info->fix.line_length = cfg->lcd_cfg.xres * (cfg->bpp / 8); | 1141 | info->fix.line_length = lcd_cfg->xres * (cfg->bpp / 8); |
1056 | info->fix.smem_len = info->fix.line_length * | 1142 | info->fix.smem_len = info->fix.line_length * |
1057 | info->var.yres_virtual; | 1143 | var->yres_virtual; |
1058 | 1144 | ||
1059 | buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len, | 1145 | buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len, |
1060 | &priv->ch[i].dma_handle, GFP_KERNEL); | 1146 | &priv->ch[i].dma_handle, GFP_KERNEL); |
@@ -1119,10 +1205,14 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
1119 | ch->cfg.bpp); | 1205 | ch->cfg.bpp); |
1120 | 1206 | ||
1121 | /* deferred io mode: disable clock to save power */ | 1207 | /* deferred io mode: disable clock to save power */ |
1122 | if (info->fbdefio) | 1208 | if (info->fbdefio || info->state == FBINFO_STATE_SUSPENDED) |
1123 | sh_mobile_lcdc_clk_off(priv); | 1209 | sh_mobile_lcdc_clk_off(priv); |
1124 | } | 1210 | } |
1125 | 1211 | ||
1212 | /* Failure ignored */ | ||
1213 | priv->notifier.notifier_call = sh_mobile_lcdc_notify; | ||
1214 | fb_register_client(&priv->notifier); | ||
1215 | |||
1126 | return 0; | 1216 | return 0; |
1127 | err1: | 1217 | err1: |
1128 | sh_mobile_lcdc_remove(pdev); | 1218 | sh_mobile_lcdc_remove(pdev); |
@@ -1136,6 +1226,8 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) | |||
1136 | struct fb_info *info; | 1226 | struct fb_info *info; |
1137 | int i; | 1227 | int i; |
1138 | 1228 | ||
1229 | fb_unregister_client(&priv->notifier); | ||
1230 | |||
1139 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) | 1231 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) |
1140 | if (priv->ch[i].info && priv->ch[i].info->dev) | 1232 | if (priv->ch[i].info && priv->ch[i].info->dev) |
1141 | unregister_framebuffer(priv->ch[i].info); | 1233 | unregister_framebuffer(priv->ch[i].info); |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index f10db6e5f3b5..522832023a69 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
@@ -186,6 +186,9 @@ | |||
186 | #define PORT_ALTERA_JTAGUART 91 | 186 | #define PORT_ALTERA_JTAGUART 91 |
187 | #define PORT_ALTERA_UART 92 | 187 | #define PORT_ALTERA_UART 92 |
188 | 188 | ||
189 | /* SH-SCI */ | ||
190 | #define PORT_SCIFB 93 | ||
191 | |||
189 | #ifdef __KERNEL__ | 192 | #ifdef __KERNEL__ |
190 | 193 | ||
191 | #include <linux/compiler.h> | 194 | #include <linux/compiler.h> |
diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 1636d1e2a5f1..875ce50719a9 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h | |||
@@ -25,6 +25,10 @@ struct clk { | |||
25 | int id; | 25 | int id; |
26 | 26 | ||
27 | struct clk *parent; | 27 | struct clk *parent; |
28 | struct clk **parent_table; /* list of parents to */ | ||
29 | unsigned short parent_num; /* choose between */ | ||
30 | unsigned char src_shift; /* source clock field in the */ | ||
31 | unsigned char src_width; /* configuration register */ | ||
28 | struct clk_ops *ops; | 32 | struct clk_ops *ops; |
29 | 33 | ||
30 | struct list_head children; | 34 | struct list_head children; |
@@ -138,13 +142,22 @@ int sh_clk_div4_enable_register(struct clk *clks, int nr, | |||
138 | int sh_clk_div4_reparent_register(struct clk *clks, int nr, | 142 | int sh_clk_div4_reparent_register(struct clk *clks, int nr, |
139 | struct clk_div4_table *table); | 143 | struct clk_div4_table *table); |
140 | 144 | ||
141 | #define SH_CLK_DIV6(_parent, _reg, _flags) \ | 145 | #define SH_CLK_DIV6_EXT(_parent, _reg, _flags, _parents, \ |
142 | { \ | 146 | _num_parents, _src_shift, _src_width) \ |
143 | .parent = _parent, \ | 147 | { \ |
144 | .enable_reg = (void __iomem *)_reg, \ | 148 | .parent = _parent, \ |
145 | .flags = _flags, \ | 149 | .enable_reg = (void __iomem *)_reg, \ |
150 | .flags = _flags, \ | ||
151 | .parent_table = _parents, \ | ||
152 | .parent_num = _num_parents, \ | ||
153 | .src_shift = _src_shift, \ | ||
154 | .src_width = _src_width, \ | ||
146 | } | 155 | } |
147 | 156 | ||
157 | #define SH_CLK_DIV6(_parent, _reg, _flags) \ | ||
158 | SH_CLK_DIV6_EXT(_parent, _reg, _flags, NULL, 0, 0, 0) | ||
159 | |||
148 | int sh_clk_div6_register(struct clk *clks, int nr); | 160 | int sh_clk_div6_register(struct clk *clks, int nr); |
161 | int sh_clk_div6_reparent_register(struct clk *clks, int nr); | ||
149 | 162 | ||
150 | #endif /* __SH_CLOCK_H */ | 163 | #endif /* __SH_CLOCK_H */ |
diff --git a/include/video/mipi_display.h b/include/video/mipi_display.h new file mode 100644 index 000000000000..ddcc8ca7316b --- /dev/null +++ b/include/video/mipi_display.h | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * Defines for Mobile Industry Processor Interface (MIPI(R)) | ||
3 | * Display Working Group standards: DSI, DCS, DBI, DPI | ||
4 | * | ||
5 | * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
6 | * Copyright (C) 2006 Nokia Corporation | ||
7 | * Author: Imre Deak <imre.deak@nokia.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | #ifndef MIPI_DISPLAY_H | ||
14 | #define MIPI_DISPLAY_H | ||
15 | |||
16 | /* MIPI DSI Processor-to-Peripheral transaction types */ | ||
17 | enum { | ||
18 | MIPI_DSI_V_SYNC_START = 0x01, | ||
19 | MIPI_DSI_V_SYNC_END = 0x11, | ||
20 | MIPI_DSI_H_SYNC_START = 0x21, | ||
21 | MIPI_DSI_H_SYNC_END = 0x31, | ||
22 | |||
23 | MIPI_DSI_COLOR_MODE_OFF = 0x02, | ||
24 | MIPI_DSI_COLOR_MODE_ON = 0x12, | ||
25 | MIPI_DSI_SHUTDOWN_PERIPHERAL = 0x22, | ||
26 | MIPI_DSI_TURN_ON_PERIPHERAL = 0x32, | ||
27 | |||
28 | MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM = 0x03, | ||
29 | MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM = 0x13, | ||
30 | MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM = 0x23, | ||
31 | |||
32 | MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM = 0x04, | ||
33 | MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM = 0x14, | ||
34 | MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM = 0x24, | ||
35 | |||
36 | MIPI_DSI_DCS_SHORT_WRITE = 0x05, | ||
37 | MIPI_DSI_DCS_SHORT_WRITE_PARAM = 0x15, | ||
38 | |||
39 | MIPI_DSI_DCS_READ = 0x06, | ||
40 | |||
41 | MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE = 0x37, | ||
42 | |||
43 | MIPI_DSI_END_OF_TRANSMISSION = 0x08, | ||
44 | |||
45 | MIPI_DSI_NULL_PACKET = 0x09, | ||
46 | MIPI_DSI_BLANKING_PACKET = 0x19, | ||
47 | MIPI_DSI_GENERIC_LONG_WRITE = 0x29, | ||
48 | MIPI_DSI_DCS_LONG_WRITE = 0x39, | ||
49 | |||
50 | MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20 = 0x0c, | ||
51 | MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24 = 0x1c, | ||
52 | MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16 = 0x2c, | ||
53 | |||
54 | MIPI_DSI_PACKED_PIXEL_STREAM_30 = 0x0d, | ||
55 | MIPI_DSI_PACKED_PIXEL_STREAM_36 = 0x1d, | ||
56 | MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12 = 0x3d, | ||
57 | |||
58 | MIPI_DSI_PACKED_PIXEL_STREAM_16 = 0x0e, | ||
59 | MIPI_DSI_PACKED_PIXEL_STREAM_18 = 0x1e, | ||
60 | MIPI_DSI_PIXEL_STREAM_3BYTE_18 = 0x2e, | ||
61 | MIPI_DSI_PACKED_PIXEL_STREAM_24 = 0x3e, | ||
62 | }; | ||
63 | |||
64 | /* MIPI DSI Peripheral-to-Processor transaction types */ | ||
65 | enum { | ||
66 | MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT = 0x02, | ||
67 | MIPI_DSI_RX_END_OF_TRANSMISSION = 0x08, | ||
68 | MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE = 0x11, | ||
69 | MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE = 0x12, | ||
70 | MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE = 0x1a, | ||
71 | MIPI_DSI_RX_DCS_LONG_READ_RESPONSE = 0x1c, | ||
72 | MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE = 0x21, | ||
73 | MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE = 0x22, | ||
74 | }; | ||
75 | |||
76 | /* MIPI DCS commands */ | ||
77 | enum { | ||
78 | MIPI_DCS_NOP = 0x00, | ||
79 | MIPI_DCS_SOFT_RESET = 0x01, | ||
80 | MIPI_DCS_GET_DISPLAY_ID = 0x04, | ||
81 | MIPI_DCS_GET_RED_CHANNEL = 0x06, | ||
82 | MIPI_DCS_GET_GREEN_CHANNEL = 0x07, | ||
83 | MIPI_DCS_GET_BLUE_CHANNEL = 0x08, | ||
84 | MIPI_DCS_GET_DISPLAY_STATUS = 0x09, | ||
85 | MIPI_DCS_GET_POWER_MODE = 0x0A, | ||
86 | MIPI_DCS_GET_ADDRESS_MODE = 0x0B, | ||
87 | MIPI_DCS_GET_PIXEL_FORMAT = 0x0C, | ||
88 | MIPI_DCS_GET_DISPLAY_MODE = 0x0D, | ||
89 | MIPI_DCS_GET_SIGNAL_MODE = 0x0E, | ||
90 | MIPI_DCS_GET_DIAGNOSTIC_RESULT = 0x0F, | ||
91 | MIPI_DCS_ENTER_SLEEP_MODE = 0x10, | ||
92 | MIPI_DCS_EXIT_SLEEP_MODE = 0x11, | ||
93 | MIPI_DCS_ENTER_PARTIAL_MODE = 0x12, | ||
94 | MIPI_DCS_ENTER_NORMAL_MODE = 0x13, | ||
95 | MIPI_DCS_EXIT_INVERT_MODE = 0x20, | ||
96 | MIPI_DCS_ENTER_INVERT_MODE = 0x21, | ||
97 | MIPI_DCS_SET_GAMMA_CURVE = 0x26, | ||
98 | MIPI_DCS_SET_DISPLAY_OFF = 0x28, | ||
99 | MIPI_DCS_SET_DISPLAY_ON = 0x29, | ||
100 | MIPI_DCS_SET_COLUMN_ADDRESS = 0x2A, | ||
101 | MIPI_DCS_SET_PAGE_ADDRESS = 0x2B, | ||
102 | MIPI_DCS_WRITE_MEMORY_START = 0x2C, | ||
103 | MIPI_DCS_WRITE_LUT = 0x2D, | ||
104 | MIPI_DCS_READ_MEMORY_START = 0x2E, | ||
105 | MIPI_DCS_SET_PARTIAL_AREA = 0x30, | ||
106 | MIPI_DCS_SET_SCROLL_AREA = 0x33, | ||
107 | MIPI_DCS_SET_TEAR_OFF = 0x34, | ||
108 | MIPI_DCS_SET_TEAR_ON = 0x35, | ||
109 | MIPI_DCS_SET_ADDRESS_MODE = 0x36, | ||
110 | MIPI_DCS_SET_SCROLL_START = 0x37, | ||
111 | MIPI_DCS_EXIT_IDLE_MODE = 0x38, | ||
112 | MIPI_DCS_ENTER_IDLE_MODE = 0x39, | ||
113 | MIPI_DCS_SET_PIXEL_FORMAT = 0x3A, | ||
114 | MIPI_DCS_WRITE_MEMORY_CONTINUE = 0x3C, | ||
115 | MIPI_DCS_READ_MEMORY_CONTINUE = 0x3E, | ||
116 | MIPI_DCS_SET_TEAR_SCANLINE = 0x44, | ||
117 | MIPI_DCS_GET_SCANLINE = 0x45, | ||
118 | MIPI_DCS_READ_DDB_START = 0xA1, | ||
119 | MIPI_DCS_READ_DDB_CONTINUE = 0xA8, | ||
120 | }; | ||
121 | |||
122 | /* MIPI DCS pixel formats */ | ||
123 | #define MIPI_DCS_PIXEL_FMT_24BIT 7 | ||
124 | #define MIPI_DCS_PIXEL_FMT_18BIT 6 | ||
125 | #define MIPI_DCS_PIXEL_FMT_16BIT 5 | ||
126 | #define MIPI_DCS_PIXEL_FMT_12BIT 3 | ||
127 | #define MIPI_DCS_PIXEL_FMT_8BIT 2 | ||
128 | #define MIPI_DCS_PIXEL_FMT_3BIT 1 | ||
129 | |||
130 | #endif | ||
diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h new file mode 100644 index 000000000000..18bca08f9f59 --- /dev/null +++ b/include/video/sh_mipi_dsi.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Public SH-mobile MIPI DSI header | ||
3 | * | ||
4 | * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #ifndef VIDEO_SH_MIPI_DSI_H | ||
11 | #define VIDEO_SH_MIPI_DSI_H | ||
12 | |||
13 | enum sh_mipi_dsi_data_fmt { | ||
14 | MIPI_RGB888, | ||
15 | MIPI_RGB565, | ||
16 | MIPI_RGB666_LP, | ||
17 | MIPI_RGB666, | ||
18 | MIPI_BGR888, | ||
19 | MIPI_BGR565, | ||
20 | MIPI_BGR666_LP, | ||
21 | MIPI_BGR666, | ||
22 | MIPI_YUYV, | ||
23 | MIPI_UYVY, | ||
24 | MIPI_YUV420_L, | ||
25 | MIPI_YUV420, | ||
26 | }; | ||
27 | |||
28 | struct sh_mobile_lcdc_chan_cfg; | ||
29 | |||
30 | struct sh_mipi_dsi_info { | ||
31 | enum sh_mipi_dsi_data_fmt data_format; | ||
32 | struct sh_mobile_lcdc_chan_cfg *lcd_chan; | ||
33 | }; | ||
34 | |||
35 | #endif | ||
diff --git a/include/video/sh_mobile_hdmi.h b/include/video/sh_mobile_hdmi.h new file mode 100644 index 000000000000..577cf18cce89 --- /dev/null +++ b/include/video/sh_mobile_hdmi.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * SH-Mobile High-Definition Multimedia Interface (HDMI) | ||
3 | * | ||
4 | * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef SH_MOBILE_HDMI_H | ||
12 | #define SH_MOBILE_HDMI_H | ||
13 | |||
14 | struct sh_mobile_lcdc_chan_cfg; | ||
15 | struct device; | ||
16 | |||
17 | struct sh_mobile_hdmi_info { | ||
18 | struct sh_mobile_lcdc_chan_cfg *lcd_chan; | ||
19 | struct device *lcd_dev; | ||
20 | }; | ||
21 | |||
22 | #endif | ||
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h index 288205457713..55d700e8566e 100644 --- a/include/video/sh_mobile_lcdc.h +++ b/include/video/sh_mobile_lcdc.h | |||
@@ -3,24 +3,27 @@ | |||
3 | 3 | ||
4 | #include <linux/fb.h> | 4 | #include <linux/fb.h> |
5 | 5 | ||
6 | enum { RGB8, /* 24bpp, 8:8:8 */ | 6 | enum { |
7 | RGB9, /* 18bpp, 9:9 */ | 7 | RGB8, /* 24bpp, 8:8:8 */ |
8 | RGB12A, /* 24bpp, 12:12 */ | 8 | RGB9, /* 18bpp, 9:9 */ |
9 | RGB12B, /* 12bpp */ | 9 | RGB12A, /* 24bpp, 12:12 */ |
10 | RGB16, /* 16bpp */ | 10 | RGB12B, /* 12bpp */ |
11 | RGB18, /* 18bpp */ | 11 | RGB16, /* 16bpp */ |
12 | RGB24, /* 24bpp */ | 12 | RGB18, /* 18bpp */ |
13 | SYS8A, /* 24bpp, 8:8:8 */ | 13 | RGB24, /* 24bpp */ |
14 | SYS8B, /* 18bpp, 8:8:2 */ | 14 | YUV422, /* 16bpp */ |
15 | SYS8C, /* 18bpp, 2:8:8 */ | 15 | SYS8A, /* 24bpp, 8:8:8 */ |
16 | SYS8D, /* 16bpp, 8:8 */ | 16 | SYS8B, /* 18bpp, 8:8:2 */ |
17 | SYS9, /* 18bpp, 9:9 */ | 17 | SYS8C, /* 18bpp, 2:8:8 */ |
18 | SYS12, /* 24bpp, 12:12 */ | 18 | SYS8D, /* 16bpp, 8:8 */ |
19 | SYS16A, /* 16bpp */ | 19 | SYS9, /* 18bpp, 9:9 */ |
20 | SYS16B, /* 18bpp, 16:2 */ | 20 | SYS12, /* 24bpp, 12:12 */ |
21 | SYS16C, /* 18bpp, 2:16 */ | 21 | SYS16A, /* 16bpp */ |
22 | SYS18, /* 18bpp */ | 22 | SYS16B, /* 18bpp, 16:2 */ |
23 | SYS24 };/* 24bpp */ | 23 | SYS16C, /* 18bpp, 2:16 */ |
24 | SYS18, /* 18bpp */ | ||
25 | SYS24, /* 24bpp */ | ||
26 | }; | ||
24 | 27 | ||
25 | enum { LCDC_CHAN_DISABLED = 0, | 28 | enum { LCDC_CHAN_DISABLED = 0, |
26 | LCDC_CHAN_MAINLCD, | 29 | LCDC_CHAN_MAINLCD, |
@@ -52,7 +55,7 @@ struct sh_mobile_lcdc_board_cfg { | |||
52 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops); | 55 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops); |
53 | void (*start_transfer)(void *board_data, void *sys_ops_handle, | 56 | void (*start_transfer)(void *board_data, void *sys_ops_handle, |
54 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops); | 57 | struct sh_mobile_lcdc_sys_bus_ops *sys_ops); |
55 | void (*display_on)(void *board_data); | 58 | void (*display_on)(void *board_data, struct fb_info *info); |
56 | void (*display_off)(void *board_data); | 59 | void (*display_off)(void *board_data); |
57 | }; | 60 | }; |
58 | 61 | ||