diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-10-28 07:27:34 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-10-28 07:27:34 -0400 |
commit | f9cef506815386df4bd7e463b59e0a0984ce0355 (patch) | |
tree | b26a202b2f0472e3ebe889012312b115917717f9 /arch/arm/mach-s5pv210 | |
parent | 9ae21ca362679757786f5abe556c7943e9001426 (diff) | |
parent | cbff3eb3e6e3c618583a7435f87c1548aa12b0ad (diff) |
Merge branch 'for-rmk' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into devel-stable
Conflicts:
arch/arm/mach-s3c64xx/dev-audio.c
Diffstat (limited to 'arch/arm/mach-s5pv210')
30 files changed, 1986 insertions, 214 deletions
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index 5315fec3db86..862f239a0fdb 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig | |||
@@ -11,9 +11,9 @@ if ARCH_S5PV210 | |||
11 | 11 | ||
12 | config CPU_S5PV210 | 12 | config CPU_S5PV210 |
13 | bool | 13 | bool |
14 | select PLAT_S5P | ||
15 | select S3C_PL330_DMA | 14 | select S3C_PL330_DMA |
16 | select S5P_EXT_INT | 15 | select S5P_EXT_INT |
16 | select S5PV210_PM if PM | ||
17 | help | 17 | help |
18 | Enable S5PV210 CPU support | 18 | Enable S5PV210 CPU support |
19 | 19 | ||
@@ -58,7 +58,6 @@ menu "S5PC110 Machines" | |||
58 | config MACH_AQUILA | 58 | config MACH_AQUILA |
59 | bool "Aquila" | 59 | bool "Aquila" |
60 | select CPU_S5PV210 | 60 | select CPU_S5PV210 |
61 | select ARCH_SPARSEMEM_ENABLE | ||
62 | select S3C_DEV_FB | 61 | select S3C_DEV_FB |
63 | select S5P_DEV_FIMC0 | 62 | select S5P_DEV_FIMC0 |
64 | select S5P_DEV_FIMC1 | 63 | select S5P_DEV_FIMC1 |
@@ -75,7 +74,7 @@ config MACH_AQUILA | |||
75 | config MACH_GONI | 74 | config MACH_GONI |
76 | bool "GONI" | 75 | bool "GONI" |
77 | select CPU_S5PV210 | 76 | select CPU_S5PV210 |
78 | select ARCH_SPARSEMEM_ENABLE | 77 | select S5P_GPIO_INT |
79 | select S3C_DEV_FB | 78 | select S3C_DEV_FB |
80 | select S5P_DEV_FIMC0 | 79 | select S5P_DEV_FIMC0 |
81 | select S5P_DEV_FIMC1 | 80 | select S5P_DEV_FIMC1 |
@@ -83,8 +82,15 @@ config MACH_GONI | |||
83 | select S3C_DEV_HSMMC | 82 | select S3C_DEV_HSMMC |
84 | select S3C_DEV_HSMMC1 | 83 | select S3C_DEV_HSMMC1 |
85 | select S3C_DEV_HSMMC2 | 84 | select S3C_DEV_HSMMC2 |
85 | select S3C_DEV_I2C1 | ||
86 | select S3C_DEV_I2C2 | ||
87 | select S3C_DEV_USB_HSOTG | ||
86 | select S5P_DEV_ONENAND | 88 | select S5P_DEV_ONENAND |
89 | select SAMSUNG_DEV_KEYPAD | ||
87 | select S5PV210_SETUP_FB_24BPP | 90 | select S5PV210_SETUP_FB_24BPP |
91 | select S5PV210_SETUP_I2C1 | ||
92 | select S5PV210_SETUP_I2C2 | ||
93 | select S5PV210_SETUP_KEYPAD | ||
88 | select S5PV210_SETUP_SDHCI | 94 | select S5PV210_SETUP_SDHCI |
89 | help | 95 | help |
90 | Machine support for Samsung GONI board | 96 | Machine support for Samsung GONI board |
@@ -93,7 +99,6 @@ config MACH_GONI | |||
93 | config MACH_SMDKC110 | 99 | config MACH_SMDKC110 |
94 | bool "SMDKC110" | 100 | bool "SMDKC110" |
95 | select CPU_S5PV210 | 101 | select CPU_S5PV210 |
96 | select ARCH_SPARSEMEM_ENABLE | ||
97 | select S3C_DEV_I2C1 | 102 | select S3C_DEV_I2C1 |
98 | select S3C_DEV_I2C2 | 103 | select S3C_DEV_I2C2 |
99 | select S3C_DEV_RTC | 104 | select S3C_DEV_RTC |
@@ -113,7 +118,6 @@ menu "S5PV210 Machines" | |||
113 | config MACH_SMDKV210 | 118 | config MACH_SMDKV210 |
114 | bool "SMDKV210" | 119 | bool "SMDKV210" |
115 | select CPU_S5PV210 | 120 | select CPU_S5PV210 |
116 | select ARCH_SPARSEMEM_ENABLE | ||
117 | select S3C_DEV_HSMMC | 121 | select S3C_DEV_HSMMC |
118 | select S3C_DEV_HSMMC1 | 122 | select S3C_DEV_HSMMC1 |
119 | select S3C_DEV_HSMMC2 | 123 | select S3C_DEV_HSMMC2 |
@@ -134,6 +138,29 @@ config MACH_SMDKV210 | |||
134 | help | 138 | help |
135 | Machine support for Samsung SMDKV210 | 139 | Machine support for Samsung SMDKV210 |
136 | 140 | ||
141 | config MACH_TORBRECK | ||
142 | bool "Torbreck" | ||
143 | select CPU_S5PV210 | ||
144 | select ARCH_SPARSEMEM_ENABLE | ||
145 | select S3C_DEV_HSMMC | ||
146 | select S3C_DEV_HSMMC1 | ||
147 | select S3C_DEV_HSMMC2 | ||
148 | select S3C_DEV_HSMMC3 | ||
149 | select S3C_DEV_I2C1 | ||
150 | select S3C_DEV_I2C2 | ||
151 | select S3C_DEV_RTC | ||
152 | select S3C_DEV_WDT | ||
153 | select S5PV210_SETUP_I2C1 | ||
154 | select S5PV210_SETUP_I2C2 | ||
155 | select S5PV210_SETUP_SDHCI | ||
156 | help | ||
157 | Machine support for aESOP Torbreck | ||
158 | |||
137 | endmenu | 159 | endmenu |
138 | 160 | ||
161 | config S5PV210_PM | ||
162 | bool | ||
163 | help | ||
164 | Power Management code common to S5PV210 | ||
165 | |||
139 | endif | 166 | endif |
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 704548912408..ff1a0db57a2f 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile | |||
@@ -14,6 +14,8 @@ obj- := | |||
14 | 14 | ||
15 | obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o | 15 | obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o |
16 | obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o | 16 | obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o |
17 | obj-$(CONFIG_S5PV210_PM) += pm.o sleep.o | ||
18 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o | ||
17 | 19 | ||
18 | # machine support | 20 | # machine support |
19 | 21 | ||
@@ -21,6 +23,7 @@ obj-$(CONFIG_MACH_AQUILA) += mach-aquila.o | |||
21 | obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o | 23 | obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o |
22 | obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o | 24 | obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o |
23 | obj-$(CONFIG_MACH_GONI) += mach-goni.o | 25 | obj-$(CONFIG_MACH_GONI) += mach-goni.o |
26 | obj-$(CONFIG_MACH_TORBRECK) += mach-torbreck.o | ||
24 | 27 | ||
25 | # device support | 28 | # device support |
26 | 29 | ||
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index d562670e1b0b..019c3a69b0e4 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <plat/clock-clksrc.h> | 31 | #include <plat/clock-clksrc.h> |
32 | #include <plat/s5pv210.h> | 32 | #include <plat/s5pv210.h> |
33 | 33 | ||
34 | static unsigned long xtal; | ||
35 | |||
34 | static struct clksrc_clk clk_mout_apll = { | 36 | static struct clksrc_clk clk_mout_apll = { |
35 | .clk = { | 37 | .clk = { |
36 | .name = "mout_apll", | 38 | .name = "mout_apll", |
@@ -259,6 +261,36 @@ static struct clksrc_clk clk_sclk_vpll = { | |||
259 | .reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 }, | 261 | .reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 }, |
260 | }; | 262 | }; |
261 | 263 | ||
264 | static struct clk *clkset_moutdmc0src_list[] = { | ||
265 | [0] = &clk_sclk_a2m.clk, | ||
266 | [1] = &clk_mout_mpll.clk, | ||
267 | [2] = NULL, | ||
268 | [3] = NULL, | ||
269 | }; | ||
270 | |||
271 | static struct clksrc_sources clkset_moutdmc0src = { | ||
272 | .sources = clkset_moutdmc0src_list, | ||
273 | .nr_sources = ARRAY_SIZE(clkset_moutdmc0src_list), | ||
274 | }; | ||
275 | |||
276 | static struct clksrc_clk clk_mout_dmc0 = { | ||
277 | .clk = { | ||
278 | .name = "mout_dmc0", | ||
279 | .id = -1, | ||
280 | }, | ||
281 | .sources = &clkset_moutdmc0src, | ||
282 | .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 }, | ||
283 | }; | ||
284 | |||
285 | static struct clksrc_clk clk_sclk_dmc0 = { | ||
286 | .clk = { | ||
287 | .name = "sclk_dmc0", | ||
288 | .id = -1, | ||
289 | .parent = &clk_mout_dmc0.clk, | ||
290 | }, | ||
291 | .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 }, | ||
292 | }; | ||
293 | |||
262 | static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk) | 294 | static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk) |
263 | { | 295 | { |
264 | return clk_get_rate(clk->parent) / 2; | 296 | return clk_get_rate(clk->parent) / 2; |
@@ -268,8 +300,29 @@ static struct clk_ops clk_hclk_imem_ops = { | |||
268 | .get_rate = s5pv210_clk_imem_get_rate, | 300 | .get_rate = s5pv210_clk_imem_get_rate, |
269 | }; | 301 | }; |
270 | 302 | ||
303 | static unsigned long s5pv210_clk_fout_apll_get_rate(struct clk *clk) | ||
304 | { | ||
305 | return s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508); | ||
306 | } | ||
307 | |||
308 | static struct clk_ops clk_fout_apll_ops = { | ||
309 | .get_rate = s5pv210_clk_fout_apll_get_rate, | ||
310 | }; | ||
311 | |||
271 | static struct clk init_clocks_disable[] = { | 312 | static struct clk init_clocks_disable[] = { |
272 | { | 313 | { |
314 | .name = "pdma", | ||
315 | .id = 0, | ||
316 | .parent = &clk_hclk_psys.clk, | ||
317 | .enable = s5pv210_clk_ip0_ctrl, | ||
318 | .ctrlbit = (1 << 3), | ||
319 | }, { | ||
320 | .name = "pdma", | ||
321 | .id = 1, | ||
322 | .parent = &clk_hclk_psys.clk, | ||
323 | .enable = s5pv210_clk_ip0_ctrl, | ||
324 | .ctrlbit = (1 << 4), | ||
325 | }, { | ||
273 | .name = "rot", | 326 | .name = "rot", |
274 | .id = -1, | 327 | .id = -1, |
275 | .parent = &clk_hclk_dsys.clk, | 328 | .parent = &clk_hclk_dsys.clk, |
@@ -431,6 +484,12 @@ static struct clk init_clocks_disable[] = { | |||
431 | .parent = &clk_p, | 484 | .parent = &clk_p, |
432 | .enable = s5pv210_clk_ip3_ctrl, | 485 | .enable = s5pv210_clk_ip3_ctrl, |
433 | .ctrlbit = (1 << 6), | 486 | .ctrlbit = (1 << 6), |
487 | }, { | ||
488 | .name = "spdif", | ||
489 | .id = -1, | ||
490 | .parent = &clk_p, | ||
491 | .enable = s5pv210_clk_ip3_ctrl, | ||
492 | .ctrlbit = (1 << 0), | ||
434 | }, | 493 | }, |
435 | }; | 494 | }; |
436 | 495 | ||
@@ -660,6 +719,53 @@ static struct clksrc_sources clkset_sclk_spdif = { | |||
660 | .nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list), | 719 | .nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list), |
661 | }; | 720 | }; |
662 | 721 | ||
722 | static int s5pv210_spdif_set_rate(struct clk *clk, unsigned long rate) | ||
723 | { | ||
724 | struct clk *pclk; | ||
725 | int ret; | ||
726 | |||
727 | pclk = clk_get_parent(clk); | ||
728 | if (IS_ERR(pclk)) | ||
729 | return -EINVAL; | ||
730 | |||
731 | ret = pclk->ops->set_rate(pclk, rate); | ||
732 | clk_put(pclk); | ||
733 | |||
734 | return ret; | ||
735 | } | ||
736 | |||
737 | static unsigned long s5pv210_spdif_get_rate(struct clk *clk) | ||
738 | { | ||
739 | struct clk *pclk; | ||
740 | int rate; | ||
741 | |||
742 | pclk = clk_get_parent(clk); | ||
743 | if (IS_ERR(pclk)) | ||
744 | return -EINVAL; | ||
745 | |||
746 | rate = pclk->ops->get_rate(clk); | ||
747 | clk_put(pclk); | ||
748 | |||
749 | return rate; | ||
750 | } | ||
751 | |||
752 | static struct clk_ops s5pv210_sclk_spdif_ops = { | ||
753 | .set_rate = s5pv210_spdif_set_rate, | ||
754 | .get_rate = s5pv210_spdif_get_rate, | ||
755 | }; | ||
756 | |||
757 | static struct clksrc_clk clk_sclk_spdif = { | ||
758 | .clk = { | ||
759 | .name = "sclk_spdif", | ||
760 | .id = -1, | ||
761 | .enable = s5pv210_clk_mask0_ctrl, | ||
762 | .ctrlbit = (1 << 27), | ||
763 | .ops = &s5pv210_sclk_spdif_ops, | ||
764 | }, | ||
765 | .sources = &clkset_sclk_spdif, | ||
766 | .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 }, | ||
767 | }; | ||
768 | |||
663 | static struct clk *clkset_group2_list[] = { | 769 | static struct clk *clkset_group2_list[] = { |
664 | [0] = &clk_ext_xtal_mux, | 770 | [0] = &clk_ext_xtal_mux, |
665 | [1] = &clk_xusbxti, | 771 | [1] = &clk_xusbxti, |
@@ -744,15 +850,6 @@ static struct clksrc_clk clksrcs[] = { | |||
744 | .sources = &clkset_sclk_mixer, | 850 | .sources = &clkset_sclk_mixer, |
745 | .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 }, | 851 | .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 }, |
746 | }, { | 852 | }, { |
747 | .clk = { | ||
748 | .name = "sclk_spdif", | ||
749 | .id = -1, | ||
750 | .enable = s5pv210_clk_mask0_ctrl, | ||
751 | .ctrlbit = (1 << 27), | ||
752 | }, | ||
753 | .sources = &clkset_sclk_spdif, | ||
754 | .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 }, | ||
755 | }, { | ||
756 | .clk = { | 853 | .clk = { |
757 | .name = "sclk_fimc", | 854 | .name = "sclk_fimc", |
758 | .id = 0, | 855 | .id = 0, |
@@ -953,12 +1050,93 @@ static struct clksrc_clk *sysclks[] = { | |||
953 | &clk_sclk_dac, | 1050 | &clk_sclk_dac, |
954 | &clk_sclk_pixel, | 1051 | &clk_sclk_pixel, |
955 | &clk_sclk_hdmi, | 1052 | &clk_sclk_hdmi, |
1053 | &clk_mout_dmc0, | ||
1054 | &clk_sclk_dmc0, | ||
1055 | &clk_sclk_audio0, | ||
1056 | &clk_sclk_audio1, | ||
1057 | &clk_sclk_audio2, | ||
1058 | &clk_sclk_spdif, | ||
1059 | }; | ||
1060 | |||
1061 | static u32 epll_div[][6] = { | ||
1062 | { 48000000, 0, 48, 3, 3, 0 }, | ||
1063 | { 96000000, 0, 48, 3, 2, 0 }, | ||
1064 | { 144000000, 1, 72, 3, 2, 0 }, | ||
1065 | { 192000000, 0, 48, 3, 1, 0 }, | ||
1066 | { 288000000, 1, 72, 3, 1, 0 }, | ||
1067 | { 32750000, 1, 65, 3, 4, 35127 }, | ||
1068 | { 32768000, 1, 65, 3, 4, 35127 }, | ||
1069 | { 45158400, 0, 45, 3, 3, 10355 }, | ||
1070 | { 45000000, 0, 45, 3, 3, 10355 }, | ||
1071 | { 45158000, 0, 45, 3, 3, 10355 }, | ||
1072 | { 49125000, 0, 49, 3, 3, 9961 }, | ||
1073 | { 49152000, 0, 49, 3, 3, 9961 }, | ||
1074 | { 67737600, 1, 67, 3, 3, 48366 }, | ||
1075 | { 67738000, 1, 67, 3, 3, 48366 }, | ||
1076 | { 73800000, 1, 73, 3, 3, 47710 }, | ||
1077 | { 73728000, 1, 73, 3, 3, 47710 }, | ||
1078 | { 36000000, 1, 32, 3, 4, 0 }, | ||
1079 | { 60000000, 1, 60, 3, 3, 0 }, | ||
1080 | { 72000000, 1, 72, 3, 3, 0 }, | ||
1081 | { 80000000, 1, 80, 3, 3, 0 }, | ||
1082 | { 84000000, 0, 42, 3, 2, 0 }, | ||
1083 | { 50000000, 0, 50, 3, 3, 0 }, | ||
1084 | }; | ||
1085 | |||
1086 | static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate) | ||
1087 | { | ||
1088 | unsigned int epll_con, epll_con_k; | ||
1089 | unsigned int i; | ||
1090 | |||
1091 | /* Return if nothing changed */ | ||
1092 | if (clk->rate == rate) | ||
1093 | return 0; | ||
1094 | |||
1095 | epll_con = __raw_readl(S5P_EPLL_CON); | ||
1096 | epll_con_k = __raw_readl(S5P_EPLL_CON1); | ||
1097 | |||
1098 | epll_con_k &= ~PLL46XX_KDIV_MASK; | ||
1099 | epll_con &= ~(1 << 27 | | ||
1100 | PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | | ||
1101 | PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | | ||
1102 | PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT); | ||
1103 | |||
1104 | for (i = 0; i < ARRAY_SIZE(epll_div); i++) { | ||
1105 | if (epll_div[i][0] == rate) { | ||
1106 | epll_con_k |= epll_div[i][5] << 0; | ||
1107 | epll_con |= (epll_div[i][1] << 27 | | ||
1108 | epll_div[i][2] << PLL46XX_MDIV_SHIFT | | ||
1109 | epll_div[i][3] << PLL46XX_PDIV_SHIFT | | ||
1110 | epll_div[i][4] << PLL46XX_SDIV_SHIFT); | ||
1111 | break; | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | if (i == ARRAY_SIZE(epll_div)) { | ||
1116 | printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", | ||
1117 | __func__); | ||
1118 | return -EINVAL; | ||
1119 | } | ||
1120 | |||
1121 | __raw_writel(epll_con, S5P_EPLL_CON); | ||
1122 | __raw_writel(epll_con_k, S5P_EPLL_CON1); | ||
1123 | |||
1124 | printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n", | ||
1125 | clk->rate, rate); | ||
1126 | |||
1127 | clk->rate = rate; | ||
1128 | |||
1129 | return 0; | ||
1130 | } | ||
1131 | |||
1132 | static struct clk_ops s5pv210_epll_ops = { | ||
1133 | .set_rate = s5pv210_epll_set_rate, | ||
1134 | .get_rate = s5p_epll_get_rate, | ||
956 | }; | 1135 | }; |
957 | 1136 | ||
958 | void __init_or_cpufreq s5pv210_setup_clocks(void) | 1137 | void __init_or_cpufreq s5pv210_setup_clocks(void) |
959 | { | 1138 | { |
960 | struct clk *xtal_clk; | 1139 | struct clk *xtal_clk; |
961 | unsigned long xtal; | ||
962 | unsigned long vpllsrc; | 1140 | unsigned long vpllsrc; |
963 | unsigned long armclk; | 1141 | unsigned long armclk; |
964 | unsigned long hclk_msys; | 1142 | unsigned long hclk_msys; |
@@ -974,6 +1152,10 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) | |||
974 | unsigned int ptr; | 1152 | unsigned int ptr; |
975 | u32 clkdiv0, clkdiv1; | 1153 | u32 clkdiv0, clkdiv1; |
976 | 1154 | ||
1155 | /* Set functions for clk_fout_epll */ | ||
1156 | clk_fout_epll.enable = s5p_epll_enable; | ||
1157 | clk_fout_epll.ops = &s5pv210_epll_ops; | ||
1158 | |||
977 | printk(KERN_DEBUG "%s: registering clocks\n", __func__); | 1159 | printk(KERN_DEBUG "%s: registering clocks\n", __func__); |
978 | 1160 | ||
979 | clkdiv0 = __raw_readl(S5P_CLK_DIV0); | 1161 | clkdiv0 = __raw_readl(S5P_CLK_DIV0); |
@@ -992,11 +1174,12 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) | |||
992 | 1174 | ||
993 | apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508); | 1175 | apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508); |
994 | mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); | 1176 | mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); |
995 | epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500); | 1177 | epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON), |
1178 | __raw_readl(S5P_EPLL_CON1), pll_4600); | ||
996 | vpllsrc = clk_get_rate(&clk_vpllsrc.clk); | 1179 | vpllsrc = clk_get_rate(&clk_vpllsrc.clk); |
997 | vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502); | 1180 | vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502); |
998 | 1181 | ||
999 | clk_fout_apll.rate = apll; | 1182 | clk_fout_apll.ops = &clk_fout_apll_ops; |
1000 | clk_fout_mpll.rate = mpll; | 1183 | clk_fout_mpll.rate = mpll; |
1001 | clk_fout_epll.rate = epll; | 1184 | clk_fout_epll.rate = epll; |
1002 | clk_fout_vpll.rate = vpll; | 1185 | clk_fout_vpll.rate = vpll; |
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c index 2f16bfc0a116..8eb480e201b0 100644 --- a/arch/arm/mach-s5pv210/cpu.c +++ b/arch/arm/mach-s5pv210/cpu.c | |||
@@ -85,6 +85,21 @@ static struct map_desc s5pv210_iodesc[] __initdata = { | |||
85 | .pfn = __phys_to_pfn(S5PV210_PA_SROMC), | 85 | .pfn = __phys_to_pfn(S5PV210_PA_SROMC), |
86 | .length = SZ_4K, | 86 | .length = SZ_4K, |
87 | .type = MT_DEVICE, | 87 | .type = MT_DEVICE, |
88 | }, { | ||
89 | .virtual = (unsigned long)S5P_VA_DMC0, | ||
90 | .pfn = __phys_to_pfn(S5PV210_PA_DMC0), | ||
91 | .length = SZ_4K, | ||
92 | .type = MT_DEVICE, | ||
93 | }, { | ||
94 | .virtual = (unsigned long)S5P_VA_DMC1, | ||
95 | .pfn = __phys_to_pfn(S5PV210_PA_DMC1), | ||
96 | .length = SZ_4K, | ||
97 | .type = MT_DEVICE, | ||
98 | }, { | ||
99 | .virtual = (unsigned long)S3C_VA_USB_HSPHY, | ||
100 | .pfn =__phys_to_pfn(S5PV210_PA_HSPHY), | ||
101 | .length = SZ_4K, | ||
102 | .type = MT_DEVICE, | ||
88 | } | 103 | } |
89 | }; | 104 | }; |
90 | 105 | ||
diff --git a/arch/arm/mach-s5pv210/cpufreq.c b/arch/arm/mach-s5pv210/cpufreq.c new file mode 100644 index 000000000000..a6f22920a2c2 --- /dev/null +++ b/arch/arm/mach-s5pv210/cpufreq.c | |||
@@ -0,0 +1,484 @@ | |||
1 | /* linux/arch/arm/mach-s5pv210/cpufreq.c | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com | ||
5 | * | ||
6 | * CPU frequency scaling for S5PC110/S5PV210 | ||
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 | #include <linux/types.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/cpufreq.h> | ||
20 | |||
21 | #include <mach/map.h> | ||
22 | #include <mach/regs-clock.h> | ||
23 | |||
24 | static struct clk *cpu_clk; | ||
25 | static struct clk *dmc0_clk; | ||
26 | static struct clk *dmc1_clk; | ||
27 | static struct cpufreq_freqs freqs; | ||
28 | |||
29 | /* APLL M,P,S values for 1G/800Mhz */ | ||
30 | #define APLL_VAL_1000 ((1 << 31) | (125 << 16) | (3 << 8) | 1) | ||
31 | #define APLL_VAL_800 ((1 << 31) | (100 << 16) | (3 << 8) | 1) | ||
32 | |||
33 | /* | ||
34 | * DRAM configurations to calculate refresh counter for changing | ||
35 | * frequency of memory. | ||
36 | */ | ||
37 | struct dram_conf { | ||
38 | unsigned long freq; /* HZ */ | ||
39 | unsigned long refresh; /* DRAM refresh counter * 1000 */ | ||
40 | }; | ||
41 | |||
42 | /* DRAM configuration (DMC0 and DMC1) */ | ||
43 | static struct dram_conf s5pv210_dram_conf[2]; | ||
44 | |||
45 | enum perf_level { | ||
46 | L0, L1, L2, L3, L4, | ||
47 | }; | ||
48 | |||
49 | enum s5pv210_mem_type { | ||
50 | LPDDR = 0x1, | ||
51 | LPDDR2 = 0x2, | ||
52 | DDR2 = 0x4, | ||
53 | }; | ||
54 | |||
55 | enum s5pv210_dmc_port { | ||
56 | DMC0 = 0, | ||
57 | DMC1, | ||
58 | }; | ||
59 | |||
60 | static struct cpufreq_frequency_table s5pv210_freq_table[] = { | ||
61 | {L0, 1000*1000}, | ||
62 | {L1, 800*1000}, | ||
63 | {L2, 400*1000}, | ||
64 | {L3, 200*1000}, | ||
65 | {L4, 100*1000}, | ||
66 | {0, CPUFREQ_TABLE_END}, | ||
67 | }; | ||
68 | |||
69 | static u32 clkdiv_val[5][11] = { | ||
70 | /* | ||
71 | * Clock divider value for following | ||
72 | * { APLL, A2M, HCLK_MSYS, PCLK_MSYS, | ||
73 | * HCLK_DSYS, PCLK_DSYS, HCLK_PSYS, PCLK_PSYS, | ||
74 | * ONEDRAM, MFC, G3D } | ||
75 | */ | ||
76 | |||
77 | /* L0 : [1000/200/100][166/83][133/66][200/200] */ | ||
78 | {0, 4, 4, 1, 3, 1, 4, 1, 3, 0, 0}, | ||
79 | |||
80 | /* L1 : [800/200/100][166/83][133/66][200/200] */ | ||
81 | {0, 3, 3, 1, 3, 1, 4, 1, 3, 0, 0}, | ||
82 | |||
83 | /* L2 : [400/200/100][166/83][133/66][200/200] */ | ||
84 | {1, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0}, | ||
85 | |||
86 | /* L3 : [200/200/100][166/83][133/66][200/200] */ | ||
87 | {3, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0}, | ||
88 | |||
89 | /* L4 : [100/100/100][83/83][66/66][100/100] */ | ||
90 | {7, 7, 0, 0, 7, 0, 9, 0, 7, 0, 0}, | ||
91 | }; | ||
92 | |||
93 | /* | ||
94 | * This function set DRAM refresh counter | ||
95 | * accoriding to operating frequency of DRAM | ||
96 | * ch: DMC port number 0 or 1 | ||
97 | * freq: Operating frequency of DRAM(KHz) | ||
98 | */ | ||
99 | static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq) | ||
100 | { | ||
101 | unsigned long tmp, tmp1; | ||
102 | void __iomem *reg = NULL; | ||
103 | |||
104 | if (ch == DMC0) | ||
105 | reg = (S5P_VA_DMC0 + 0x30); | ||
106 | else if (ch == DMC1) | ||
107 | reg = (S5P_VA_DMC1 + 0x30); | ||
108 | else | ||
109 | printk(KERN_ERR "Cannot find DMC port\n"); | ||
110 | |||
111 | /* Find current DRAM frequency */ | ||
112 | tmp = s5pv210_dram_conf[ch].freq; | ||
113 | |||
114 | do_div(tmp, freq); | ||
115 | |||
116 | tmp1 = s5pv210_dram_conf[ch].refresh; | ||
117 | |||
118 | do_div(tmp1, tmp); | ||
119 | |||
120 | __raw_writel(tmp1, reg); | ||
121 | } | ||
122 | |||
123 | int s5pv210_verify_speed(struct cpufreq_policy *policy) | ||
124 | { | ||
125 | if (policy->cpu) | ||
126 | return -EINVAL; | ||
127 | |||
128 | return cpufreq_frequency_table_verify(policy, s5pv210_freq_table); | ||
129 | } | ||
130 | |||
131 | unsigned int s5pv210_getspeed(unsigned int cpu) | ||
132 | { | ||
133 | if (cpu) | ||
134 | return 0; | ||
135 | |||
136 | return clk_get_rate(cpu_clk) / 1000; | ||
137 | } | ||
138 | |||
139 | static int s5pv210_target(struct cpufreq_policy *policy, | ||
140 | unsigned int target_freq, | ||
141 | unsigned int relation) | ||
142 | { | ||
143 | unsigned long reg; | ||
144 | unsigned int index, priv_index; | ||
145 | unsigned int pll_changing = 0; | ||
146 | unsigned int bus_speed_changing = 0; | ||
147 | |||
148 | freqs.old = s5pv210_getspeed(0); | ||
149 | |||
150 | if (cpufreq_frequency_table_target(policy, s5pv210_freq_table, | ||
151 | target_freq, relation, &index)) | ||
152 | return -EINVAL; | ||
153 | |||
154 | freqs.new = s5pv210_freq_table[index].frequency; | ||
155 | freqs.cpu = 0; | ||
156 | |||
157 | if (freqs.new == freqs.old) | ||
158 | return 0; | ||
159 | |||
160 | /* Finding current running level index */ | ||
161 | if (cpufreq_frequency_table_target(policy, s5pv210_freq_table, | ||
162 | freqs.old, relation, &priv_index)) | ||
163 | return -EINVAL; | ||
164 | |||
165 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
166 | |||
167 | if (freqs.new > freqs.old) { | ||
168 | /* Voltage up: will be implemented */ | ||
169 | } | ||
170 | |||
171 | /* Check if there need to change PLL */ | ||
172 | if ((index == L0) || (priv_index == L0)) | ||
173 | pll_changing = 1; | ||
174 | |||
175 | /* Check if there need to change System bus clock */ | ||
176 | if ((index == L4) || (priv_index == L4)) | ||
177 | bus_speed_changing = 1; | ||
178 | |||
179 | if (bus_speed_changing) { | ||
180 | /* | ||
181 | * Reconfigure DRAM refresh counter value for minimum | ||
182 | * temporary clock while changing divider. | ||
183 | * expected clock is 83Mhz : 7.8usec/(1/83Mhz) = 0x287 | ||
184 | */ | ||
185 | if (pll_changing) | ||
186 | s5pv210_set_refresh(DMC1, 83000); | ||
187 | else | ||
188 | s5pv210_set_refresh(DMC1, 100000); | ||
189 | |||
190 | s5pv210_set_refresh(DMC0, 83000); | ||
191 | } | ||
192 | |||
193 | /* | ||
194 | * APLL should be changed in this level | ||
195 | * APLL -> MPLL(for stable transition) -> APLL | ||
196 | * Some clock source's clock API are not prepared. | ||
197 | * Do not use clock API in below code. | ||
198 | */ | ||
199 | if (pll_changing) { | ||
200 | /* | ||
201 | * 1. Temporary Change divider for MFC and G3D | ||
202 | * SCLKA2M(200/1=200)->(200/4=50)Mhz | ||
203 | */ | ||
204 | reg = __raw_readl(S5P_CLK_DIV2); | ||
205 | reg &= ~(S5P_CLKDIV2_G3D_MASK | S5P_CLKDIV2_MFC_MASK); | ||
206 | reg |= (3 << S5P_CLKDIV2_G3D_SHIFT) | | ||
207 | (3 << S5P_CLKDIV2_MFC_SHIFT); | ||
208 | __raw_writel(reg, S5P_CLK_DIV2); | ||
209 | |||
210 | /* For MFC, G3D dividing */ | ||
211 | do { | ||
212 | reg = __raw_readl(S5P_CLKDIV_STAT0); | ||
213 | } while (reg & ((1 << 16) | (1 << 17))); | ||
214 | |||
215 | /* | ||
216 | * 2. Change SCLKA2M(200Mhz)to SCLKMPLL in MFC_MUX, G3D MUX | ||
217 | * (200/4=50)->(667/4=166)Mhz | ||
218 | */ | ||
219 | reg = __raw_readl(S5P_CLK_SRC2); | ||
220 | reg &= ~(S5P_CLKSRC2_G3D_MASK | S5P_CLKSRC2_MFC_MASK); | ||
221 | reg |= (1 << S5P_CLKSRC2_G3D_SHIFT) | | ||
222 | (1 << S5P_CLKSRC2_MFC_SHIFT); | ||
223 | __raw_writel(reg, S5P_CLK_SRC2); | ||
224 | |||
225 | do { | ||
226 | reg = __raw_readl(S5P_CLKMUX_STAT1); | ||
227 | } while (reg & ((1 << 7) | (1 << 3))); | ||
228 | |||
229 | /* | ||
230 | * 3. DMC1 refresh count for 133Mhz if (index == L4) is | ||
231 | * true refresh counter is already programed in upper | ||
232 | * code. 0x287@83Mhz | ||
233 | */ | ||
234 | if (!bus_speed_changing) | ||
235 | s5pv210_set_refresh(DMC1, 133000); | ||
236 | |||
237 | /* 4. SCLKAPLL -> SCLKMPLL */ | ||
238 | reg = __raw_readl(S5P_CLK_SRC0); | ||
239 | reg &= ~(S5P_CLKSRC0_MUX200_MASK); | ||
240 | reg |= (0x1 << S5P_CLKSRC0_MUX200_SHIFT); | ||
241 | __raw_writel(reg, S5P_CLK_SRC0); | ||
242 | |||
243 | do { | ||
244 | reg = __raw_readl(S5P_CLKMUX_STAT0); | ||
245 | } while (reg & (0x1 << 18)); | ||
246 | |||
247 | } | ||
248 | |||
249 | /* Change divider */ | ||
250 | reg = __raw_readl(S5P_CLK_DIV0); | ||
251 | |||
252 | reg &= ~(S5P_CLKDIV0_APLL_MASK | S5P_CLKDIV0_A2M_MASK | | ||
253 | S5P_CLKDIV0_HCLK200_MASK | S5P_CLKDIV0_PCLK100_MASK | | ||
254 | S5P_CLKDIV0_HCLK166_MASK | S5P_CLKDIV0_PCLK83_MASK | | ||
255 | S5P_CLKDIV0_HCLK133_MASK | S5P_CLKDIV0_PCLK66_MASK); | ||
256 | |||
257 | reg |= ((clkdiv_val[index][0] << S5P_CLKDIV0_APLL_SHIFT) | | ||
258 | (clkdiv_val[index][1] << S5P_CLKDIV0_A2M_SHIFT) | | ||
259 | (clkdiv_val[index][2] << S5P_CLKDIV0_HCLK200_SHIFT) | | ||
260 | (clkdiv_val[index][3] << S5P_CLKDIV0_PCLK100_SHIFT) | | ||
261 | (clkdiv_val[index][4] << S5P_CLKDIV0_HCLK166_SHIFT) | | ||
262 | (clkdiv_val[index][5] << S5P_CLKDIV0_PCLK83_SHIFT) | | ||
263 | (clkdiv_val[index][6] << S5P_CLKDIV0_HCLK133_SHIFT) | | ||
264 | (clkdiv_val[index][7] << S5P_CLKDIV0_PCLK66_SHIFT)); | ||
265 | |||
266 | __raw_writel(reg, S5P_CLK_DIV0); | ||
267 | |||
268 | do { | ||
269 | reg = __raw_readl(S5P_CLKDIV_STAT0); | ||
270 | } while (reg & 0xff); | ||
271 | |||
272 | /* ARM MCS value changed */ | ||
273 | reg = __raw_readl(S5P_ARM_MCS_CON); | ||
274 | reg &= ~0x3; | ||
275 | if (index >= L3) | ||
276 | reg |= 0x3; | ||
277 | else | ||
278 | reg |= 0x1; | ||
279 | |||
280 | __raw_writel(reg, S5P_ARM_MCS_CON); | ||
281 | |||
282 | if (pll_changing) { | ||
283 | /* 5. Set Lock time = 30us*24Mhz = 0x2cf */ | ||
284 | __raw_writel(0x2cf, S5P_APLL_LOCK); | ||
285 | |||
286 | /* | ||
287 | * 6. Turn on APLL | ||
288 | * 6-1. Set PMS values | ||
289 | * 6-2. Wait untile the PLL is locked | ||
290 | */ | ||
291 | if (index == L0) | ||
292 | __raw_writel(APLL_VAL_1000, S5P_APLL_CON); | ||
293 | else | ||
294 | __raw_writel(APLL_VAL_800, S5P_APLL_CON); | ||
295 | |||
296 | do { | ||
297 | reg = __raw_readl(S5P_APLL_CON); | ||
298 | } while (!(reg & (0x1 << 29))); | ||
299 | |||
300 | /* | ||
301 | * 7. Change souce clock from SCLKMPLL(667Mhz) | ||
302 | * to SCLKA2M(200Mhz) in MFC_MUX and G3D MUX | ||
303 | * (667/4=166)->(200/4=50)Mhz | ||
304 | */ | ||
305 | reg = __raw_readl(S5P_CLK_SRC2); | ||
306 | reg &= ~(S5P_CLKSRC2_G3D_MASK | S5P_CLKSRC2_MFC_MASK); | ||
307 | reg |= (0 << S5P_CLKSRC2_G3D_SHIFT) | | ||
308 | (0 << S5P_CLKSRC2_MFC_SHIFT); | ||
309 | __raw_writel(reg, S5P_CLK_SRC2); | ||
310 | |||
311 | do { | ||
312 | reg = __raw_readl(S5P_CLKMUX_STAT1); | ||
313 | } while (reg & ((1 << 7) | (1 << 3))); | ||
314 | |||
315 | /* | ||
316 | * 8. Change divider for MFC and G3D | ||
317 | * (200/4=50)->(200/1=200)Mhz | ||
318 | */ | ||
319 | reg = __raw_readl(S5P_CLK_DIV2); | ||
320 | reg &= ~(S5P_CLKDIV2_G3D_MASK | S5P_CLKDIV2_MFC_MASK); | ||
321 | reg |= (clkdiv_val[index][10] << S5P_CLKDIV2_G3D_SHIFT) | | ||
322 | (clkdiv_val[index][9] << S5P_CLKDIV2_MFC_SHIFT); | ||
323 | __raw_writel(reg, S5P_CLK_DIV2); | ||
324 | |||
325 | /* For MFC, G3D dividing */ | ||
326 | do { | ||
327 | reg = __raw_readl(S5P_CLKDIV_STAT0); | ||
328 | } while (reg & ((1 << 16) | (1 << 17))); | ||
329 | |||
330 | /* 9. Change MPLL to APLL in MSYS_MUX */ | ||
331 | reg = __raw_readl(S5P_CLK_SRC0); | ||
332 | reg &= ~(S5P_CLKSRC0_MUX200_MASK); | ||
333 | reg |= (0x0 << S5P_CLKSRC0_MUX200_SHIFT); | ||
334 | __raw_writel(reg, S5P_CLK_SRC0); | ||
335 | |||
336 | do { | ||
337 | reg = __raw_readl(S5P_CLKMUX_STAT0); | ||
338 | } while (reg & (0x1 << 18)); | ||
339 | |||
340 | /* | ||
341 | * 10. DMC1 refresh counter | ||
342 | * L4 : DMC1 = 100Mhz 7.8us/(1/100) = 0x30c | ||
343 | * Others : DMC1 = 200Mhz 7.8us/(1/200) = 0x618 | ||
344 | */ | ||
345 | if (!bus_speed_changing) | ||
346 | s5pv210_set_refresh(DMC1, 200000); | ||
347 | } | ||
348 | |||
349 | /* | ||
350 | * L4 level need to change memory bus speed, hence onedram clock divier | ||
351 | * and memory refresh parameter should be changed | ||
352 | */ | ||
353 | if (bus_speed_changing) { | ||
354 | reg = __raw_readl(S5P_CLK_DIV6); | ||
355 | reg &= ~S5P_CLKDIV6_ONEDRAM_MASK; | ||
356 | reg |= (clkdiv_val[index][8] << S5P_CLKDIV6_ONEDRAM_SHIFT); | ||
357 | __raw_writel(reg, S5P_CLK_DIV6); | ||
358 | |||
359 | do { | ||
360 | reg = __raw_readl(S5P_CLKDIV_STAT1); | ||
361 | } while (reg & (1 << 15)); | ||
362 | |||
363 | /* Reconfigure DRAM refresh counter value */ | ||
364 | if (index != L4) { | ||
365 | /* | ||
366 | * DMC0 : 166Mhz | ||
367 | * DMC1 : 200Mhz | ||
368 | */ | ||
369 | s5pv210_set_refresh(DMC0, 166000); | ||
370 | s5pv210_set_refresh(DMC1, 200000); | ||
371 | } else { | ||
372 | /* | ||
373 | * DMC0 : 83Mhz | ||
374 | * DMC1 : 100Mhz | ||
375 | */ | ||
376 | s5pv210_set_refresh(DMC0, 83000); | ||
377 | s5pv210_set_refresh(DMC1, 100000); | ||
378 | } | ||
379 | } | ||
380 | |||
381 | if (freqs.new < freqs.old) { | ||
382 | /* Voltage down: will be implemented */ | ||
383 | } | ||
384 | |||
385 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
386 | |||
387 | printk(KERN_DEBUG "Perf changed[L%d]\n", index); | ||
388 | |||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | #ifdef CONFIG_PM | ||
393 | static int s5pv210_cpufreq_suspend(struct cpufreq_policy *policy, | ||
394 | pm_message_t pmsg) | ||
395 | { | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | static int s5pv210_cpufreq_resume(struct cpufreq_policy *policy) | ||
400 | { | ||
401 | return 0; | ||
402 | } | ||
403 | #endif | ||
404 | |||
405 | static int check_mem_type(void __iomem *dmc_reg) | ||
406 | { | ||
407 | unsigned long val; | ||
408 | |||
409 | val = __raw_readl(dmc_reg + 0x4); | ||
410 | val = (val & (0xf << 8)); | ||
411 | |||
412 | return val >> 8; | ||
413 | } | ||
414 | |||
415 | static int __init s5pv210_cpu_init(struct cpufreq_policy *policy) | ||
416 | { | ||
417 | unsigned long mem_type; | ||
418 | |||
419 | cpu_clk = clk_get(NULL, "armclk"); | ||
420 | if (IS_ERR(cpu_clk)) | ||
421 | return PTR_ERR(cpu_clk); | ||
422 | |||
423 | dmc0_clk = clk_get(NULL, "sclk_dmc0"); | ||
424 | if (IS_ERR(dmc0_clk)) { | ||
425 | clk_put(cpu_clk); | ||
426 | return PTR_ERR(dmc0_clk); | ||
427 | } | ||
428 | |||
429 | dmc1_clk = clk_get(NULL, "hclk_msys"); | ||
430 | if (IS_ERR(dmc1_clk)) { | ||
431 | clk_put(dmc0_clk); | ||
432 | clk_put(cpu_clk); | ||
433 | return PTR_ERR(dmc1_clk); | ||
434 | } | ||
435 | |||
436 | if (policy->cpu != 0) | ||
437 | return -EINVAL; | ||
438 | |||
439 | /* | ||
440 | * check_mem_type : This driver only support LPDDR & LPDDR2. | ||
441 | * other memory type is not supported. | ||
442 | */ | ||
443 | mem_type = check_mem_type(S5P_VA_DMC0); | ||
444 | |||
445 | if ((mem_type != LPDDR) && (mem_type != LPDDR2)) { | ||
446 | printk(KERN_ERR "CPUFreq doesn't support this memory type\n"); | ||
447 | return -EINVAL; | ||
448 | } | ||
449 | |||
450 | /* Find current refresh counter and frequency each DMC */ | ||
451 | s5pv210_dram_conf[0].refresh = (__raw_readl(S5P_VA_DMC0 + 0x30) * 1000); | ||
452 | s5pv210_dram_conf[0].freq = clk_get_rate(dmc0_clk); | ||
453 | |||
454 | s5pv210_dram_conf[1].refresh = (__raw_readl(S5P_VA_DMC1 + 0x30) * 1000); | ||
455 | s5pv210_dram_conf[1].freq = clk_get_rate(dmc1_clk); | ||
456 | |||
457 | policy->cur = policy->min = policy->max = s5pv210_getspeed(0); | ||
458 | |||
459 | cpufreq_frequency_table_get_attr(s5pv210_freq_table, policy->cpu); | ||
460 | |||
461 | policy->cpuinfo.transition_latency = 40000; | ||
462 | |||
463 | return cpufreq_frequency_table_cpuinfo(policy, s5pv210_freq_table); | ||
464 | } | ||
465 | |||
466 | static struct cpufreq_driver s5pv210_driver = { | ||
467 | .flags = CPUFREQ_STICKY, | ||
468 | .verify = s5pv210_verify_speed, | ||
469 | .target = s5pv210_target, | ||
470 | .get = s5pv210_getspeed, | ||
471 | .init = s5pv210_cpu_init, | ||
472 | .name = "s5pv210", | ||
473 | #ifdef CONFIG_PM | ||
474 | .suspend = s5pv210_cpufreq_suspend, | ||
475 | .resume = s5pv210_cpufreq_resume, | ||
476 | #endif | ||
477 | }; | ||
478 | |||
479 | static int __init s5pv210_cpufreq_init(void) | ||
480 | { | ||
481 | return cpufreq_register_driver(&s5pv210_driver); | ||
482 | } | ||
483 | |||
484 | late_initcall(s5pv210_cpufreq_init); | ||
diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c index 21dc6cf955c3..1303fcb12b51 100644 --- a/arch/arm/mach-s5pv210/dev-audio.c +++ b/arch/arm/mach-s5pv210/dev-audio.c | |||
@@ -24,29 +24,15 @@ static int s5pv210_cfg_i2s(struct platform_device *pdev) | |||
24 | /* configure GPIO for i2s port */ | 24 | /* configure GPIO for i2s port */ |
25 | switch (pdev->id) { | 25 | switch (pdev->id) { |
26 | case 1: | 26 | case 1: |
27 | s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(2)); | 27 | s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2)); |
28 | s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(2)); | ||
29 | s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(2)); | ||
30 | s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(2)); | ||
31 | s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(2)); | ||
32 | break; | 28 | break; |
33 | 29 | ||
34 | case 2: | 30 | case 2: |
35 | s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(4)); | 31 | s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4)); |
36 | s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(4)); | ||
37 | s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(4)); | ||
38 | s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(4)); | ||
39 | s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(4)); | ||
40 | break; | 32 | break; |
41 | 33 | ||
42 | case -1: | 34 | case -1: |
43 | s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(2)); | 35 | s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2)); |
44 | s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(2)); | ||
45 | s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(2)); | ||
46 | s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(2)); | ||
47 | s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(2)); | ||
48 | s3c_gpio_cfgpin(S5PV210_GPI(5), S3C_GPIO_SFN(2)); | ||
49 | s3c_gpio_cfgpin(S5PV210_GPI(6), S3C_GPIO_SFN(2)); | ||
50 | break; | 36 | break; |
51 | 37 | ||
52 | default: | 38 | default: |
@@ -151,25 +137,13 @@ static int s5pv210_pcm_cfg_gpio(struct platform_device *pdev) | |||
151 | { | 137 | { |
152 | switch (pdev->id) { | 138 | switch (pdev->id) { |
153 | case 0: | 139 | case 0: |
154 | s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(3)); | 140 | s3c_gpio_cfgpin_range(S5PV210_GPI(0), 5, S3C_GPIO_SFN(3)); |
155 | s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(3)); | ||
156 | s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(3)); | ||
157 | s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(3)); | ||
158 | s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(3)); | ||
159 | break; | 141 | break; |
160 | case 1: | 142 | case 1: |
161 | s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(3)); | 143 | s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(3)); |
162 | s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(3)); | ||
163 | s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(3)); | ||
164 | s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(3)); | ||
165 | s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(3)); | ||
166 | break; | 144 | break; |
167 | case 2: | 145 | case 2: |
168 | s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(2)); | 146 | s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(2)); |
169 | s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(2)); | ||
170 | s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(2)); | ||
171 | s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(2)); | ||
172 | s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(2)); | ||
173 | break; | 147 | break; |
174 | default: | 148 | default: |
175 | printk(KERN_DEBUG "Invalid PCM Controller number!"); | 149 | printk(KERN_DEBUG "Invalid PCM Controller number!"); |
@@ -271,13 +245,7 @@ struct platform_device s5pv210_device_pcm2 = { | |||
271 | 245 | ||
272 | static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev) | 246 | static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev) |
273 | { | 247 | { |
274 | s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(4)); | 248 | return s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(4)); |
275 | s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(4)); | ||
276 | s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(4)); | ||
277 | s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(4)); | ||
278 | s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(4)); | ||
279 | |||
280 | return 0; | ||
281 | } | 249 | } |
282 | 250 | ||
283 | static struct resource s5pv210_ac97_resource[] = { | 251 | static struct resource s5pv210_ac97_resource[] = { |
@@ -325,3 +293,43 @@ struct platform_device s5pv210_device_ac97 = { | |||
325 | .coherent_dma_mask = DMA_BIT_MASK(32), | 293 | .coherent_dma_mask = DMA_BIT_MASK(32), |
326 | }, | 294 | }, |
327 | }; | 295 | }; |
296 | |||
297 | /* S/PDIF Controller platform_device */ | ||
298 | |||
299 | static int s5pv210_spdif_cfg_gpio(struct platform_device *pdev) | ||
300 | { | ||
301 | s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 2, S3C_GPIO_SFN(3)); | ||
302 | |||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | static struct resource s5pv210_spdif_resource[] = { | ||
307 | [0] = { | ||
308 | .start = S5PV210_PA_SPDIF, | ||
309 | .end = S5PV210_PA_SPDIF + 0x100 - 1, | ||
310 | .flags = IORESOURCE_MEM, | ||
311 | }, | ||
312 | [1] = { | ||
313 | .start = DMACH_SPDIF, | ||
314 | .end = DMACH_SPDIF, | ||
315 | .flags = IORESOURCE_DMA, | ||
316 | }, | ||
317 | }; | ||
318 | |||
319 | static struct s3c_audio_pdata samsung_spdif_pdata = { | ||
320 | .cfg_gpio = s5pv210_spdif_cfg_gpio, | ||
321 | }; | ||
322 | |||
323 | static u64 s5pv210_spdif_dmamask = DMA_BIT_MASK(32); | ||
324 | |||
325 | struct platform_device s5pv210_device_spdif = { | ||
326 | .name = "samsung-spdif", | ||
327 | .id = -1, | ||
328 | .num_resources = ARRAY_SIZE(s5pv210_spdif_resource), | ||
329 | .resource = s5pv210_spdif_resource, | ||
330 | .dev = { | ||
331 | .platform_data = &samsung_spdif_pdata, | ||
332 | .dma_mask = &s5pv210_spdif_dmamask, | ||
333 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
334 | }, | ||
335 | }; | ||
diff --git a/arch/arm/mach-s5pv210/dev-spi.c b/arch/arm/mach-s5pv210/dev-spi.c index 826cdbc43e20..e3249a47e3b1 100644 --- a/arch/arm/mach-s5pv210/dev-spi.c +++ b/arch/arm/mach-s5pv210/dev-spi.c | |||
@@ -35,23 +35,15 @@ static char *spi_src_clks[] = { | |||
35 | */ | 35 | */ |
36 | static int s5pv210_spi_cfg_gpio(struct platform_device *pdev) | 36 | static int s5pv210_spi_cfg_gpio(struct platform_device *pdev) |
37 | { | 37 | { |
38 | unsigned int base; | ||
39 | |||
38 | switch (pdev->id) { | 40 | switch (pdev->id) { |
39 | case 0: | 41 | case 0: |
40 | s3c_gpio_cfgpin(S5PV210_GPB(0), S3C_GPIO_SFN(2)); | 42 | base = S5PV210_GPB(0); |
41 | s3c_gpio_cfgpin(S5PV210_GPB(1), S3C_GPIO_SFN(2)); | ||
42 | s3c_gpio_cfgpin(S5PV210_GPB(2), S3C_GPIO_SFN(2)); | ||
43 | s3c_gpio_setpull(S5PV210_GPB(0), S3C_GPIO_PULL_UP); | ||
44 | s3c_gpio_setpull(S5PV210_GPB(1), S3C_GPIO_PULL_UP); | ||
45 | s3c_gpio_setpull(S5PV210_GPB(2), S3C_GPIO_PULL_UP); | ||
46 | break; | 43 | break; |
47 | 44 | ||
48 | case 1: | 45 | case 1: |
49 | s3c_gpio_cfgpin(S5PV210_GPB(4), S3C_GPIO_SFN(2)); | 46 | base = S5PV210_GPB(4); |
50 | s3c_gpio_cfgpin(S5PV210_GPB(5), S3C_GPIO_SFN(2)); | ||
51 | s3c_gpio_cfgpin(S5PV210_GPB(6), S3C_GPIO_SFN(2)); | ||
52 | s3c_gpio_setpull(S5PV210_GPB(4), S3C_GPIO_PULL_UP); | ||
53 | s3c_gpio_setpull(S5PV210_GPB(5), S3C_GPIO_PULL_UP); | ||
54 | s3c_gpio_setpull(S5PV210_GPB(6), S3C_GPIO_PULL_UP); | ||
55 | break; | 47 | break; |
56 | 48 | ||
57 | default: | 49 | default: |
@@ -59,6 +51,9 @@ static int s5pv210_spi_cfg_gpio(struct platform_device *pdev) | |||
59 | return -EINVAL; | 51 | return -EINVAL; |
60 | } | 52 | } |
61 | 53 | ||
54 | s3c_gpio_cfgall_range(base, 3, | ||
55 | S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); | ||
56 | |||
62 | return 0; | 57 | return 0; |
63 | } | 58 | } |
64 | 59 | ||
diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c index 778ad5fe231a..497d3439a142 100644 --- a/arch/arm/mach-s5pv210/dma.c +++ b/arch/arm/mach-s5pv210/dma.c | |||
@@ -82,7 +82,7 @@ static struct s3c_pl330_platdata s5pv210_pdma0_pdata = { | |||
82 | 82 | ||
83 | static struct platform_device s5pv210_device_pdma0 = { | 83 | static struct platform_device s5pv210_device_pdma0 = { |
84 | .name = "s3c-pl330", | 84 | .name = "s3c-pl330", |
85 | .id = 1, | 85 | .id = 0, |
86 | .num_resources = ARRAY_SIZE(s5pv210_pdma0_resource), | 86 | .num_resources = ARRAY_SIZE(s5pv210_pdma0_resource), |
87 | .resource = s5pv210_pdma0_resource, | 87 | .resource = s5pv210_pdma0_resource, |
88 | .dev = { | 88 | .dev = { |
@@ -144,7 +144,7 @@ static struct s3c_pl330_platdata s5pv210_pdma1_pdata = { | |||
144 | 144 | ||
145 | static struct platform_device s5pv210_device_pdma1 = { | 145 | static struct platform_device s5pv210_device_pdma1 = { |
146 | .name = "s3c-pl330", | 146 | .name = "s3c-pl330", |
147 | .id = 2, | 147 | .id = 1, |
148 | .num_resources = ARRAY_SIZE(s5pv210_pdma1_resource), | 148 | .num_resources = ARRAY_SIZE(s5pv210_pdma1_resource), |
149 | .resource = s5pv210_pdma1_resource, | 149 | .resource = s5pv210_pdma1_resource, |
150 | .dev = { | 150 | .dev = { |
diff --git a/arch/arm/mach-s5pv210/gpiolib.c b/arch/arm/mach-s5pv210/gpiolib.c index 0d459112d039..ab673effd767 100644 --- a/arch/arm/mach-s5pv210/gpiolib.c +++ b/arch/arm/mach-s5pv210/gpiolib.c | |||
@@ -150,6 +150,7 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = { | |||
150 | .label = "GPG3", | 150 | .label = "GPG3", |
151 | }, | 151 | }, |
152 | }, { | 152 | }, { |
153 | .config = &gpio_cfg_noint, | ||
153 | .chip = { | 154 | .chip = { |
154 | .base = S5PV210_GPI(0), | 155 | .base = S5PV210_GPI(0), |
155 | .ngpio = S5PV210_GPIO_I_NR, | 156 | .ngpio = S5PV210_GPIO_I_NR, |
@@ -223,34 +224,42 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = { | |||
223 | }, { | 224 | }, { |
224 | .base = (S5P_VA_GPIO + 0xC00), | 225 | .base = (S5P_VA_GPIO + 0xC00), |
225 | .config = &gpio_cfg_noint, | 226 | .config = &gpio_cfg_noint, |
227 | .irq_base = IRQ_EINT(0), | ||
226 | .chip = { | 228 | .chip = { |
227 | .base = S5PV210_GPH0(0), | 229 | .base = S5PV210_GPH0(0), |
228 | .ngpio = S5PV210_GPIO_H0_NR, | 230 | .ngpio = S5PV210_GPIO_H0_NR, |
229 | .label = "GPH0", | 231 | .label = "GPH0", |
232 | .to_irq = samsung_gpiolib_to_irq, | ||
230 | }, | 233 | }, |
231 | }, { | 234 | }, { |
232 | .base = (S5P_VA_GPIO + 0xC20), | 235 | .base = (S5P_VA_GPIO + 0xC20), |
233 | .config = &gpio_cfg_noint, | 236 | .config = &gpio_cfg_noint, |
237 | .irq_base = IRQ_EINT(8), | ||
234 | .chip = { | 238 | .chip = { |
235 | .base = S5PV210_GPH1(0), | 239 | .base = S5PV210_GPH1(0), |
236 | .ngpio = S5PV210_GPIO_H1_NR, | 240 | .ngpio = S5PV210_GPIO_H1_NR, |
237 | .label = "GPH1", | 241 | .label = "GPH1", |
242 | .to_irq = samsung_gpiolib_to_irq, | ||
238 | }, | 243 | }, |
239 | }, { | 244 | }, { |
240 | .base = (S5P_VA_GPIO + 0xC40), | 245 | .base = (S5P_VA_GPIO + 0xC40), |
241 | .config = &gpio_cfg_noint, | 246 | .config = &gpio_cfg_noint, |
247 | .irq_base = IRQ_EINT(16), | ||
242 | .chip = { | 248 | .chip = { |
243 | .base = S5PV210_GPH2(0), | 249 | .base = S5PV210_GPH2(0), |
244 | .ngpio = S5PV210_GPIO_H2_NR, | 250 | .ngpio = S5PV210_GPIO_H2_NR, |
245 | .label = "GPH2", | 251 | .label = "GPH2", |
252 | .to_irq = samsung_gpiolib_to_irq, | ||
246 | }, | 253 | }, |
247 | }, { | 254 | }, { |
248 | .base = (S5P_VA_GPIO + 0xC60), | 255 | .base = (S5P_VA_GPIO + 0xC60), |
249 | .config = &gpio_cfg_noint, | 256 | .config = &gpio_cfg_noint, |
257 | .irq_base = IRQ_EINT(24), | ||
250 | .chip = { | 258 | .chip = { |
251 | .base = S5PV210_GPH3(0), | 259 | .base = S5PV210_GPH3(0), |
252 | .ngpio = S5PV210_GPIO_H3_NR, | 260 | .ngpio = S5PV210_GPIO_H3_NR, |
253 | .label = "GPH3", | 261 | .label = "GPH3", |
262 | .to_irq = samsung_gpiolib_to_irq, | ||
254 | }, | 263 | }, |
255 | }, | 264 | }, |
256 | }; | 265 | }; |
@@ -259,11 +268,14 @@ static __init int s5pv210_gpiolib_init(void) | |||
259 | { | 268 | { |
260 | struct s3c_gpio_chip *chip = s5pv210_gpio_4bit; | 269 | struct s3c_gpio_chip *chip = s5pv210_gpio_4bit; |
261 | int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit); | 270 | int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit); |
271 | int gpioint_group = 0; | ||
262 | int i = 0; | 272 | int i = 0; |
263 | 273 | ||
264 | for (i = 0; i < nr_chips; i++, chip++) { | 274 | for (i = 0; i < nr_chips; i++, chip++) { |
265 | if (chip->config == NULL) | 275 | if (chip->config == NULL) { |
266 | chip->config = &gpio_cfg; | 276 | chip->config = &gpio_cfg; |
277 | chip->group = gpioint_group++; | ||
278 | } | ||
267 | if (chip->base == NULL) | 279 | if (chip->base == NULL) |
268 | chip->base = S5PV210_BANK_BASE(i); | 280 | chip->base = S5PV210_BANK_BASE(i); |
269 | } | 281 | } |
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h index e1c020e5a49b..119b95fdc3ce 100644 --- a/arch/arm/mach-s5pv210/include/mach/irqs.h +++ b/arch/arm/mach-s5pv210/include/mach/irqs.h | |||
@@ -55,8 +55,8 @@ | |||
55 | #define IRQ_SPI1 S5P_IRQ_VIC1(16) | 55 | #define IRQ_SPI1 S5P_IRQ_VIC1(16) |
56 | #define IRQ_SPI2 S5P_IRQ_VIC1(17) | 56 | #define IRQ_SPI2 S5P_IRQ_VIC1(17) |
57 | #define IRQ_IRDA S5P_IRQ_VIC1(18) | 57 | #define IRQ_IRDA S5P_IRQ_VIC1(18) |
58 | #define IRQ_CAN0 S5P_IRQ_VIC1(19) | 58 | #define IRQ_IIC2 S5P_IRQ_VIC1(19) |
59 | #define IRQ_CAN1 S5P_IRQ_VIC1(20) | 59 | #define IRQ_IIC3 S5P_IRQ_VIC1(20) |
60 | #define IRQ_HSIRX S5P_IRQ_VIC1(21) | 60 | #define IRQ_HSIRX S5P_IRQ_VIC1(21) |
61 | #define IRQ_HSITX S5P_IRQ_VIC1(22) | 61 | #define IRQ_HSITX S5P_IRQ_VIC1(22) |
62 | #define IRQ_UHOST S5P_IRQ_VIC1(23) | 62 | #define IRQ_UHOST S5P_IRQ_VIC1(23) |
@@ -109,7 +109,7 @@ | |||
109 | 109 | ||
110 | #define IRQ_IPC S5P_IRQ_VIC3(0) | 110 | #define IRQ_IPC S5P_IRQ_VIC3(0) |
111 | #define IRQ_HOSTIF S5P_IRQ_VIC3(1) | 111 | #define IRQ_HOSTIF S5P_IRQ_VIC3(1) |
112 | #define IRQ_MMC3 S5P_IRQ_VIC3(2) | 112 | #define IRQ_HSMMC3 S5P_IRQ_VIC3(2) |
113 | #define IRQ_CEC S5P_IRQ_VIC3(3) | 113 | #define IRQ_CEC S5P_IRQ_VIC3(3) |
114 | #define IRQ_TSI S5P_IRQ_VIC3(4) | 114 | #define IRQ_TSI S5P_IRQ_VIC3(4) |
115 | #define IRQ_MDNIE0 S5P_IRQ_VIC3(5) | 115 | #define IRQ_MDNIE0 S5P_IRQ_VIC3(5) |
@@ -121,8 +121,12 @@ | |||
121 | #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) | 121 | #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) |
122 | #define S5P_EINT_BASE2 (IRQ_VIC_END + 1) | 122 | #define S5P_EINT_BASE2 (IRQ_VIC_END + 1) |
123 | 123 | ||
124 | /* GPIO interrupt */ | ||
125 | #define S5P_GPIOINT_BASE (IRQ_EINT(31) + 1) | ||
126 | #define S5P_GPIOINT_GROUP_MAXNR 22 | ||
127 | |||
124 | /* Set the default NR_IRQS */ | 128 | /* Set the default NR_IRQS */ |
125 | #define NR_IRQS (IRQ_EINT(31) + 1) | 129 | #define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1) |
126 | 130 | ||
127 | /* Compatibility */ | 131 | /* Compatibility */ |
128 | #define IRQ_LCD_FIFO IRQ_LCD0 | 132 | #define IRQ_LCD_FIFO IRQ_LCD0 |
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h index bd9afd52466a..861d7fe11fc9 100644 --- a/arch/arm/mach-s5pv210/include/mach/map.h +++ b/arch/arm/mach-s5pv210/include/mach/map.h | |||
@@ -57,6 +57,8 @@ | |||
57 | 57 | ||
58 | #define S5P_SZ_UART SZ_256 | 58 | #define S5P_SZ_UART SZ_256 |
59 | 59 | ||
60 | #define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) | ||
61 | |||
60 | #define S5PV210_PA_SROMC (0xE8000000) | 62 | #define S5PV210_PA_SROMC (0xE8000000) |
61 | 63 | ||
62 | #define S5PV210_PA_CFCON (0xE8200000) | 64 | #define S5PV210_PA_CFCON (0xE8200000) |
@@ -73,6 +75,9 @@ | |||
73 | 75 | ||
74 | #define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000)) | 76 | #define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000)) |
75 | 77 | ||
78 | #define S5PV210_PA_HSOTG (0xEC000000) | ||
79 | #define S5PV210_PA_HSPHY (0xEC100000) | ||
80 | |||
76 | #define S5PV210_PA_VIC0 (0xF2000000) | 81 | #define S5PV210_PA_VIC0 (0xF2000000) |
77 | #define S5PV210_PA_VIC1 (0xF2100000) | 82 | #define S5PV210_PA_VIC1 (0xF2100000) |
78 | #define S5PV210_PA_VIC2 (0xF2200000) | 83 | #define S5PV210_PA_VIC2 (0xF2200000) |
@@ -81,6 +86,9 @@ | |||
81 | #define S5PV210_PA_SDRAM (0x20000000) | 86 | #define S5PV210_PA_SDRAM (0x20000000) |
82 | #define S5P_PA_SDRAM S5PV210_PA_SDRAM | 87 | #define S5P_PA_SDRAM S5PV210_PA_SDRAM |
83 | 88 | ||
89 | /* S/PDIF */ | ||
90 | #define S5PV210_PA_SPDIF 0xE1100000 | ||
91 | |||
84 | /* I2S */ | 92 | /* I2S */ |
85 | #define S5PV210_PA_IIS0 0xEEE30000 | 93 | #define S5PV210_PA_IIS0 0xEEE30000 |
86 | #define S5PV210_PA_IIS1 0xE2100000 | 94 | #define S5PV210_PA_IIS1 0xE2100000 |
@@ -96,6 +104,9 @@ | |||
96 | 104 | ||
97 | #define S5PV210_PA_ADC (0xE1700000) | 105 | #define S5PV210_PA_ADC (0xE1700000) |
98 | 106 | ||
107 | #define S5PV210_PA_DMC0 (0xF0000000) | ||
108 | #define S5PV210_PA_DMC1 (0xF1400000) | ||
109 | |||
99 | /* compatibiltiy defines. */ | 110 | /* compatibiltiy defines. */ |
100 | #define S3C_PA_UART S5PV210_PA_UART | 111 | #define S3C_PA_UART S5PV210_PA_UART |
101 | #define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0) | 112 | #define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0) |
@@ -108,6 +119,7 @@ | |||
108 | #define S3C_PA_FB S5PV210_PA_FB | 119 | #define S3C_PA_FB S5PV210_PA_FB |
109 | #define S3C_PA_RTC S5PV210_PA_RTC | 120 | #define S3C_PA_RTC S5PV210_PA_RTC |
110 | #define S3C_PA_WDT S5PV210_PA_WATCHDOG | 121 | #define S3C_PA_WDT S5PV210_PA_WATCHDOG |
122 | #define S3C_PA_USB_HSOTG S5PV210_PA_HSOTG | ||
111 | #define S5P_PA_FIMC0 S5PV210_PA_FIMC0 | 123 | #define S5P_PA_FIMC0 S5PV210_PA_FIMC0 |
112 | #define S5P_PA_FIMC1 S5PV210_PA_FIMC1 | 124 | #define S5P_PA_FIMC1 S5PV210_PA_FIMC1 |
113 | #define S5P_PA_FIMC2 S5PV210_PA_FIMC2 | 125 | #define S5P_PA_FIMC2 S5PV210_PA_FIMC2 |
diff --git a/arch/arm/mach-s5pv210/include/mach/pm-core.h b/arch/arm/mach-s5pv210/include/mach/pm-core.h new file mode 100644 index 000000000000..e8d394f8b057 --- /dev/null +++ b/arch/arm/mach-s5pv210/include/mach/pm-core.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* linux/arch/arm/mach-s5pv210/include/mach/pm-core.h | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com | ||
5 | * | ||
6 | * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h, | ||
7 | * Copyright 2008 Simtec Electronics | ||
8 | * Ben Dooks <ben@simtec.co.uk> | ||
9 | * http://armlinux.simtec.co.uk/ | ||
10 | * | ||
11 | * S5PV210 - PM core support for arch/arm/plat-s5p/pm.c | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License version 2 as | ||
15 | * published by the Free Software Foundation. | ||
16 | */ | ||
17 | |||
18 | static inline void s3c_pm_debug_init_uart(void) | ||
19 | { | ||
20 | /* nothing here yet */ | ||
21 | } | ||
22 | |||
23 | static inline void s3c_pm_arch_prepare_irqs(void) | ||
24 | { | ||
25 | __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK); | ||
26 | __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK); | ||
27 | } | ||
28 | |||
29 | static inline void s3c_pm_arch_stop_clocks(void) | ||
30 | { | ||
31 | /* nothing here yet */ | ||
32 | } | ||
33 | |||
34 | static inline void s3c_pm_arch_show_resume_irqs(void) | ||
35 | { | ||
36 | /* nothing here yet */ | ||
37 | } | ||
38 | |||
39 | static inline void s3c_pm_arch_update_uart(void __iomem *regs, | ||
40 | struct pm_uart_save *save) | ||
41 | { | ||
42 | /* nothing here yet */ | ||
43 | } | ||
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h index 499aef737476..ebaabe021af9 100644 --- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h +++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define S5P_APLL_CON S5P_CLKREG(0x100) | 25 | #define S5P_APLL_CON S5P_CLKREG(0x100) |
26 | #define S5P_MPLL_CON S5P_CLKREG(0x108) | 26 | #define S5P_MPLL_CON S5P_CLKREG(0x108) |
27 | #define S5P_EPLL_CON S5P_CLKREG(0x110) | 27 | #define S5P_EPLL_CON S5P_CLKREG(0x110) |
28 | #define S5P_EPLL_CON1 S5P_CLKREG(0x114) | ||
28 | #define S5P_VPLL_CON S5P_CLKREG(0x120) | 29 | #define S5P_VPLL_CON S5P_CLKREG(0x120) |
29 | 30 | ||
30 | #define S5P_CLK_SRC0 S5P_CLKREG(0x200) | 31 | #define S5P_CLK_SRC0 S5P_CLKREG(0x200) |
@@ -67,11 +68,28 @@ | |||
67 | #define S5P_CLKGATE_BUS1 S5P_CLKREG(0x488) | 68 | #define S5P_CLKGATE_BUS1 S5P_CLKREG(0x488) |
68 | #define S5P_CLK_OUT S5P_CLKREG(0x500) | 69 | #define S5P_CLK_OUT S5P_CLKREG(0x500) |
69 | 70 | ||
71 | /* DIV/MUX STATUS */ | ||
72 | #define S5P_CLKDIV_STAT0 S5P_CLKREG(0x1000) | ||
73 | #define S5P_CLKDIV_STAT1 S5P_CLKREG(0x1004) | ||
74 | #define S5P_CLKMUX_STAT0 S5P_CLKREG(0x1100) | ||
75 | #define S5P_CLKMUX_STAT1 S5P_CLKREG(0x1104) | ||
76 | |||
70 | /* CLKSRC0 */ | 77 | /* CLKSRC0 */ |
71 | #define S5P_CLKSRC0_MUX200_MASK (0x1<<16) | 78 | #define S5P_CLKSRC0_MUX200_SHIFT (16) |
79 | #define S5P_CLKSRC0_MUX200_MASK (0x1 << S5P_CLKSRC0_MUX200_SHIFT) | ||
72 | #define S5P_CLKSRC0_MUX166_MASK (0x1<<20) | 80 | #define S5P_CLKSRC0_MUX166_MASK (0x1<<20) |
73 | #define S5P_CLKSRC0_MUX133_MASK (0x1<<24) | 81 | #define S5P_CLKSRC0_MUX133_MASK (0x1<<24) |
74 | 82 | ||
83 | /* CLKSRC2 */ | ||
84 | #define S5P_CLKSRC2_G3D_SHIFT (0) | ||
85 | #define S5P_CLKSRC2_G3D_MASK (0x3 << S5P_CLKSRC2_G3D_SHIFT) | ||
86 | #define S5P_CLKSRC2_MFC_SHIFT (4) | ||
87 | #define S5P_CLKSRC2_MFC_MASK (0x3 << S5P_CLKSRC2_MFC_SHIFT) | ||
88 | |||
89 | /* CLKSRC6*/ | ||
90 | #define S5P_CLKSRC6_ONEDRAM_SHIFT (24) | ||
91 | #define S5P_CLKSRC6_ONEDRAM_MASK (0x3 << S5P_CLKSRC6_ONEDRAM_SHIFT) | ||
92 | |||
75 | /* CLKDIV0 */ | 93 | /* CLKDIV0 */ |
76 | #define S5P_CLKDIV0_APLL_SHIFT (0) | 94 | #define S5P_CLKDIV0_APLL_SHIFT (0) |
77 | #define S5P_CLKDIV0_APLL_MASK (0x7 << S5P_CLKDIV0_APLL_SHIFT) | 95 | #define S5P_CLKDIV0_APLL_MASK (0x7 << S5P_CLKDIV0_APLL_SHIFT) |
@@ -90,12 +108,24 @@ | |||
90 | #define S5P_CLKDIV0_PCLK66_SHIFT (28) | 108 | #define S5P_CLKDIV0_PCLK66_SHIFT (28) |
91 | #define S5P_CLKDIV0_PCLK66_MASK (0x7 << S5P_CLKDIV0_PCLK66_SHIFT) | 109 | #define S5P_CLKDIV0_PCLK66_MASK (0x7 << S5P_CLKDIV0_PCLK66_SHIFT) |
92 | 110 | ||
111 | /* CLKDIV2 */ | ||
112 | #define S5P_CLKDIV2_G3D_SHIFT (0) | ||
113 | #define S5P_CLKDIV2_G3D_MASK (0xF << S5P_CLKDIV2_G3D_SHIFT) | ||
114 | #define S5P_CLKDIV2_MFC_SHIFT (4) | ||
115 | #define S5P_CLKDIV2_MFC_MASK (0xF << S5P_CLKDIV2_MFC_SHIFT) | ||
116 | |||
117 | /* CLKDIV6 */ | ||
118 | #define S5P_CLKDIV6_ONEDRAM_SHIFT (28) | ||
119 | #define S5P_CLKDIV6_ONEDRAM_MASK (0xF << S5P_CLKDIV6_ONEDRAM_SHIFT) | ||
120 | |||
93 | #define S5P_SWRESET S5P_CLKREG(0x2000) | 121 | #define S5P_SWRESET S5P_CLKREG(0x2000) |
94 | 122 | ||
123 | #define S5P_ARM_MCS_CON S5P_CLKREG(0x6100) | ||
124 | |||
95 | /* Registers related to power management */ | 125 | /* Registers related to power management */ |
96 | #define S5P_PWR_CFG S5P_CLKREG(0xC000) | 126 | #define S5P_PWR_CFG S5P_CLKREG(0xC000) |
97 | #define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0xC004) | 127 | #define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0xC004) |
98 | #define S5P_WAKEUP_MASK S5P_CLKREG(0xC008) | 128 | #define S5P_WAKEUP_MASK S5P_CLKREG(0xC008) |
99 | #define S5P_PWR_MODE S5P_CLKREG(0xC00C) | 129 | #define S5P_PWR_MODE S5P_CLKREG(0xC00C) |
100 | #define S5P_NORMAL_CFG S5P_CLKREG(0xC010) | 130 | #define S5P_NORMAL_CFG S5P_CLKREG(0xC010) |
101 | #define S5P_IDLE_CFG S5P_CLKREG(0xC020) | 131 | #define S5P_IDLE_CFG S5P_CLKREG(0xC020) |
@@ -159,8 +189,11 @@ | |||
159 | #define S5P_SLEEP_CFG_USBOSC_EN (1 << 1) | 189 | #define S5P_SLEEP_CFG_USBOSC_EN (1 << 1) |
160 | 190 | ||
161 | /* OTHERS Resgister */ | 191 | /* OTHERS Resgister */ |
192 | #define S5P_OTHERS_RET_IO (1 << 31) | ||
193 | #define S5P_OTHERS_RET_CF (1 << 30) | ||
194 | #define S5P_OTHERS_RET_MMC (1 << 29) | ||
195 | #define S5P_OTHERS_RET_UART (1 << 28) | ||
162 | #define S5P_OTHERS_USB_SIG_MASK (1 << 16) | 196 | #define S5P_OTHERS_USB_SIG_MASK (1 << 16) |
163 | #define S5P_OTHERS_MIPI_DPHY_EN (1 << 28) | ||
164 | 197 | ||
165 | /* MIPI */ | 198 | /* MIPI */ |
166 | #define S5P_MIPI_DPHY_EN (3) | 199 | #define S5P_MIPI_DPHY_EN (3) |
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h index 49e029b4978a..de0c89976078 100644 --- a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h +++ b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h | |||
@@ -31,13 +31,6 @@ | |||
31 | 31 | ||
32 | #define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7)) | 32 | #define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7)) |
33 | 33 | ||
34 | /* values for S5P_EXTINT0 */ | ||
35 | #define S5P_EXTINT_LOWLEV (0x00) | ||
36 | #define S5P_EXTINT_HILEV (0x01) | ||
37 | #define S5P_EXTINT_FALLEDGE (0x02) | ||
38 | #define S5P_EXTINT_RISEEDGE (0x03) | ||
39 | #define S5P_EXTINT_BOTHEDGE (0x04) | ||
40 | |||
41 | #define EINT_MODE S3C_GPIO_SFN(0xf) | 34 | #define EINT_MODE S3C_GPIO_SFN(0xf) |
42 | 35 | ||
43 | #define EINT_GPIO_0(x) S5PV210_GPH0(x) | 36 | #define EINT_GPIO_0(x) S5PV210_GPH0(x) |
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-sys.h b/arch/arm/mach-s5pv210/include/mach/regs-sys.h new file mode 100644 index 000000000000..26691d39d0f4 --- /dev/null +++ b/arch/arm/mach-s5pv210/include/mach/regs-sys.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* arch/arm/mach-s5pv210/include/mach/regs-sys.h | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com/ | ||
5 | * | ||
6 | * S5PV210 - System registers definitions | ||
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 | #define S5PV210_USB_PHY_CON (S3C_VA_SYS + 0xE80C) | ||
14 | #define S5PV210_USB_PHY0_EN (1 << 0) | ||
15 | #define S5PV210_USB_PHY1_EN (1 << 1) | ||
16 | |||
17 | /* compatibility defines for s3c-hsotg driver */ | ||
18 | #define S3C64XX_OTHERS S5PV210_USB_PHY_CON | ||
19 | #define S3C64XX_OTHERS_USBMASK S5PV210_USB_PHY0_EN | ||
diff --git a/arch/arm/mach-s5pv210/include/mach/vmalloc.h b/arch/arm/mach-s5pv210/include/mach/vmalloc.h index df9a28808323..a6c659d68a5d 100644 --- a/arch/arm/mach-s5pv210/include/mach/vmalloc.h +++ b/arch/arm/mach-s5pv210/include/mach/vmalloc.h | |||
@@ -17,6 +17,6 @@ | |||
17 | #ifndef __ASM_ARCH_VMALLOC_H | 17 | #ifndef __ASM_ARCH_VMALLOC_H |
18 | #define __ASM_ARCH_VMALLOC_H __FILE__ | 18 | #define __ASM_ARCH_VMALLOC_H __FILE__ |
19 | 19 | ||
20 | #define VMALLOC_END (0xE0000000UL) | 20 | #define VMALLOC_END 0xF6000000UL |
21 | 21 | ||
22 | #endif /* __ASM_ARCH_VMALLOC_H */ | 22 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c index 00883087363c..28677caf3613 100644 --- a/arch/arm/mach-s5pv210/mach-aquila.c +++ b/arch/arm/mach-s5pv210/mach-aquila.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <linux/i2c.h> | 16 | #include <linux/i2c.h> |
17 | #include <linux/i2c-gpio.h> | 17 | #include <linux/i2c-gpio.h> |
18 | #include <linux/mfd/max8998.h> | 18 | #include <linux/mfd/max8998.h> |
19 | #include <linux/mfd/wm8994/pdata.h> | ||
20 | #include <linux/regulator/fixed.h> | ||
19 | #include <linux/gpio_keys.h> | 21 | #include <linux/gpio_keys.h> |
20 | #include <linux/input.h> | 22 | #include <linux/input.h> |
21 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
@@ -379,6 +381,119 @@ static struct max8998_platform_data aquila_max8998_pdata = { | |||
379 | }; | 381 | }; |
380 | #endif | 382 | #endif |
381 | 383 | ||
384 | static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = { | ||
385 | { | ||
386 | .dev_name = "5-001a", | ||
387 | .supply = "DBVDD", | ||
388 | }, { | ||
389 | .dev_name = "5-001a", | ||
390 | .supply = "AVDD2", | ||
391 | }, { | ||
392 | .dev_name = "5-001a", | ||
393 | .supply = "CPVDD", | ||
394 | }, | ||
395 | }; | ||
396 | |||
397 | static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = { | ||
398 | { | ||
399 | .dev_name = "5-001a", | ||
400 | .supply = "SPKVDD1", | ||
401 | }, { | ||
402 | .dev_name = "5-001a", | ||
403 | .supply = "SPKVDD2", | ||
404 | }, | ||
405 | }; | ||
406 | |||
407 | static struct regulator_init_data wm8994_fixed_voltage0_init_data = { | ||
408 | .constraints = { | ||
409 | .always_on = 1, | ||
410 | }, | ||
411 | .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies), | ||
412 | .consumer_supplies = wm8994_fixed_voltage0_supplies, | ||
413 | }; | ||
414 | |||
415 | static struct regulator_init_data wm8994_fixed_voltage1_init_data = { | ||
416 | .constraints = { | ||
417 | .always_on = 1, | ||
418 | }, | ||
419 | .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies), | ||
420 | .consumer_supplies = wm8994_fixed_voltage1_supplies, | ||
421 | }; | ||
422 | |||
423 | static struct fixed_voltage_config wm8994_fixed_voltage0_config = { | ||
424 | .supply_name = "VCC_1.8V_PDA", | ||
425 | .microvolts = 1800000, | ||
426 | .gpio = -EINVAL, | ||
427 | .init_data = &wm8994_fixed_voltage0_init_data, | ||
428 | }; | ||
429 | |||
430 | static struct fixed_voltage_config wm8994_fixed_voltage1_config = { | ||
431 | .supply_name = "V_BAT", | ||
432 | .microvolts = 3700000, | ||
433 | .gpio = -EINVAL, | ||
434 | .init_data = &wm8994_fixed_voltage1_init_data, | ||
435 | }; | ||
436 | |||
437 | static struct platform_device wm8994_fixed_voltage0 = { | ||
438 | .name = "reg-fixed-voltage", | ||
439 | .id = 0, | ||
440 | .dev = { | ||
441 | .platform_data = &wm8994_fixed_voltage0_config, | ||
442 | }, | ||
443 | }; | ||
444 | |||
445 | static struct platform_device wm8994_fixed_voltage1 = { | ||
446 | .name = "reg-fixed-voltage", | ||
447 | .id = 1, | ||
448 | .dev = { | ||
449 | .platform_data = &wm8994_fixed_voltage1_config, | ||
450 | }, | ||
451 | }; | ||
452 | |||
453 | static struct regulator_consumer_supply wm8994_avdd1_supply = { | ||
454 | .dev_name = "5-001a", | ||
455 | .supply = "AVDD1", | ||
456 | }; | ||
457 | |||
458 | static struct regulator_consumer_supply wm8994_dcvdd_supply = { | ||
459 | .dev_name = "5-001a", | ||
460 | .supply = "DCVDD", | ||
461 | }; | ||
462 | |||
463 | static struct regulator_init_data wm8994_ldo1_data = { | ||
464 | .constraints = { | ||
465 | .name = "AVDD1_3.0V", | ||
466 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
467 | }, | ||
468 | .num_consumer_supplies = 1, | ||
469 | .consumer_supplies = &wm8994_avdd1_supply, | ||
470 | }; | ||
471 | |||
472 | static struct regulator_init_data wm8994_ldo2_data = { | ||
473 | .constraints = { | ||
474 | .name = "DCVDD_1.0V", | ||
475 | }, | ||
476 | .num_consumer_supplies = 1, | ||
477 | .consumer_supplies = &wm8994_dcvdd_supply, | ||
478 | }; | ||
479 | |||
480 | static struct wm8994_pdata wm8994_platform_data = { | ||
481 | /* configure gpio1 function: 0x0001(Logic level input/output) */ | ||
482 | .gpio_defaults[0] = 0x0001, | ||
483 | /* configure gpio3/4/5/7 function for AIF2 voice */ | ||
484 | .gpio_defaults[2] = 0x8100, | ||
485 | .gpio_defaults[3] = 0x8100, | ||
486 | .gpio_defaults[4] = 0x8100, | ||
487 | .gpio_defaults[6] = 0x0100, | ||
488 | /* configure gpio8/9/10/11 function for AIF3 BT */ | ||
489 | .gpio_defaults[7] = 0x8100, | ||
490 | .gpio_defaults[8] = 0x0100, | ||
491 | .gpio_defaults[9] = 0x0100, | ||
492 | .gpio_defaults[10] = 0x0100, | ||
493 | .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */ | ||
494 | .ldo[1] = { 0, NULL, &wm8994_ldo2_data }, | ||
495 | }; | ||
496 | |||
382 | /* GPIO I2C PMIC */ | 497 | /* GPIO I2C PMIC */ |
383 | #define AP_I2C_GPIO_PMIC_BUS_4 4 | 498 | #define AP_I2C_GPIO_PMIC_BUS_4 4 |
384 | static struct i2c_gpio_platform_data aquila_i2c_gpio_pmic_data = { | 499 | static struct i2c_gpio_platform_data aquila_i2c_gpio_pmic_data = { |
@@ -404,6 +519,29 @@ static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = { | |||
404 | #endif | 519 | #endif |
405 | }; | 520 | }; |
406 | 521 | ||
522 | /* GPIO I2C AP 1.8V */ | ||
523 | #define AP_I2C_GPIO_BUS_5 5 | ||
524 | static struct i2c_gpio_platform_data aquila_i2c_gpio5_data = { | ||
525 | .sda_pin = S5PV210_MP05(3), /* XM0ADDR_11 */ | ||
526 | .scl_pin = S5PV210_MP05(2), /* XM0ADDR_10 */ | ||
527 | }; | ||
528 | |||
529 | static struct platform_device aquila_i2c_gpio5 = { | ||
530 | .name = "i2c-gpio", | ||
531 | .id = AP_I2C_GPIO_BUS_5, | ||
532 | .dev = { | ||
533 | .platform_data = &aquila_i2c_gpio5_data, | ||
534 | }, | ||
535 | }; | ||
536 | |||
537 | static struct i2c_board_info i2c_gpio5_devs[] __initdata = { | ||
538 | { | ||
539 | /* CS/ADDR = low 0x34 (FYI: high = 0x36) */ | ||
540 | I2C_BOARD_INFO("wm8994", 0x1a), | ||
541 | .platform_data = &wm8994_platform_data, | ||
542 | }, | ||
543 | }; | ||
544 | |||
407 | /* PMIC Power button */ | 545 | /* PMIC Power button */ |
408 | static struct gpio_keys_button aquila_gpio_keys_table[] = { | 546 | static struct gpio_keys_button aquila_gpio_keys_table[] = { |
409 | { | 547 | { |
@@ -475,6 +613,7 @@ static void aquila_setup_sdhci(void) | |||
475 | 613 | ||
476 | static struct platform_device *aquila_devices[] __initdata = { | 614 | static struct platform_device *aquila_devices[] __initdata = { |
477 | &aquila_i2c_gpio_pmic, | 615 | &aquila_i2c_gpio_pmic, |
616 | &aquila_i2c_gpio5, | ||
478 | &aquila_device_gpiokeys, | 617 | &aquila_device_gpiokeys, |
479 | &s3c_device_fb, | 618 | &s3c_device_fb, |
480 | &s5p_device_onenand, | 619 | &s5p_device_onenand, |
@@ -484,8 +623,33 @@ static struct platform_device *aquila_devices[] __initdata = { | |||
484 | &s5p_device_fimc0, | 623 | &s5p_device_fimc0, |
485 | &s5p_device_fimc1, | 624 | &s5p_device_fimc1, |
486 | &s5p_device_fimc2, | 625 | &s5p_device_fimc2, |
626 | &s5pv210_device_iis0, | ||
627 | &wm8994_fixed_voltage0, | ||
628 | &wm8994_fixed_voltage1, | ||
487 | }; | 629 | }; |
488 | 630 | ||
631 | static void __init aquila_sound_init(void) | ||
632 | { | ||
633 | unsigned int gpio; | ||
634 | |||
635 | /* CODEC_XTAL_EN | ||
636 | * | ||
637 | * The Aquila board have a oscillator which provide main clock | ||
638 | * to WM8994 codec. The oscillator provide 24MHz clock to WM8994 | ||
639 | * clock. Set gpio setting of "CODEC_XTAL_EN" to enable a oscillator. | ||
640 | * */ | ||
641 | gpio = S5PV210_GPH3(2); /* XEINT_26 */ | ||
642 | gpio_request(gpio, "CODEC_XTAL_EN"); | ||
643 | s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT); | ||
644 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
645 | |||
646 | /* Ths main clock of WM8994 codec uses the output of CLKOUT pin. | ||
647 | * The CLKOUT[9:8] set to 0x3(XUSBXTI) of 0xE010E000(OTHERS) | ||
648 | * because it needs 24MHz clock to operate WM8994 codec. | ||
649 | */ | ||
650 | __raw_writel(__raw_readl(S5P_OTHERS) | (0x3 << 8), S5P_OTHERS); | ||
651 | } | ||
652 | |||
489 | static void __init aquila_map_io(void) | 653 | static void __init aquila_map_io(void) |
490 | { | 654 | { |
491 | s5p_init_io(NULL, 0, S5P_VA_CHIPID); | 655 | s5p_init_io(NULL, 0, S5P_VA_CHIPID); |
@@ -506,6 +670,11 @@ static void __init aquila_machine_init(void) | |||
506 | s3c_fimc_setname(1, "s5p-fimc"); | 670 | s3c_fimc_setname(1, "s5p-fimc"); |
507 | s3c_fimc_setname(2, "s5p-fimc"); | 671 | s3c_fimc_setname(2, "s5p-fimc"); |
508 | 672 | ||
673 | /* SOUND */ | ||
674 | aquila_sound_init(); | ||
675 | i2c_register_board_info(AP_I2C_GPIO_BUS_5, i2c_gpio5_devs, | ||
676 | ARRAY_SIZE(i2c_gpio5_devs)); | ||
677 | |||
509 | /* FB */ | 678 | /* FB */ |
510 | s3c_fb_set_platdata(&aquila_lcd_pdata); | 679 | s3c_fb_set_platdata(&aquila_lcd_pdata); |
511 | 680 | ||
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c index d9ecf57fc2a5..b1dcf964a768 100644 --- a/arch/arm/mach-s5pv210/mach-goni.c +++ b/arch/arm/mach-s5pv210/mach-goni.c | |||
@@ -15,7 +15,13 @@ | |||
15 | #include <linux/fb.h> | 15 | #include <linux/fb.h> |
16 | #include <linux/i2c.h> | 16 | #include <linux/i2c.h> |
17 | #include <linux/i2c-gpio.h> | 17 | #include <linux/i2c-gpio.h> |
18 | #include <linux/i2c/qt602240_ts.h> | ||
18 | #include <linux/mfd/max8998.h> | 19 | #include <linux/mfd/max8998.h> |
20 | #include <linux/mfd/wm8994/pdata.h> | ||
21 | #include <linux/regulator/fixed.h> | ||
22 | #include <linux/spi/spi.h> | ||
23 | #include <linux/spi/spi_gpio.h> | ||
24 | #include <linux/lcd.h> | ||
19 | #include <linux/gpio_keys.h> | 25 | #include <linux/gpio_keys.h> |
20 | #include <linux/input.h> | 26 | #include <linux/input.h> |
21 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
@@ -35,7 +41,10 @@ | |||
35 | #include <plat/devs.h> | 41 | #include <plat/devs.h> |
36 | #include <plat/cpu.h> | 42 | #include <plat/cpu.h> |
37 | #include <plat/fb.h> | 43 | #include <plat/fb.h> |
44 | #include <plat/iic.h> | ||
45 | #include <plat/keypad.h> | ||
38 | #include <plat/sdhci.h> | 46 | #include <plat/sdhci.h> |
47 | #include <plat/clock.h> | ||
39 | 48 | ||
40 | /* Following are default values for UCON, ULCON and UFCON UART registers */ | 49 | /* Following are default values for UCON, ULCON and UFCON UART registers */ |
41 | #define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ | 50 | #define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ |
@@ -87,13 +96,12 @@ static struct s3c2410_uartcfg goni_uartcfgs[] __initdata = { | |||
87 | /* Frame Buffer */ | 96 | /* Frame Buffer */ |
88 | static struct s3c_fb_pd_win goni_fb_win0 = { | 97 | static struct s3c_fb_pd_win goni_fb_win0 = { |
89 | .win_mode = { | 98 | .win_mode = { |
90 | .pixclock = 1000000000000ULL / ((16+16+2+480)*(28+3+2+800)*55), | ||
91 | .left_margin = 16, | 99 | .left_margin = 16, |
92 | .right_margin = 16, | 100 | .right_margin = 16, |
93 | .upper_margin = 3, | 101 | .upper_margin = 2, |
94 | .lower_margin = 28, | 102 | .lower_margin = 28, |
95 | .hsync_len = 2, | 103 | .hsync_len = 2, |
96 | .vsync_len = 2, | 104 | .vsync_len = 1, |
97 | .xres = 480, | 105 | .xres = 480, |
98 | .yres = 800, | 106 | .yres = 800, |
99 | .refresh = 55, | 107 | .refresh = 55, |
@@ -111,9 +119,160 @@ static struct s3c_fb_platdata goni_lcd_pdata __initdata = { | |||
111 | .setup_gpio = s5pv210_fb_gpio_setup_24bpp, | 119 | .setup_gpio = s5pv210_fb_gpio_setup_24bpp, |
112 | }; | 120 | }; |
113 | 121 | ||
122 | static int lcd_power_on(struct lcd_device *ld, int enable) | ||
123 | { | ||
124 | return 1; | ||
125 | } | ||
126 | |||
127 | static int reset_lcd(struct lcd_device *ld) | ||
128 | { | ||
129 | static unsigned int first = 1; | ||
130 | int reset_gpio = -1; | ||
131 | |||
132 | reset_gpio = S5PV210_MP05(5); | ||
133 | |||
134 | if (first) { | ||
135 | gpio_request(reset_gpio, "MLCD_RST"); | ||
136 | first = 0; | ||
137 | } | ||
138 | |||
139 | gpio_direction_output(reset_gpio, 1); | ||
140 | return 1; | ||
141 | } | ||
142 | |||
143 | static struct lcd_platform_data goni_lcd_platform_data = { | ||
144 | .reset = reset_lcd, | ||
145 | .power_on = lcd_power_on, | ||
146 | .lcd_enabled = 0, | ||
147 | .reset_delay = 120, /* 120ms */ | ||
148 | .power_on_delay = 25, /* 25ms */ | ||
149 | .power_off_delay = 200, /* 200ms */ | ||
150 | }; | ||
151 | |||
152 | #define LCD_BUS_NUM 3 | ||
153 | static struct spi_board_info spi_board_info[] __initdata = { | ||
154 | { | ||
155 | .modalias = "s6e63m0", | ||
156 | .platform_data = &goni_lcd_platform_data, | ||
157 | .max_speed_hz = 1200000, | ||
158 | .bus_num = LCD_BUS_NUM, | ||
159 | .chip_select = 0, | ||
160 | .mode = SPI_MODE_3, | ||
161 | .controller_data = (void *)S5PV210_MP01(1), /* DISPLAY_CS */ | ||
162 | }, | ||
163 | }; | ||
164 | |||
165 | static struct spi_gpio_platform_data lcd_spi_gpio_data = { | ||
166 | .sck = S5PV210_MP04(1), /* DISPLAY_CLK */ | ||
167 | .mosi = S5PV210_MP04(3), /* DISPLAY_SI */ | ||
168 | .miso = SPI_GPIO_NO_MISO, | ||
169 | .num_chipselect = 1, | ||
170 | }; | ||
171 | |||
172 | static struct platform_device goni_spi_gpio = { | ||
173 | .name = "spi_gpio", | ||
174 | .id = LCD_BUS_NUM, | ||
175 | .dev = { | ||
176 | .parent = &s3c_device_fb.dev, | ||
177 | .platform_data = &lcd_spi_gpio_data, | ||
178 | }, | ||
179 | }; | ||
180 | |||
181 | /* KEYPAD */ | ||
182 | static uint32_t keymap[] __initdata = { | ||
183 | /* KEY(row, col, keycode) */ | ||
184 | KEY(0, 1, KEY_MENU), /* Send */ | ||
185 | KEY(0, 2, KEY_BACK), /* End */ | ||
186 | KEY(1, 1, KEY_CONFIG), /* Half shot */ | ||
187 | KEY(1, 2, KEY_VOLUMEUP), | ||
188 | KEY(2, 1, KEY_CAMERA), /* Full shot */ | ||
189 | KEY(2, 2, KEY_VOLUMEDOWN), | ||
190 | }; | ||
191 | |||
192 | static struct matrix_keymap_data keymap_data __initdata = { | ||
193 | .keymap = keymap, | ||
194 | .keymap_size = ARRAY_SIZE(keymap), | ||
195 | }; | ||
196 | |||
197 | static struct samsung_keypad_platdata keypad_data __initdata = { | ||
198 | .keymap_data = &keymap_data, | ||
199 | .rows = 3, | ||
200 | .cols = 3, | ||
201 | }; | ||
202 | |||
203 | /* Radio */ | ||
204 | static struct i2c_board_info i2c1_devs[] __initdata = { | ||
205 | { | ||
206 | I2C_BOARD_INFO("si470x", 0x10), | ||
207 | }, | ||
208 | }; | ||
209 | |||
210 | static void __init goni_radio_init(void) | ||
211 | { | ||
212 | int gpio; | ||
213 | |||
214 | gpio = S5PV210_GPJ2(4); /* XMSMDATA_4 */ | ||
215 | gpio_request(gpio, "FM_INT"); | ||
216 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); | ||
217 | i2c1_devs[0].irq = gpio_to_irq(gpio); | ||
218 | |||
219 | gpio = S5PV210_GPJ2(5); /* XMSMDATA_5 */ | ||
220 | gpio_request(gpio, "FM_RST"); | ||
221 | gpio_direction_output(gpio, 1); | ||
222 | } | ||
223 | |||
224 | /* TSP */ | ||
225 | static struct qt602240_platform_data qt602240_platform_data = { | ||
226 | .x_line = 17, | ||
227 | .y_line = 11, | ||
228 | .x_size = 800, | ||
229 | .y_size = 480, | ||
230 | .blen = 0x21, | ||
231 | .threshold = 0x28, | ||
232 | .voltage = 2800000, /* 2.8V */ | ||
233 | .orient = QT602240_DIAGONAL, | ||
234 | }; | ||
235 | |||
236 | static struct s3c2410_platform_i2c i2c2_data __initdata = { | ||
237 | .flags = 0, | ||
238 | .bus_num = 2, | ||
239 | .slave_addr = 0x10, | ||
240 | .frequency = 400 * 1000, | ||
241 | .sda_delay = 100, | ||
242 | }; | ||
243 | |||
244 | static struct i2c_board_info i2c2_devs[] __initdata = { | ||
245 | { | ||
246 | I2C_BOARD_INFO("qt602240_ts", 0x4a), | ||
247 | .platform_data = &qt602240_platform_data, | ||
248 | }, | ||
249 | }; | ||
250 | |||
251 | static void __init goni_tsp_init(void) | ||
252 | { | ||
253 | int gpio; | ||
254 | |||
255 | gpio = S5PV210_GPJ1(3); /* XMSMADDR_11 */ | ||
256 | gpio_request(gpio, "TSP_LDO_ON"); | ||
257 | gpio_direction_output(gpio, 1); | ||
258 | gpio_export(gpio, 0); | ||
259 | |||
260 | gpio = S5PV210_GPJ0(5); /* XMSMADDR_5 */ | ||
261 | gpio_request(gpio, "TSP_INT"); | ||
262 | |||
263 | s5p_register_gpio_interrupt(gpio); | ||
264 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); | ||
265 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); | ||
266 | i2c2_devs[0].irq = gpio_to_irq(gpio); | ||
267 | } | ||
268 | |||
114 | /* MAX8998 regulators */ | 269 | /* MAX8998 regulators */ |
115 | #if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE) | 270 | #if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE) |
116 | 271 | ||
272 | static struct regulator_consumer_supply goni_ldo5_consumers[] = { | ||
273 | REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"), | ||
274 | }; | ||
275 | |||
117 | static struct regulator_init_data goni_ldo2_data = { | 276 | static struct regulator_init_data goni_ldo2_data = { |
118 | .constraints = { | 277 | .constraints = { |
119 | .name = "VALIVE_1.1V", | 278 | .name = "VALIVE_1.1V", |
@@ -153,6 +312,8 @@ static struct regulator_init_data goni_ldo5_data = { | |||
153 | .max_uV = 2800000, | 312 | .max_uV = 2800000, |
154 | .apply_uV = 1, | 313 | .apply_uV = 1, |
155 | }, | 314 | }, |
315 | .num_consumer_supplies = ARRAY_SIZE(goni_ldo5_consumers), | ||
316 | .consumer_supplies = goni_ldo5_consumers, | ||
156 | }; | 317 | }; |
157 | 318 | ||
158 | static struct regulator_init_data goni_ldo6_data = { | 319 | static struct regulator_init_data goni_ldo6_data = { |
@@ -360,6 +521,119 @@ static struct max8998_platform_data goni_max8998_pdata = { | |||
360 | }; | 521 | }; |
361 | #endif | 522 | #endif |
362 | 523 | ||
524 | static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = { | ||
525 | { | ||
526 | .dev_name = "5-001a", | ||
527 | .supply = "DBVDD", | ||
528 | }, { | ||
529 | .dev_name = "5-001a", | ||
530 | .supply = "AVDD2", | ||
531 | }, { | ||
532 | .dev_name = "5-001a", | ||
533 | .supply = "CPVDD", | ||
534 | }, | ||
535 | }; | ||
536 | |||
537 | static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = { | ||
538 | { | ||
539 | .dev_name = "5-001a", | ||
540 | .supply = "SPKVDD1", | ||
541 | }, { | ||
542 | .dev_name = "5-001a", | ||
543 | .supply = "SPKVDD2", | ||
544 | }, | ||
545 | }; | ||
546 | |||
547 | static struct regulator_init_data wm8994_fixed_voltage0_init_data = { | ||
548 | .constraints = { | ||
549 | .always_on = 1, | ||
550 | }, | ||
551 | .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies), | ||
552 | .consumer_supplies = wm8994_fixed_voltage0_supplies, | ||
553 | }; | ||
554 | |||
555 | static struct regulator_init_data wm8994_fixed_voltage1_init_data = { | ||
556 | .constraints = { | ||
557 | .always_on = 1, | ||
558 | }, | ||
559 | .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies), | ||
560 | .consumer_supplies = wm8994_fixed_voltage1_supplies, | ||
561 | }; | ||
562 | |||
563 | static struct fixed_voltage_config wm8994_fixed_voltage0_config = { | ||
564 | .supply_name = "VCC_1.8V_PDA", | ||
565 | .microvolts = 1800000, | ||
566 | .gpio = -EINVAL, | ||
567 | .init_data = &wm8994_fixed_voltage0_init_data, | ||
568 | }; | ||
569 | |||
570 | static struct fixed_voltage_config wm8994_fixed_voltage1_config = { | ||
571 | .supply_name = "V_BAT", | ||
572 | .microvolts = 3700000, | ||
573 | .gpio = -EINVAL, | ||
574 | .init_data = &wm8994_fixed_voltage1_init_data, | ||
575 | }; | ||
576 | |||
577 | static struct platform_device wm8994_fixed_voltage0 = { | ||
578 | .name = "reg-fixed-voltage", | ||
579 | .id = 0, | ||
580 | .dev = { | ||
581 | .platform_data = &wm8994_fixed_voltage0_config, | ||
582 | }, | ||
583 | }; | ||
584 | |||
585 | static struct platform_device wm8994_fixed_voltage1 = { | ||
586 | .name = "reg-fixed-voltage", | ||
587 | .id = 1, | ||
588 | .dev = { | ||
589 | .platform_data = &wm8994_fixed_voltage1_config, | ||
590 | }, | ||
591 | }; | ||
592 | |||
593 | static struct regulator_consumer_supply wm8994_avdd1_supply = { | ||
594 | .dev_name = "5-001a", | ||
595 | .supply = "AVDD1", | ||
596 | }; | ||
597 | |||
598 | static struct regulator_consumer_supply wm8994_dcvdd_supply = { | ||
599 | .dev_name = "5-001a", | ||
600 | .supply = "DCVDD", | ||
601 | }; | ||
602 | |||
603 | static struct regulator_init_data wm8994_ldo1_data = { | ||
604 | .constraints = { | ||
605 | .name = "AVDD1_3.0V", | ||
606 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
607 | }, | ||
608 | .num_consumer_supplies = 1, | ||
609 | .consumer_supplies = &wm8994_avdd1_supply, | ||
610 | }; | ||
611 | |||
612 | static struct regulator_init_data wm8994_ldo2_data = { | ||
613 | .constraints = { | ||
614 | .name = "DCVDD_1.0V", | ||
615 | }, | ||
616 | .num_consumer_supplies = 1, | ||
617 | .consumer_supplies = &wm8994_dcvdd_supply, | ||
618 | }; | ||
619 | |||
620 | static struct wm8994_pdata wm8994_platform_data = { | ||
621 | /* configure gpio1 function: 0x0001(Logic level input/output) */ | ||
622 | .gpio_defaults[0] = 0x0001, | ||
623 | /* configure gpio3/4/5/7 function for AIF2 voice */ | ||
624 | .gpio_defaults[2] = 0x8100, | ||
625 | .gpio_defaults[3] = 0x8100, | ||
626 | .gpio_defaults[4] = 0x8100, | ||
627 | .gpio_defaults[6] = 0x0100, | ||
628 | /* configure gpio8/9/10/11 function for AIF3 BT */ | ||
629 | .gpio_defaults[7] = 0x8100, | ||
630 | .gpio_defaults[8] = 0x0100, | ||
631 | .gpio_defaults[9] = 0x0100, | ||
632 | .gpio_defaults[10] = 0x0100, | ||
633 | .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */ | ||
634 | .ldo[1] = { 0, NULL, &wm8994_ldo2_data }, | ||
635 | }; | ||
636 | |||
363 | /* GPIO I2C PMIC */ | 637 | /* GPIO I2C PMIC */ |
364 | #define AP_I2C_GPIO_PMIC_BUS_4 4 | 638 | #define AP_I2C_GPIO_PMIC_BUS_4 4 |
365 | static struct i2c_gpio_platform_data goni_i2c_gpio_pmic_data = { | 639 | static struct i2c_gpio_platform_data goni_i2c_gpio_pmic_data = { |
@@ -385,6 +659,29 @@ static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = { | |||
385 | #endif | 659 | #endif |
386 | }; | 660 | }; |
387 | 661 | ||
662 | /* GPIO I2C AP 1.8V */ | ||
663 | #define AP_I2C_GPIO_BUS_5 5 | ||
664 | static struct i2c_gpio_platform_data goni_i2c_gpio5_data = { | ||
665 | .sda_pin = S5PV210_MP05(3), /* XM0ADDR_11 */ | ||
666 | .scl_pin = S5PV210_MP05(2), /* XM0ADDR_10 */ | ||
667 | }; | ||
668 | |||
669 | static struct platform_device goni_i2c_gpio5 = { | ||
670 | .name = "i2c-gpio", | ||
671 | .id = AP_I2C_GPIO_BUS_5, | ||
672 | .dev = { | ||
673 | .platform_data = &goni_i2c_gpio5_data, | ||
674 | }, | ||
675 | }; | ||
676 | |||
677 | static struct i2c_board_info i2c_gpio5_devs[] __initdata = { | ||
678 | { | ||
679 | /* CS/ADDR = low 0x34 (FYI: high = 0x36) */ | ||
680 | I2C_BOARD_INFO("wm8994", 0x1a), | ||
681 | .platform_data = &wm8994_platform_data, | ||
682 | }, | ||
683 | }; | ||
684 | |||
388 | /* PMIC Power button */ | 685 | /* PMIC Power button */ |
389 | static struct gpio_keys_button goni_gpio_keys_table[] = { | 686 | static struct gpio_keys_button goni_gpio_keys_table[] = { |
390 | { | 687 | { |
@@ -444,11 +741,37 @@ static struct s3c_sdhci_platdata goni_hsmmc2_data __initdata = { | |||
444 | .ext_cd_gpio_invert = 1, | 741 | .ext_cd_gpio_invert = 1, |
445 | }; | 742 | }; |
446 | 743 | ||
744 | static struct regulator_consumer_supply mmc2_supplies[] = { | ||
745 | REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"), | ||
746 | }; | ||
747 | |||
748 | static struct regulator_init_data mmc2_fixed_voltage_init_data = { | ||
749 | .constraints = { | ||
750 | .name = "V_TF_2.8V", | ||
751 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
752 | }, | ||
753 | .num_consumer_supplies = ARRAY_SIZE(mmc2_supplies), | ||
754 | .consumer_supplies = mmc2_supplies, | ||
755 | }; | ||
756 | |||
757 | static struct fixed_voltage_config mmc2_fixed_voltage_config = { | ||
758 | .supply_name = "EXT_FLASH_EN", | ||
759 | .microvolts = 2800000, | ||
760 | .gpio = GONI_EXT_FLASH_EN, | ||
761 | .enable_high = true, | ||
762 | .init_data = &mmc2_fixed_voltage_init_data, | ||
763 | }; | ||
764 | |||
765 | static struct platform_device mmc2_fixed_voltage = { | ||
766 | .name = "reg-fixed-voltage", | ||
767 | .id = 2, | ||
768 | .dev = { | ||
769 | .platform_data = &mmc2_fixed_voltage_config, | ||
770 | }, | ||
771 | }; | ||
772 | |||
447 | static void goni_setup_sdhci(void) | 773 | static void goni_setup_sdhci(void) |
448 | { | 774 | { |
449 | gpio_request(GONI_EXT_FLASH_EN, "FLASH_EN"); | ||
450 | gpio_direction_output(GONI_EXT_FLASH_EN, 1); | ||
451 | |||
452 | s3c_sdhci0_set_platdata(&goni_hsmmc0_data); | 775 | s3c_sdhci0_set_platdata(&goni_hsmmc0_data); |
453 | s3c_sdhci1_set_platdata(&goni_hsmmc1_data); | 776 | s3c_sdhci1_set_platdata(&goni_hsmmc1_data); |
454 | s3c_sdhci2_set_platdata(&goni_hsmmc2_data); | 777 | s3c_sdhci2_set_platdata(&goni_hsmmc2_data); |
@@ -457,7 +780,10 @@ static void goni_setup_sdhci(void) | |||
457 | static struct platform_device *goni_devices[] __initdata = { | 780 | static struct platform_device *goni_devices[] __initdata = { |
458 | &s3c_device_fb, | 781 | &s3c_device_fb, |
459 | &s5p_device_onenand, | 782 | &s5p_device_onenand, |
783 | &goni_spi_gpio, | ||
460 | &goni_i2c_gpio_pmic, | 784 | &goni_i2c_gpio_pmic, |
785 | &goni_i2c_gpio5, | ||
786 | &mmc2_fixed_voltage, | ||
461 | &goni_device_gpiokeys, | 787 | &goni_device_gpiokeys, |
462 | &s5p_device_fimc0, | 788 | &s5p_device_fimc0, |
463 | &s5p_device_fimc1, | 789 | &s5p_device_fimc1, |
@@ -465,8 +791,24 @@ static struct platform_device *goni_devices[] __initdata = { | |||
465 | &s3c_device_hsmmc0, | 791 | &s3c_device_hsmmc0, |
466 | &s3c_device_hsmmc1, | 792 | &s3c_device_hsmmc1, |
467 | &s3c_device_hsmmc2, | 793 | &s3c_device_hsmmc2, |
794 | &s5pv210_device_iis0, | ||
795 | &s3c_device_usb_hsotg, | ||
796 | &samsung_device_keypad, | ||
797 | &s3c_device_i2c1, | ||
798 | &s3c_device_i2c2, | ||
799 | &wm8994_fixed_voltage0, | ||
800 | &wm8994_fixed_voltage1, | ||
468 | }; | 801 | }; |
469 | 802 | ||
803 | static void __init goni_sound_init(void) | ||
804 | { | ||
805 | /* Ths main clock of WM8994 codec uses the output of CLKOUT pin. | ||
806 | * The CLKOUT[9:8] set to 0x3(XUSBXTI) of 0xE010E000(OTHERS) | ||
807 | * because it needs 24MHz clock to operate WM8994 codec. | ||
808 | */ | ||
809 | __raw_writel(__raw_readl(S5P_OTHERS) | (0x3 << 8), S5P_OTHERS); | ||
810 | } | ||
811 | |||
470 | static void __init goni_map_io(void) | 812 | static void __init goni_map_io(void) |
471 | { | 813 | { |
472 | s5p_init_io(NULL, 0, S5P_VA_CHIPID); | 814 | s5p_init_io(NULL, 0, S5P_VA_CHIPID); |
@@ -476,6 +818,20 @@ static void __init goni_map_io(void) | |||
476 | 818 | ||
477 | static void __init goni_machine_init(void) | 819 | static void __init goni_machine_init(void) |
478 | { | 820 | { |
821 | /* Radio: call before I2C 1 registeration */ | ||
822 | goni_radio_init(); | ||
823 | |||
824 | /* I2C1 */ | ||
825 | s3c_i2c1_set_platdata(NULL); | ||
826 | i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs)); | ||
827 | |||
828 | /* TSP: call before I2C 2 registeration */ | ||
829 | goni_tsp_init(); | ||
830 | |||
831 | /* I2C2 */ | ||
832 | s3c_i2c2_set_platdata(&i2c2_data); | ||
833 | i2c_register_board_info(2, i2c2_devs, ARRAY_SIZE(i2c2_devs)); | ||
834 | |||
479 | /* PMIC */ | 835 | /* PMIC */ |
480 | goni_pmic_init(); | 836 | goni_pmic_init(); |
481 | i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs, | 837 | i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs, |
@@ -483,9 +839,22 @@ static void __init goni_machine_init(void) | |||
483 | /* SDHCI */ | 839 | /* SDHCI */ |
484 | goni_setup_sdhci(); | 840 | goni_setup_sdhci(); |
485 | 841 | ||
842 | /* SOUND */ | ||
843 | goni_sound_init(); | ||
844 | i2c_register_board_info(AP_I2C_GPIO_BUS_5, i2c_gpio5_devs, | ||
845 | ARRAY_SIZE(i2c_gpio5_devs)); | ||
846 | |||
486 | /* FB */ | 847 | /* FB */ |
487 | s3c_fb_set_platdata(&goni_lcd_pdata); | 848 | s3c_fb_set_platdata(&goni_lcd_pdata); |
488 | 849 | ||
850 | /* SPI */ | ||
851 | spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); | ||
852 | |||
853 | /* KEYPAD */ | ||
854 | samsung_keypad_set_platdata(&keypad_data); | ||
855 | |||
856 | clk_xusbxti.rate = 24000000; | ||
857 | |||
489 | platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices)); | 858 | platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices)); |
490 | } | 859 | } |
491 | 860 | ||
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c index cea9bca79d88..0ad7924fe62e 100644 --- a/arch/arm/mach-s5pv210/mach-smdkc110.c +++ b/arch/arm/mach-s5pv210/mach-smdkc110.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <plat/cpu.h> | 28 | #include <plat/cpu.h> |
29 | #include <plat/ata.h> | 29 | #include <plat/ata.h> |
30 | #include <plat/iic.h> | 30 | #include <plat/iic.h> |
31 | #include <plat/pm.h> | ||
31 | 32 | ||
32 | /* Following are default values for UCON, ULCON and UFCON UART registers */ | 33 | /* Following are default values for UCON, ULCON and UFCON UART registers */ |
33 | #define SMDKC110_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ | 34 | #define SMDKC110_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ |
@@ -81,6 +82,7 @@ static struct s3c_ide_platdata smdkc110_ide_pdata __initdata = { | |||
81 | static struct platform_device *smdkc110_devices[] __initdata = { | 82 | static struct platform_device *smdkc110_devices[] __initdata = { |
82 | &s5pv210_device_iis0, | 83 | &s5pv210_device_iis0, |
83 | &s5pv210_device_ac97, | 84 | &s5pv210_device_ac97, |
85 | &s5pv210_device_spdif, | ||
84 | &s3c_device_cfcon, | 86 | &s3c_device_cfcon, |
85 | &s3c_device_i2c0, | 87 | &s3c_device_i2c0, |
86 | &s3c_device_i2c1, | 88 | &s3c_device_i2c1, |
@@ -110,6 +112,8 @@ static void __init smdkc110_map_io(void) | |||
110 | 112 | ||
111 | static void __init smdkc110_machine_init(void) | 113 | static void __init smdkc110_machine_init(void) |
112 | { | 114 | { |
115 | s3c_pm_init(); | ||
116 | |||
113 | s3c_i2c0_set_platdata(NULL); | 117 | s3c_i2c0_set_platdata(NULL); |
114 | s3c_i2c1_set_platdata(NULL); | 118 | s3c_i2c1_set_platdata(NULL); |
115 | s3c_i2c2_set_platdata(NULL); | 119 | s3c_i2c2_set_platdata(NULL); |
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c index 83189ae9da9a..bcd7a5d53401 100644 --- a/arch/arm/mach-s5pv210/mach-smdkv210.c +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <plat/ata.h> | 31 | #include <plat/ata.h> |
32 | #include <plat/iic.h> | 32 | #include <plat/iic.h> |
33 | #include <plat/keypad.h> | 33 | #include <plat/keypad.h> |
34 | #include <plat/pm.h> | ||
34 | 35 | ||
35 | /* Following are default values for UCON, ULCON and UFCON UART registers */ | 36 | /* Following are default values for UCON, ULCON and UFCON UART registers */ |
36 | #define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ | 37 | #define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ |
@@ -103,6 +104,7 @@ static struct samsung_keypad_platdata smdkv210_keypad_data __initdata = { | |||
103 | static struct platform_device *smdkv210_devices[] __initdata = { | 104 | static struct platform_device *smdkv210_devices[] __initdata = { |
104 | &s5pv210_device_iis0, | 105 | &s5pv210_device_iis0, |
105 | &s5pv210_device_ac97, | 106 | &s5pv210_device_ac97, |
107 | &s5pv210_device_spdif, | ||
106 | &s3c_device_adc, | 108 | &s3c_device_adc, |
107 | &s3c_device_cfcon, | 109 | &s3c_device_cfcon, |
108 | &s3c_device_hsmmc0, | 110 | &s3c_device_hsmmc0, |
@@ -145,6 +147,8 @@ static void __init smdkv210_map_io(void) | |||
145 | 147 | ||
146 | static void __init smdkv210_machine_init(void) | 148 | static void __init smdkv210_machine_init(void) |
147 | { | 149 | { |
150 | s3c_pm_init(); | ||
151 | |||
148 | samsung_keypad_set_platdata(&smdkv210_keypad_data); | 152 | samsung_keypad_set_platdata(&smdkv210_keypad_data); |
149 | s3c24xx_ts_set_platdata(&s3c_ts_platform); | 153 | s3c24xx_ts_set_platdata(&s3c_ts_platform); |
150 | 154 | ||
diff --git a/arch/arm/mach-s5pv210/mach-torbreck.c b/arch/arm/mach-s5pv210/mach-torbreck.c new file mode 100644 index 000000000000..043c938806b0 --- /dev/null +++ b/arch/arm/mach-s5pv210/mach-torbreck.c | |||
@@ -0,0 +1,131 @@ | |||
1 | /* linux/arch/arm/mach-s5pv210/mach-torbreck.c | ||
2 | * | ||
3 | * Copyright (c) 2010 aESOP Community | ||
4 | * http://www.aesop.or.kr/ | ||
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/types.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/serial_core.h> | ||
16 | |||
17 | #include <asm/mach/arch.h> | ||
18 | #include <asm/mach/map.h> | ||
19 | #include <asm/setup.h> | ||
20 | #include <asm/mach-types.h> | ||
21 | |||
22 | #include <mach/map.h> | ||
23 | #include <mach/regs-clock.h> | ||
24 | |||
25 | #include <plat/regs-serial.h> | ||
26 | #include <plat/s5pv210.h> | ||
27 | #include <plat/devs.h> | ||
28 | #include <plat/cpu.h> | ||
29 | #include <plat/iic.h> | ||
30 | |||
31 | /* Following are default values for UCON, ULCON and UFCON UART registers */ | ||
32 | #define TORBRECK_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ | ||
33 | S3C2410_UCON_RXILEVEL | \ | ||
34 | S3C2410_UCON_TXIRQMODE | \ | ||
35 | S3C2410_UCON_RXIRQMODE | \ | ||
36 | S3C2410_UCON_RXFIFO_TOI | \ | ||
37 | S3C2443_UCON_RXERR_IRQEN) | ||
38 | |||
39 | #define TORBRECK_ULCON_DEFAULT S3C2410_LCON_CS8 | ||
40 | |||
41 | #define TORBRECK_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ | ||
42 | S5PV210_UFCON_TXTRIG4 | \ | ||
43 | S5PV210_UFCON_RXTRIG4) | ||
44 | |||
45 | static struct s3c2410_uartcfg torbreck_uartcfgs[] __initdata = { | ||
46 | [0] = { | ||
47 | .hwport = 0, | ||
48 | .flags = 0, | ||
49 | .ucon = TORBRECK_UCON_DEFAULT, | ||
50 | .ulcon = TORBRECK_ULCON_DEFAULT, | ||
51 | .ufcon = TORBRECK_UFCON_DEFAULT, | ||
52 | }, | ||
53 | [1] = { | ||
54 | .hwport = 1, | ||
55 | .flags = 0, | ||
56 | .ucon = TORBRECK_UCON_DEFAULT, | ||
57 | .ulcon = TORBRECK_ULCON_DEFAULT, | ||
58 | .ufcon = TORBRECK_UFCON_DEFAULT, | ||
59 | }, | ||
60 | [2] = { | ||
61 | .hwport = 2, | ||
62 | .flags = 0, | ||
63 | .ucon = TORBRECK_UCON_DEFAULT, | ||
64 | .ulcon = TORBRECK_ULCON_DEFAULT, | ||
65 | .ufcon = TORBRECK_UFCON_DEFAULT, | ||
66 | }, | ||
67 | [3] = { | ||
68 | .hwport = 3, | ||
69 | .flags = 0, | ||
70 | .ucon = TORBRECK_UCON_DEFAULT, | ||
71 | .ulcon = TORBRECK_ULCON_DEFAULT, | ||
72 | .ufcon = TORBRECK_UFCON_DEFAULT, | ||
73 | }, | ||
74 | }; | ||
75 | |||
76 | static struct platform_device *torbreck_devices[] __initdata = { | ||
77 | &s5pv210_device_iis0, | ||
78 | &s3c_device_cfcon, | ||
79 | &s3c_device_hsmmc0, | ||
80 | &s3c_device_hsmmc1, | ||
81 | &s3c_device_hsmmc2, | ||
82 | &s3c_device_hsmmc3, | ||
83 | &s3c_device_i2c0, | ||
84 | &s3c_device_i2c1, | ||
85 | &s3c_device_i2c2, | ||
86 | &s3c_device_rtc, | ||
87 | &s3c_device_wdt, | ||
88 | }; | ||
89 | |||
90 | static struct i2c_board_info torbreck_i2c_devs0[] __initdata = { | ||
91 | /* To Be Updated */ | ||
92 | }; | ||
93 | |||
94 | static struct i2c_board_info torbreck_i2c_devs1[] __initdata = { | ||
95 | /* To Be Updated */ | ||
96 | }; | ||
97 | |||
98 | static struct i2c_board_info torbreck_i2c_devs2[] __initdata = { | ||
99 | /* To Be Updated */ | ||
100 | }; | ||
101 | |||
102 | static void __init torbreck_map_io(void) | ||
103 | { | ||
104 | s5p_init_io(NULL, 0, S5P_VA_CHIPID); | ||
105 | s3c24xx_init_clocks(24000000); | ||
106 | s3c24xx_init_uarts(torbreck_uartcfgs, ARRAY_SIZE(torbreck_uartcfgs)); | ||
107 | } | ||
108 | |||
109 | static void __init torbreck_machine_init(void) | ||
110 | { | ||
111 | s3c_i2c0_set_platdata(NULL); | ||
112 | s3c_i2c1_set_platdata(NULL); | ||
113 | s3c_i2c2_set_platdata(NULL); | ||
114 | i2c_register_board_info(0, torbreck_i2c_devs0, | ||
115 | ARRAY_SIZE(torbreck_i2c_devs0)); | ||
116 | i2c_register_board_info(1, torbreck_i2c_devs1, | ||
117 | ARRAY_SIZE(torbreck_i2c_devs1)); | ||
118 | i2c_register_board_info(2, torbreck_i2c_devs2, | ||
119 | ARRAY_SIZE(torbreck_i2c_devs2)); | ||
120 | |||
121 | platform_add_devices(torbreck_devices, ARRAY_SIZE(torbreck_devices)); | ||
122 | } | ||
123 | |||
124 | MACHINE_START(TORBRECK, "TORBRECK") | ||
125 | /* Maintainer: Hyunchul Ko <ghcstop@gmail.com> */ | ||
126 | .boot_params = S5P_PA_SDRAM + 0x100, | ||
127 | .init_irq = s5pv210_init_irq, | ||
128 | .map_io = torbreck_map_io, | ||
129 | .init_machine = torbreck_machine_init, | ||
130 | .timer = &s3c24xx_timer, | ||
131 | MACHINE_END | ||
diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c new file mode 100644 index 000000000000..549d7924fd4c --- /dev/null +++ b/arch/arm/mach-s5pv210/pm.c | |||
@@ -0,0 +1,166 @@ | |||
1 | /* linux/arch/arm/mach-s5pv210/pm.c | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com | ||
5 | * | ||
6 | * S5PV210 - Power Management support | ||
7 | * | ||
8 | * Based on arch/arm/mach-s3c2410/pm.c | ||
9 | * Copyright (c) 2006 Simtec Electronics | ||
10 | * Ben Dooks <ben@simtec.co.uk> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | */ | ||
16 | |||
17 | #include <linux/init.h> | ||
18 | #include <linux/suspend.h> | ||
19 | #include <linux/io.h> | ||
20 | |||
21 | #include <plat/cpu.h> | ||
22 | #include <plat/pm.h> | ||
23 | #include <plat/regs-timer.h> | ||
24 | |||
25 | #include <mach/regs-irq.h> | ||
26 | #include <mach/regs-clock.h> | ||
27 | |||
28 | static struct sleep_save s5pv210_core_save[] = { | ||
29 | /* Clock source */ | ||
30 | SAVE_ITEM(S5P_CLK_SRC0), | ||
31 | SAVE_ITEM(S5P_CLK_SRC1), | ||
32 | SAVE_ITEM(S5P_CLK_SRC2), | ||
33 | SAVE_ITEM(S5P_CLK_SRC3), | ||
34 | SAVE_ITEM(S5P_CLK_SRC4), | ||
35 | SAVE_ITEM(S5P_CLK_SRC5), | ||
36 | SAVE_ITEM(S5P_CLK_SRC6), | ||
37 | |||
38 | /* Clock source Mask */ | ||
39 | SAVE_ITEM(S5P_CLK_SRC_MASK0), | ||
40 | SAVE_ITEM(S5P_CLK_SRC_MASK1), | ||
41 | |||
42 | /* Clock Divider */ | ||
43 | SAVE_ITEM(S5P_CLK_DIV0), | ||
44 | SAVE_ITEM(S5P_CLK_DIV1), | ||
45 | SAVE_ITEM(S5P_CLK_DIV2), | ||
46 | SAVE_ITEM(S5P_CLK_DIV3), | ||
47 | SAVE_ITEM(S5P_CLK_DIV4), | ||
48 | SAVE_ITEM(S5P_CLK_DIV5), | ||
49 | SAVE_ITEM(S5P_CLK_DIV6), | ||
50 | SAVE_ITEM(S5P_CLK_DIV7), | ||
51 | |||
52 | /* Clock Main Gate */ | ||
53 | SAVE_ITEM(S5P_CLKGATE_MAIN0), | ||
54 | SAVE_ITEM(S5P_CLKGATE_MAIN1), | ||
55 | SAVE_ITEM(S5P_CLKGATE_MAIN2), | ||
56 | |||
57 | /* Clock source Peri Gate */ | ||
58 | SAVE_ITEM(S5P_CLKGATE_PERI0), | ||
59 | SAVE_ITEM(S5P_CLKGATE_PERI1), | ||
60 | |||
61 | /* Clock source SCLK Gate */ | ||
62 | SAVE_ITEM(S5P_CLKGATE_SCLK0), | ||
63 | SAVE_ITEM(S5P_CLKGATE_SCLK1), | ||
64 | |||
65 | /* Clock IP Clock gate */ | ||
66 | SAVE_ITEM(S5P_CLKGATE_IP0), | ||
67 | SAVE_ITEM(S5P_CLKGATE_IP1), | ||
68 | SAVE_ITEM(S5P_CLKGATE_IP2), | ||
69 | SAVE_ITEM(S5P_CLKGATE_IP3), | ||
70 | SAVE_ITEM(S5P_CLKGATE_IP4), | ||
71 | |||
72 | /* Clock Blcok and Bus gate */ | ||
73 | SAVE_ITEM(S5P_CLKGATE_BLOCK), | ||
74 | SAVE_ITEM(S5P_CLKGATE_BUS0), | ||
75 | |||
76 | /* Clock ETC */ | ||
77 | SAVE_ITEM(S5P_CLK_OUT), | ||
78 | SAVE_ITEM(S5P_MDNIE_SEL), | ||
79 | |||
80 | /* PWM Register */ | ||
81 | SAVE_ITEM(S3C2410_TCFG0), | ||
82 | SAVE_ITEM(S3C2410_TCFG1), | ||
83 | SAVE_ITEM(S3C64XX_TINT_CSTAT), | ||
84 | SAVE_ITEM(S3C2410_TCON), | ||
85 | SAVE_ITEM(S3C2410_TCNTB(0)), | ||
86 | SAVE_ITEM(S3C2410_TCMPB(0)), | ||
87 | SAVE_ITEM(S3C2410_TCNTO(0)), | ||
88 | }; | ||
89 | |||
90 | void s5pv210_cpu_suspend(void) | ||
91 | { | ||
92 | unsigned long tmp; | ||
93 | |||
94 | /* issue the standby signal into the pm unit. Note, we | ||
95 | * issue a write-buffer drain just in case */ | ||
96 | |||
97 | tmp = 0; | ||
98 | |||
99 | asm("b 1f\n\t" | ||
100 | ".align 5\n\t" | ||
101 | "1:\n\t" | ||
102 | "mcr p15, 0, %0, c7, c10, 5\n\t" | ||
103 | "mcr p15, 0, %0, c7, c10, 4\n\t" | ||
104 | "wfi" : : "r" (tmp)); | ||
105 | |||
106 | /* we should never get past here */ | ||
107 | panic("sleep resumed to originator?"); | ||
108 | } | ||
109 | |||
110 | static void s5pv210_pm_prepare(void) | ||
111 | { | ||
112 | unsigned int tmp; | ||
113 | |||
114 | /* ensure at least INFORM0 has the resume address */ | ||
115 | __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0); | ||
116 | |||
117 | tmp = __raw_readl(S5P_SLEEP_CFG); | ||
118 | tmp &= ~(S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN); | ||
119 | __raw_writel(tmp, S5P_SLEEP_CFG); | ||
120 | |||
121 | /* WFI for SLEEP mode configuration by SYSCON */ | ||
122 | tmp = __raw_readl(S5P_PWR_CFG); | ||
123 | tmp &= S5P_CFG_WFI_CLEAN; | ||
124 | tmp |= S5P_CFG_WFI_SLEEP; | ||
125 | __raw_writel(tmp, S5P_PWR_CFG); | ||
126 | |||
127 | /* SYSCON interrupt handling disable */ | ||
128 | tmp = __raw_readl(S5P_OTHERS); | ||
129 | tmp |= S5P_OTHER_SYSC_INTOFF; | ||
130 | __raw_writel(tmp, S5P_OTHERS); | ||
131 | |||
132 | s3c_pm_do_save(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save)); | ||
133 | } | ||
134 | |||
135 | static int s5pv210_pm_add(struct sys_device *sysdev) | ||
136 | { | ||
137 | pm_cpu_prep = s5pv210_pm_prepare; | ||
138 | pm_cpu_sleep = s5pv210_cpu_suspend; | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static int s5pv210_pm_resume(struct sys_device *dev) | ||
144 | { | ||
145 | u32 tmp; | ||
146 | |||
147 | tmp = __raw_readl(S5P_OTHERS); | ||
148 | tmp |= (S5P_OTHERS_RET_IO | S5P_OTHERS_RET_CF |\ | ||
149 | S5P_OTHERS_RET_MMC | S5P_OTHERS_RET_UART); | ||
150 | __raw_writel(tmp , S5P_OTHERS); | ||
151 | |||
152 | s3c_pm_do_restore_core(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save)); | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static struct sysdev_driver s5pv210_pm_driver = { | ||
158 | .add = s5pv210_pm_add, | ||
159 | .resume = s5pv210_pm_resume, | ||
160 | }; | ||
161 | |||
162 | static __init int s5pv210_pm_drvinit(void) | ||
163 | { | ||
164 | return sysdev_driver_register(&s5pv210_sysclass, &s5pv210_pm_driver); | ||
165 | } | ||
166 | arch_initcall(s5pv210_pm_drvinit); | ||
diff --git a/arch/arm/mach-s5pv210/setup-fb-24bpp.c b/arch/arm/mach-s5pv210/setup-fb-24bpp.c index 928cf1f125fa..e932ebfac56d 100644 --- a/arch/arm/mach-s5pv210/setup-fb-24bpp.c +++ b/arch/arm/mach-s5pv210/setup-fb-24bpp.c | |||
@@ -21,33 +21,21 @@ | |||
21 | #include <mach/regs-clock.h> | 21 | #include <mach/regs-clock.h> |
22 | #include <plat/gpio-cfg.h> | 22 | #include <plat/gpio-cfg.h> |
23 | 23 | ||
24 | void s5pv210_fb_gpio_setup_24bpp(void) | 24 | static void s5pv210_fb_cfg_gpios(unsigned int base, unsigned int nr) |
25 | { | 25 | { |
26 | unsigned int gpio = 0; | 26 | s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2)); |
27 | |||
28 | for (gpio = S5PV210_GPF0(0); gpio <= S5PV210_GPF0(7); gpio++) { | ||
29 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | ||
30 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
31 | s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); | ||
32 | } | ||
33 | 27 | ||
34 | for (gpio = S5PV210_GPF1(0); gpio <= S5PV210_GPF1(7); gpio++) { | 28 | for (; nr > 0; nr--, base++) |
35 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | 29 | s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4); |
36 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | 30 | } |
37 | s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); | ||
38 | } | ||
39 | 31 | ||
40 | for (gpio = S5PV210_GPF2(0); gpio <= S5PV210_GPF2(7); gpio++) { | ||
41 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | ||
42 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
43 | s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); | ||
44 | } | ||
45 | 32 | ||
46 | for (gpio = S5PV210_GPF3(0); gpio <= S5PV210_GPF3(3); gpio++) { | 33 | void s5pv210_fb_gpio_setup_24bpp(void) |
47 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | 34 | { |
48 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | 35 | s5pv210_fb_cfg_gpios(S5PV210_GPF0(0), 8); |
49 | s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); | 36 | s5pv210_fb_cfg_gpios(S5PV210_GPF1(0), 8); |
50 | } | 37 | s5pv210_fb_cfg_gpios(S5PV210_GPF2(0), 8); |
38 | s5pv210_fb_cfg_gpios(S5PV210_GPF3(0), 4); | ||
51 | 39 | ||
52 | /* Set DISPLAY_CONTROL register for Display path selection. | 40 | /* Set DISPLAY_CONTROL register for Display path selection. |
53 | * | 41 | * |
diff --git a/arch/arm/mach-s5pv210/setup-i2c0.c b/arch/arm/mach-s5pv210/setup-i2c0.c index d38f7cb7e662..0f1cc3a1c1e8 100644 --- a/arch/arm/mach-s5pv210/setup-i2c0.c +++ b/arch/arm/mach-s5pv210/setup-i2c0.c | |||
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */ | |||
23 | 23 | ||
24 | void s3c_i2c0_cfg_gpio(struct platform_device *dev) | 24 | void s3c_i2c0_cfg_gpio(struct platform_device *dev) |
25 | { | 25 | { |
26 | s3c_gpio_cfgpin(S5PV210_GPD1(0), S3C_GPIO_SFN(2)); | 26 | s3c_gpio_cfgall_range(S5PV210_GPD1(0), 2, |
27 | s3c_gpio_setpull(S5PV210_GPD1(0), S3C_GPIO_PULL_UP); | 27 | S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); |
28 | s3c_gpio_cfgpin(S5PV210_GPD1(1), S3C_GPIO_SFN(2)); | ||
29 | s3c_gpio_setpull(S5PV210_GPD1(1), S3C_GPIO_PULL_UP); | ||
30 | } | 28 | } |
diff --git a/arch/arm/mach-s5pv210/setup-i2c1.c b/arch/arm/mach-s5pv210/setup-i2c1.c index 148bb7857d89..f61365a34c56 100644 --- a/arch/arm/mach-s5pv210/setup-i2c1.c +++ b/arch/arm/mach-s5pv210/setup-i2c1.c | |||
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */ | |||
23 | 23 | ||
24 | void s3c_i2c1_cfg_gpio(struct platform_device *dev) | 24 | void s3c_i2c1_cfg_gpio(struct platform_device *dev) |
25 | { | 25 | { |
26 | s3c_gpio_cfgpin(S5PV210_GPD1(2), S3C_GPIO_SFN(2)); | 26 | s3c_gpio_cfgall_range(S5PV210_GPD1(2), 2, |
27 | s3c_gpio_setpull(S5PV210_GPD1(2), S3C_GPIO_PULL_UP); | 27 | S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); |
28 | s3c_gpio_cfgpin(S5PV210_GPD1(3), S3C_GPIO_SFN(2)); | ||
29 | s3c_gpio_setpull(S5PV210_GPD1(3), S3C_GPIO_PULL_UP); | ||
30 | } | 28 | } |
diff --git a/arch/arm/mach-s5pv210/setup-i2c2.c b/arch/arm/mach-s5pv210/setup-i2c2.c index 2396cb8c373e..2f91b5cefbc6 100644 --- a/arch/arm/mach-s5pv210/setup-i2c2.c +++ b/arch/arm/mach-s5pv210/setup-i2c2.c | |||
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */ | |||
23 | 23 | ||
24 | void s3c_i2c2_cfg_gpio(struct platform_device *dev) | 24 | void s3c_i2c2_cfg_gpio(struct platform_device *dev) |
25 | { | 25 | { |
26 | s3c_gpio_cfgpin(S5PV210_GPD1(4), S3C_GPIO_SFN(2)); | 26 | s3c_gpio_cfgall_range(S5PV210_GPD1(4), 2, |
27 | s3c_gpio_setpull(S5PV210_GPD1(4), S3C_GPIO_PULL_UP); | 27 | S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); |
28 | s3c_gpio_cfgpin(S5PV210_GPD1(5), S3C_GPIO_SFN(2)); | ||
29 | s3c_gpio_setpull(S5PV210_GPD1(5), S3C_GPIO_PULL_UP); | ||
30 | } | 28 | } |
diff --git a/arch/arm/mach-s5pv210/setup-ide.c b/arch/arm/mach-s5pv210/setup-ide.c index b558b1cc8d60..ea123d546bd2 100644 --- a/arch/arm/mach-s5pv210/setup-ide.c +++ b/arch/arm/mach-s5pv210/setup-ide.c | |||
@@ -15,36 +15,25 @@ | |||
15 | 15 | ||
16 | #include <plat/gpio-cfg.h> | 16 | #include <plat/gpio-cfg.h> |
17 | 17 | ||
18 | static void s5pv210_ide_cfg_gpios(unsigned int base, unsigned int nr) | ||
19 | { | ||
20 | s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(4)); | ||
21 | |||
22 | for (; nr > 0; nr--, base++) | ||
23 | s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4); | ||
24 | } | ||
25 | |||
18 | void s5pv210_ide_setup_gpio(void) | 26 | void s5pv210_ide_setup_gpio(void) |
19 | { | 27 | { |
20 | unsigned int gpio = 0; | 28 | /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */ |
21 | 29 | s5pv210_ide_cfg_gpios(S5PV210_GPJ0(0), 8); | |
22 | for (gpio = S5PV210_GPJ0(0); gpio <= S5PV210_GPJ0(7); gpio++) { | 30 | |
23 | /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, | 31 | /* CF_Data[0 - 7] */ |
24 | CF_DMACK */ | 32 | s5pv210_ide_cfg_gpios(S5PV210_GPJ2(0), 8); |
25 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4)); | 33 | |
26 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | 34 | /* CF_Data[8 - 15] */ |
27 | s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); | 35 | s5pv210_ide_cfg_gpios(S5PV210_GPJ3(0), 8); |
28 | } | 36 | |
29 | 37 | /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */ | |
30 | for (gpio = S5PV210_GPJ2(0); gpio <= S5PV210_GPJ2(7); gpio++) { | 38 | s5pv210_ide_cfg_gpios(S5PV210_GPJ4(0), 4); |
31 | /*CF_Data[0 - 7] */ | ||
32 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4)); | ||
33 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
34 | s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); | ||
35 | } | ||
36 | |||
37 | for (gpio = S5PV210_GPJ3(0); gpio <= S5PV210_GPJ3(7); gpio++) { | ||
38 | /* CF_Data[8 - 15] */ | ||
39 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4)); | ||
40 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
41 | s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); | ||
42 | } | ||
43 | |||
44 | for (gpio = S5PV210_GPJ4(0); gpio <= S5PV210_GPJ4(3); gpio++) { | ||
45 | /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */ | ||
46 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4)); | ||
47 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
48 | s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); | ||
49 | } | ||
50 | } | 39 | } |
diff --git a/arch/arm/mach-s5pv210/setup-keypad.c b/arch/arm/mach-s5pv210/setup-keypad.c index 37b2790aafc3..c56420a52f48 100644 --- a/arch/arm/mach-s5pv210/setup-keypad.c +++ b/arch/arm/mach-s5pv210/setup-keypad.c | |||
@@ -16,19 +16,9 @@ | |||
16 | 16 | ||
17 | void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) | 17 | void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) |
18 | { | 18 | { |
19 | unsigned int gpio, end; | ||
20 | |||
21 | /* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */ | 19 | /* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */ |
22 | end = S5PV210_GPH3(rows); | 20 | s3c_gpio_cfgrange_nopull(S5PV210_GPH3(0), rows, S3C_GPIO_SFN(3)); |
23 | for (gpio = S5PV210_GPH3(0); gpio < end; gpio++) { | ||
24 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3)); | ||
25 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
26 | } | ||
27 | 21 | ||
28 | /* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */ | 22 | /* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */ |
29 | end = S5PV210_GPH2(cols); | 23 | s3c_gpio_cfgrange_nopull(S5PV210_GPH2(0), cols, S3C_GPIO_SFN(3)); |
30 | for (gpio = S5PV210_GPH2(0); gpio < end; gpio++) { | ||
31 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3)); | ||
32 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
33 | } | ||
34 | } | 24 | } |
diff --git a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c index b18587b1ec58..746777d56df9 100644 --- a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c +++ b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c | |||
@@ -26,26 +26,17 @@ | |||
26 | void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) | 26 | void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) |
27 | { | 27 | { |
28 | struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; | 28 | struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; |
29 | unsigned int gpio; | ||
30 | 29 | ||
31 | /* Set all the necessary GPG0/GPG1 pins to special-function 2 */ | 30 | /* Set all the necessary GPG0/GPG1 pins to special-function 2 */ |
32 | for (gpio = S5PV210_GPG0(0); gpio < S5PV210_GPG0(2); gpio++) { | 31 | s3c_gpio_cfgrange_nopull(S5PV210_GPG0(0), 2, S3C_GPIO_SFN(2)); |
33 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | 32 | |
34 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
35 | } | ||
36 | switch (width) { | 33 | switch (width) { |
37 | case 8: | 34 | case 8: |
38 | /* GPG1[3:6] special-funtion 3 */ | 35 | /* GPG1[3:6] special-funtion 3 */ |
39 | for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) { | 36 | s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(3)); |
40 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3)); | ||
41 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
42 | } | ||
43 | case 4: | 37 | case 4: |
44 | /* GPG0[3:6] special-funtion 2 */ | 38 | /* GPG0[3:6] special-funtion 2 */ |
45 | for (gpio = S5PV210_GPG0(3); gpio <= S5PV210_GPG0(6); gpio++) { | 39 | s3c_gpio_cfgrange_nopull(S5PV210_GPG0(3), 4, S3C_GPIO_SFN(2)); |
46 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | ||
47 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
48 | } | ||
49 | default: | 40 | default: |
50 | break; | 41 | break; |
51 | } | 42 | } |
@@ -59,19 +50,12 @@ void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) | |||
59 | void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) | 50 | void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) |
60 | { | 51 | { |
61 | struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; | 52 | struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; |
62 | unsigned int gpio; | ||
63 | 53 | ||
64 | /* Set all the necessary GPG1[0:1] pins to special-function 2 */ | 54 | /* Set all the necessary GPG1[0:1] pins to special-function 2 */ |
65 | for (gpio = S5PV210_GPG1(0); gpio < S5PV210_GPG1(2); gpio++) { | 55 | s3c_gpio_cfgrange_nopull(S5PV210_GPG1(0), 2, S3C_GPIO_SFN(2)); |
66 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | ||
67 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
68 | } | ||
69 | 56 | ||
70 | /* Data pin GPG1[3:6] to special-function 2 */ | 57 | /* Data pin GPG1[3:6] to special-function 2 */ |
71 | for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) { | 58 | s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(2)); |
72 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | ||
73 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
74 | } | ||
75 | 59 | ||
76 | if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { | 60 | if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { |
77 | s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP); | 61 | s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP); |
@@ -82,27 +66,17 @@ void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) | |||
82 | void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) | 66 | void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) |
83 | { | 67 | { |
84 | struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; | 68 | struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; |
85 | unsigned int gpio; | ||
86 | 69 | ||
87 | /* Set all the necessary GPG2[0:1] pins to special-function 2 */ | 70 | /* Set all the necessary GPG2[0:1] pins to special-function 2 */ |
88 | for (gpio = S5PV210_GPG2(0); gpio < S5PV210_GPG2(2); gpio++) { | 71 | s3c_gpio_cfgrange_nopull(S5PV210_GPG2(0), 2, S3C_GPIO_SFN(2)); |
89 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | ||
90 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
91 | } | ||
92 | 72 | ||
93 | switch (width) { | 73 | switch (width) { |
94 | case 8: | 74 | case 8: |
95 | /* Data pin GPG3[3:6] to special-function 3 */ | 75 | /* Data pin GPG3[3:6] to special-function 3 */ |
96 | for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) { | 76 | s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(3)); |
97 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3)); | ||
98 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
99 | } | ||
100 | case 4: | 77 | case 4: |
101 | /* Data pin GPG2[3:6] to special-function 2 */ | 78 | /* Data pin GPG2[3:6] to special-function 2 */ |
102 | for (gpio = S5PV210_GPG2(3); gpio <= S5PV210_GPG2(6); gpio++) { | 79 | s3c_gpio_cfgrange_nopull(S5PV210_GPG2(3), 4, S3C_GPIO_SFN(2)); |
103 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | ||
104 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
105 | } | ||
106 | default: | 80 | default: |
107 | break; | 81 | break; |
108 | } | 82 | } |
@@ -116,19 +90,12 @@ void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) | |||
116 | void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width) | 90 | void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width) |
117 | { | 91 | { |
118 | struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; | 92 | struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; |
119 | unsigned int gpio; | ||
120 | 93 | ||
121 | /* Set all the necessary GPG3[0:2] pins to special-function 2 */ | 94 | /* Set all the necessary GPG3[0:1] pins to special-function 2 */ |
122 | for (gpio = S5PV210_GPG3(0); gpio < S5PV210_GPG3(2); gpio++) { | 95 | s3c_gpio_cfgrange_nopull(S5PV210_GPG3(0), 2, S3C_GPIO_SFN(2)); |
123 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | ||
124 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
125 | } | ||
126 | 96 | ||
127 | /* Data pin GPG3[3:6] to special-function 2 */ | 97 | /* Data pin GPG3[3:6] to special-function 2 */ |
128 | for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) { | 98 | s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(2)); |
129 | s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | ||
130 | s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||
131 | } | ||
132 | 99 | ||
133 | if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { | 100 | if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { |
134 | s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP); | 101 | s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP); |
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S new file mode 100644 index 000000000000..d4d222b716b4 --- /dev/null +++ b/arch/arm/mach-s5pv210/sleep.S | |||
@@ -0,0 +1,170 @@ | |||
1 | /* linux/arch/arm/plat-s5p/sleep.S | ||
2 | * | ||
3 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com | ||
5 | * | ||
6 | * S5PV210 power Manager (Suspend-To-RAM) support | ||
7 | * Based on S3C2410 sleep code by: | ||
8 | * Ben Dooks, (c) 2004 Simtec Electronics | ||
9 | * | ||
10 | * Based on PXA/SA1100 sleep code by: | ||
11 | * Nicolas Pitre, (c) 2002 Monta Vista Software Inc | ||
12 | * Cliff Brake, (c) 2001 | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
27 | */ | ||
28 | |||
29 | #include <linux/linkage.h> | ||
30 | #include <asm/assembler.h> | ||
31 | #include <asm/memory.h> | ||
32 | |||
33 | .text | ||
34 | |||
35 | /* s3c_cpu_save | ||
36 | * | ||
37 | * entry: | ||
38 | * r0 = save address (virtual addr of s3c_sleep_save_phys) | ||
39 | */ | ||
40 | |||
41 | ENTRY(s3c_cpu_save) | ||
42 | |||
43 | stmfd sp!, { r3 - r12, lr } | ||
44 | |||
45 | mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID | ||
46 | mrc p15, 0, r5, c3, c0, 0 @ Domain ID | ||
47 | mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0 | ||
48 | mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1 | ||
49 | mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control | ||
50 | mrc p15, 0, r9, c1, c0, 0 @ Control register | ||
51 | mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register | ||
52 | mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls | ||
53 | mrc p15, 0, r12, c10, c2, 0 @ Read PRRR | ||
54 | mrc p15, 0, r3, c10, c2, 1 @ READ NMRR | ||
55 | |||
56 | stmia r0, { r3 - r13 } | ||
57 | |||
58 | bl s3c_pm_cb_flushcache | ||
59 | |||
60 | ldr r0, =pm_cpu_sleep | ||
61 | ldr r0, [ r0 ] | ||
62 | mov pc, r0 | ||
63 | |||
64 | resume_with_mmu: | ||
65 | /* | ||
66 | * After MMU is turned on, restore the previous MMU table. | ||
67 | */ | ||
68 | ldr r9 , =(PAGE_OFFSET - PHYS_OFFSET) | ||
69 | add r4, r4, r9 | ||
70 | str r12, [r4] | ||
71 | |||
72 | ldmfd sp!, { r3 - r12, pc } | ||
73 | |||
74 | .ltorg | ||
75 | |||
76 | .data | ||
77 | |||
78 | .global s3c_sleep_save_phys | ||
79 | s3c_sleep_save_phys: | ||
80 | .word 0 | ||
81 | |||
82 | /* sleep magic, to allow the bootloader to check for an valid | ||
83 | * image to resume to. Must be the first word before the | ||
84 | * s3c_cpu_resume entry. | ||
85 | */ | ||
86 | |||
87 | .word 0x2bedf00d | ||
88 | |||
89 | /* s3c_cpu_resume | ||
90 | * | ||
91 | * resume code entry for bootloader to call | ||
92 | * | ||
93 | * we must put this code here in the data segment as we have no | ||
94 | * other way of restoring the stack pointer after sleep, and we | ||
95 | * must not write to the code segment (code is read-only) | ||
96 | */ | ||
97 | |||
98 | ENTRY(s3c_cpu_resume) | ||
99 | mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE | ||
100 | msr cpsr_c, r0 | ||
101 | |||
102 | mov r1, #0 | ||
103 | mcr p15, 0, r1, c8, c7, 0 @ invalidate TLBs | ||
104 | mcr p15, 0, r1, c7, c5, 0 @ invalidate I Cache | ||
105 | |||
106 | ldr r0, s3c_sleep_save_phys @ address of restore block | ||
107 | ldmia r0, { r3 - r13 } | ||
108 | |||
109 | mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID | ||
110 | mcr p15, 0, r5, c3, c0, 0 @ Domain ID | ||
111 | |||
112 | mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control | ||
113 | mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1 | ||
114 | mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0 | ||
115 | |||
116 | mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register | ||
117 | |||
118 | mov r0, #0 | ||
119 | mcr p15, 0, r0, c8, c7, 0 @ Invalidate I & D TLB | ||
120 | |||
121 | mov r0, #0 @ restore copro access | ||
122 | mcr p15, 0, r11, c1, c0, 2 @ Co-processor access | ||
123 | mcr p15, 0, r0, c7, c5, 4 | ||
124 | |||
125 | mcr p15, 0, r12, c10, c2, 0 @ write PRRR | ||
126 | mcr p15, 0, r3, c10, c2, 1 @ write NMRR | ||
127 | |||
128 | /* | ||
129 | * In Cortex-A8, when MMU is turned on, the pipeline is flushed. | ||
130 | * And there are no valid entries in the MMU table at this point. | ||
131 | * So before turning on the MMU, the MMU entry for the DRAM address | ||
132 | * range is added. After the MMU is turned on, the other entries | ||
133 | * in the MMU table will be restored. | ||
134 | */ | ||
135 | |||
136 | /* r6 = Translation Table BASE0 */ | ||
137 | mov r4, r6 | ||
138 | mov r4, r4, LSR #14 | ||
139 | mov r4, r4, LSL #14 | ||
140 | |||
141 | /* Load address for adding to MMU table list */ | ||
142 | ldr r11, =0xE010F000 @ INFORM0 reg. | ||
143 | ldr r10, [r11, #0] | ||
144 | mov r10, r10, LSR #18 | ||
145 | bic r10, r10, #0x3 | ||
146 | orr r4, r4, r10 | ||
147 | |||
148 | /* Calculate MMU table entry */ | ||
149 | mov r10, r10, LSL #18 | ||
150 | ldr r5, =0x40E | ||
151 | orr r10, r10, r5 | ||
152 | |||
153 | /* Back up originally data */ | ||
154 | ldr r12, [r4] | ||
155 | |||
156 | /* Add calculated MMU table entry into MMU table list */ | ||
157 | str r10, [r4] | ||
158 | |||
159 | ldr r2, =resume_with_mmu | ||
160 | mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, etc | ||
161 | |||
162 | nop | ||
163 | nop | ||
164 | nop | ||
165 | nop | ||
166 | nop @ second-to-last before mmu | ||
167 | |||
168 | mov pc, r2 @ go back to virtual address | ||
169 | |||
170 | .ltorg | ||