diff options
Diffstat (limited to 'arch/arm/plat-samsung')
24 files changed, 1807 insertions, 535 deletions
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index a0ffc77da809..a2fae4ea0936 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig | |||
@@ -13,6 +13,24 @@ config PLAT_SAMSUNG | |||
13 | help | 13 | help |
14 | Base platform code for all Samsung SoC based systems | 14 | Base platform code for all Samsung SoC based systems |
15 | 15 | ||
16 | config PLAT_S5P | ||
17 | bool | ||
18 | depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) | ||
19 | default y | ||
20 | select ARM_VIC if !ARCH_EXYNOS | ||
21 | select ARM_GIC if ARCH_EXYNOS | ||
22 | select GIC_NON_BANKED if ARCH_EXYNOS4 | ||
23 | select NO_IOPORT | ||
24 | select ARCH_REQUIRE_GPIOLIB | ||
25 | select S3C_GPIO_TRACK | ||
26 | select S5P_GPIO_DRVSTR | ||
27 | select SAMSUNG_GPIOLIB_4BIT | ||
28 | select PLAT_SAMSUNG | ||
29 | select SAMSUNG_CLKSRC | ||
30 | select SAMSUNG_IRQ_VIC_TIMER | ||
31 | help | ||
32 | Base platform code for Samsung's S5P series SoC. | ||
33 | |||
16 | if PLAT_SAMSUNG | 34 | if PLAT_SAMSUNG |
17 | 35 | ||
18 | # boot configurations | 36 | # boot configurations |
@@ -50,6 +68,14 @@ config S3C_LOWLEVEL_UART_PORT | |||
50 | this configuration should be between zero and two. The port | 68 | this configuration should be between zero and two. The port |
51 | must have been initialised by the boot-loader before use. | 69 | must have been initialised by the boot-loader before use. |
52 | 70 | ||
71 | # timer options | ||
72 | |||
73 | config S5P_HRT | ||
74 | bool | ||
75 | select SAMSUNG_DEV_PWM | ||
76 | help | ||
77 | Use the High Resolution timer support | ||
78 | |||
53 | # clock options | 79 | # clock options |
54 | 80 | ||
55 | config SAMSUNG_CLKSRC | 81 | config SAMSUNG_CLKSRC |
@@ -58,6 +84,11 @@ config SAMSUNG_CLKSRC | |||
58 | Select the clock code for the clksrc implementation | 84 | Select the clock code for the clksrc implementation |
59 | used by newer systems such as the S3C64XX. | 85 | used by newer systems such as the S3C64XX. |
60 | 86 | ||
87 | config S5P_CLOCK | ||
88 | def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) | ||
89 | help | ||
90 | Support common clock part for ARCH_S5P and ARCH_EXYNOS SoCs | ||
91 | |||
61 | # options for IRQ support | 92 | # options for IRQ support |
62 | 93 | ||
63 | config SAMSUNG_IRQ_VIC_TIMER | 94 | config SAMSUNG_IRQ_VIC_TIMER |
@@ -65,6 +96,22 @@ config SAMSUNG_IRQ_VIC_TIMER | |||
65 | help | 96 | help |
66 | Internal configuration to build the VIC timer interrupt code. | 97 | Internal configuration to build the VIC timer interrupt code. |
67 | 98 | ||
99 | config S5P_IRQ | ||
100 | def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) | ||
101 | help | ||
102 | Support common interrup part for ARCH_S5P and ARCH_EXYNOS SoCs | ||
103 | |||
104 | config S5P_EXT_INT | ||
105 | bool | ||
106 | help | ||
107 | Use the external interrupts (other than GPIO interrupts.) | ||
108 | Note: Do not choose this for S5P6440 and S5P6450. | ||
109 | |||
110 | config S5P_GPIO_INT | ||
111 | bool | ||
112 | help | ||
113 | Common code for the GPIO interrupts (other than external interrupts.) | ||
114 | |||
68 | # options for gpio configuration support | 115 | # options for gpio configuration support |
69 | 116 | ||
70 | config SAMSUNG_GPIOLIB_4BIT | 117 | config SAMSUNG_GPIOLIB_4BIT |
@@ -117,6 +164,12 @@ config S3C_GPIO_TRACK | |||
117 | Internal configuration option to enable the s3c specific gpio | 164 | Internal configuration option to enable the s3c specific gpio |
118 | chip tracking if the platform requires it. | 165 | chip tracking if the platform requires it. |
119 | 166 | ||
167 | # uart options | ||
168 | |||
169 | config S5P_DEV_UART | ||
170 | def_bool y | ||
171 | depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210) | ||
172 | |||
120 | # ADC driver | 173 | # ADC driver |
121 | 174 | ||
122 | config S3C_ADC | 175 | config S3C_ADC |
@@ -274,6 +327,76 @@ config SAMSUNG_DEV_BACKLIGHT | |||
274 | help | 327 | help |
275 | Compile in platform device definition LCD backlight with PWM Timer | 328 | Compile in platform device definition LCD backlight with PWM Timer |
276 | 329 | ||
330 | config S5P_DEV_CSIS0 | ||
331 | bool | ||
332 | help | ||
333 | Compile in platform device definitions for MIPI-CSIS channel 0 | ||
334 | |||
335 | config S5P_DEV_CSIS1 | ||
336 | bool | ||
337 | help | ||
338 | Compile in platform device definitions for MIPI-CSIS channel 1 | ||
339 | |||
340 | config S5P_DEV_FIMC0 | ||
341 | bool | ||
342 | help | ||
343 | Compile in platform device definitions for FIMC controller 0 | ||
344 | |||
345 | config S5P_DEV_FIMC1 | ||
346 | bool | ||
347 | help | ||
348 | Compile in platform device definitions for FIMC controller 1 | ||
349 | |||
350 | config S5P_DEV_FIMC2 | ||
351 | bool | ||
352 | help | ||
353 | Compile in platform device definitions for FIMC controller 2 | ||
354 | |||
355 | config S5P_DEV_FIMC3 | ||
356 | bool | ||
357 | help | ||
358 | Compile in platform device definitions for FIMC controller 3 | ||
359 | |||
360 | config S5P_DEV_FIMD0 | ||
361 | bool | ||
362 | help | ||
363 | Compile in platform device definitions for FIMD controller 0 | ||
364 | |||
365 | config S5P_DEV_G2D | ||
366 | bool | ||
367 | help | ||
368 | Compile in platform device definitions for G2D device | ||
369 | |||
370 | config S5P_DEV_I2C_HDMIPHY | ||
371 | bool | ||
372 | help | ||
373 | Compile in platform device definitions for I2C HDMIPHY controller | ||
374 | |||
375 | config S5P_DEV_JPEG | ||
376 | bool | ||
377 | help | ||
378 | Compile in platform device definitions for JPEG codec | ||
379 | |||
380 | config S5P_DEV_MFC | ||
381 | bool | ||
382 | help | ||
383 | Compile in setup memory (init) code for MFC | ||
384 | |||
385 | config S5P_DEV_ONENAND | ||
386 | bool | ||
387 | help | ||
388 | Compile in platform device definition for OneNAND controller | ||
389 | |||
390 | config S5P_DEV_TV | ||
391 | bool | ||
392 | help | ||
393 | Compile in platform device definition for TV interface | ||
394 | |||
395 | config S5P_DEV_USB_EHCI | ||
396 | bool | ||
397 | help | ||
398 | Compile in platform device definition for USB EHCI | ||
399 | |||
277 | config S3C24XX_PWM | 400 | config S3C24XX_PWM |
278 | bool "PWM device support" | 401 | bool "PWM device support" |
279 | select HAVE_PWM | 402 | select HAVE_PWM |
@@ -281,6 +404,11 @@ config S3C24XX_PWM | |||
281 | Support for exporting the PWM timer blocks via the pwm device | 404 | Support for exporting the PWM timer blocks via the pwm device |
282 | system | 405 | system |
283 | 406 | ||
407 | config S5P_SETUP_MIPIPHY | ||
408 | bool | ||
409 | help | ||
410 | Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices | ||
411 | |||
284 | # DMA | 412 | # DMA |
285 | 413 | ||
286 | config S3C_DMA | 414 | config S3C_DMA |
@@ -291,7 +419,7 @@ config S3C_DMA | |||
291 | config SAMSUNG_DMADEV | 419 | config SAMSUNG_DMADEV |
292 | bool | 420 | bool |
293 | select DMADEVICES | 421 | select DMADEVICES |
294 | select PL330_DMA if (CPU_EXYNOS4210 || CPU_S5PV210 || CPU_S5PC100 || \ | 422 | select PL330_DMA if (ARCH_EXYNOS5 || ARCH_EXYNOS4 || CPU_S5PV210 || CPU_S5PC100 || \ |
295 | CPU_S5P6450 || CPU_S5P6440) | 423 | CPU_S5P6450 || CPU_S5P6440) |
296 | select ARM_AMBA | 424 | select ARM_AMBA |
297 | help | 425 | help |
@@ -351,6 +479,18 @@ config SAMSUNG_WAKEMASK | |||
351 | and above. This code allows a set of interrupt to wakeup-mask | 479 | and above. This code allows a set of interrupt to wakeup-mask |
352 | mappings. See <plat/wakeup-mask.h> | 480 | mappings. See <plat/wakeup-mask.h> |
353 | 481 | ||
482 | config S5P_PM | ||
483 | bool | ||
484 | help | ||
485 | Common code for power management support on S5P and newer SoCs | ||
486 | Note: Do not select this for S5P6440 and S5P6450. | ||
487 | |||
488 | config S5P_SLEEP | ||
489 | bool | ||
490 | help | ||
491 | Internal config node to apply common S5P sleep management code. | ||
492 | Can be selected by S5P and newer SoCs with similar sleep procedure. | ||
493 | |||
354 | comment "Power Domain" | 494 | comment "Power Domain" |
355 | 495 | ||
356 | config SAMSUNG_PD | 496 | config SAMSUNG_PD |
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 6012366f33cb..860b2db4db15 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile | |||
@@ -13,12 +13,18 @@ obj- := | |||
13 | 13 | ||
14 | obj-y += init.o cpu.o | 14 | obj-y += init.o cpu.o |
15 | obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o | 15 | obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o |
16 | obj-$(CONFIG_S5P_HRT) += s5p-time.o | ||
17 | |||
16 | obj-y += clock.o | 18 | obj-y += clock.o |
17 | obj-y += pwm-clock.o | 19 | obj-y += pwm-clock.o |
18 | 20 | ||
19 | obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o | 21 | obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o |
22 | obj-$(CONFIG_S5P_CLOCK) += s5p-clock.o | ||
20 | 23 | ||
21 | obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o | 24 | obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o |
25 | obj-$(CONFIG_S5P_IRQ) += s5p-irq.o | ||
26 | obj-$(CONFIG_S5P_EXT_INT) += s5p-irq-eint.o | ||
27 | obj-$(CONFIG_S5P_GPIO_INT) += s5p-irq-gpioint.o | ||
22 | 28 | ||
23 | # ADC | 29 | # ADC |
24 | 30 | ||
@@ -30,9 +36,13 @@ obj-y += platformdata.o | |||
30 | 36 | ||
31 | obj-y += devs.o | 37 | obj-y += devs.o |
32 | obj-y += dev-uart.o | 38 | obj-y += dev-uart.o |
39 | obj-$(CONFIG_S5P_DEV_MFC) += s5p-dev-mfc.o | ||
40 | obj-$(CONFIG_S5P_DEV_UART) += s5p-dev-uart.o | ||
33 | 41 | ||
34 | obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o | 42 | obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o |
35 | 43 | ||
44 | obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o | ||
45 | |||
36 | # DMA support | 46 | # DMA support |
37 | 47 | ||
38 | obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o | 48 | obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o |
@@ -47,6 +57,9 @@ obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o | |||
47 | 57 | ||
48 | obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o | 58 | obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o |
49 | 59 | ||
60 | obj-$(CONFIG_S5P_PM) += s5p-pm.o s5p-irq-pm.o | ||
61 | obj-$(CONFIG_S5P_SLEEP) += s5p-sleep.o | ||
62 | |||
50 | # PD support | 63 | # PD support |
51 | 64 | ||
52 | obj-$(CONFIG_SAMSUNG_PD) += pd.o | 65 | obj-$(CONFIG_SAMSUNG_PD) += pd.o |
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 8b928f9bc1c3..1d214cb9d770 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/mmc/host.h> | 30 | #include <linux/mmc/host.h> |
31 | #include <linux/ioport.h> | 31 | #include <linux/ioport.h> |
32 | #include <linux/platform_data/s3c-hsudc.h> | 32 | #include <linux/platform_data/s3c-hsudc.h> |
33 | #include <linux/platform_data/s3c-hsotg.h> | ||
33 | 34 | ||
34 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
35 | #include <asm/pmu.h> | 36 | #include <asm/pmu.h> |
@@ -57,7 +58,6 @@ | |||
57 | #include <plat/sdhci.h> | 58 | #include <plat/sdhci.h> |
58 | #include <plat/ts.h> | 59 | #include <plat/ts.h> |
59 | #include <plat/udc.h> | 60 | #include <plat/udc.h> |
60 | #include <plat/udc-hs.h> | ||
61 | #include <plat/usb-control.h> | 61 | #include <plat/usb-control.h> |
62 | #include <plat/usb-phy.h> | 62 | #include <plat/usb-phy.h> |
63 | #include <plat/regs-iic.h> | 63 | #include <plat/regs-iic.h> |
@@ -272,16 +272,8 @@ struct platform_device s5p_device_fimc3 = { | |||
272 | 272 | ||
273 | #ifdef CONFIG_S5P_DEV_G2D | 273 | #ifdef CONFIG_S5P_DEV_G2D |
274 | static struct resource s5p_g2d_resource[] = { | 274 | static struct resource s5p_g2d_resource[] = { |
275 | [0] = { | 275 | [0] = DEFINE_RES_MEM(S5P_PA_G2D, SZ_4K), |
276 | .start = S5P_PA_G2D, | 276 | [1] = DEFINE_RES_IRQ(IRQ_2D), |
277 | .end = S5P_PA_G2D + SZ_4K - 1, | ||
278 | .flags = IORESOURCE_MEM, | ||
279 | }, | ||
280 | [1] = { | ||
281 | .start = IRQ_2D, | ||
282 | .end = IRQ_2D, | ||
283 | .flags = IORESOURCE_IRQ, | ||
284 | }, | ||
285 | }; | 277 | }; |
286 | 278 | ||
287 | struct platform_device s5p_device_g2d = { | 279 | struct platform_device s5p_device_g2d = { |
@@ -370,7 +362,6 @@ struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = { | |||
370 | .max_width = 4, | 362 | .max_width = 4, |
371 | .host_caps = (MMC_CAP_4_BIT_DATA | | 363 | .host_caps = (MMC_CAP_4_BIT_DATA | |
372 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), | 364 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), |
373 | .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, | ||
374 | }; | 365 | }; |
375 | 366 | ||
376 | struct platform_device s3c_device_hsmmc0 = { | 367 | struct platform_device s3c_device_hsmmc0 = { |
@@ -401,7 +392,6 @@ struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = { | |||
401 | .max_width = 4, | 392 | .max_width = 4, |
402 | .host_caps = (MMC_CAP_4_BIT_DATA | | 393 | .host_caps = (MMC_CAP_4_BIT_DATA | |
403 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), | 394 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), |
404 | .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, | ||
405 | }; | 395 | }; |
406 | 396 | ||
407 | struct platform_device s3c_device_hsmmc1 = { | 397 | struct platform_device s3c_device_hsmmc1 = { |
@@ -434,7 +424,6 @@ struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = { | |||
434 | .max_width = 4, | 424 | .max_width = 4, |
435 | .host_caps = (MMC_CAP_4_BIT_DATA | | 425 | .host_caps = (MMC_CAP_4_BIT_DATA | |
436 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), | 426 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), |
437 | .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, | ||
438 | }; | 427 | }; |
439 | 428 | ||
440 | struct platform_device s3c_device_hsmmc2 = { | 429 | struct platform_device s3c_device_hsmmc2 = { |
@@ -465,7 +454,6 @@ struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = { | |||
465 | .max_width = 4, | 454 | .max_width = 4, |
466 | .host_caps = (MMC_CAP_4_BIT_DATA | | 455 | .host_caps = (MMC_CAP_4_BIT_DATA | |
467 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), | 456 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), |
468 | .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, | ||
469 | }; | 457 | }; |
470 | 458 | ||
471 | struct platform_device s3c_device_hsmmc3 = { | 459 | struct platform_device s3c_device_hsmmc3 = { |
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index 787ceaca0be8..0721293fad63 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h | |||
@@ -202,7 +202,7 @@ extern struct bus_type s3c2443_subsys; | |||
202 | extern struct bus_type s3c6410_subsys; | 202 | extern struct bus_type s3c6410_subsys; |
203 | extern struct bus_type s5p64x0_subsys; | 203 | extern struct bus_type s5p64x0_subsys; |
204 | extern struct bus_type s5pv210_subsys; | 204 | extern struct bus_type s5pv210_subsys; |
205 | extern struct bus_type exynos4_subsys; | 205 | extern struct bus_type exynos_subsys; |
206 | 206 | ||
207 | extern void (*s5pc1xx_idle)(void); | 207 | extern void (*s5pc1xx_idle)(void); |
208 | 208 | ||
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 2155d4af62a3..61ca2f356c52 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h | |||
@@ -133,7 +133,8 @@ extern struct platform_device exynos4_device_pcm1; | |||
133 | extern struct platform_device exynos4_device_pcm2; | 133 | extern struct platform_device exynos4_device_pcm2; |
134 | extern struct platform_device exynos4_device_pd[]; | 134 | extern struct platform_device exynos4_device_pd[]; |
135 | extern struct platform_device exynos4_device_spdif; | 135 | extern struct platform_device exynos4_device_spdif; |
136 | extern struct platform_device exynos4_device_sysmmu; | 136 | |
137 | extern struct platform_device exynos_device_drm; | ||
137 | 138 | ||
138 | extern struct platform_device samsung_asoc_dma; | 139 | extern struct platform_device samsung_asoc_dma; |
139 | extern struct platform_device samsung_asoc_idma; | 140 | extern struct platform_device samsung_asoc_idma; |
diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h index 0670f37aaaed..d384a8016b47 100644 --- a/arch/arm/plat-samsung/include/plat/dma-pl330.h +++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h | |||
@@ -90,6 +90,7 @@ enum dma_ch { | |||
90 | DMACH_MIPI_HSI5, | 90 | DMACH_MIPI_HSI5, |
91 | DMACH_MIPI_HSI6, | 91 | DMACH_MIPI_HSI6, |
92 | DMACH_MIPI_HSI7, | 92 | DMACH_MIPI_HSI7, |
93 | DMACH_DISP1, | ||
93 | DMACH_MTOM_0, | 94 | DMACH_MTOM_0, |
94 | DMACH_MTOM_1, | 95 | DMACH_MTOM_1, |
95 | DMACH_MTOM_2, | 96 | DMACH_MTOM_2, |
diff --git a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h deleted file mode 100644 index dc90f5ede88f..000000000000 --- a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h +++ /dev/null | |||
@@ -1,379 +0,0 @@ | |||
1 | /* arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * Ben Dooks <ben@simtec.co.uk> | ||
7 | * | ||
8 | * S3C - USB2.0 Highspeed/OtG device block registers | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef __PLAT_S3C64XX_REGS_USB_HSOTG_H | ||
16 | #define __PLAT_S3C64XX_REGS_USB_HSOTG_H __FILE__ | ||
17 | |||
18 | #define S3C_HSOTG_REG(x) (x) | ||
19 | |||
20 | #define S3C_GOTGCTL S3C_HSOTG_REG(0x000) | ||
21 | #define S3C_GOTGCTL_BSESVLD (1 << 19) | ||
22 | #define S3C_GOTGCTL_ASESVLD (1 << 18) | ||
23 | #define S3C_GOTGCTL_DBNC_SHORT (1 << 17) | ||
24 | #define S3C_GOTGCTL_CONID_B (1 << 16) | ||
25 | #define S3C_GOTGCTL_DEVHNPEN (1 << 11) | ||
26 | #define S3C_GOTGCTL_HSSETHNPEN (1 << 10) | ||
27 | #define S3C_GOTGCTL_HNPREQ (1 << 9) | ||
28 | #define S3C_GOTGCTL_HSTNEGSCS (1 << 8) | ||
29 | #define S3C_GOTGCTL_SESREQ (1 << 1) | ||
30 | #define S3C_GOTGCTL_SESREQSCS (1 << 0) | ||
31 | |||
32 | #define S3C_GOTGINT S3C_HSOTG_REG(0x004) | ||
33 | #define S3C_GOTGINT_DbnceDone (1 << 19) | ||
34 | #define S3C_GOTGINT_ADevTOUTChg (1 << 18) | ||
35 | #define S3C_GOTGINT_HstNegDet (1 << 17) | ||
36 | #define S3C_GOTGINT_HstnegSucStsChng (1 << 9) | ||
37 | #define S3C_GOTGINT_SesReqSucStsChng (1 << 8) | ||
38 | #define S3C_GOTGINT_SesEndDet (1 << 2) | ||
39 | |||
40 | #define S3C_GAHBCFG S3C_HSOTG_REG(0x008) | ||
41 | #define S3C_GAHBCFG_PTxFEmpLvl (1 << 8) | ||
42 | #define S3C_GAHBCFG_NPTxFEmpLvl (1 << 7) | ||
43 | #define S3C_GAHBCFG_DMAEn (1 << 5) | ||
44 | #define S3C_GAHBCFG_HBstLen_MASK (0xf << 1) | ||
45 | #define S3C_GAHBCFG_HBstLen_SHIFT (1) | ||
46 | #define S3C_GAHBCFG_HBstLen_Single (0x0 << 1) | ||
47 | #define S3C_GAHBCFG_HBstLen_Incr (0x1 << 1) | ||
48 | #define S3C_GAHBCFG_HBstLen_Incr4 (0x3 << 1) | ||
49 | #define S3C_GAHBCFG_HBstLen_Incr8 (0x5 << 1) | ||
50 | #define S3C_GAHBCFG_HBstLen_Incr16 (0x7 << 1) | ||
51 | #define S3C_GAHBCFG_GlblIntrEn (1 << 0) | ||
52 | |||
53 | #define S3C_GUSBCFG S3C_HSOTG_REG(0x00C) | ||
54 | #define S3C_GUSBCFG_PHYLPClkSel (1 << 15) | ||
55 | #define S3C_GUSBCFG_HNPCap (1 << 9) | ||
56 | #define S3C_GUSBCFG_SRPCap (1 << 8) | ||
57 | #define S3C_GUSBCFG_PHYIf16 (1 << 3) | ||
58 | #define S3C_GUSBCFG_TOutCal_MASK (0x7 << 0) | ||
59 | #define S3C_GUSBCFG_TOutCal_SHIFT (0) | ||
60 | #define S3C_GUSBCFG_TOutCal_LIMIT (0x7) | ||
61 | #define S3C_GUSBCFG_TOutCal(_x) ((_x) << 0) | ||
62 | |||
63 | #define S3C_GRSTCTL S3C_HSOTG_REG(0x010) | ||
64 | |||
65 | #define S3C_GRSTCTL_AHBIdle (1 << 31) | ||
66 | #define S3C_GRSTCTL_DMAReq (1 << 30) | ||
67 | #define S3C_GRSTCTL_TxFNum_MASK (0x1f << 6) | ||
68 | #define S3C_GRSTCTL_TxFNum_SHIFT (6) | ||
69 | #define S3C_GRSTCTL_TxFNum_LIMIT (0x1f) | ||
70 | #define S3C_GRSTCTL_TxFNum(_x) ((_x) << 6) | ||
71 | #define S3C_GRSTCTL_TxFFlsh (1 << 5) | ||
72 | #define S3C_GRSTCTL_RxFFlsh (1 << 4) | ||
73 | #define S3C_GRSTCTL_INTknQFlsh (1 << 3) | ||
74 | #define S3C_GRSTCTL_FrmCntrRst (1 << 2) | ||
75 | #define S3C_GRSTCTL_HSftRst (1 << 1) | ||
76 | #define S3C_GRSTCTL_CSftRst (1 << 0) | ||
77 | |||
78 | #define S3C_GINTSTS S3C_HSOTG_REG(0x014) | ||
79 | #define S3C_GINTMSK S3C_HSOTG_REG(0x018) | ||
80 | |||
81 | #define S3C_GINTSTS_WkUpInt (1 << 31) | ||
82 | #define S3C_GINTSTS_SessReqInt (1 << 30) | ||
83 | #define S3C_GINTSTS_DisconnInt (1 << 29) | ||
84 | #define S3C_GINTSTS_ConIDStsChng (1 << 28) | ||
85 | #define S3C_GINTSTS_PTxFEmp (1 << 26) | ||
86 | #define S3C_GINTSTS_HChInt (1 << 25) | ||
87 | #define S3C_GINTSTS_PrtInt (1 << 24) | ||
88 | #define S3C_GINTSTS_FetSusp (1 << 22) | ||
89 | #define S3C_GINTSTS_incompIP (1 << 21) | ||
90 | #define S3C_GINTSTS_IncomplSOIN (1 << 20) | ||
91 | #define S3C_GINTSTS_OEPInt (1 << 19) | ||
92 | #define S3C_GINTSTS_IEPInt (1 << 18) | ||
93 | #define S3C_GINTSTS_EPMis (1 << 17) | ||
94 | #define S3C_GINTSTS_EOPF (1 << 15) | ||
95 | #define S3C_GINTSTS_ISOutDrop (1 << 14) | ||
96 | #define S3C_GINTSTS_EnumDone (1 << 13) | ||
97 | #define S3C_GINTSTS_USBRst (1 << 12) | ||
98 | #define S3C_GINTSTS_USBSusp (1 << 11) | ||
99 | #define S3C_GINTSTS_ErlySusp (1 << 10) | ||
100 | #define S3C_GINTSTS_GOUTNakEff (1 << 7) | ||
101 | #define S3C_GINTSTS_GINNakEff (1 << 6) | ||
102 | #define S3C_GINTSTS_NPTxFEmp (1 << 5) | ||
103 | #define S3C_GINTSTS_RxFLvl (1 << 4) | ||
104 | #define S3C_GINTSTS_SOF (1 << 3) | ||
105 | #define S3C_GINTSTS_OTGInt (1 << 2) | ||
106 | #define S3C_GINTSTS_ModeMis (1 << 1) | ||
107 | #define S3C_GINTSTS_CurMod_Host (1 << 0) | ||
108 | |||
109 | #define S3C_GRXSTSR S3C_HSOTG_REG(0x01C) | ||
110 | #define S3C_GRXSTSP S3C_HSOTG_REG(0x020) | ||
111 | |||
112 | #define S3C_GRXSTS_FN_MASK (0x7f << 25) | ||
113 | #define S3C_GRXSTS_FN_SHIFT (25) | ||
114 | |||
115 | #define S3C_GRXSTS_PktSts_MASK (0xf << 17) | ||
116 | #define S3C_GRXSTS_PktSts_SHIFT (17) | ||
117 | #define S3C_GRXSTS_PktSts_GlobalOutNAK (0x1 << 17) | ||
118 | #define S3C_GRXSTS_PktSts_OutRX (0x2 << 17) | ||
119 | #define S3C_GRXSTS_PktSts_OutDone (0x3 << 17) | ||
120 | #define S3C_GRXSTS_PktSts_SetupDone (0x4 << 17) | ||
121 | #define S3C_GRXSTS_PktSts_SetupRX (0x6 << 17) | ||
122 | |||
123 | #define S3C_GRXSTS_DPID_MASK (0x3 << 15) | ||
124 | #define S3C_GRXSTS_DPID_SHIFT (15) | ||
125 | #define S3C_GRXSTS_ByteCnt_MASK (0x7ff << 4) | ||
126 | #define S3C_GRXSTS_ByteCnt_SHIFT (4) | ||
127 | #define S3C_GRXSTS_EPNum_MASK (0xf << 0) | ||
128 | #define S3C_GRXSTS_EPNum_SHIFT (0) | ||
129 | |||
130 | #define S3C_GRXFSIZ S3C_HSOTG_REG(0x024) | ||
131 | |||
132 | #define S3C_GNPTXFSIZ S3C_HSOTG_REG(0x028) | ||
133 | |||
134 | #define S3C_GNPTXFSIZ_NPTxFDep_MASK (0xffff << 16) | ||
135 | #define S3C_GNPTXFSIZ_NPTxFDep_SHIFT (16) | ||
136 | #define S3C_GNPTXFSIZ_NPTxFDep_LIMIT (0xffff) | ||
137 | #define S3C_GNPTXFSIZ_NPTxFDep(_x) ((_x) << 16) | ||
138 | #define S3C_GNPTXFSIZ_NPTxFStAddr_MASK (0xffff << 0) | ||
139 | #define S3C_GNPTXFSIZ_NPTxFStAddr_SHIFT (0) | ||
140 | #define S3C_GNPTXFSIZ_NPTxFStAddr_LIMIT (0xffff) | ||
141 | #define S3C_GNPTXFSIZ_NPTxFStAddr(_x) ((_x) << 0) | ||
142 | |||
143 | #define S3C_GNPTXSTS S3C_HSOTG_REG(0x02C) | ||
144 | |||
145 | #define S3C_GNPTXSTS_NPtxQTop_MASK (0x7f << 24) | ||
146 | #define S3C_GNPTXSTS_NPtxQTop_SHIFT (24) | ||
147 | |||
148 | #define S3C_GNPTXSTS_NPTxQSpcAvail_MASK (0xff << 16) | ||
149 | #define S3C_GNPTXSTS_NPTxQSpcAvail_SHIFT (16) | ||
150 | #define S3C_GNPTXSTS_NPTxQSpcAvail_GET(_v) (((_v) >> 16) & 0xff) | ||
151 | |||
152 | #define S3C_GNPTXSTS_NPTxFSpcAvail_MASK (0xffff << 0) | ||
153 | #define S3C_GNPTXSTS_NPTxFSpcAvail_SHIFT (0) | ||
154 | #define S3C_GNPTXSTS_NPTxFSpcAvail_GET(_v) (((_v) >> 0) & 0xffff) | ||
155 | |||
156 | |||
157 | #define S3C_HPTXFSIZ S3C_HSOTG_REG(0x100) | ||
158 | |||
159 | #define S3C_DPTXFSIZn(_a) S3C_HSOTG_REG(0x104 + (((_a) - 1) * 4)) | ||
160 | |||
161 | #define S3C_DPTXFSIZn_DPTxFSize_MASK (0xffff << 16) | ||
162 | #define S3C_DPTXFSIZn_DPTxFSize_SHIFT (16) | ||
163 | #define S3C_DPTXFSIZn_DPTxFSize_GET(_v) (((_v) >> 16) & 0xffff) | ||
164 | #define S3C_DPTXFSIZn_DPTxFSize_LIMIT (0xffff) | ||
165 | #define S3C_DPTXFSIZn_DPTxFSize(_x) ((_x) << 16) | ||
166 | |||
167 | #define S3C_DPTXFSIZn_DPTxFStAddr_MASK (0xffff << 0) | ||
168 | #define S3C_DPTXFSIZn_DPTxFStAddr_SHIFT (0) | ||
169 | |||
170 | /* Device mode registers */ | ||
171 | #define S3C_DCFG S3C_HSOTG_REG(0x800) | ||
172 | |||
173 | #define S3C_DCFG_EPMisCnt_MASK (0x1f << 18) | ||
174 | #define S3C_DCFG_EPMisCnt_SHIFT (18) | ||
175 | #define S3C_DCFG_EPMisCnt_LIMIT (0x1f) | ||
176 | #define S3C_DCFG_EPMisCnt(_x) ((_x) << 18) | ||
177 | |||
178 | #define S3C_DCFG_PerFrInt_MASK (0x3 << 11) | ||
179 | #define S3C_DCFG_PerFrInt_SHIFT (11) | ||
180 | #define S3C_DCFG_PerFrInt_LIMIT (0x3) | ||
181 | #define S3C_DCFG_PerFrInt(_x) ((_x) << 11) | ||
182 | |||
183 | #define S3C_DCFG_DevAddr_MASK (0x7f << 4) | ||
184 | #define S3C_DCFG_DevAddr_SHIFT (4) | ||
185 | #define S3C_DCFG_DevAddr_LIMIT (0x7f) | ||
186 | #define S3C_DCFG_DevAddr(_x) ((_x) << 4) | ||
187 | |||
188 | #define S3C_DCFG_NZStsOUTHShk (1 << 2) | ||
189 | |||
190 | #define S3C_DCFG_DevSpd_MASK (0x3 << 0) | ||
191 | #define S3C_DCFG_DevSpd_SHIFT (0) | ||
192 | #define S3C_DCFG_DevSpd_HS (0x0 << 0) | ||
193 | #define S3C_DCFG_DevSpd_FS (0x1 << 0) | ||
194 | #define S3C_DCFG_DevSpd_LS (0x2 << 0) | ||
195 | #define S3C_DCFG_DevSpd_FS48 (0x3 << 0) | ||
196 | |||
197 | #define S3C_DCTL S3C_HSOTG_REG(0x804) | ||
198 | |||
199 | #define S3C_DCTL_PWROnPrgDone (1 << 11) | ||
200 | #define S3C_DCTL_CGOUTNak (1 << 10) | ||
201 | #define S3C_DCTL_SGOUTNak (1 << 9) | ||
202 | #define S3C_DCTL_CGNPInNAK (1 << 8) | ||
203 | #define S3C_DCTL_SGNPInNAK (1 << 7) | ||
204 | #define S3C_DCTL_TstCtl_MASK (0x7 << 4) | ||
205 | #define S3C_DCTL_TstCtl_SHIFT (4) | ||
206 | #define S3C_DCTL_GOUTNakSts (1 << 3) | ||
207 | #define S3C_DCTL_GNPINNakSts (1 << 2) | ||
208 | #define S3C_DCTL_SftDiscon (1 << 1) | ||
209 | #define S3C_DCTL_RmtWkUpSig (1 << 0) | ||
210 | |||
211 | #define S3C_DSTS S3C_HSOTG_REG(0x808) | ||
212 | |||
213 | #define S3C_DSTS_SOFFN_MASK (0x3fff << 8) | ||
214 | #define S3C_DSTS_SOFFN_SHIFT (8) | ||
215 | #define S3C_DSTS_SOFFN_LIMIT (0x3fff) | ||
216 | #define S3C_DSTS_SOFFN(_x) ((_x) << 8) | ||
217 | #define S3C_DSTS_ErraticErr (1 << 3) | ||
218 | #define S3C_DSTS_EnumSpd_MASK (0x3 << 1) | ||
219 | #define S3C_DSTS_EnumSpd_SHIFT (1) | ||
220 | #define S3C_DSTS_EnumSpd_HS (0x0 << 1) | ||
221 | #define S3C_DSTS_EnumSpd_FS (0x1 << 1) | ||
222 | #define S3C_DSTS_EnumSpd_LS (0x2 << 1) | ||
223 | #define S3C_DSTS_EnumSpd_FS48 (0x3 << 1) | ||
224 | |||
225 | #define S3C_DSTS_SuspSts (1 << 0) | ||
226 | |||
227 | #define S3C_DIEPMSK S3C_HSOTG_REG(0x810) | ||
228 | |||
229 | #define S3C_DIEPMSK_TxFIFOEmpty (1 << 7) | ||
230 | #define S3C_DIEPMSK_INEPNakEffMsk (1 << 6) | ||
231 | #define S3C_DIEPMSK_INTknEPMisMsk (1 << 5) | ||
232 | #define S3C_DIEPMSK_INTknTXFEmpMsk (1 << 4) | ||
233 | #define S3C_DIEPMSK_TimeOUTMsk (1 << 3) | ||
234 | #define S3C_DIEPMSK_AHBErrMsk (1 << 2) | ||
235 | #define S3C_DIEPMSK_EPDisbldMsk (1 << 1) | ||
236 | #define S3C_DIEPMSK_XferComplMsk (1 << 0) | ||
237 | |||
238 | #define S3C_DOEPMSK S3C_HSOTG_REG(0x814) | ||
239 | |||
240 | #define S3C_DOEPMSK_Back2BackSetup (1 << 6) | ||
241 | #define S3C_DOEPMSK_OUTTknEPdisMsk (1 << 4) | ||
242 | #define S3C_DOEPMSK_SetupMsk (1 << 3) | ||
243 | #define S3C_DOEPMSK_AHBErrMsk (1 << 2) | ||
244 | #define S3C_DOEPMSK_EPDisbldMsk (1 << 1) | ||
245 | #define S3C_DOEPMSK_XferComplMsk (1 << 0) | ||
246 | |||
247 | #define S3C_DAINT S3C_HSOTG_REG(0x818) | ||
248 | #define S3C_DAINTMSK S3C_HSOTG_REG(0x81C) | ||
249 | |||
250 | #define S3C_DAINT_OutEP_SHIFT (16) | ||
251 | #define S3C_DAINT_OutEP(x) (1 << ((x) + 16)) | ||
252 | #define S3C_DAINT_InEP(x) (1 << (x)) | ||
253 | |||
254 | #define S3C_DTKNQR1 S3C_HSOTG_REG(0x820) | ||
255 | #define S3C_DTKNQR2 S3C_HSOTG_REG(0x824) | ||
256 | #define S3C_DTKNQR3 S3C_HSOTG_REG(0x830) | ||
257 | #define S3C_DTKNQR4 S3C_HSOTG_REG(0x834) | ||
258 | |||
259 | #define S3C_DVBUSDIS S3C_HSOTG_REG(0x828) | ||
260 | #define S3C_DVBUSPULSE S3C_HSOTG_REG(0x82C) | ||
261 | |||
262 | #define S3C_DIEPCTL0 S3C_HSOTG_REG(0x900) | ||
263 | #define S3C_DOEPCTL0 S3C_HSOTG_REG(0xB00) | ||
264 | #define S3C_DIEPCTL(_a) S3C_HSOTG_REG(0x900 + ((_a) * 0x20)) | ||
265 | #define S3C_DOEPCTL(_a) S3C_HSOTG_REG(0xB00 + ((_a) * 0x20)) | ||
266 | |||
267 | /* EP0 specialness: | ||
268 | * bits[29..28] - reserved (no SetD0PID, SetD1PID) | ||
269 | * bits[25..22] - should always be zero, this isn't a periodic endpoint | ||
270 | * bits[10..0] - MPS setting differenct for EP0 | ||
271 | */ | ||
272 | #define S3C_D0EPCTL_MPS_MASK (0x3 << 0) | ||
273 | #define S3C_D0EPCTL_MPS_SHIFT (0) | ||
274 | #define S3C_D0EPCTL_MPS_64 (0x0 << 0) | ||
275 | #define S3C_D0EPCTL_MPS_32 (0x1 << 0) | ||
276 | #define S3C_D0EPCTL_MPS_16 (0x2 << 0) | ||
277 | #define S3C_D0EPCTL_MPS_8 (0x3 << 0) | ||
278 | |||
279 | #define S3C_DxEPCTL_EPEna (1 << 31) | ||
280 | #define S3C_DxEPCTL_EPDis (1 << 30) | ||
281 | #define S3C_DxEPCTL_SetD1PID (1 << 29) | ||
282 | #define S3C_DxEPCTL_SetOddFr (1 << 29) | ||
283 | #define S3C_DxEPCTL_SetD0PID (1 << 28) | ||
284 | #define S3C_DxEPCTL_SetEvenFr (1 << 28) | ||
285 | #define S3C_DxEPCTL_SNAK (1 << 27) | ||
286 | #define S3C_DxEPCTL_CNAK (1 << 26) | ||
287 | #define S3C_DxEPCTL_TxFNum_MASK (0xf << 22) | ||
288 | #define S3C_DxEPCTL_TxFNum_SHIFT (22) | ||
289 | #define S3C_DxEPCTL_TxFNum_LIMIT (0xf) | ||
290 | #define S3C_DxEPCTL_TxFNum(_x) ((_x) << 22) | ||
291 | |||
292 | #define S3C_DxEPCTL_Stall (1 << 21) | ||
293 | #define S3C_DxEPCTL_Snp (1 << 20) | ||
294 | #define S3C_DxEPCTL_EPType_MASK (0x3 << 18) | ||
295 | #define S3C_DxEPCTL_EPType_SHIFT (18) | ||
296 | #define S3C_DxEPCTL_EPType_Control (0x0 << 18) | ||
297 | #define S3C_DxEPCTL_EPType_Iso (0x1 << 18) | ||
298 | #define S3C_DxEPCTL_EPType_Bulk (0x2 << 18) | ||
299 | #define S3C_DxEPCTL_EPType_Intterupt (0x3 << 18) | ||
300 | |||
301 | #define S3C_DxEPCTL_NAKsts (1 << 17) | ||
302 | #define S3C_DxEPCTL_DPID (1 << 16) | ||
303 | #define S3C_DxEPCTL_EOFrNum (1 << 16) | ||
304 | #define S3C_DxEPCTL_USBActEp (1 << 15) | ||
305 | #define S3C_DxEPCTL_NextEp_MASK (0xf << 11) | ||
306 | #define S3C_DxEPCTL_NextEp_SHIFT (11) | ||
307 | #define S3C_DxEPCTL_NextEp_LIMIT (0xf) | ||
308 | #define S3C_DxEPCTL_NextEp(_x) ((_x) << 11) | ||
309 | |||
310 | #define S3C_DxEPCTL_MPS_MASK (0x7ff << 0) | ||
311 | #define S3C_DxEPCTL_MPS_SHIFT (0) | ||
312 | #define S3C_DxEPCTL_MPS_LIMIT (0x7ff) | ||
313 | #define S3C_DxEPCTL_MPS(_x) ((_x) << 0) | ||
314 | |||
315 | #define S3C_DIEPINT(_a) S3C_HSOTG_REG(0x908 + ((_a) * 0x20)) | ||
316 | #define S3C_DOEPINT(_a) S3C_HSOTG_REG(0xB08 + ((_a) * 0x20)) | ||
317 | |||
318 | #define S3C_DxEPINT_INEPNakEff (1 << 6) | ||
319 | #define S3C_DxEPINT_Back2BackSetup (1 << 6) | ||
320 | #define S3C_DxEPINT_INTknEPMis (1 << 5) | ||
321 | #define S3C_DxEPINT_INTknTXFEmp (1 << 4) | ||
322 | #define S3C_DxEPINT_OUTTknEPdis (1 << 4) | ||
323 | #define S3C_DxEPINT_Timeout (1 << 3) | ||
324 | #define S3C_DxEPINT_Setup (1 << 3) | ||
325 | #define S3C_DxEPINT_AHBErr (1 << 2) | ||
326 | #define S3C_DxEPINT_EPDisbld (1 << 1) | ||
327 | #define S3C_DxEPINT_XferCompl (1 << 0) | ||
328 | |||
329 | #define S3C_DIEPTSIZ0 S3C_HSOTG_REG(0x910) | ||
330 | |||
331 | #define S3C_DIEPTSIZ0_PktCnt_MASK (0x3 << 19) | ||
332 | #define S3C_DIEPTSIZ0_PktCnt_SHIFT (19) | ||
333 | #define S3C_DIEPTSIZ0_PktCnt_LIMIT (0x3) | ||
334 | #define S3C_DIEPTSIZ0_PktCnt(_x) ((_x) << 19) | ||
335 | |||
336 | #define S3C_DIEPTSIZ0_XferSize_MASK (0x7f << 0) | ||
337 | #define S3C_DIEPTSIZ0_XferSize_SHIFT (0) | ||
338 | #define S3C_DIEPTSIZ0_XferSize_LIMIT (0x7f) | ||
339 | #define S3C_DIEPTSIZ0_XferSize(_x) ((_x) << 0) | ||
340 | |||
341 | |||
342 | #define DOEPTSIZ0 S3C_HSOTG_REG(0xB10) | ||
343 | #define S3C_DOEPTSIZ0_SUPCnt_MASK (0x3 << 29) | ||
344 | #define S3C_DOEPTSIZ0_SUPCnt_SHIFT (29) | ||
345 | #define S3C_DOEPTSIZ0_SUPCnt_LIMIT (0x3) | ||
346 | #define S3C_DOEPTSIZ0_SUPCnt(_x) ((_x) << 29) | ||
347 | |||
348 | #define S3C_DOEPTSIZ0_PktCnt (1 << 19) | ||
349 | #define S3C_DOEPTSIZ0_XferSize_MASK (0x7f << 0) | ||
350 | #define S3C_DOEPTSIZ0_XferSize_SHIFT (0) | ||
351 | |||
352 | #define S3C_DIEPTSIZ(_a) S3C_HSOTG_REG(0x910 + ((_a) * 0x20)) | ||
353 | #define S3C_DOEPTSIZ(_a) S3C_HSOTG_REG(0xB10 + ((_a) * 0x20)) | ||
354 | |||
355 | #define S3C_DxEPTSIZ_MC_MASK (0x3 << 29) | ||
356 | #define S3C_DxEPTSIZ_MC_SHIFT (29) | ||
357 | #define S3C_DxEPTSIZ_MC_LIMIT (0x3) | ||
358 | #define S3C_DxEPTSIZ_MC(_x) ((_x) << 29) | ||
359 | |||
360 | #define S3C_DxEPTSIZ_PktCnt_MASK (0x3ff << 19) | ||
361 | #define S3C_DxEPTSIZ_PktCnt_SHIFT (19) | ||
362 | #define S3C_DxEPTSIZ_PktCnt_GET(_v) (((_v) >> 19) & 0x3ff) | ||
363 | #define S3C_DxEPTSIZ_PktCnt_LIMIT (0x3ff) | ||
364 | #define S3C_DxEPTSIZ_PktCnt(_x) ((_x) << 19) | ||
365 | |||
366 | #define S3C_DxEPTSIZ_XferSize_MASK (0x7ffff << 0) | ||
367 | #define S3C_DxEPTSIZ_XferSize_SHIFT (0) | ||
368 | #define S3C_DxEPTSIZ_XferSize_GET(_v) (((_v) >> 0) & 0x7ffff) | ||
369 | #define S3C_DxEPTSIZ_XferSize_LIMIT (0x7ffff) | ||
370 | #define S3C_DxEPTSIZ_XferSize(_x) ((_x) << 0) | ||
371 | |||
372 | |||
373 | #define S3C_DIEPDMA(_a) S3C_HSOTG_REG(0x914 + ((_a) * 0x20)) | ||
374 | #define S3C_DOEPDMA(_a) S3C_HSOTG_REG(0xB14 + ((_a) * 0x20)) | ||
375 | #define S3C_DTXFSTS(_a) S3C_HSOTG_REG(0x918 + ((_a) * 0x20)) | ||
376 | |||
377 | #define S3C_EPFIFO(_a) S3C_HSOTG_REG(0x1000 + ((_a) * 0x1000)) | ||
378 | |||
379 | #endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_H */ | ||
diff --git a/arch/arm/plat-samsung/include/plat/s3c2416.h b/arch/arm/plat-samsung/include/plat/s3c2416.h index de2b5bdc5ebd..7178e338e25e 100644 --- a/arch/arm/plat-samsung/include/plat/s3c2416.h +++ b/arch/arm/plat-samsung/include/plat/s3c2416.h | |||
@@ -24,6 +24,9 @@ extern void s3c2416_init_clocks(int xtal); | |||
24 | extern int s3c2416_baseclk_add(void); | 24 | extern int s3c2416_baseclk_add(void); |
25 | 25 | ||
26 | extern void s3c2416_restart(char mode, const char *cmd); | 26 | extern void s3c2416_restart(char mode, const char *cmd); |
27 | |||
28 | extern struct syscore_ops s3c2416_irq_syscore_ops; | ||
29 | |||
27 | #else | 30 | #else |
28 | #define s3c2416_init_clocks NULL | 31 | #define s3c2416_init_clocks NULL |
29 | #define s3c2416_init_uarts NULL | 32 | #define s3c2416_init_uarts NULL |
diff --git a/arch/arm/plat-samsung/include/plat/s5p-clock.h b/arch/arm/plat-samsung/include/plat/s5p-clock.h index 1de4b32f98e9..8364b4bea8b8 100644 --- a/arch/arm/plat-samsung/include/plat/s5p-clock.h +++ b/arch/arm/plat-samsung/include/plat/s5p-clock.h | |||
@@ -32,8 +32,10 @@ extern struct clk clk_48m; | |||
32 | extern struct clk s5p_clk_27m; | 32 | extern struct clk s5p_clk_27m; |
33 | extern struct clk clk_fout_apll; | 33 | extern struct clk clk_fout_apll; |
34 | extern struct clk clk_fout_bpll; | 34 | extern struct clk clk_fout_bpll; |
35 | extern struct clk clk_fout_bpll_div2; | ||
35 | extern struct clk clk_fout_cpll; | 36 | extern struct clk clk_fout_cpll; |
36 | extern struct clk clk_fout_mpll; | 37 | extern struct clk clk_fout_mpll; |
38 | extern struct clk clk_fout_mpll_div2; | ||
37 | extern struct clk clk_fout_epll; | 39 | extern struct clk clk_fout_epll; |
38 | extern struct clk clk_fout_dpll; | 40 | extern struct clk clk_fout_dpll; |
39 | extern struct clk clk_fout_vpll; | 41 | extern struct clk clk_fout_vpll; |
@@ -42,8 +44,10 @@ extern struct clk clk_vpll; | |||
42 | 44 | ||
43 | extern struct clksrc_sources clk_src_apll; | 45 | extern struct clksrc_sources clk_src_apll; |
44 | extern struct clksrc_sources clk_src_bpll; | 46 | extern struct clksrc_sources clk_src_bpll; |
47 | extern struct clksrc_sources clk_src_bpll_fout; | ||
45 | extern struct clksrc_sources clk_src_cpll; | 48 | extern struct clksrc_sources clk_src_cpll; |
46 | extern struct clksrc_sources clk_src_mpll; | 49 | extern struct clksrc_sources clk_src_mpll; |
50 | extern struct clksrc_sources clk_src_mpll_fout; | ||
47 | extern struct clksrc_sources clk_src_epll; | 51 | extern struct clksrc_sources clk_src_epll; |
48 | extern struct clksrc_sources clk_src_dpll; | 52 | extern struct clksrc_sources clk_src_dpll; |
49 | 53 | ||
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h index 317e246ffc56..151cc9195cf6 100644 --- a/arch/arm/plat-samsung/include/plat/sdhci.h +++ b/arch/arm/plat-samsung/include/plat/sdhci.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #ifndef __PLAT_S3C_SDHCI_H | 18 | #ifndef __PLAT_S3C_SDHCI_H |
19 | #define __PLAT_S3C_SDHCI_H __FILE__ | 19 | #define __PLAT_S3C_SDHCI_H __FILE__ |
20 | 20 | ||
21 | #include <plat/devs.h> | ||
22 | |||
21 | struct platform_device; | 23 | struct platform_device; |
22 | struct mmc_host; | 24 | struct mmc_host; |
23 | struct mmc_card; | 25 | struct mmc_card; |
@@ -31,18 +33,12 @@ enum cd_types { | |||
31 | S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */ | 33 | S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */ |
32 | }; | 34 | }; |
33 | 35 | ||
34 | enum clk_types { | ||
35 | S3C_SDHCI_CLK_DIV_INTERNAL, /* use mmc internal clock divider */ | ||
36 | S3C_SDHCI_CLK_DIV_EXTERNAL, /* use external clock divider */ | ||
37 | }; | ||
38 | |||
39 | /** | 36 | /** |
40 | * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI | 37 | * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI |
41 | * @max_width: The maximum number of data bits supported. | 38 | * @max_width: The maximum number of data bits supported. |
42 | * @host_caps: Standard MMC host capabilities bit field. | 39 | * @host_caps: Standard MMC host capabilities bit field. |
43 | * @host_caps2: The second standard MMC host capabilities bit field. | 40 | * @host_caps2: The second standard MMC host capabilities bit field. |
44 | * @cd_type: Type of Card Detection method (see cd_types enum above) | 41 | * @cd_type: Type of Card Detection method (see cd_types enum above) |
45 | * @clk_type: Type of clock divider method (see clk_types enum above) | ||
46 | * @ext_cd_init: Initialize external card detect subsystem. Called on | 42 | * @ext_cd_init: Initialize external card detect subsystem. Called on |
47 | * sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL. | 43 | * sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL. |
48 | * notify_func argument is a callback to the sdhci-s3c driver | 44 | * notify_func argument is a callback to the sdhci-s3c driver |
@@ -67,7 +63,6 @@ struct s3c_sdhci_platdata { | |||
67 | unsigned int host_caps2; | 63 | unsigned int host_caps2; |
68 | unsigned int pm_caps; | 64 | unsigned int pm_caps; |
69 | enum cd_types cd_type; | 65 | enum cd_types cd_type; |
70 | enum clk_types clk_type; | ||
71 | 66 | ||
72 | int ext_cd_gpio; | 67 | int ext_cd_gpio; |
73 | bool ext_cd_gpio_invert; | 68 | bool ext_cd_gpio_invert; |
@@ -356,4 +351,30 @@ static inline void exynos4_default_sdhci3(void) { } | |||
356 | 351 | ||
357 | #endif /* CONFIG_EXYNOS4_SETUP_SDHCI */ | 352 | #endif /* CONFIG_EXYNOS4_SETUP_SDHCI */ |
358 | 353 | ||
354 | static inline void s3c_sdhci_setname(int id, char *name) | ||
355 | { | ||
356 | switch (id) { | ||
357 | #ifdef CONFIG_S3C_DEV_HSMMC | ||
358 | case 0: | ||
359 | s3c_device_hsmmc0.name = name; | ||
360 | break; | ||
361 | #endif | ||
362 | #ifdef CONFIG_S3C_DEV_HSMMC1 | ||
363 | case 1: | ||
364 | s3c_device_hsmmc1.name = name; | ||
365 | break; | ||
366 | #endif | ||
367 | #ifdef CONFIG_S3C_DEV_HSMMC2 | ||
368 | case 2: | ||
369 | s3c_device_hsmmc2.name = name; | ||
370 | break; | ||
371 | #endif | ||
372 | #ifdef CONFIG_S3C_DEV_HSMMC3 | ||
373 | case 3: | ||
374 | s3c_device_hsmmc3.name = name; | ||
375 | break; | ||
376 | #endif | ||
377 | } | ||
378 | } | ||
379 | |||
359 | #endif /* __PLAT_S3C_SDHCI_H */ | 380 | #endif /* __PLAT_S3C_SDHCI_H */ |
diff --git a/arch/arm/plat-samsung/include/plat/sysmmu.h b/arch/arm/plat-samsung/include/plat/sysmmu.h deleted file mode 100644 index 5fe8ee01a5ba..000000000000 --- a/arch/arm/plat-samsung/include/plat/sysmmu.h +++ /dev/null | |||
@@ -1,95 +0,0 @@ | |||
1 | /* linux/arch/arm/plat-samsung/include/plat/sysmmu.h | ||
2 | * | ||
3 | * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com | ||
5 | * | ||
6 | * Samsung System MMU driver for S5P platform | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __PLAT_SAMSUNG_SYSMMU_H | ||
14 | #define __PLAT_SAMSUNG_SYSMMU_H __FILE__ | ||
15 | |||
16 | enum S5P_SYSMMU_INTERRUPT_TYPE { | ||
17 | SYSMMU_PAGEFAULT, | ||
18 | SYSMMU_AR_MULTIHIT, | ||
19 | SYSMMU_AW_MULTIHIT, | ||
20 | SYSMMU_BUSERROR, | ||
21 | SYSMMU_AR_SECURITY, | ||
22 | SYSMMU_AR_ACCESS, | ||
23 | SYSMMU_AW_SECURITY, | ||
24 | SYSMMU_AW_PROTECTION, /* 7 */ | ||
25 | SYSMMU_FAULTS_NUM | ||
26 | }; | ||
27 | |||
28 | #ifdef CONFIG_S5P_SYSTEM_MMU | ||
29 | |||
30 | #include <mach/sysmmu.h> | ||
31 | |||
32 | /** | ||
33 | * s5p_sysmmu_enable() - enable system mmu of ip | ||
34 | * @ips: The ip connected system mmu. | ||
35 | * #pgd: Base physical address of the 1st level page table | ||
36 | * | ||
37 | * This function enable system mmu to transfer address | ||
38 | * from virtual address to physical address | ||
39 | */ | ||
40 | void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd); | ||
41 | |||
42 | /** | ||
43 | * s5p_sysmmu_disable() - disable sysmmu mmu of ip | ||
44 | * @ips: The ip connected system mmu. | ||
45 | * | ||
46 | * This function disable system mmu to transfer address | ||
47 | * from virtual address to physical address | ||
48 | */ | ||
49 | void s5p_sysmmu_disable(sysmmu_ips ips); | ||
50 | |||
51 | /** | ||
52 | * s5p_sysmmu_set_tablebase_pgd() - set page table base address to refer page table | ||
53 | * @ips: The ip connected system mmu. | ||
54 | * @pgd: The page table base address. | ||
55 | * | ||
56 | * This function set page table base address | ||
57 | * When system mmu transfer address from virtaul address to physical address, | ||
58 | * system mmu refer address information from page table | ||
59 | */ | ||
60 | void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd); | ||
61 | |||
62 | /** | ||
63 | * s5p_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu | ||
64 | * @ips: The ip connected system mmu. | ||
65 | * | ||
66 | * This function flush all TLB entry in system mmu | ||
67 | */ | ||
68 | void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips); | ||
69 | |||
70 | /** s5p_sysmmu_set_fault_handler() - Fault handler for System MMUs | ||
71 | * @itype: type of fault. | ||
72 | * @pgtable_base: the physical address of page table base. This is 0 if @ips is | ||
73 | * SYSMMU_BUSERROR. | ||
74 | * @fault_addr: the device (virtual) address that the System MMU tried to | ||
75 | * translated. This is 0 if @ips is SYSMMU_BUSERROR. | ||
76 | * Called when interrupt occurred by the System MMUs | ||
77 | * The device drivers of peripheral devices that has a System MMU can implement | ||
78 | * a fault handler to resolve address translation fault by System MMU. | ||
79 | * The meanings of return value and parameters are described below. | ||
80 | |||
81 | * return value: non-zero if the fault is correctly resolved. | ||
82 | * zero if the fault is not handled. | ||
83 | */ | ||
84 | void s5p_sysmmu_set_fault_handler(sysmmu_ips ips, | ||
85 | int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype, | ||
86 | unsigned long pgtable_base, | ||
87 | unsigned long fault_addr)); | ||
88 | #else | ||
89 | #define s5p_sysmmu_enable(ips, pgd) do { } while (0) | ||
90 | #define s5p_sysmmu_disable(ips) do { } while (0) | ||
91 | #define s5p_sysmmu_set_tablebase_pgd(ips, pgd) do { } while (0) | ||
92 | #define s5p_sysmmu_tlb_invalidate(ips) do { } while (0) | ||
93 | #define s5p_sysmmu_set_fault_handler(ips, handler) do { } while (0) | ||
94 | #endif | ||
95 | #endif /* __ASM_PLAT_SYSMMU_H */ | ||
diff --git a/arch/arm/plat-samsung/include/plat/udc-hs.h b/arch/arm/plat-samsung/include/plat/udc-hs.h deleted file mode 100644 index c9e3667cb2b1..000000000000 --- a/arch/arm/plat-samsung/include/plat/udc-hs.h +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | /* arch/arm/plat-s3c/include/plat/udc-hs.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * http://armlinux.simtec.co.uk/ | ||
7 | * | ||
8 | * S3C USB2.0 High-speed / OtG platform information | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | enum s3c_hsotg_dmamode { | ||
16 | S3C_HSOTG_DMA_NONE, /* do not use DMA at-all */ | ||
17 | S3C_HSOTG_DMA_ONLY, /* always use DMA */ | ||
18 | S3C_HSOTG_DMA_DRV, /* DMA is chosen by driver */ | ||
19 | }; | ||
20 | |||
21 | /** | ||
22 | * struct s3c_hsotg_plat - platform data for high-speed otg/udc | ||
23 | * @dma: Whether to use DMA or not. | ||
24 | * @is_osc: The clock source is an oscillator, not a crystal | ||
25 | */ | ||
26 | struct s3c_hsotg_plat { | ||
27 | enum s3c_hsotg_dmamode dma; | ||
28 | unsigned int is_osc : 1; | ||
29 | |||
30 | int (*phy_init)(struct platform_device *pdev, int type); | ||
31 | int (*phy_exit)(struct platform_device *pdev, int type); | ||
32 | }; | ||
33 | |||
34 | extern void s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd); | ||
diff --git a/arch/arm/plat-samsung/platformdata.c b/arch/arm/plat-samsung/platformdata.c index fa78aa710ed1..b430e9946287 100644 --- a/arch/arm/plat-samsung/platformdata.c +++ b/arch/arm/plat-samsung/platformdata.c | |||
@@ -57,6 +57,4 @@ void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd, | |||
57 | set->host_caps2 |= pd->host_caps2; | 57 | set->host_caps2 |= pd->host_caps2; |
58 | if (pd->pm_caps) | 58 | if (pd->pm_caps) |
59 | set->pm_caps |= pd->pm_caps; | 59 | set->pm_caps |= pd->pm_caps; |
60 | if (pd->clk_type) | ||
61 | set->clk_type = pd->clk_type; | ||
62 | } | 60 | } |
diff --git a/arch/arm/plat-samsung/s5p-clock.c b/arch/arm/plat-samsung/s5p-clock.c new file mode 100644 index 000000000000..031a61899bef --- /dev/null +++ b/arch/arm/plat-samsung/s5p-clock.c | |||
@@ -0,0 +1,293 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com/ | ||
4 | * | ||
5 | * S5P - Common clock support | ||
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/init.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/list.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/device.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <asm/div64.h> | ||
22 | |||
23 | #include <mach/regs-clock.h> | ||
24 | |||
25 | #include <plat/clock.h> | ||
26 | #include <plat/clock-clksrc.h> | ||
27 | #include <plat/s5p-clock.h> | ||
28 | |||
29 | /* fin_apll, fin_mpll and fin_epll are all the same clock, which we call | ||
30 | * clk_ext_xtal_mux. | ||
31 | */ | ||
32 | struct clk clk_ext_xtal_mux = { | ||
33 | .name = "ext_xtal", | ||
34 | .id = -1, | ||
35 | }; | ||
36 | |||
37 | struct clk clk_xusbxti = { | ||
38 | .name = "xusbxti", | ||
39 | .id = -1, | ||
40 | }; | ||
41 | |||
42 | struct clk s5p_clk_27m = { | ||
43 | .name = "clk_27m", | ||
44 | .id = -1, | ||
45 | .rate = 27000000, | ||
46 | }; | ||
47 | |||
48 | /* 48MHz USB Phy clock output */ | ||
49 | struct clk clk_48m = { | ||
50 | .name = "clk_48m", | ||
51 | .id = -1, | ||
52 | .rate = 48000000, | ||
53 | }; | ||
54 | |||
55 | /* APLL clock output | ||
56 | * No need .ctrlbit, this is always on | ||
57 | */ | ||
58 | struct clk clk_fout_apll = { | ||
59 | .name = "fout_apll", | ||
60 | .id = -1, | ||
61 | }; | ||
62 | |||
63 | /* BPLL clock output */ | ||
64 | |||
65 | struct clk clk_fout_bpll = { | ||
66 | .name = "fout_bpll", | ||
67 | .id = -1, | ||
68 | }; | ||
69 | |||
70 | struct clk clk_fout_bpll_div2 = { | ||
71 | .name = "fout_bpll_div2", | ||
72 | .id = -1, | ||
73 | }; | ||
74 | |||
75 | /* CPLL clock output */ | ||
76 | |||
77 | struct clk clk_fout_cpll = { | ||
78 | .name = "fout_cpll", | ||
79 | .id = -1, | ||
80 | }; | ||
81 | |||
82 | /* MPLL clock output | ||
83 | * No need .ctrlbit, this is always on | ||
84 | */ | ||
85 | struct clk clk_fout_mpll = { | ||
86 | .name = "fout_mpll", | ||
87 | .id = -1, | ||
88 | }; | ||
89 | |||
90 | struct clk clk_fout_mpll_div2 = { | ||
91 | .name = "fout_mpll_div2", | ||
92 | .id = -1, | ||
93 | }; | ||
94 | |||
95 | /* EPLL clock output */ | ||
96 | struct clk clk_fout_epll = { | ||
97 | .name = "fout_epll", | ||
98 | .id = -1, | ||
99 | .ctrlbit = (1 << 31), | ||
100 | }; | ||
101 | |||
102 | /* DPLL clock output */ | ||
103 | struct clk clk_fout_dpll = { | ||
104 | .name = "fout_dpll", | ||
105 | .id = -1, | ||
106 | .ctrlbit = (1 << 31), | ||
107 | }; | ||
108 | |||
109 | /* VPLL clock output */ | ||
110 | struct clk clk_fout_vpll = { | ||
111 | .name = "fout_vpll", | ||
112 | .id = -1, | ||
113 | .ctrlbit = (1 << 31), | ||
114 | }; | ||
115 | |||
116 | /* Possible clock sources for APLL Mux */ | ||
117 | static struct clk *clk_src_apll_list[] = { | ||
118 | [0] = &clk_fin_apll, | ||
119 | [1] = &clk_fout_apll, | ||
120 | }; | ||
121 | |||
122 | struct clksrc_sources clk_src_apll = { | ||
123 | .sources = clk_src_apll_list, | ||
124 | .nr_sources = ARRAY_SIZE(clk_src_apll_list), | ||
125 | }; | ||
126 | |||
127 | /* Possible clock sources for BPLL Mux */ | ||
128 | static struct clk *clk_src_bpll_list[] = { | ||
129 | [0] = &clk_fin_bpll, | ||
130 | [1] = &clk_fout_bpll, | ||
131 | }; | ||
132 | |||
133 | struct clksrc_sources clk_src_bpll = { | ||
134 | .sources = clk_src_bpll_list, | ||
135 | .nr_sources = ARRAY_SIZE(clk_src_bpll_list), | ||
136 | }; | ||
137 | |||
138 | static struct clk *clk_src_bpll_fout_list[] = { | ||
139 | [0] = &clk_fout_bpll_div2, | ||
140 | [1] = &clk_fout_bpll, | ||
141 | }; | ||
142 | |||
143 | struct clksrc_sources clk_src_bpll_fout = { | ||
144 | .sources = clk_src_bpll_fout_list, | ||
145 | .nr_sources = ARRAY_SIZE(clk_src_bpll_fout_list), | ||
146 | }; | ||
147 | |||
148 | /* Possible clock sources for CPLL Mux */ | ||
149 | static struct clk *clk_src_cpll_list[] = { | ||
150 | [0] = &clk_fin_cpll, | ||
151 | [1] = &clk_fout_cpll, | ||
152 | }; | ||
153 | |||
154 | struct clksrc_sources clk_src_cpll = { | ||
155 | .sources = clk_src_cpll_list, | ||
156 | .nr_sources = ARRAY_SIZE(clk_src_cpll_list), | ||
157 | }; | ||
158 | |||
159 | /* Possible clock sources for MPLL Mux */ | ||
160 | static struct clk *clk_src_mpll_list[] = { | ||
161 | [0] = &clk_fin_mpll, | ||
162 | [1] = &clk_fout_mpll, | ||
163 | }; | ||
164 | |||
165 | struct clksrc_sources clk_src_mpll = { | ||
166 | .sources = clk_src_mpll_list, | ||
167 | .nr_sources = ARRAY_SIZE(clk_src_mpll_list), | ||
168 | }; | ||
169 | |||
170 | static struct clk *clk_src_mpll_fout_list[] = { | ||
171 | [0] = &clk_fout_mpll_div2, | ||
172 | [1] = &clk_fout_mpll, | ||
173 | }; | ||
174 | |||
175 | struct clksrc_sources clk_src_mpll_fout = { | ||
176 | .sources = clk_src_mpll_fout_list, | ||
177 | .nr_sources = ARRAY_SIZE(clk_src_mpll_fout_list), | ||
178 | }; | ||
179 | |||
180 | /* Possible clock sources for EPLL Mux */ | ||
181 | static struct clk *clk_src_epll_list[] = { | ||
182 | [0] = &clk_fin_epll, | ||
183 | [1] = &clk_fout_epll, | ||
184 | }; | ||
185 | |||
186 | struct clksrc_sources clk_src_epll = { | ||
187 | .sources = clk_src_epll_list, | ||
188 | .nr_sources = ARRAY_SIZE(clk_src_epll_list), | ||
189 | }; | ||
190 | |||
191 | /* Possible clock sources for DPLL Mux */ | ||
192 | static struct clk *clk_src_dpll_list[] = { | ||
193 | [0] = &clk_fin_dpll, | ||
194 | [1] = &clk_fout_dpll, | ||
195 | }; | ||
196 | |||
197 | struct clksrc_sources clk_src_dpll = { | ||
198 | .sources = clk_src_dpll_list, | ||
199 | .nr_sources = ARRAY_SIZE(clk_src_dpll_list), | ||
200 | }; | ||
201 | |||
202 | struct clk clk_vpll = { | ||
203 | .name = "vpll", | ||
204 | .id = -1, | ||
205 | }; | ||
206 | |||
207 | int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable) | ||
208 | { | ||
209 | unsigned int ctrlbit = clk->ctrlbit; | ||
210 | u32 con; | ||
211 | |||
212 | con = __raw_readl(reg); | ||
213 | con = enable ? (con | ctrlbit) : (con & ~ctrlbit); | ||
214 | __raw_writel(con, reg); | ||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | int s5p_epll_enable(struct clk *clk, int enable) | ||
219 | { | ||
220 | unsigned int ctrlbit = clk->ctrlbit; | ||
221 | unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit; | ||
222 | |||
223 | if (enable) | ||
224 | __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON); | ||
225 | else | ||
226 | __raw_writel(epll_con, S5P_EPLL_CON); | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | unsigned long s5p_epll_get_rate(struct clk *clk) | ||
232 | { | ||
233 | return clk->rate; | ||
234 | } | ||
235 | |||
236 | int s5p_spdif_set_rate(struct clk *clk, unsigned long rate) | ||
237 | { | ||
238 | struct clk *pclk; | ||
239 | int ret; | ||
240 | |||
241 | pclk = clk_get_parent(clk); | ||
242 | if (IS_ERR(pclk)) | ||
243 | return -EINVAL; | ||
244 | |||
245 | ret = pclk->ops->set_rate(pclk, rate); | ||
246 | clk_put(pclk); | ||
247 | |||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | unsigned long s5p_spdif_get_rate(struct clk *clk) | ||
252 | { | ||
253 | struct clk *pclk; | ||
254 | int rate; | ||
255 | |||
256 | pclk = clk_get_parent(clk); | ||
257 | if (IS_ERR(pclk)) | ||
258 | return -EINVAL; | ||
259 | |||
260 | rate = pclk->ops->get_rate(pclk); | ||
261 | clk_put(pclk); | ||
262 | |||
263 | return rate; | ||
264 | } | ||
265 | |||
266 | struct clk_ops s5p_sclk_spdif_ops = { | ||
267 | .set_rate = s5p_spdif_set_rate, | ||
268 | .get_rate = s5p_spdif_get_rate, | ||
269 | }; | ||
270 | |||
271 | static struct clk *s5p_clks[] __initdata = { | ||
272 | &clk_ext_xtal_mux, | ||
273 | &clk_48m, | ||
274 | &s5p_clk_27m, | ||
275 | &clk_fout_apll, | ||
276 | &clk_fout_mpll, | ||
277 | &clk_fout_epll, | ||
278 | &clk_fout_dpll, | ||
279 | &clk_fout_vpll, | ||
280 | &clk_vpll, | ||
281 | &clk_xusbxti, | ||
282 | }; | ||
283 | |||
284 | void __init s5p_register_clocks(unsigned long xtal_freq) | ||
285 | { | ||
286 | int ret; | ||
287 | |||
288 | clk_ext_xtal_mux.rate = xtal_freq; | ||
289 | |||
290 | ret = s3c24xx_register_clocks(s5p_clks, ARRAY_SIZE(s5p_clks)); | ||
291 | if (ret > 0) | ||
292 | printk(KERN_ERR "Failed to register s5p clocks\n"); | ||
293 | } | ||
diff --git a/arch/arm/plat-samsung/s5p-dev-mfc.c b/arch/arm/plat-samsung/s5p-dev-mfc.c new file mode 100644 index 000000000000..ad6089465e2a --- /dev/null +++ b/arch/arm/plat-samsung/s5p-dev-mfc.c | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010-2011 Samsung Electronics Co.Ltd | ||
3 | * | ||
4 | * Base S5P MFC resource and device definitions | ||
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 | #include <linux/kernel.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/dma-mapping.h> | ||
15 | #include <linux/memblock.h> | ||
16 | #include <linux/ioport.h> | ||
17 | |||
18 | #include <mach/map.h> | ||
19 | #include <plat/devs.h> | ||
20 | #include <plat/irqs.h> | ||
21 | #include <plat/mfc.h> | ||
22 | |||
23 | struct s5p_mfc_reserved_mem { | ||
24 | phys_addr_t base; | ||
25 | unsigned long size; | ||
26 | struct device *dev; | ||
27 | }; | ||
28 | |||
29 | static struct s5p_mfc_reserved_mem s5p_mfc_mem[2] __initdata; | ||
30 | |||
31 | void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize, | ||
32 | phys_addr_t lbase, unsigned int lsize) | ||
33 | { | ||
34 | int i; | ||
35 | |||
36 | s5p_mfc_mem[0].dev = &s5p_device_mfc_r.dev; | ||
37 | s5p_mfc_mem[0].base = rbase; | ||
38 | s5p_mfc_mem[0].size = rsize; | ||
39 | |||
40 | s5p_mfc_mem[1].dev = &s5p_device_mfc_l.dev; | ||
41 | s5p_mfc_mem[1].base = lbase; | ||
42 | s5p_mfc_mem[1].size = lsize; | ||
43 | |||
44 | for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) { | ||
45 | struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i]; | ||
46 | if (memblock_remove(area->base, area->size)) { | ||
47 | printk(KERN_ERR "Failed to reserve memory for MFC device (%ld bytes at 0x%08lx)\n", | ||
48 | area->size, (unsigned long) area->base); | ||
49 | area->base = 0; | ||
50 | } | ||
51 | } | ||
52 | } | ||
53 | |||
54 | static int __init s5p_mfc_memory_init(void) | ||
55 | { | ||
56 | int i; | ||
57 | |||
58 | for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) { | ||
59 | struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i]; | ||
60 | if (!area->base) | ||
61 | continue; | ||
62 | |||
63 | if (dma_declare_coherent_memory(area->dev, area->base, | ||
64 | area->base, area->size, | ||
65 | DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) | ||
66 | printk(KERN_ERR "Failed to declare coherent memory for MFC device (%ld bytes at 0x%08lx)\n", | ||
67 | area->size, (unsigned long) area->base); | ||
68 | } | ||
69 | return 0; | ||
70 | } | ||
71 | device_initcall(s5p_mfc_memory_init); | ||
diff --git a/arch/arm/plat-samsung/s5p-dev-uart.c b/arch/arm/plat-samsung/s5p-dev-uart.c new file mode 100644 index 000000000000..cafa3deddcc1 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-dev-uart.c | |||
@@ -0,0 +1,89 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2009,2012 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com/ | ||
4 | * | ||
5 | * Base S5P UART resource and device definitions | ||
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/kernel.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/list.h> | ||
16 | #include <linux/ioport.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | |||
19 | #include <asm/mach/arch.h> | ||
20 | #include <asm/mach/irq.h> | ||
21 | #include <mach/hardware.h> | ||
22 | #include <mach/map.h> | ||
23 | |||
24 | #include <plat/devs.h> | ||
25 | |||
26 | /* Serial port registrations */ | ||
27 | |||
28 | static struct resource s5p_uart0_resource[] = { | ||
29 | [0] = DEFINE_RES_MEM(S5P_PA_UART0, S5P_SZ_UART), | ||
30 | [1] = DEFINE_RES_IRQ(IRQ_UART0), | ||
31 | }; | ||
32 | |||
33 | static struct resource s5p_uart1_resource[] = { | ||
34 | [0] = DEFINE_RES_MEM(S5P_PA_UART1, S5P_SZ_UART), | ||
35 | [1] = DEFINE_RES_IRQ(IRQ_UART1), | ||
36 | }; | ||
37 | |||
38 | static struct resource s5p_uart2_resource[] = { | ||
39 | [0] = DEFINE_RES_MEM(S5P_PA_UART2, S5P_SZ_UART), | ||
40 | [1] = DEFINE_RES_IRQ(IRQ_UART2), | ||
41 | }; | ||
42 | |||
43 | static struct resource s5p_uart3_resource[] = { | ||
44 | #if CONFIG_SERIAL_SAMSUNG_UARTS > 3 | ||
45 | [0] = DEFINE_RES_MEM(S5P_PA_UART3, S5P_SZ_UART), | ||
46 | [1] = DEFINE_RES_IRQ(IRQ_UART3), | ||
47 | #endif | ||
48 | }; | ||
49 | |||
50 | static struct resource s5p_uart4_resource[] = { | ||
51 | #if CONFIG_SERIAL_SAMSUNG_UARTS > 4 | ||
52 | [0] = DEFINE_RES_MEM(S5P_PA_UART4, S5P_SZ_UART), | ||
53 | [1] = DEFINE_RES_IRQ(IRQ_UART4), | ||
54 | #endif | ||
55 | }; | ||
56 | |||
57 | static struct resource s5p_uart5_resource[] = { | ||
58 | #if CONFIG_SERIAL_SAMSUNG_UARTS > 5 | ||
59 | [0] = DEFINE_RES_MEM(S5P_PA_UART5, S5P_SZ_UART), | ||
60 | [1] = DEFINE_RES_IRQ(IRQ_UART5), | ||
61 | #endif | ||
62 | }; | ||
63 | |||
64 | struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = { | ||
65 | [0] = { | ||
66 | .resources = s5p_uart0_resource, | ||
67 | .nr_resources = ARRAY_SIZE(s5p_uart0_resource), | ||
68 | }, | ||
69 | [1] = { | ||
70 | .resources = s5p_uart1_resource, | ||
71 | .nr_resources = ARRAY_SIZE(s5p_uart1_resource), | ||
72 | }, | ||
73 | [2] = { | ||
74 | .resources = s5p_uart2_resource, | ||
75 | .nr_resources = ARRAY_SIZE(s5p_uart2_resource), | ||
76 | }, | ||
77 | [3] = { | ||
78 | .resources = s5p_uart3_resource, | ||
79 | .nr_resources = ARRAY_SIZE(s5p_uart3_resource), | ||
80 | }, | ||
81 | [4] = { | ||
82 | .resources = s5p_uart4_resource, | ||
83 | .nr_resources = ARRAY_SIZE(s5p_uart4_resource), | ||
84 | }, | ||
85 | [5] = { | ||
86 | .resources = s5p_uart5_resource, | ||
87 | .nr_resources = ARRAY_SIZE(s5p_uart5_resource), | ||
88 | }, | ||
89 | }; | ||
diff --git a/arch/arm/plat-samsung/s5p-irq-eint.c b/arch/arm/plat-samsung/s5p-irq-eint.c new file mode 100644 index 000000000000..33bd3f3d20f5 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-irq-eint.c | |||
@@ -0,0 +1,218 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com | ||
4 | * | ||
5 | * S5P - IRQ EINT support | ||
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/kernel.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/gpio.h> | ||
18 | |||
19 | #include <asm/hardware/vic.h> | ||
20 | |||
21 | #include <plat/regs-irqtype.h> | ||
22 | |||
23 | #include <mach/map.h> | ||
24 | #include <plat/cpu.h> | ||
25 | #include <plat/pm.h> | ||
26 | |||
27 | #include <plat/gpio-cfg.h> | ||
28 | #include <mach/regs-gpio.h> | ||
29 | |||
30 | static inline void s5p_irq_eint_mask(struct irq_data *data) | ||
31 | { | ||
32 | u32 mask; | ||
33 | |||
34 | mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); | ||
35 | mask |= eint_irq_to_bit(data->irq); | ||
36 | __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); | ||
37 | } | ||
38 | |||
39 | static void s5p_irq_eint_unmask(struct irq_data *data) | ||
40 | { | ||
41 | u32 mask; | ||
42 | |||
43 | mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); | ||
44 | mask &= ~(eint_irq_to_bit(data->irq)); | ||
45 | __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); | ||
46 | } | ||
47 | |||
48 | static inline void s5p_irq_eint_ack(struct irq_data *data) | ||
49 | { | ||
50 | __raw_writel(eint_irq_to_bit(data->irq), | ||
51 | S5P_EINT_PEND(EINT_REG_NR(data->irq))); | ||
52 | } | ||
53 | |||
54 | static void s5p_irq_eint_maskack(struct irq_data *data) | ||
55 | { | ||
56 | /* compiler should in-line these */ | ||
57 | s5p_irq_eint_mask(data); | ||
58 | s5p_irq_eint_ack(data); | ||
59 | } | ||
60 | |||
61 | static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type) | ||
62 | { | ||
63 | int offs = EINT_OFFSET(data->irq); | ||
64 | int shift; | ||
65 | u32 ctrl, mask; | ||
66 | u32 newvalue = 0; | ||
67 | |||
68 | switch (type) { | ||
69 | case IRQ_TYPE_EDGE_RISING: | ||
70 | newvalue = S5P_IRQ_TYPE_EDGE_RISING; | ||
71 | break; | ||
72 | |||
73 | case IRQ_TYPE_EDGE_FALLING: | ||
74 | newvalue = S5P_IRQ_TYPE_EDGE_FALLING; | ||
75 | break; | ||
76 | |||
77 | case IRQ_TYPE_EDGE_BOTH: | ||
78 | newvalue = S5P_IRQ_TYPE_EDGE_BOTH; | ||
79 | break; | ||
80 | |||
81 | case IRQ_TYPE_LEVEL_LOW: | ||
82 | newvalue = S5P_IRQ_TYPE_LEVEL_LOW; | ||
83 | break; | ||
84 | |||
85 | case IRQ_TYPE_LEVEL_HIGH: | ||
86 | newvalue = S5P_IRQ_TYPE_LEVEL_HIGH; | ||
87 | break; | ||
88 | |||
89 | default: | ||
90 | printk(KERN_ERR "No such irq type %d", type); | ||
91 | return -EINVAL; | ||
92 | } | ||
93 | |||
94 | shift = (offs & 0x7) * 4; | ||
95 | mask = 0x7 << shift; | ||
96 | |||
97 | ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq))); | ||
98 | ctrl &= ~mask; | ||
99 | ctrl |= newvalue << shift; | ||
100 | __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq))); | ||
101 | |||
102 | if ((0 <= offs) && (offs < 8)) | ||
103 | s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE); | ||
104 | |||
105 | else if ((8 <= offs) && (offs < 16)) | ||
106 | s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE); | ||
107 | |||
108 | else if ((16 <= offs) && (offs < 24)) | ||
109 | s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE); | ||
110 | |||
111 | else if ((24 <= offs) && (offs < 32)) | ||
112 | s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE); | ||
113 | |||
114 | else | ||
115 | printk(KERN_ERR "No such irq number %d", offs); | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static struct irq_chip s5p_irq_eint = { | ||
121 | .name = "s5p-eint", | ||
122 | .irq_mask = s5p_irq_eint_mask, | ||
123 | .irq_unmask = s5p_irq_eint_unmask, | ||
124 | .irq_mask_ack = s5p_irq_eint_maskack, | ||
125 | .irq_ack = s5p_irq_eint_ack, | ||
126 | .irq_set_type = s5p_irq_eint_set_type, | ||
127 | #ifdef CONFIG_PM | ||
128 | .irq_set_wake = s3c_irqext_wake, | ||
129 | #endif | ||
130 | }; | ||
131 | |||
132 | /* s5p_irq_demux_eint | ||
133 | * | ||
134 | * This function demuxes the IRQ from the group0 external interrupts, | ||
135 | * from EINTs 16 to 31. It is designed to be inlined into the specific | ||
136 | * handler s5p_irq_demux_eintX_Y. | ||
137 | * | ||
138 | * Each EINT pend/mask registers handle eight of them. | ||
139 | */ | ||
140 | static inline void s5p_irq_demux_eint(unsigned int start) | ||
141 | { | ||
142 | u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); | ||
143 | u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); | ||
144 | unsigned int irq; | ||
145 | |||
146 | status &= ~mask; | ||
147 | status &= 0xff; | ||
148 | |||
149 | while (status) { | ||
150 | irq = fls(status) - 1; | ||
151 | generic_handle_irq(irq + start); | ||
152 | status &= ~(1 << irq); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) | ||
157 | { | ||
158 | s5p_irq_demux_eint(IRQ_EINT(16)); | ||
159 | s5p_irq_demux_eint(IRQ_EINT(24)); | ||
160 | } | ||
161 | |||
162 | static inline void s5p_irq_vic_eint_mask(struct irq_data *data) | ||
163 | { | ||
164 | void __iomem *base = irq_data_get_irq_chip_data(data); | ||
165 | |||
166 | s5p_irq_eint_mask(data); | ||
167 | writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE_CLEAR); | ||
168 | } | ||
169 | |||
170 | static void s5p_irq_vic_eint_unmask(struct irq_data *data) | ||
171 | { | ||
172 | void __iomem *base = irq_data_get_irq_chip_data(data); | ||
173 | |||
174 | s5p_irq_eint_unmask(data); | ||
175 | writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE); | ||
176 | } | ||
177 | |||
178 | static inline void s5p_irq_vic_eint_ack(struct irq_data *data) | ||
179 | { | ||
180 | __raw_writel(eint_irq_to_bit(data->irq), | ||
181 | S5P_EINT_PEND(EINT_REG_NR(data->irq))); | ||
182 | } | ||
183 | |||
184 | static void s5p_irq_vic_eint_maskack(struct irq_data *data) | ||
185 | { | ||
186 | s5p_irq_vic_eint_mask(data); | ||
187 | s5p_irq_vic_eint_ack(data); | ||
188 | } | ||
189 | |||
190 | static struct irq_chip s5p_irq_vic_eint = { | ||
191 | .name = "s5p_vic_eint", | ||
192 | .irq_mask = s5p_irq_vic_eint_mask, | ||
193 | .irq_unmask = s5p_irq_vic_eint_unmask, | ||
194 | .irq_mask_ack = s5p_irq_vic_eint_maskack, | ||
195 | .irq_ack = s5p_irq_vic_eint_ack, | ||
196 | .irq_set_type = s5p_irq_eint_set_type, | ||
197 | #ifdef CONFIG_PM | ||
198 | .irq_set_wake = s3c_irqext_wake, | ||
199 | #endif | ||
200 | }; | ||
201 | |||
202 | static int __init s5p_init_irq_eint(void) | ||
203 | { | ||
204 | int irq; | ||
205 | |||
206 | for (irq = IRQ_EINT(0); irq <= IRQ_EINT(15); irq++) | ||
207 | irq_set_chip(irq, &s5p_irq_vic_eint); | ||
208 | |||
209 | for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) { | ||
210 | irq_set_chip_and_handler(irq, &s5p_irq_eint, handle_level_irq); | ||
211 | set_irq_flags(irq, IRQF_VALID); | ||
212 | } | ||
213 | |||
214 | irq_set_chained_handler(IRQ_EINT16_31, s5p_irq_demux_eint16_31); | ||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | arch_initcall(s5p_init_irq_eint); | ||
diff --git a/arch/arm/plat-samsung/s5p-irq-gpioint.c b/arch/arm/plat-samsung/s5p-irq-gpioint.c new file mode 100644 index 000000000000..f9431fe5b06e --- /dev/null +++ b/arch/arm/plat-samsung/s5p-irq-gpioint.c | |||
@@ -0,0 +1,215 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
3 | * Author: Kyungmin Park <kyungmin.park@samsung.com> | ||
4 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
5 | * Author: Marek Szyprowski <m.szyprowski@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | #include <mach/map.h> | ||
22 | #include <plat/gpio-core.h> | ||
23 | #include <plat/gpio-cfg.h> | ||
24 | |||
25 | #include <asm/mach/irq.h> | ||
26 | |||
27 | #define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u) | ||
28 | |||
29 | #define CON_OFFSET 0x700 | ||
30 | #define MASK_OFFSET 0x900 | ||
31 | #define PEND_OFFSET 0xA00 | ||
32 | #define REG_OFFSET(x) ((x) << 2) | ||
33 | |||
34 | struct s5p_gpioint_bank { | ||
35 | struct list_head list; | ||
36 | int start; | ||
37 | int nr_groups; | ||
38 | int irq; | ||
39 | struct samsung_gpio_chip **chips; | ||
40 | void (*handler)(unsigned int, struct irq_desc *); | ||
41 | }; | ||
42 | |||
43 | static LIST_HEAD(banks); | ||
44 | |||
45 | static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type) | ||
46 | { | ||
47 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
48 | struct irq_chip_type *ct = gc->chip_types; | ||
49 | unsigned int shift = (d->irq - gc->irq_base) << 2; | ||
50 | |||
51 | switch (type) { | ||
52 | case IRQ_TYPE_EDGE_RISING: | ||
53 | type = S5P_IRQ_TYPE_EDGE_RISING; | ||
54 | break; | ||
55 | case IRQ_TYPE_EDGE_FALLING: | ||
56 | type = S5P_IRQ_TYPE_EDGE_FALLING; | ||
57 | break; | ||
58 | case IRQ_TYPE_EDGE_BOTH: | ||
59 | type = S5P_IRQ_TYPE_EDGE_BOTH; | ||
60 | break; | ||
61 | case IRQ_TYPE_LEVEL_HIGH: | ||
62 | type = S5P_IRQ_TYPE_LEVEL_HIGH; | ||
63 | break; | ||
64 | case IRQ_TYPE_LEVEL_LOW: | ||
65 | type = S5P_IRQ_TYPE_LEVEL_LOW; | ||
66 | break; | ||
67 | case IRQ_TYPE_NONE: | ||
68 | default: | ||
69 | printk(KERN_WARNING "No irq type\n"); | ||
70 | return -EINVAL; | ||
71 | } | ||
72 | |||
73 | gc->type_cache &= ~(0x7 << shift); | ||
74 | gc->type_cache |= type << shift; | ||
75 | writel(gc->type_cache, gc->reg_base + ct->regs.type); | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc) | ||
80 | { | ||
81 | struct s5p_gpioint_bank *bank = irq_get_handler_data(irq); | ||
82 | int group, pend_offset, mask_offset; | ||
83 | unsigned int pend, mask; | ||
84 | |||
85 | struct irq_chip *chip = irq_get_chip(irq); | ||
86 | chained_irq_enter(chip, desc); | ||
87 | |||
88 | for (group = 0; group < bank->nr_groups; group++) { | ||
89 | struct samsung_gpio_chip *chip = bank->chips[group]; | ||
90 | if (!chip) | ||
91 | continue; | ||
92 | |||
93 | pend_offset = REG_OFFSET(group); | ||
94 | pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset); | ||
95 | if (!pend) | ||
96 | continue; | ||
97 | |||
98 | mask_offset = REG_OFFSET(group); | ||
99 | mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset); | ||
100 | pend &= ~mask; | ||
101 | |||
102 | while (pend) { | ||
103 | int offset = fls(pend) - 1; | ||
104 | int real_irq = chip->irq_base + offset; | ||
105 | generic_handle_irq(real_irq); | ||
106 | pend &= ~BIT(offset); | ||
107 | } | ||
108 | } | ||
109 | chained_irq_exit(chip, desc); | ||
110 | } | ||
111 | |||
112 | static __init int s5p_gpioint_add(struct samsung_gpio_chip *chip) | ||
113 | { | ||
114 | static int used_gpioint_groups = 0; | ||
115 | int group = chip->group; | ||
116 | struct s5p_gpioint_bank *b, *bank = NULL; | ||
117 | struct irq_chip_generic *gc; | ||
118 | struct irq_chip_type *ct; | ||
119 | |||
120 | if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT) | ||
121 | return -ENOMEM; | ||
122 | |||
123 | list_for_each_entry(b, &banks, list) { | ||
124 | if (group >= b->start && group < b->start + b->nr_groups) { | ||
125 | bank = b; | ||
126 | break; | ||
127 | } | ||
128 | } | ||
129 | if (!bank) | ||
130 | return -EINVAL; | ||
131 | |||
132 | if (!bank->handler) { | ||
133 | bank->chips = kzalloc(sizeof(struct samsung_gpio_chip *) * | ||
134 | bank->nr_groups, GFP_KERNEL); | ||
135 | if (!bank->chips) | ||
136 | return -ENOMEM; | ||
137 | |||
138 | irq_set_chained_handler(bank->irq, s5p_gpioint_handler); | ||
139 | irq_set_handler_data(bank->irq, bank); | ||
140 | bank->handler = s5p_gpioint_handler; | ||
141 | printk(KERN_INFO "Registered chained gpio int handler for interrupt %d.\n", | ||
142 | bank->irq); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * chained GPIO irq has been successfully registered, allocate new gpio | ||
147 | * int group and assign irq nubmers | ||
148 | */ | ||
149 | chip->irq_base = S5P_GPIOINT_BASE + | ||
150 | used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE; | ||
151 | used_gpioint_groups++; | ||
152 | |||
153 | bank->chips[group - bank->start] = chip; | ||
154 | |||
155 | gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base, | ||
156 | (void __iomem *)GPIO_BASE(chip), | ||
157 | handle_level_irq); | ||
158 | if (!gc) | ||
159 | return -ENOMEM; | ||
160 | ct = gc->chip_types; | ||
161 | ct->chip.irq_ack = irq_gc_ack_set_bit; | ||
162 | ct->chip.irq_mask = irq_gc_mask_set_bit; | ||
163 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; | ||
164 | ct->chip.irq_set_type = s5p_gpioint_set_type, | ||
165 | ct->regs.ack = PEND_OFFSET + REG_OFFSET(group - bank->start); | ||
166 | ct->regs.mask = MASK_OFFSET + REG_OFFSET(group - bank->start); | ||
167 | ct->regs.type = CON_OFFSET + REG_OFFSET(group - bank->start); | ||
168 | irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio), | ||
169 | IRQ_GC_INIT_MASK_CACHE, | ||
170 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | int __init s5p_register_gpio_interrupt(int pin) | ||
175 | { | ||
176 | struct samsung_gpio_chip *my_chip = samsung_gpiolib_getchip(pin); | ||
177 | int offset, group; | ||
178 | int ret; | ||
179 | |||
180 | if (!my_chip) | ||
181 | return -EINVAL; | ||
182 | |||
183 | offset = pin - my_chip->chip.base; | ||
184 | group = my_chip->group; | ||
185 | |||
186 | /* check if the group has been already registered */ | ||
187 | if (my_chip->irq_base) | ||
188 | return my_chip->irq_base + offset; | ||
189 | |||
190 | /* register gpio group */ | ||
191 | ret = s5p_gpioint_add(my_chip); | ||
192 | if (ret == 0) { | ||
193 | my_chip->chip.to_irq = samsung_gpiolib_to_irq; | ||
194 | printk(KERN_INFO "Registered interrupt support for gpio group %d.\n", | ||
195 | group); | ||
196 | return my_chip->irq_base + offset; | ||
197 | } | ||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups) | ||
202 | { | ||
203 | struct s5p_gpioint_bank *bank; | ||
204 | |||
205 | bank = kzalloc(sizeof(*bank), GFP_KERNEL); | ||
206 | if (!bank) | ||
207 | return -ENOMEM; | ||
208 | |||
209 | bank->start = start; | ||
210 | bank->nr_groups = nr_groups; | ||
211 | bank->irq = chain_irq; | ||
212 | |||
213 | list_add_tail(&bank->list, &banks); | ||
214 | return 0; | ||
215 | } | ||
diff --git a/arch/arm/plat-samsung/s5p-irq-pm.c b/arch/arm/plat-samsung/s5p-irq-pm.c new file mode 100644 index 000000000000..7c1e3b7072fc --- /dev/null +++ b/arch/arm/plat-samsung/s5p-irq-pm.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com | ||
4 | * | ||
5 | * Based on arch/arm/plat-s3c24xx/irq-pm.c, | ||
6 | * Copyright (c) 2003,2004 Simtec Electronics | ||
7 | * Ben Dooks <ben@simtec.co.uk> | ||
8 | * http://armlinux.simtec.co.uk/ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/init.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | |||
19 | #include <plat/cpu.h> | ||
20 | #include <plat/irqs.h> | ||
21 | #include <plat/pm.h> | ||
22 | #include <mach/map.h> | ||
23 | |||
24 | #include <mach/regs-gpio.h> | ||
25 | #include <mach/regs-irq.h> | ||
26 | |||
27 | /* state for IRQs over sleep */ | ||
28 | |||
29 | /* default is to allow for EINT0..EINT31, and IRQ_RTC_TIC, IRQ_RTC_ALARM, | ||
30 | * as wakeup sources | ||
31 | * | ||
32 | * set bit to 1 in allow bitfield to enable the wakeup settings on it | ||
33 | */ | ||
34 | |||
35 | unsigned long s3c_irqwake_intallow = 0x00000006L; | ||
36 | unsigned long s3c_irqwake_eintallow = 0xffffffffL; | ||
37 | |||
38 | int s3c_irq_wake(struct irq_data *data, unsigned int state) | ||
39 | { | ||
40 | unsigned long irqbit; | ||
41 | unsigned int irq_rtc_tic, irq_rtc_alarm; | ||
42 | |||
43 | #ifdef CONFIG_ARCH_EXYNOS | ||
44 | if (soc_is_exynos5250()) { | ||
45 | irq_rtc_tic = EXYNOS5_IRQ_RTC_TIC; | ||
46 | irq_rtc_alarm = EXYNOS5_IRQ_RTC_ALARM; | ||
47 | } else { | ||
48 | irq_rtc_tic = EXYNOS4_IRQ_RTC_TIC; | ||
49 | irq_rtc_alarm = EXYNOS4_IRQ_RTC_ALARM; | ||
50 | } | ||
51 | #else | ||
52 | irq_rtc_tic = IRQ_RTC_TIC; | ||
53 | irq_rtc_alarm = IRQ_RTC_ALARM; | ||
54 | #endif | ||
55 | |||
56 | if (data->irq == irq_rtc_tic || data->irq == irq_rtc_alarm) { | ||
57 | irqbit = 1 << (data->irq + 1 - irq_rtc_alarm); | ||
58 | |||
59 | if (!state) | ||
60 | s3c_irqwake_intmask |= irqbit; | ||
61 | else | ||
62 | s3c_irqwake_intmask &= ~irqbit; | ||
63 | } else { | ||
64 | return -ENOENT; | ||
65 | } | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static struct sleep_save eint_save[] = { | ||
71 | SAVE_ITEM(S5P_EINT_CON(0)), | ||
72 | SAVE_ITEM(S5P_EINT_CON(1)), | ||
73 | SAVE_ITEM(S5P_EINT_CON(2)), | ||
74 | SAVE_ITEM(S5P_EINT_CON(3)), | ||
75 | |||
76 | SAVE_ITEM(S5P_EINT_FLTCON(0)), | ||
77 | SAVE_ITEM(S5P_EINT_FLTCON(1)), | ||
78 | SAVE_ITEM(S5P_EINT_FLTCON(2)), | ||
79 | SAVE_ITEM(S5P_EINT_FLTCON(3)), | ||
80 | SAVE_ITEM(S5P_EINT_FLTCON(4)), | ||
81 | SAVE_ITEM(S5P_EINT_FLTCON(5)), | ||
82 | SAVE_ITEM(S5P_EINT_FLTCON(6)), | ||
83 | SAVE_ITEM(S5P_EINT_FLTCON(7)), | ||
84 | |||
85 | SAVE_ITEM(S5P_EINT_MASK(0)), | ||
86 | SAVE_ITEM(S5P_EINT_MASK(1)), | ||
87 | SAVE_ITEM(S5P_EINT_MASK(2)), | ||
88 | SAVE_ITEM(S5P_EINT_MASK(3)), | ||
89 | }; | ||
90 | |||
91 | int s3c24xx_irq_suspend(void) | ||
92 | { | ||
93 | s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save)); | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | void s3c24xx_irq_resume(void) | ||
99 | { | ||
100 | s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save)); | ||
101 | } | ||
102 | |||
diff --git a/arch/arm/plat-samsung/s5p-irq.c b/arch/arm/plat-samsung/s5p-irq.c new file mode 100644 index 000000000000..dfb47d638f03 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-irq.c | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2009 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com/ | ||
4 | * | ||
5 | * S5P - Interrupt handling | ||
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/kernel.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/io.h> | ||
16 | |||
17 | #include <asm/hardware/vic.h> | ||
18 | |||
19 | #include <mach/map.h> | ||
20 | #include <plat/regs-timer.h> | ||
21 | #include <plat/cpu.h> | ||
22 | #include <plat/irq-vic-timer.h> | ||
23 | |||
24 | void __init s5p_init_irq(u32 *vic, u32 num_vic) | ||
25 | { | ||
26 | #ifdef CONFIG_ARM_VIC | ||
27 | int irq; | ||
28 | |||
29 | /* initialize the VICs */ | ||
30 | for (irq = 0; irq < num_vic; irq++) | ||
31 | vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0); | ||
32 | #endif | ||
33 | |||
34 | s3c_init_vic_timer_irq(5, IRQ_TIMER0); | ||
35 | } | ||
diff --git a/arch/arm/plat-samsung/s5p-pm.c b/arch/arm/plat-samsung/s5p-pm.c new file mode 100644 index 000000000000..0747468f0936 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-pm.c | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com | ||
4 | * | ||
5 | * S5P Power Manager (Suspend-To-RAM) support | ||
6 | * | ||
7 | * Based on arch/arm/plat-s3c24xx/pm.c | ||
8 | * Copyright (c) 2004,2006 Simtec Electronics | ||
9 | * Ben Dooks <ben@simtec.co.uk> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/suspend.h> | ||
17 | #include <plat/pm.h> | ||
18 | |||
19 | #define PFX "s5p pm: " | ||
20 | |||
21 | /* s3c_pm_configure_extint | ||
22 | * | ||
23 | * configure all external interrupt pins | ||
24 | */ | ||
25 | |||
26 | void s3c_pm_configure_extint(void) | ||
27 | { | ||
28 | /* nothing here yet */ | ||
29 | } | ||
30 | |||
31 | void s3c_pm_restore_core(void) | ||
32 | { | ||
33 | /* nothing here yet */ | ||
34 | } | ||
35 | |||
36 | void s3c_pm_save_core(void) | ||
37 | { | ||
38 | /* nothing here yet */ | ||
39 | } | ||
40 | |||
diff --git a/arch/arm/plat-samsung/s5p-sleep.S b/arch/arm/plat-samsung/s5p-sleep.S new file mode 100644 index 000000000000..bdf6dadf8790 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-sleep.S | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com | ||
4 | * | ||
5 | * Common S5P Sleep Code | ||
6 | * Based on S3C64XX sleep code by: | ||
7 | * Ben Dooks, (c) 2008 Simtec Electronics | ||
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 as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/linkage.h> | ||
25 | #include <asm/asm-offsets.h> | ||
26 | #include <asm/hardware/cache-l2x0.h> | ||
27 | |||
28 | /* | ||
29 | * The following code is located into the .data section. This is to | ||
30 | * allow l2x0_regs_phys to be accessed with a relative load while we | ||
31 | * can't rely on any MMU translation. We could have put l2x0_regs_phys | ||
32 | * in the .text section as well, but some setups might insist on it to | ||
33 | * be truly read-only. (Reference from: arch/arm/kernel/sleep.S) | ||
34 | */ | ||
35 | .data | ||
36 | .align | ||
37 | |||
38 | /* | ||
39 | * sleep magic, to allow the bootloader to check for an valid | ||
40 | * image to resume to. Must be the first word before the | ||
41 | * s3c_cpu_resume entry. | ||
42 | */ | ||
43 | |||
44 | .word 0x2bedf00d | ||
45 | |||
46 | /* | ||
47 | * s3c_cpu_resume | ||
48 | * | ||
49 | * resume code entry for bootloader to call | ||
50 | */ | ||
51 | |||
52 | ENTRY(s3c_cpu_resume) | ||
53 | #ifdef CONFIG_CACHE_L2X0 | ||
54 | adr r0, l2x0_regs_phys | ||
55 | ldr r0, [r0] | ||
56 | ldr r1, [r0, #L2X0_R_PHY_BASE] | ||
57 | ldr r2, [r1, #L2X0_CTRL] | ||
58 | tst r2, #0x1 | ||
59 | bne resume_l2on | ||
60 | ldr r2, [r0, #L2X0_R_AUX_CTRL] | ||
61 | str r2, [r1, #L2X0_AUX_CTRL] | ||
62 | ldr r2, [r0, #L2X0_R_TAG_LATENCY] | ||
63 | str r2, [r1, #L2X0_TAG_LATENCY_CTRL] | ||
64 | ldr r2, [r0, #L2X0_R_DATA_LATENCY] | ||
65 | str r2, [r1, #L2X0_DATA_LATENCY_CTRL] | ||
66 | ldr r2, [r0, #L2X0_R_PREFETCH_CTRL] | ||
67 | str r2, [r1, #L2X0_PREFETCH_CTRL] | ||
68 | ldr r2, [r0, #L2X0_R_PWR_CTRL] | ||
69 | str r2, [r1, #L2X0_POWER_CTRL] | ||
70 | mov r2, #1 | ||
71 | str r2, [r1, #L2X0_CTRL] | ||
72 | resume_l2on: | ||
73 | #endif | ||
74 | b cpu_resume | ||
75 | ENDPROC(s3c_cpu_resume) | ||
76 | #ifdef CONFIG_CACHE_L2X0 | ||
77 | .globl l2x0_regs_phys | ||
78 | l2x0_regs_phys: | ||
79 | .long 0 | ||
80 | #endif | ||
diff --git a/arch/arm/plat-samsung/s5p-time.c b/arch/arm/plat-samsung/s5p-time.c new file mode 100644 index 000000000000..028b6e877eb9 --- /dev/null +++ b/arch/arm/plat-samsung/s5p-time.c | |||
@@ -0,0 +1,405 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com/ | ||
4 | * | ||
5 | * S5P - Common hr-timer support | ||
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/interrupt.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/clockchips.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | |||
19 | #include <asm/smp_twd.h> | ||
20 | #include <asm/mach/time.h> | ||
21 | #include <asm/mach/arch.h> | ||
22 | #include <asm/mach/map.h> | ||
23 | #include <asm/sched_clock.h> | ||
24 | |||
25 | #include <mach/map.h> | ||
26 | #include <plat/devs.h> | ||
27 | #include <plat/regs-timer.h> | ||
28 | #include <plat/s5p-time.h> | ||
29 | |||
30 | static struct clk *tin_event; | ||
31 | static struct clk *tin_source; | ||
32 | static struct clk *tdiv_event; | ||
33 | static struct clk *tdiv_source; | ||
34 | static struct clk *timerclk; | ||
35 | static struct s5p_timer_source timer_source; | ||
36 | static unsigned long clock_count_per_tick; | ||
37 | static void s5p_timer_resume(void); | ||
38 | |||
39 | static void s5p_time_stop(enum s5p_timer_mode mode) | ||
40 | { | ||
41 | unsigned long tcon; | ||
42 | |||
43 | tcon = __raw_readl(S3C2410_TCON); | ||
44 | |||
45 | switch (mode) { | ||
46 | case S5P_PWM0: | ||
47 | tcon &= ~S3C2410_TCON_T0START; | ||
48 | break; | ||
49 | |||
50 | case S5P_PWM1: | ||
51 | tcon &= ~S3C2410_TCON_T1START; | ||
52 | break; | ||
53 | |||
54 | case S5P_PWM2: | ||
55 | tcon &= ~S3C2410_TCON_T2START; | ||
56 | break; | ||
57 | |||
58 | case S5P_PWM3: | ||
59 | tcon &= ~S3C2410_TCON_T3START; | ||
60 | break; | ||
61 | |||
62 | case S5P_PWM4: | ||
63 | tcon &= ~S3C2410_TCON_T4START; | ||
64 | break; | ||
65 | |||
66 | default: | ||
67 | printk(KERN_ERR "Invalid Timer %d\n", mode); | ||
68 | break; | ||
69 | } | ||
70 | __raw_writel(tcon, S3C2410_TCON); | ||
71 | } | ||
72 | |||
73 | static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt) | ||
74 | { | ||
75 | unsigned long tcon; | ||
76 | |||
77 | tcon = __raw_readl(S3C2410_TCON); | ||
78 | |||
79 | tcnt--; | ||
80 | |||
81 | switch (mode) { | ||
82 | case S5P_PWM0: | ||
83 | tcon &= ~(0x0f << 0); | ||
84 | tcon |= S3C2410_TCON_T0MANUALUPD; | ||
85 | break; | ||
86 | |||
87 | case S5P_PWM1: | ||
88 | tcon &= ~(0x0f << 8); | ||
89 | tcon |= S3C2410_TCON_T1MANUALUPD; | ||
90 | break; | ||
91 | |||
92 | case S5P_PWM2: | ||
93 | tcon &= ~(0x0f << 12); | ||
94 | tcon |= S3C2410_TCON_T2MANUALUPD; | ||
95 | break; | ||
96 | |||
97 | case S5P_PWM3: | ||
98 | tcon &= ~(0x0f << 16); | ||
99 | tcon |= S3C2410_TCON_T3MANUALUPD; | ||
100 | break; | ||
101 | |||
102 | case S5P_PWM4: | ||
103 | tcon &= ~(0x07 << 20); | ||
104 | tcon |= S3C2410_TCON_T4MANUALUPD; | ||
105 | break; | ||
106 | |||
107 | default: | ||
108 | printk(KERN_ERR "Invalid Timer %d\n", mode); | ||
109 | break; | ||
110 | } | ||
111 | |||
112 | __raw_writel(tcnt, S3C2410_TCNTB(mode)); | ||
113 | __raw_writel(tcnt, S3C2410_TCMPB(mode)); | ||
114 | __raw_writel(tcon, S3C2410_TCON); | ||
115 | } | ||
116 | |||
117 | static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) | ||
118 | { | ||
119 | unsigned long tcon; | ||
120 | |||
121 | tcon = __raw_readl(S3C2410_TCON); | ||
122 | |||
123 | switch (mode) { | ||
124 | case S5P_PWM0: | ||
125 | tcon |= S3C2410_TCON_T0START; | ||
126 | tcon &= ~S3C2410_TCON_T0MANUALUPD; | ||
127 | |||
128 | if (periodic) | ||
129 | tcon |= S3C2410_TCON_T0RELOAD; | ||
130 | else | ||
131 | tcon &= ~S3C2410_TCON_T0RELOAD; | ||
132 | break; | ||
133 | |||
134 | case S5P_PWM1: | ||
135 | tcon |= S3C2410_TCON_T1START; | ||
136 | tcon &= ~S3C2410_TCON_T1MANUALUPD; | ||
137 | |||
138 | if (periodic) | ||
139 | tcon |= S3C2410_TCON_T1RELOAD; | ||
140 | else | ||
141 | tcon &= ~S3C2410_TCON_T1RELOAD; | ||
142 | break; | ||
143 | |||
144 | case S5P_PWM2: | ||
145 | tcon |= S3C2410_TCON_T2START; | ||
146 | tcon &= ~S3C2410_TCON_T2MANUALUPD; | ||
147 | |||
148 | if (periodic) | ||
149 | tcon |= S3C2410_TCON_T2RELOAD; | ||
150 | else | ||
151 | tcon &= ~S3C2410_TCON_T2RELOAD; | ||
152 | break; | ||
153 | |||
154 | case S5P_PWM3: | ||
155 | tcon |= S3C2410_TCON_T3START; | ||
156 | tcon &= ~S3C2410_TCON_T3MANUALUPD; | ||
157 | |||
158 | if (periodic) | ||
159 | tcon |= S3C2410_TCON_T3RELOAD; | ||
160 | else | ||
161 | tcon &= ~S3C2410_TCON_T3RELOAD; | ||
162 | break; | ||
163 | |||
164 | case S5P_PWM4: | ||
165 | tcon |= S3C2410_TCON_T4START; | ||
166 | tcon &= ~S3C2410_TCON_T4MANUALUPD; | ||
167 | |||
168 | if (periodic) | ||
169 | tcon |= S3C2410_TCON_T4RELOAD; | ||
170 | else | ||
171 | tcon &= ~S3C2410_TCON_T4RELOAD; | ||
172 | break; | ||
173 | |||
174 | default: | ||
175 | printk(KERN_ERR "Invalid Timer %d\n", mode); | ||
176 | break; | ||
177 | } | ||
178 | __raw_writel(tcon, S3C2410_TCON); | ||
179 | } | ||
180 | |||
181 | static int s5p_set_next_event(unsigned long cycles, | ||
182 | struct clock_event_device *evt) | ||
183 | { | ||
184 | s5p_time_setup(timer_source.event_id, cycles); | ||
185 | s5p_time_start(timer_source.event_id, NON_PERIODIC); | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | static void s5p_set_mode(enum clock_event_mode mode, | ||
191 | struct clock_event_device *evt) | ||
192 | { | ||
193 | s5p_time_stop(timer_source.event_id); | ||
194 | |||
195 | switch (mode) { | ||
196 | case CLOCK_EVT_MODE_PERIODIC: | ||
197 | s5p_time_setup(timer_source.event_id, clock_count_per_tick); | ||
198 | s5p_time_start(timer_source.event_id, PERIODIC); | ||
199 | break; | ||
200 | |||
201 | case CLOCK_EVT_MODE_ONESHOT: | ||
202 | break; | ||
203 | |||
204 | case CLOCK_EVT_MODE_UNUSED: | ||
205 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
206 | break; | ||
207 | |||
208 | case CLOCK_EVT_MODE_RESUME: | ||
209 | s5p_timer_resume(); | ||
210 | break; | ||
211 | } | ||
212 | } | ||
213 | |||
214 | static void s5p_timer_resume(void) | ||
215 | { | ||
216 | /* event timer restart */ | ||
217 | s5p_time_setup(timer_source.event_id, clock_count_per_tick); | ||
218 | s5p_time_start(timer_source.event_id, PERIODIC); | ||
219 | |||
220 | /* source timer restart */ | ||
221 | s5p_time_setup(timer_source.source_id, TCNT_MAX); | ||
222 | s5p_time_start(timer_source.source_id, PERIODIC); | ||
223 | } | ||
224 | |||
225 | void __init s5p_set_timer_source(enum s5p_timer_mode event, | ||
226 | enum s5p_timer_mode source) | ||
227 | { | ||
228 | s3c_device_timer[event].dev.bus = &platform_bus_type; | ||
229 | s3c_device_timer[source].dev.bus = &platform_bus_type; | ||
230 | |||
231 | timer_source.event_id = event; | ||
232 | timer_source.source_id = source; | ||
233 | } | ||
234 | |||
235 | static struct clock_event_device time_event_device = { | ||
236 | .name = "s5p_event_timer", | ||
237 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
238 | .rating = 200, | ||
239 | .set_next_event = s5p_set_next_event, | ||
240 | .set_mode = s5p_set_mode, | ||
241 | }; | ||
242 | |||
243 | static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id) | ||
244 | { | ||
245 | struct clock_event_device *evt = dev_id; | ||
246 | |||
247 | evt->event_handler(evt); | ||
248 | |||
249 | return IRQ_HANDLED; | ||
250 | } | ||
251 | |||
252 | static struct irqaction s5p_clock_event_irq = { | ||
253 | .name = "s5p_time_irq", | ||
254 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | ||
255 | .handler = s5p_clock_event_isr, | ||
256 | .dev_id = &time_event_device, | ||
257 | }; | ||
258 | |||
259 | static void __init s5p_clockevent_init(void) | ||
260 | { | ||
261 | unsigned long pclk; | ||
262 | unsigned long clock_rate; | ||
263 | unsigned int irq_number; | ||
264 | struct clk *tscaler; | ||
265 | |||
266 | pclk = clk_get_rate(timerclk); | ||
267 | |||
268 | tscaler = clk_get_parent(tdiv_event); | ||
269 | |||
270 | clk_set_rate(tscaler, pclk / 2); | ||
271 | clk_set_rate(tdiv_event, pclk / 2); | ||
272 | clk_set_parent(tin_event, tdiv_event); | ||
273 | |||
274 | clock_rate = clk_get_rate(tin_event); | ||
275 | clock_count_per_tick = clock_rate / HZ; | ||
276 | |||
277 | clockevents_calc_mult_shift(&time_event_device, | ||
278 | clock_rate, S5PTIMER_MIN_RANGE); | ||
279 | time_event_device.max_delta_ns = | ||
280 | clockevent_delta2ns(-1, &time_event_device); | ||
281 | time_event_device.min_delta_ns = | ||
282 | clockevent_delta2ns(1, &time_event_device); | ||
283 | |||
284 | time_event_device.cpumask = cpumask_of(0); | ||
285 | clockevents_register_device(&time_event_device); | ||
286 | |||
287 | irq_number = timer_source.event_id + IRQ_TIMER0; | ||
288 | setup_irq(irq_number, &s5p_clock_event_irq); | ||
289 | } | ||
290 | |||
291 | static void __iomem *s5p_timer_reg(void) | ||
292 | { | ||
293 | unsigned long offset = 0; | ||
294 | |||
295 | switch (timer_source.source_id) { | ||
296 | case S5P_PWM0: | ||
297 | case S5P_PWM1: | ||
298 | case S5P_PWM2: | ||
299 | case S5P_PWM3: | ||
300 | offset = (timer_source.source_id * 0x0c) + 0x14; | ||
301 | break; | ||
302 | |||
303 | case S5P_PWM4: | ||
304 | offset = 0x40; | ||
305 | break; | ||
306 | |||
307 | default: | ||
308 | printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id); | ||
309 | return NULL; | ||
310 | } | ||
311 | |||
312 | return S3C_TIMERREG(offset); | ||
313 | } | ||
314 | |||
315 | /* | ||
316 | * Override the global weak sched_clock symbol with this | ||
317 | * local implementation which uses the clocksource to get some | ||
318 | * better resolution when scheduling the kernel. We accept that | ||
319 | * this wraps around for now, since it is just a relative time | ||
320 | * stamp. (Inspired by U300 implementation.) | ||
321 | */ | ||
322 | static u32 notrace s5p_read_sched_clock(void) | ||
323 | { | ||
324 | void __iomem *reg = s5p_timer_reg(); | ||
325 | |||
326 | if (!reg) | ||
327 | return 0; | ||
328 | |||
329 | return ~__raw_readl(reg); | ||
330 | } | ||
331 | |||
332 | static void __init s5p_clocksource_init(void) | ||
333 | { | ||
334 | unsigned long pclk; | ||
335 | unsigned long clock_rate; | ||
336 | |||
337 | pclk = clk_get_rate(timerclk); | ||
338 | |||
339 | clk_set_rate(tdiv_source, pclk / 2); | ||
340 | clk_set_parent(tin_source, tdiv_source); | ||
341 | |||
342 | clock_rate = clk_get_rate(tin_source); | ||
343 | |||
344 | s5p_time_setup(timer_source.source_id, TCNT_MAX); | ||
345 | s5p_time_start(timer_source.source_id, PERIODIC); | ||
346 | |||
347 | setup_sched_clock(s5p_read_sched_clock, 32, clock_rate); | ||
348 | |||
349 | if (clocksource_mmio_init(s5p_timer_reg(), "s5p_clocksource_timer", | ||
350 | clock_rate, 250, 32, clocksource_mmio_readl_down)) | ||
351 | panic("s5p_clocksource_timer: can't register clocksource\n"); | ||
352 | } | ||
353 | |||
354 | static void __init s5p_timer_resources(void) | ||
355 | { | ||
356 | |||
357 | unsigned long event_id = timer_source.event_id; | ||
358 | unsigned long source_id = timer_source.source_id; | ||
359 | char devname[15]; | ||
360 | |||
361 | timerclk = clk_get(NULL, "timers"); | ||
362 | if (IS_ERR(timerclk)) | ||
363 | panic("failed to get timers clock for timer"); | ||
364 | |||
365 | clk_enable(timerclk); | ||
366 | |||
367 | sprintf(devname, "s3c24xx-pwm.%lu", event_id); | ||
368 | s3c_device_timer[event_id].id = event_id; | ||
369 | s3c_device_timer[event_id].dev.init_name = devname; | ||
370 | |||
371 | tin_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tin"); | ||
372 | if (IS_ERR(tin_event)) | ||
373 | panic("failed to get pwm-tin clock for event timer"); | ||
374 | |||
375 | tdiv_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tdiv"); | ||
376 | if (IS_ERR(tdiv_event)) | ||
377 | panic("failed to get pwm-tdiv clock for event timer"); | ||
378 | |||
379 | clk_enable(tin_event); | ||
380 | |||
381 | sprintf(devname, "s3c24xx-pwm.%lu", source_id); | ||
382 | s3c_device_timer[source_id].id = source_id; | ||
383 | s3c_device_timer[source_id].dev.init_name = devname; | ||
384 | |||
385 | tin_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tin"); | ||
386 | if (IS_ERR(tin_source)) | ||
387 | panic("failed to get pwm-tin clock for source timer"); | ||
388 | |||
389 | tdiv_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tdiv"); | ||
390 | if (IS_ERR(tdiv_source)) | ||
391 | panic("failed to get pwm-tdiv clock for source timer"); | ||
392 | |||
393 | clk_enable(tin_source); | ||
394 | } | ||
395 | |||
396 | static void __init s5p_timer_init(void) | ||
397 | { | ||
398 | s5p_timer_resources(); | ||
399 | s5p_clockevent_init(); | ||
400 | s5p_clocksource_init(); | ||
401 | } | ||
402 | |||
403 | struct sys_timer s5p_timer = { | ||
404 | .init = s5p_timer_init, | ||
405 | }; | ||
diff --git a/arch/arm/plat-samsung/setup-mipiphy.c b/arch/arm/plat-samsung/setup-mipiphy.c new file mode 100644 index 000000000000..683c466c0e6a --- /dev/null +++ b/arch/arm/plat-samsung/setup-mipiphy.c | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. | ||
3 | * | ||
4 | * S5P - Helper functions for MIPI-CSIS and MIPI-DSIM D-PHY control | ||
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 | #include <linux/kernel.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/spinlock.h> | ||
15 | #include <mach/regs-clock.h> | ||
16 | |||
17 | static int __s5p_mipi_phy_control(struct platform_device *pdev, | ||
18 | bool on, u32 reset) | ||
19 | { | ||
20 | static DEFINE_SPINLOCK(lock); | ||
21 | void __iomem *addr; | ||
22 | unsigned long flags; | ||
23 | int pid; | ||
24 | u32 cfg; | ||
25 | |||
26 | if (!pdev) | ||
27 | return -EINVAL; | ||
28 | |||
29 | pid = (pdev->id == -1) ? 0 : pdev->id; | ||
30 | |||
31 | if (pid != 0 && pid != 1) | ||
32 | return -EINVAL; | ||
33 | |||
34 | addr = S5P_MIPI_DPHY_CONTROL(pid); | ||
35 | |||
36 | spin_lock_irqsave(&lock, flags); | ||
37 | |||
38 | cfg = __raw_readl(addr); | ||
39 | cfg = on ? (cfg | reset) : (cfg & ~reset); | ||
40 | __raw_writel(cfg, addr); | ||
41 | |||
42 | if (on) { | ||
43 | cfg |= S5P_MIPI_DPHY_ENABLE; | ||
44 | } else if (!(cfg & (S5P_MIPI_DPHY_SRESETN | | ||
45 | S5P_MIPI_DPHY_MRESETN) & ~reset)) { | ||
46 | cfg &= ~S5P_MIPI_DPHY_ENABLE; | ||
47 | } | ||
48 | |||
49 | __raw_writel(cfg, addr); | ||
50 | spin_unlock_irqrestore(&lock, flags); | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | int s5p_csis_phy_enable(struct platform_device *pdev, bool on) | ||
56 | { | ||
57 | return __s5p_mipi_phy_control(pdev, on, S5P_MIPI_DPHY_SRESETN); | ||
58 | } | ||
59 | |||
60 | int s5p_dsim_phy_enable(struct platform_device *pdev, bool on) | ||
61 | { | ||
62 | return __s5p_mipi_phy_control(pdev, on, S5P_MIPI_DPHY_MRESETN); | ||
63 | } | ||