diff options
24 files changed, 544 insertions, 37 deletions
diff --git a/Documentation/devicetree/bindings/arm/altera/socfpga-reset.txt b/Documentation/devicetree/bindings/arm/altera/socfpga-reset.txt new file mode 100644 index 000000000000..ecdb57d69dbf --- /dev/null +++ b/Documentation/devicetree/bindings/arm/altera/socfpga-reset.txt | |||
@@ -0,0 +1,11 @@ | |||
1 | Altera SOCFPGA Reset Manager | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "altr,rst-mgr" | ||
5 | - reg : Should contain 1 register ranges(address and length) | ||
6 | |||
7 | Example: | ||
8 | rstmgr@ffd05000 { | ||
9 | compatible = "altr,rst-mgr"; | ||
10 | reg = <0xffd05000 0x1000>; | ||
11 | }; | ||
diff --git a/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt b/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt new file mode 100644 index 000000000000..07c65e3cdcbe --- /dev/null +++ b/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt | |||
@@ -0,0 +1,11 @@ | |||
1 | Altera SOCFPGA System Manager | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "altr,sys-mgr" | ||
5 | - reg : Should contain 1 register ranges(address and length) | ||
6 | |||
7 | Example: | ||
8 | sysmgr@ffd08000 { | ||
9 | compatible = "altr,sys-mgr"; | ||
10 | reg = <0xffd08000 0x1000>; | ||
11 | }; | ||
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 36d8246ea50e..2e3b6efaf1a2 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi | |||
@@ -35,6 +35,15 @@ | |||
35 | mshc1 = &dwmmc_1; | 35 | mshc1 = &dwmmc_1; |
36 | mshc2 = &dwmmc_2; | 36 | mshc2 = &dwmmc_2; |
37 | mshc3 = &dwmmc_3; | 37 | mshc3 = &dwmmc_3; |
38 | i2c0 = &i2c_0; | ||
39 | i2c1 = &i2c_1; | ||
40 | i2c2 = &i2c_2; | ||
41 | i2c3 = &i2c_3; | ||
42 | i2c4 = &i2c_4; | ||
43 | i2c5 = &i2c_5; | ||
44 | i2c6 = &i2c_6; | ||
45 | i2c7 = &i2c_7; | ||
46 | i2c8 = &i2c_8; | ||
38 | }; | 47 | }; |
39 | 48 | ||
40 | gic:interrupt-controller@10481000 { | 49 | gic:interrupt-controller@10481000 { |
@@ -119,7 +128,7 @@ | |||
119 | reg = <0x12170000 0x1ff>; | 128 | reg = <0x12170000 0x1ff>; |
120 | }; | 129 | }; |
121 | 130 | ||
122 | i2c@12C60000 { | 131 | i2c_0: i2c@12C60000 { |
123 | compatible = "samsung,s3c2440-i2c"; | 132 | compatible = "samsung,s3c2440-i2c"; |
124 | reg = <0x12C60000 0x100>; | 133 | reg = <0x12C60000 0x100>; |
125 | interrupts = <0 56 0>; | 134 | interrupts = <0 56 0>; |
@@ -127,7 +136,7 @@ | |||
127 | #size-cells = <0>; | 136 | #size-cells = <0>; |
128 | }; | 137 | }; |
129 | 138 | ||
130 | i2c@12C70000 { | 139 | i2c_1: i2c@12C70000 { |
131 | compatible = "samsung,s3c2440-i2c"; | 140 | compatible = "samsung,s3c2440-i2c"; |
132 | reg = <0x12C70000 0x100>; | 141 | reg = <0x12C70000 0x100>; |
133 | interrupts = <0 57 0>; | 142 | interrupts = <0 57 0>; |
@@ -135,7 +144,7 @@ | |||
135 | #size-cells = <0>; | 144 | #size-cells = <0>; |
136 | }; | 145 | }; |
137 | 146 | ||
138 | i2c@12C80000 { | 147 | i2c_2: i2c@12C80000 { |
139 | compatible = "samsung,s3c2440-i2c"; | 148 | compatible = "samsung,s3c2440-i2c"; |
140 | reg = <0x12C80000 0x100>; | 149 | reg = <0x12C80000 0x100>; |
141 | interrupts = <0 58 0>; | 150 | interrupts = <0 58 0>; |
@@ -143,7 +152,7 @@ | |||
143 | #size-cells = <0>; | 152 | #size-cells = <0>; |
144 | }; | 153 | }; |
145 | 154 | ||
146 | i2c@12C90000 { | 155 | i2c_3: i2c@12C90000 { |
147 | compatible = "samsung,s3c2440-i2c"; | 156 | compatible = "samsung,s3c2440-i2c"; |
148 | reg = <0x12C90000 0x100>; | 157 | reg = <0x12C90000 0x100>; |
149 | interrupts = <0 59 0>; | 158 | interrupts = <0 59 0>; |
@@ -151,7 +160,7 @@ | |||
151 | #size-cells = <0>; | 160 | #size-cells = <0>; |
152 | }; | 161 | }; |
153 | 162 | ||
154 | i2c@12CA0000 { | 163 | i2c_4: i2c@12CA0000 { |
155 | compatible = "samsung,s3c2440-i2c"; | 164 | compatible = "samsung,s3c2440-i2c"; |
156 | reg = <0x12CA0000 0x100>; | 165 | reg = <0x12CA0000 0x100>; |
157 | interrupts = <0 60 0>; | 166 | interrupts = <0 60 0>; |
@@ -159,7 +168,7 @@ | |||
159 | #size-cells = <0>; | 168 | #size-cells = <0>; |
160 | }; | 169 | }; |
161 | 170 | ||
162 | i2c@12CB0000 { | 171 | i2c_5: i2c@12CB0000 { |
163 | compatible = "samsung,s3c2440-i2c"; | 172 | compatible = "samsung,s3c2440-i2c"; |
164 | reg = <0x12CB0000 0x100>; | 173 | reg = <0x12CB0000 0x100>; |
165 | interrupts = <0 61 0>; | 174 | interrupts = <0 61 0>; |
@@ -167,7 +176,7 @@ | |||
167 | #size-cells = <0>; | 176 | #size-cells = <0>; |
168 | }; | 177 | }; |
169 | 178 | ||
170 | i2c@12CC0000 { | 179 | i2c_6: i2c@12CC0000 { |
171 | compatible = "samsung,s3c2440-i2c"; | 180 | compatible = "samsung,s3c2440-i2c"; |
172 | reg = <0x12CC0000 0x100>; | 181 | reg = <0x12CC0000 0x100>; |
173 | interrupts = <0 62 0>; | 182 | interrupts = <0 62 0>; |
@@ -175,7 +184,7 @@ | |||
175 | #size-cells = <0>; | 184 | #size-cells = <0>; |
176 | }; | 185 | }; |
177 | 186 | ||
178 | i2c@12CD0000 { | 187 | i2c_7: i2c@12CD0000 { |
179 | compatible = "samsung,s3c2440-i2c"; | 188 | compatible = "samsung,s3c2440-i2c"; |
180 | reg = <0x12CD0000 0x100>; | 189 | reg = <0x12CD0000 0x100>; |
181 | interrupts = <0 63 0>; | 190 | interrupts = <0 63 0>; |
@@ -183,7 +192,7 @@ | |||
183 | #size-cells = <0>; | 192 | #size-cells = <0>; |
184 | }; | 193 | }; |
185 | 194 | ||
186 | i2c@12CE0000 { | 195 | i2c_8: i2c@12CE0000 { |
187 | compatible = "samsung,s3c2440-hdmiphy-i2c"; | 196 | compatible = "samsung,s3c2440-hdmiphy-i2c"; |
188 | reg = <0x12CE0000 0x1000>; | 197 | reg = <0x12CE0000 0x1000>; |
189 | interrupts = <0 64 0>; | 198 | interrupts = <0 64 0>; |
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi index 0772f5739f59..19aec421bb26 100644 --- a/arch/arm/boot/dts/socfpga.dtsi +++ b/arch/arm/boot/dts/socfpga.dtsi | |||
@@ -143,5 +143,15 @@ | |||
143 | reg-shift = <2>; | 143 | reg-shift = <2>; |
144 | reg-io-width = <4>; | 144 | reg-io-width = <4>; |
145 | }; | 145 | }; |
146 | |||
147 | rstmgr@ffd05000 { | ||
148 | compatible = "altr,rst-mgr"; | ||
149 | reg = <0xffd05000 0x1000>; | ||
150 | }; | ||
151 | |||
152 | sysmgr@ffd08000 { | ||
153 | compatible = "altr,sys-mgr"; | ||
154 | reg = <0xffd08000 0x4000>; | ||
155 | }; | ||
146 | }; | 156 | }; |
147 | }; | 157 | }; |
diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig index 0ac1293dba10..4e1ce211d43f 100644 --- a/arch/arm/configs/socfpga_defconfig +++ b/arch/arm/configs/socfpga_defconfig | |||
@@ -18,9 +18,10 @@ CONFIG_MODULE_UNLOAD=y | |||
18 | CONFIG_ARCH_SOCFPGA=y | 18 | CONFIG_ARCH_SOCFPGA=y |
19 | CONFIG_MACH_SOCFPGA_CYCLONE5=y | 19 | CONFIG_MACH_SOCFPGA_CYCLONE5=y |
20 | CONFIG_ARM_THUMBEE=y | 20 | CONFIG_ARM_THUMBEE=y |
21 | # CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set | ||
21 | # CONFIG_CACHE_L2X0 is not set | 22 | # CONFIG_CACHE_L2X0 is not set |
22 | CONFIG_HIGH_RES_TIMERS=y | 23 | CONFIG_HIGH_RES_TIMERS=y |
23 | CONFIG_VMSPLIT_2G=y | 24 | CONFIG_SMP=y |
24 | CONFIG_NR_CPUS=2 | 25 | CONFIG_NR_CPUS=2 |
25 | CONFIG_AEABI=y | 26 | CONFIG_AEABI=y |
26 | CONFIG_ZBOOT_ROM_TEXT=0x0 | 27 | CONFIG_ZBOOT_ROM_TEXT=0x0 |
diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c index 7652f5d78a56..e9d7b80bae49 100644 --- a/arch/arm/mach-exynos/clock-exynos5.c +++ b/arch/arm/mach-exynos/clock-exynos5.c | |||
@@ -80,6 +80,8 @@ static struct sleep_save exynos5_clock_save[] = { | |||
80 | SAVE_ITEM(EXYNOS5_VPLL_CON0), | 80 | SAVE_ITEM(EXYNOS5_VPLL_CON0), |
81 | SAVE_ITEM(EXYNOS5_VPLL_CON1), | 81 | SAVE_ITEM(EXYNOS5_VPLL_CON1), |
82 | SAVE_ITEM(EXYNOS5_VPLL_CON2), | 82 | SAVE_ITEM(EXYNOS5_VPLL_CON2), |
83 | SAVE_ITEM(EXYNOS5_PWR_CTRL1), | ||
84 | SAVE_ITEM(EXYNOS5_PWR_CTRL2), | ||
83 | }; | 85 | }; |
84 | #endif | 86 | #endif |
85 | 87 | ||
@@ -661,15 +663,20 @@ static struct clk exynos5_init_clocks_off[] = { | |||
661 | .ctrlbit = (1 << 15), | 663 | .ctrlbit = (1 << 15), |
662 | }, { | 664 | }, { |
663 | .name = "sata", | 665 | .name = "sata", |
664 | .devname = "ahci", | 666 | .devname = "exynos5-sata", |
667 | .parent = &exynos5_clk_aclk_200.clk, | ||
665 | .enable = exynos5_clk_ip_fsys_ctrl, | 668 | .enable = exynos5_clk_ip_fsys_ctrl, |
666 | .ctrlbit = (1 << 6), | 669 | .ctrlbit = (1 << 6), |
667 | }, { | 670 | }, { |
668 | .name = "sata_phy", | 671 | .name = "sata-phy", |
672 | .devname = "exynos5-sata-phy", | ||
673 | .parent = &exynos5_clk_aclk_200.clk, | ||
669 | .enable = exynos5_clk_ip_fsys_ctrl, | 674 | .enable = exynos5_clk_ip_fsys_ctrl, |
670 | .ctrlbit = (1 << 24), | 675 | .ctrlbit = (1 << 24), |
671 | }, { | 676 | }, { |
672 | .name = "sata_phy_i2c", | 677 | .name = "i2c", |
678 | .devname = "exynos5-sata-phy-i2c", | ||
679 | .parent = &exynos5_clk_aclk_200.clk, | ||
673 | .enable = exynos5_clk_ip_fsys_ctrl, | 680 | .enable = exynos5_clk_ip_fsys_ctrl, |
674 | .ctrlbit = (1 << 25), | 681 | .ctrlbit = (1 << 25), |
675 | }, { | 682 | }, { |
@@ -693,6 +700,11 @@ static struct clk exynos5_init_clocks_off[] = { | |||
693 | .enable = exynos5_clk_ip_disp1_ctrl, | 700 | .enable = exynos5_clk_ip_disp1_ctrl, |
694 | .ctrlbit = (1 << 5), | 701 | .ctrlbit = (1 << 5), |
695 | }, { | 702 | }, { |
703 | .name = "dp", | ||
704 | .devname = "exynos-dp", | ||
705 | .enable = exynos5_clk_ip_disp1_ctrl, | ||
706 | .ctrlbit = (1 << 4), | ||
707 | }, { | ||
696 | .name = "jpeg", | 708 | .name = "jpeg", |
697 | .enable = exynos5_clk_ip_gen_ctrl, | 709 | .enable = exynos5_clk_ip_gen_ctrl, |
698 | .ctrlbit = (1 << 2), | 710 | .ctrlbit = (1 << 2), |
@@ -1241,6 +1253,16 @@ static struct clksrc_clk exynos5_clksrcs[] = { | |||
1241 | .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 }, | 1253 | .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 }, |
1242 | }, { | 1254 | }, { |
1243 | .clk = { | 1255 | .clk = { |
1256 | .name = "sclk_sata", | ||
1257 | .devname = "exynos5-sata", | ||
1258 | .enable = exynos5_clksrc_mask_fsys_ctrl, | ||
1259 | .ctrlbit = (1 << 24), | ||
1260 | }, | ||
1261 | .sources = &exynos5_clkset_aclk, | ||
1262 | .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 24, .size = 1 }, | ||
1263 | .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS0, .shift = 20, .size = 4 }, | ||
1264 | }, { | ||
1265 | .clk = { | ||
1244 | .name = "sclk_gscl_wrap", | 1266 | .name = "sclk_gscl_wrap", |
1245 | .devname = "s5p-mipi-csis.0", | 1267 | .devname = "s5p-mipi-csis.0", |
1246 | .enable = exynos5_clksrc_mask_gscl_ctrl, | 1268 | .enable = exynos5_clksrc_mask_gscl_ctrl, |
diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c index 8e4ec21ef2cf..050924152776 100644 --- a/arch/arm/mach-exynos/cpuidle.c +++ b/arch/arm/mach-exynos/cpuidle.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/suspend.h> | 21 | #include <asm/suspend.h> |
22 | #include <asm/unified.h> | 22 | #include <asm/unified.h> |
23 | #include <asm/cpuidle.h> | 23 | #include <asm/cpuidle.h> |
24 | #include <mach/regs-clock.h> | ||
24 | #include <mach/regs-pmu.h> | 25 | #include <mach/regs-pmu.h> |
25 | #include <mach/pmu.h> | 26 | #include <mach/pmu.h> |
26 | 27 | ||
@@ -157,12 +158,47 @@ static int exynos4_enter_lowpower(struct cpuidle_device *dev, | |||
157 | return exynos4_enter_core0_aftr(dev, drv, new_index); | 158 | return exynos4_enter_core0_aftr(dev, drv, new_index); |
158 | } | 159 | } |
159 | 160 | ||
161 | static void __init exynos5_core_down_clk(void) | ||
162 | { | ||
163 | unsigned int tmp; | ||
164 | |||
165 | /* | ||
166 | * Enable arm clock down (in idle) and set arm divider | ||
167 | * ratios in WFI/WFE state. | ||
168 | */ | ||
169 | tmp = PWR_CTRL1_CORE2_DOWN_RATIO | \ | ||
170 | PWR_CTRL1_CORE1_DOWN_RATIO | \ | ||
171 | PWR_CTRL1_DIV2_DOWN_EN | \ | ||
172 | PWR_CTRL1_DIV1_DOWN_EN | \ | ||
173 | PWR_CTRL1_USE_CORE1_WFE | \ | ||
174 | PWR_CTRL1_USE_CORE0_WFE | \ | ||
175 | PWR_CTRL1_USE_CORE1_WFI | \ | ||
176 | PWR_CTRL1_USE_CORE0_WFI; | ||
177 | __raw_writel(tmp, EXYNOS5_PWR_CTRL1); | ||
178 | |||
179 | /* | ||
180 | * Enable arm clock up (on exiting idle). Set arm divider | ||
181 | * ratios when not in idle along with the standby duration | ||
182 | * ratios. | ||
183 | */ | ||
184 | tmp = PWR_CTRL2_DIV2_UP_EN | \ | ||
185 | PWR_CTRL2_DIV1_UP_EN | \ | ||
186 | PWR_CTRL2_DUR_STANDBY2_VAL | \ | ||
187 | PWR_CTRL2_DUR_STANDBY1_VAL | \ | ||
188 | PWR_CTRL2_CORE2_UP_RATIO | \ | ||
189 | PWR_CTRL2_CORE1_UP_RATIO; | ||
190 | __raw_writel(tmp, EXYNOS5_PWR_CTRL2); | ||
191 | } | ||
192 | |||
160 | static int __init exynos4_init_cpuidle(void) | 193 | static int __init exynos4_init_cpuidle(void) |
161 | { | 194 | { |
162 | int i, max_cpuidle_state, cpu_id; | 195 | int i, max_cpuidle_state, cpu_id; |
163 | struct cpuidle_device *device; | 196 | struct cpuidle_device *device; |
164 | struct cpuidle_driver *drv = &exynos4_idle_driver; | 197 | struct cpuidle_driver *drv = &exynos4_idle_driver; |
165 | 198 | ||
199 | if (soc_is_exynos5250()) | ||
200 | exynos5_core_down_clk(); | ||
201 | |||
166 | /* Setup cpuidle driver */ | 202 | /* Setup cpuidle driver */ |
167 | drv->state_count = (sizeof(exynos4_cpuidle_set) / | 203 | drv->state_count = (sizeof(exynos4_cpuidle_set) / |
168 | sizeof(struct cpuidle_state)); | 204 | sizeof(struct cpuidle_state)); |
diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h index 8c9b38c9c504..d36ad76ad6a4 100644 --- a/arch/arm/mach-exynos/include/mach/regs-clock.h +++ b/arch/arm/mach-exynos/include/mach/regs-clock.h | |||
@@ -267,6 +267,9 @@ | |||
267 | #define EXYNOS5_CLKDIV_STATCPU0 EXYNOS_CLKREG(0x00600) | 267 | #define EXYNOS5_CLKDIV_STATCPU0 EXYNOS_CLKREG(0x00600) |
268 | #define EXYNOS5_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x00604) | 268 | #define EXYNOS5_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x00604) |
269 | 269 | ||
270 | #define EXYNOS5_PWR_CTRL1 EXYNOS_CLKREG(0x01020) | ||
271 | #define EXYNOS5_PWR_CTRL2 EXYNOS_CLKREG(0x01024) | ||
272 | |||
270 | #define EXYNOS5_MPLL_CON0 EXYNOS_CLKREG(0x04100) | 273 | #define EXYNOS5_MPLL_CON0 EXYNOS_CLKREG(0x04100) |
271 | #define EXYNOS5_CLKSRC_CORE1 EXYNOS_CLKREG(0x04204) | 274 | #define EXYNOS5_CLKSRC_CORE1 EXYNOS_CLKREG(0x04204) |
272 | 275 | ||
@@ -344,6 +347,22 @@ | |||
344 | 347 | ||
345 | #define EXYNOS5_EPLLCON0_LOCKED_SHIFT (29) | 348 | #define EXYNOS5_EPLLCON0_LOCKED_SHIFT (29) |
346 | 349 | ||
350 | #define PWR_CTRL1_CORE2_DOWN_RATIO (7 << 28) | ||
351 | #define PWR_CTRL1_CORE1_DOWN_RATIO (7 << 16) | ||
352 | #define PWR_CTRL1_DIV2_DOWN_EN (1 << 9) | ||
353 | #define PWR_CTRL1_DIV1_DOWN_EN (1 << 8) | ||
354 | #define PWR_CTRL1_USE_CORE1_WFE (1 << 5) | ||
355 | #define PWR_CTRL1_USE_CORE0_WFE (1 << 4) | ||
356 | #define PWR_CTRL1_USE_CORE1_WFI (1 << 1) | ||
357 | #define PWR_CTRL1_USE_CORE0_WFI (1 << 0) | ||
358 | |||
359 | #define PWR_CTRL2_DIV2_UP_EN (1 << 25) | ||
360 | #define PWR_CTRL2_DIV1_UP_EN (1 << 24) | ||
361 | #define PWR_CTRL2_DUR_STANDBY2_VAL (1 << 16) | ||
362 | #define PWR_CTRL2_DUR_STANDBY1_VAL (1 << 8) | ||
363 | #define PWR_CTRL2_CORE2_UP_RATIO (1 << 4) | ||
364 | #define PWR_CTRL2_CORE1_UP_RATIO (1 << 0) | ||
365 | |||
347 | /* Compatibility defines and inclusion */ | 366 | /* Compatibility defines and inclusion */ |
348 | 367 | ||
349 | #include <mach/regs-pmu.h> | 368 | #include <mach/regs-pmu.h> |
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h index 84428e72cf5e..3f30aa1ae354 100644 --- a/arch/arm/mach-exynos/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <mach/map.h> | 15 | #include <mach/map.h> |
16 | 16 | ||
17 | #define S5P_PMUREG(x) (S5P_VA_PMU + (x)) | 17 | #define S5P_PMUREG(x) (S5P_VA_PMU + (x)) |
18 | #define S5P_SYSREG(x) (S3C_VA_SYS + (x)) | ||
18 | 19 | ||
19 | #define S5P_CENTRAL_SEQ_CONFIGURATION S5P_PMUREG(0x0200) | 20 | #define S5P_CENTRAL_SEQ_CONFIGURATION S5P_PMUREG(0x0200) |
20 | 21 | ||
@@ -231,6 +232,8 @@ | |||
231 | 232 | ||
232 | /* For EXYNOS5 */ | 233 | /* For EXYNOS5 */ |
233 | 234 | ||
235 | #define EXYNOS5_SYS_I2C_CFG S5P_SYSREG(0x0234) | ||
236 | |||
234 | #define EXYNOS5_AUTO_WDTRESET_DISABLE S5P_PMUREG(0x0408) | 237 | #define EXYNOS5_AUTO_WDTRESET_DISABLE S5P_PMUREG(0x0408) |
235 | #define EXYNOS5_MASK_WDTRESET_REQUEST S5P_PMUREG(0x040C) | 238 | #define EXYNOS5_MASK_WDTRESET_REQUEST S5P_PMUREG(0x040C) |
236 | 239 | ||
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c index 929de766d490..f038c8cadca4 100644 --- a/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c | |||
@@ -13,11 +13,12 @@ | |||
13 | #include <linux/of_fdt.h> | 13 | #include <linux/of_fdt.h> |
14 | #include <linux/serial_core.h> | 14 | #include <linux/serial_core.h> |
15 | #include <linux/memblock.h> | 15 | #include <linux/memblock.h> |
16 | #include <linux/of_fdt.h> | 16 | #include <linux/io.h> |
17 | 17 | ||
18 | #include <asm/mach/arch.h> | 18 | #include <asm/mach/arch.h> |
19 | #include <asm/hardware/gic.h> | 19 | #include <asm/hardware/gic.h> |
20 | #include <mach/map.h> | 20 | #include <mach/map.h> |
21 | #include <mach/regs-pmu.h> | ||
21 | 22 | ||
22 | #include <plat/cpu.h> | 23 | #include <plat/cpu.h> |
23 | #include <plat/regs-serial.h> | 24 | #include <plat/regs-serial.h> |
@@ -124,6 +125,28 @@ static void __init exynos5_dt_map_io(void) | |||
124 | 125 | ||
125 | static void __init exynos5_dt_machine_init(void) | 126 | static void __init exynos5_dt_machine_init(void) |
126 | { | 127 | { |
128 | struct device_node *i2c_np; | ||
129 | const char *i2c_compat = "samsung,s3c2440-i2c"; | ||
130 | unsigned int tmp; | ||
131 | |||
132 | /* | ||
133 | * Exynos5's legacy i2c controller and new high speed i2c | ||
134 | * controller have muxed interrupt sources. By default the | ||
135 | * interrupts for 4-channel HS-I2C controller are enabled. | ||
136 | * If node for first four channels of legacy i2c controller | ||
137 | * are available then re-configure the interrupts via the | ||
138 | * system register. | ||
139 | */ | ||
140 | for_each_compatible_node(i2c_np, NULL, i2c_compat) { | ||
141 | if (of_device_is_available(i2c_np)) { | ||
142 | if (of_alias_get_id(i2c_np, "i2c") < 4) { | ||
143 | tmp = readl(EXYNOS5_SYS_I2C_CFG); | ||
144 | writel(tmp & ~(0x1 << of_alias_get_id(i2c_np, "i2c")), | ||
145 | EXYNOS5_SYS_I2C_CFG); | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | |||
127 | if (of_machine_is_compatible("samsung,exynos5250")) | 150 | if (of_machine_is_compatible("samsung,exynos5250")) |
128 | of_platform_populate(NULL, of_default_bus_match_table, | 151 | of_platform_populate(NULL, of_default_bus_match_table, |
129 | exynos5250_auxdata_lookup, NULL); | 152 | exynos5250_auxdata_lookup, NULL); |
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index 8df6ec547f78..b9b539cac81e 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c | |||
@@ -62,6 +62,10 @@ static struct sleep_save exynos4_vpll_save[] = { | |||
62 | SAVE_ITEM(EXYNOS4_VPLL_CON1), | 62 | SAVE_ITEM(EXYNOS4_VPLL_CON1), |
63 | }; | 63 | }; |
64 | 64 | ||
65 | static struct sleep_save exynos5_sys_save[] = { | ||
66 | SAVE_ITEM(EXYNOS5_SYS_I2C_CFG), | ||
67 | }; | ||
68 | |||
65 | static struct sleep_save exynos_core_save[] = { | 69 | static struct sleep_save exynos_core_save[] = { |
66 | /* SROM side */ | 70 | /* SROM side */ |
67 | SAVE_ITEM(S5P_SROM_BW), | 71 | SAVE_ITEM(S5P_SROM_BW), |
@@ -101,6 +105,7 @@ static void exynos_pm_prepare(void) | |||
101 | s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); | 105 | s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); |
102 | s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); | 106 | s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); |
103 | } else { | 107 | } else { |
108 | s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save)); | ||
104 | /* Disable USE_RETENTION of JPEG_MEM_OPTION */ | 109 | /* Disable USE_RETENTION of JPEG_MEM_OPTION */ |
105 | tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION); | 110 | tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION); |
106 | tmp &= ~EXYNOS5_OPTION_USE_RETENTION; | 111 | tmp &= ~EXYNOS5_OPTION_USE_RETENTION; |
@@ -304,6 +309,10 @@ static void exynos_pm_resume(void) | |||
304 | __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); | 309 | __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); |
305 | __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); | 310 | __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); |
306 | 311 | ||
312 | if (soc_is_exynos5250()) | ||
313 | s3c_pm_do_restore(exynos5_sys_save, | ||
314 | ARRAY_SIZE(exynos5_sys_save)); | ||
315 | |||
307 | s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | 316 | s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); |
308 | 317 | ||
309 | if (!soc_is_exynos5250()) { | 318 | if (!soc_is_exynos5250()) { |
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 4d57e342537b..3ca6757b129a 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c | |||
@@ -295,10 +295,10 @@ struct clk sh7372_pllc2_clk = { | |||
295 | }; | 295 | }; |
296 | 296 | ||
297 | /* External input clock (pin name: FSIACK/FSIBCK ) */ | 297 | /* External input clock (pin name: FSIACK/FSIBCK ) */ |
298 | struct clk sh7372_fsiack_clk = { | 298 | static struct clk fsiack_clk = { |
299 | }; | 299 | }; |
300 | 300 | ||
301 | struct clk sh7372_fsibck_clk = { | 301 | static struct clk fsibck_clk = { |
302 | }; | 302 | }; |
303 | 303 | ||
304 | static struct clk *main_clks[] = { | 304 | static struct clk *main_clks[] = { |
@@ -314,8 +314,8 @@ static struct clk *main_clks[] = { | |||
314 | &pllc1_clk, | 314 | &pllc1_clk, |
315 | &pllc1_div2_clk, | 315 | &pllc1_div2_clk, |
316 | &sh7372_pllc2_clk, | 316 | &sh7372_pllc2_clk, |
317 | &sh7372_fsiack_clk, | 317 | &fsiack_clk, |
318 | &sh7372_fsibck_clk, | 318 | &fsibck_clk, |
319 | }; | 319 | }; |
320 | 320 | ||
321 | static void div4_kick(struct clk *clk) | 321 | static void div4_kick(struct clk *clk) |
@@ -399,14 +399,14 @@ static struct clk *hdmi_parent[] = { | |||
399 | static struct clk *fsiackcr_parent[] = { | 399 | static struct clk *fsiackcr_parent[] = { |
400 | [0] = &pllc1_div2_clk, | 400 | [0] = &pllc1_div2_clk, |
401 | [1] = &sh7372_pllc2_clk, | 401 | [1] = &sh7372_pllc2_clk, |
402 | [2] = &sh7372_fsiack_clk, /* external input for FSI A */ | 402 | [2] = &fsiack_clk, /* external input for FSI A */ |
403 | [3] = NULL, /* setting prohibited */ | 403 | [3] = NULL, /* setting prohibited */ |
404 | }; | 404 | }; |
405 | 405 | ||
406 | static struct clk *fsibckcr_parent[] = { | 406 | static struct clk *fsibckcr_parent[] = { |
407 | [0] = &pllc1_div2_clk, | 407 | [0] = &pllc1_div2_clk, |
408 | [1] = &sh7372_pllc2_clk, | 408 | [1] = &sh7372_pllc2_clk, |
409 | [2] = &sh7372_fsibck_clk, /* external input for FSI B */ | 409 | [2] = &fsibck_clk, /* external input for FSI B */ |
410 | [3] = NULL, /* setting prohibited */ | 410 | [3] = NULL, /* setting prohibited */ |
411 | }; | 411 | }; |
412 | 412 | ||
@@ -507,8 +507,8 @@ static struct clk_lookup lookups[] = { | |||
507 | CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), | 507 | CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), |
508 | CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), | 508 | CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), |
509 | CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk), | 509 | CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk), |
510 | CLKDEV_CON_ID("fsidiva", &fsidivs[FSIDIV_A]), | 510 | CLKDEV_CON_ID("fsiack", &fsiack_clk), |
511 | CLKDEV_CON_ID("fsidivb", &fsidivs[FSIDIV_B]), | 511 | CLKDEV_CON_ID("fsibck", &fsibck_clk), |
512 | 512 | ||
513 | /* DIV4 clocks */ | 513 | /* DIV4 clocks */ |
514 | CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), | 514 | CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), |
@@ -606,8 +606,8 @@ static struct clk_lookup lookups[] = { | |||
606 | CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]), | 606 | CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]), |
607 | CLKDEV_ICK_ID("diva", "sh_fsi2", &fsidivs[FSIDIV_A]), | 607 | CLKDEV_ICK_ID("diva", "sh_fsi2", &fsidivs[FSIDIV_A]), |
608 | CLKDEV_ICK_ID("divb", "sh_fsi2", &fsidivs[FSIDIV_B]), | 608 | CLKDEV_ICK_ID("divb", "sh_fsi2", &fsidivs[FSIDIV_B]), |
609 | CLKDEV_ICK_ID("xcka", "sh_fsi2", &sh7372_fsiack_clk), | 609 | CLKDEV_ICK_ID("xcka", "sh_fsi2", &fsiack_clk), |
610 | CLKDEV_ICK_ID("xckb", "sh_fsi2", &sh7372_fsibck_clk), | 610 | CLKDEV_ICK_ID("xckb", "sh_fsi2", &fsibck_clk), |
611 | }; | 611 | }; |
612 | 612 | ||
613 | void __init sh7372_clock_init(void) | 613 | void __init sh7372_clock_init(void) |
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index 26cd1016fad8..b582facc1cf6 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h | |||
@@ -477,8 +477,6 @@ extern struct clk sh7372_extal2_clk; | |||
477 | extern struct clk sh7372_dv_clki_clk; | 477 | extern struct clk sh7372_dv_clki_clk; |
478 | extern struct clk sh7372_dv_clki_div2_clk; | 478 | extern struct clk sh7372_dv_clki_div2_clk; |
479 | extern struct clk sh7372_pllc2_clk; | 479 | extern struct clk sh7372_pllc2_clk; |
480 | extern struct clk sh7372_fsiack_clk; | ||
481 | extern struct clk sh7372_fsibck_clk; | ||
482 | 480 | ||
483 | extern void sh7372_intcs_suspend(void); | 481 | extern void sh7372_intcs_suspend(void); |
484 | extern void sh7372_intcs_resume(void); | 482 | extern void sh7372_intcs_resume(void); |
diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index 535426c306bd..f67456286280 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c | |||
@@ -32,8 +32,24 @@ | |||
32 | 32 | ||
33 | #define EMEV2_SCU_BASE 0x1e000000 | 33 | #define EMEV2_SCU_BASE 0x1e000000 |
34 | 34 | ||
35 | static DEFINE_SPINLOCK(scu_lock); | ||
35 | static void __iomem *scu_base; | 36 | static void __iomem *scu_base; |
36 | 37 | ||
38 | static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) | ||
39 | { | ||
40 | unsigned long tmp; | ||
41 | |||
42 | /* we assume this code is running on a different cpu | ||
43 | * than the one that is changing coherency setting */ | ||
44 | spin_lock(&scu_lock); | ||
45 | tmp = readl(scu_base + 8); | ||
46 | tmp &= ~clr; | ||
47 | tmp |= set; | ||
48 | writel(tmp, scu_base + 8); | ||
49 | spin_unlock(&scu_lock); | ||
50 | |||
51 | } | ||
52 | |||
37 | static unsigned int __init emev2_get_core_count(void) | 53 | static unsigned int __init emev2_get_core_count(void) |
38 | { | 54 | { |
39 | if (!scu_base) { | 55 | if (!scu_base) { |
@@ -79,7 +95,7 @@ static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct * | |||
79 | cpu = cpu_logical_map(cpu); | 95 | cpu = cpu_logical_map(cpu); |
80 | 96 | ||
81 | /* enable cache coherency */ | 97 | /* enable cache coherency */ |
82 | scu_power_mode(scu_base, 0); | 98 | modify_scu_cpu_psr(0, 3 << (cpu * 8)); |
83 | 99 | ||
84 | /* Tell ROM loader about our vector (in headsmp.S) */ | 100 | /* Tell ROM loader about our vector (in headsmp.S) */ |
85 | emev2_set_boot_vector(__pa(shmobile_secondary_vector)); | 101 | emev2_set_boot_vector(__pa(shmobile_secondary_vector)); |
@@ -90,10 +106,12 @@ static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct * | |||
90 | 106 | ||
91 | static void __init emev2_smp_prepare_cpus(unsigned int max_cpus) | 107 | static void __init emev2_smp_prepare_cpus(unsigned int max_cpus) |
92 | { | 108 | { |
109 | int cpu = cpu_logical_map(0); | ||
110 | |||
93 | scu_enable(scu_base); | 111 | scu_enable(scu_base); |
94 | 112 | ||
95 | /* enable cache coherency on CPU0 */ | 113 | /* enable cache coherency on CPU0 */ |
96 | scu_power_mode(scu_base, 0); | 114 | modify_scu_cpu_psr(0, 3 << (cpu * 8)); |
97 | } | 115 | } |
98 | 116 | ||
99 | static void __init emev2_smp_init_cpus(void) | 117 | static void __init emev2_smp_init_cpus(void) |
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index 9def0f22bf22..2ce6af9a6a37 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c | |||
@@ -61,6 +61,9 @@ static void __iomem *scu_base_addr(void) | |||
61 | return (void __iomem *)0xf0000000; | 61 | return (void __iomem *)0xf0000000; |
62 | } | 62 | } |
63 | 63 | ||
64 | static DEFINE_SPINLOCK(scu_lock); | ||
65 | static unsigned long tmp; | ||
66 | |||
64 | #ifdef CONFIG_HAVE_ARM_TWD | 67 | #ifdef CONFIG_HAVE_ARM_TWD |
65 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); | 68 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); |
66 | 69 | ||
@@ -70,6 +73,20 @@ void __init r8a7779_register_twd(void) | |||
70 | } | 73 | } |
71 | #endif | 74 | #endif |
72 | 75 | ||
76 | static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) | ||
77 | { | ||
78 | void __iomem *scu_base = scu_base_addr(); | ||
79 | |||
80 | spin_lock(&scu_lock); | ||
81 | tmp = __raw_readl(scu_base + 8); | ||
82 | tmp &= ~clr; | ||
83 | tmp |= set; | ||
84 | spin_unlock(&scu_lock); | ||
85 | |||
86 | /* disable cache coherency after releasing the lock */ | ||
87 | __raw_writel(tmp, scu_base + 8); | ||
88 | } | ||
89 | |||
73 | static unsigned int __init r8a7779_get_core_count(void) | 90 | static unsigned int __init r8a7779_get_core_count(void) |
74 | { | 91 | { |
75 | void __iomem *scu_base = scu_base_addr(); | 92 | void __iomem *scu_base = scu_base_addr(); |
@@ -85,7 +102,7 @@ static int r8a7779_platform_cpu_kill(unsigned int cpu) | |||
85 | cpu = cpu_logical_map(cpu); | 102 | cpu = cpu_logical_map(cpu); |
86 | 103 | ||
87 | /* disable cache coherency */ | 104 | /* disable cache coherency */ |
88 | scu_power_mode(scu_base_addr(), 3); | 105 | modify_scu_cpu_psr(3 << (cpu * 8), 0); |
89 | 106 | ||
90 | if (cpu < ARRAY_SIZE(r8a7779_ch_cpu)) | 107 | if (cpu < ARRAY_SIZE(r8a7779_ch_cpu)) |
91 | ch = r8a7779_ch_cpu[cpu]; | 108 | ch = r8a7779_ch_cpu[cpu]; |
@@ -128,7 +145,7 @@ static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct | |||
128 | cpu = cpu_logical_map(cpu); | 145 | cpu = cpu_logical_map(cpu); |
129 | 146 | ||
130 | /* enable cache coherency */ | 147 | /* enable cache coherency */ |
131 | scu_power_mode(scu_base_addr(), 0); | 148 | modify_scu_cpu_psr(0, 3 << (cpu * 8)); |
132 | 149 | ||
133 | if (cpu < ARRAY_SIZE(r8a7779_ch_cpu)) | 150 | if (cpu < ARRAY_SIZE(r8a7779_ch_cpu)) |
134 | ch = r8a7779_ch_cpu[cpu]; | 151 | ch = r8a7779_ch_cpu[cpu]; |
@@ -141,13 +158,15 @@ static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct | |||
141 | 158 | ||
142 | static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) | 159 | static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) |
143 | { | 160 | { |
161 | int cpu = cpu_logical_map(0); | ||
162 | |||
144 | scu_enable(scu_base_addr()); | 163 | scu_enable(scu_base_addr()); |
145 | 164 | ||
146 | /* Map the reset vector (in headsmp.S) */ | 165 | /* Map the reset vector (in headsmp.S) */ |
147 | __raw_writel(__pa(shmobile_secondary_vector), AVECR); | 166 | __raw_writel(__pa(shmobile_secondary_vector), AVECR); |
148 | 167 | ||
149 | /* enable cache coherency on CPU0 */ | 168 | /* enable cache coherency on CPU0 */ |
150 | scu_power_mode(scu_base_addr(), 0); | 169 | modify_scu_cpu_psr(0, 3 << (cpu * 8)); |
151 | 170 | ||
152 | r8a7779_pm_init(); | 171 | r8a7779_pm_init(); |
153 | 172 | ||
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index 96ddb97babbe..624f00f70abf 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c | |||
@@ -41,6 +41,9 @@ static void __iomem *scu_base_addr(void) | |||
41 | return (void __iomem *)0xf0000000; | 41 | return (void __iomem *)0xf0000000; |
42 | } | 42 | } |
43 | 43 | ||
44 | static DEFINE_SPINLOCK(scu_lock); | ||
45 | static unsigned long tmp; | ||
46 | |||
44 | #ifdef CONFIG_HAVE_ARM_TWD | 47 | #ifdef CONFIG_HAVE_ARM_TWD |
45 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); | 48 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); |
46 | void __init sh73a0_register_twd(void) | 49 | void __init sh73a0_register_twd(void) |
@@ -49,6 +52,20 @@ void __init sh73a0_register_twd(void) | |||
49 | } | 52 | } |
50 | #endif | 53 | #endif |
51 | 54 | ||
55 | static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) | ||
56 | { | ||
57 | void __iomem *scu_base = scu_base_addr(); | ||
58 | |||
59 | spin_lock(&scu_lock); | ||
60 | tmp = __raw_readl(scu_base + 8); | ||
61 | tmp &= ~clr; | ||
62 | tmp |= set; | ||
63 | spin_unlock(&scu_lock); | ||
64 | |||
65 | /* disable cache coherency after releasing the lock */ | ||
66 | __raw_writel(tmp, scu_base + 8); | ||
67 | } | ||
68 | |||
52 | static unsigned int __init sh73a0_get_core_count(void) | 69 | static unsigned int __init sh73a0_get_core_count(void) |
53 | { | 70 | { |
54 | void __iomem *scu_base = scu_base_addr(); | 71 | void __iomem *scu_base = scu_base_addr(); |
@@ -66,7 +83,7 @@ static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct | |||
66 | cpu = cpu_logical_map(cpu); | 83 | cpu = cpu_logical_map(cpu); |
67 | 84 | ||
68 | /* enable cache coherency */ | 85 | /* enable cache coherency */ |
69 | scu_power_mode(scu_base_addr(), 0); | 86 | modify_scu_cpu_psr(0, 3 << (cpu * 8)); |
70 | 87 | ||
71 | if (((__raw_readl(PSTR) >> (4 * cpu)) & 3) == 3) | 88 | if (((__raw_readl(PSTR) >> (4 * cpu)) & 3) == 3) |
72 | __raw_writel(1 << cpu, WUPCR); /* wake up */ | 89 | __raw_writel(1 << cpu, WUPCR); /* wake up */ |
@@ -78,6 +95,8 @@ static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct | |||
78 | 95 | ||
79 | static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) | 96 | static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) |
80 | { | 97 | { |
98 | int cpu = cpu_logical_map(0); | ||
99 | |||
81 | scu_enable(scu_base_addr()); | 100 | scu_enable(scu_base_addr()); |
82 | 101 | ||
83 | /* Map the reset vector (in headsmp.S) */ | 102 | /* Map the reset vector (in headsmp.S) */ |
@@ -85,7 +104,7 @@ static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) | |||
85 | __raw_writel(__pa(shmobile_secondary_vector), SBAR); | 104 | __raw_writel(__pa(shmobile_secondary_vector), SBAR); |
86 | 105 | ||
87 | /* enable cache coherency on CPU0 */ | 106 | /* enable cache coherency on CPU0 */ |
88 | scu_power_mode(scu_base_addr(), 0); | 107 | modify_scu_cpu_psr(0, 3 << (cpu * 8)); |
89 | } | 108 | } |
90 | 109 | ||
91 | static void __init sh73a0_smp_init_cpus(void) | 110 | static void __init sh73a0_smp_init_cpus(void) |
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig index 803a3281feb5..566e804d4036 100644 --- a/arch/arm/mach-socfpga/Kconfig +++ b/arch/arm/mach-socfpga/Kconfig | |||
@@ -12,5 +12,6 @@ config ARCH_SOCFPGA | |||
12 | select GENERIC_CLOCKEVENTS | 12 | select GENERIC_CLOCKEVENTS |
13 | select GPIO_PL061 if GPIOLIB | 13 | select GPIO_PL061 if GPIOLIB |
14 | select HAVE_ARM_SCU | 14 | select HAVE_ARM_SCU |
15 | select HAVE_SMP | ||
15 | select SPARSE_IRQ | 16 | select SPARSE_IRQ |
16 | select USE_OF | 17 | select USE_OF |
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile index 4fb93240971d..6dd7a93a90fe 100644 --- a/arch/arm/mach-socfpga/Makefile +++ b/arch/arm/mach-socfpga/Makefile | |||
@@ -3,3 +3,4 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := socfpga.o | 5 | obj-y := socfpga.o |
6 | obj-$(CONFIG_SMP) += headsmp.o platsmp.o | ||
diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h new file mode 100644 index 000000000000..9941caa94931 --- /dev/null +++ b/arch/arm/mach-socfpga/core.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Pavel Machek <pavel@denx.de> | ||
3 | * Copyright (C) 2012 Altera Corporation | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #ifndef __MACH_CORE_H | ||
21 | #define __MACH_CORE_H | ||
22 | |||
23 | extern void secondary_startup(void); | ||
24 | extern void __iomem *socfpga_scu_base_addr; | ||
25 | |||
26 | extern void socfpga_init_clocks(void); | ||
27 | extern void socfpga_sysmgr_init(void); | ||
28 | |||
29 | extern struct smp_operations socfpga_smp_ops; | ||
30 | extern char secondary_trampoline, secondary_trampoline_end; | ||
31 | |||
32 | #define SOCFPGA_SCU_VIRT_BASE 0xfffec000 | ||
33 | |||
34 | #endif | ||
diff --git a/arch/arm/mach-socfpga/headsmp.S b/arch/arm/mach-socfpga/headsmp.S new file mode 100644 index 000000000000..f09b1283ffca --- /dev/null +++ b/arch/arm/mach-socfpga/headsmp.S | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2003 ARM Limited | ||
3 | * Copyright (c) u-boot contributors | ||
4 | * Copyright (c) 2012 Pavel Machek <pavel@denx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/linkage.h> | ||
11 | #include <linux/init.h> | ||
12 | |||
13 | __CPUINIT | ||
14 | .arch armv7-a | ||
15 | |||
16 | #define CPU1_START_ADDR 0xffd08010 | ||
17 | |||
18 | ENTRY(secondary_trampoline) | ||
19 | movw r0, #:lower16:CPU1_START_ADDR | ||
20 | movt r0, #:upper16:CPU1_START_ADDR | ||
21 | |||
22 | ldr r1, [r0] | ||
23 | bx r1 | ||
24 | |||
25 | ENTRY(secondary_trampoline_end) | ||
diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c new file mode 100644 index 000000000000..68dd1b69512a --- /dev/null +++ b/arch/arm/mach-socfpga/platsmp.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /* | ||
2 | * Copyright 2010-2011 Calxeda, Inc. | ||
3 | * Copyright 2012 Pavel Machek <pavel@denx.de> | ||
4 | * Based on platsmp.c, Copyright (C) 2002 ARM Ltd. | ||
5 | * Copyright (C) 2012 Altera Corporation | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms and conditions of the GNU General Public License, | ||
9 | * version 2, as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/smp.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/of_address.h> | ||
25 | |||
26 | #include <asm/cacheflush.h> | ||
27 | #include <asm/hardware/gic.h> | ||
28 | #include <asm/smp_scu.h> | ||
29 | #include <asm/smp_plat.h> | ||
30 | |||
31 | #include "core.h" | ||
32 | |||
33 | extern void __iomem *sys_manager_base_addr; | ||
34 | extern void __iomem *rst_manager_base_addr; | ||
35 | |||
36 | static void __cpuinit socfpga_secondary_init(unsigned int cpu) | ||
37 | { | ||
38 | /* | ||
39 | * if any interrupts are already enabled for the primary | ||
40 | * core (e.g. timer irq), then they will not have been enabled | ||
41 | * for us: do so | ||
42 | */ | ||
43 | gic_secondary_init(0); | ||
44 | } | ||
45 | |||
46 | static int __cpuinit socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle) | ||
47 | { | ||
48 | int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; | ||
49 | |||
50 | memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); | ||
51 | |||
52 | __raw_writel(virt_to_phys(secondary_startup), (sys_manager_base_addr+0x10)); | ||
53 | |||
54 | flush_cache_all(); | ||
55 | smp_wmb(); | ||
56 | outer_clean_range(0, trampoline_size); | ||
57 | |||
58 | /* This will release CPU #1 out of reset.*/ | ||
59 | __raw_writel(0, rst_manager_base_addr + 0x10); | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | /* | ||
65 | * Initialise the CPU possible map early - this describes the CPUs | ||
66 | * which may be present or become present in the system. | ||
67 | */ | ||
68 | static void __init socfpga_smp_init_cpus(void) | ||
69 | { | ||
70 | unsigned int i, ncores; | ||
71 | |||
72 | ncores = scu_get_core_count(socfpga_scu_base_addr); | ||
73 | |||
74 | for (i = 0; i < ncores; i++) | ||
75 | set_cpu_possible(i, true); | ||
76 | |||
77 | /* sanity check */ | ||
78 | if (ncores > num_possible_cpus()) { | ||
79 | pr_warn("socfpga: no. of cores (%d) greater than configured" | ||
80 | "maximum of %d - clipping\n", ncores, num_possible_cpus()); | ||
81 | ncores = num_possible_cpus(); | ||
82 | } | ||
83 | |||
84 | for (i = 0; i < ncores; i++) | ||
85 | set_cpu_possible(i, true); | ||
86 | |||
87 | set_smp_cross_call(gic_raise_softirq); | ||
88 | } | ||
89 | |||
90 | static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus) | ||
91 | { | ||
92 | scu_enable(socfpga_scu_base_addr); | ||
93 | } | ||
94 | |||
95 | /* | ||
96 | * platform-specific code to shutdown a CPU | ||
97 | * | ||
98 | * Called with IRQs disabled | ||
99 | */ | ||
100 | static void socfpga_cpu_die(unsigned int cpu) | ||
101 | { | ||
102 | cpu_do_idle(); | ||
103 | |||
104 | /* We should have never returned from idle */ | ||
105 | panic("cpu %d unexpectedly exit from shutdown\n", cpu); | ||
106 | } | ||
107 | |||
108 | struct smp_operations socfpga_smp_ops __initdata = { | ||
109 | .smp_init_cpus = socfpga_smp_init_cpus, | ||
110 | .smp_prepare_cpus = socfpga_smp_prepare_cpus, | ||
111 | .smp_secondary_init = socfpga_secondary_init, | ||
112 | .smp_boot_secondary = socfpga_boot_secondary, | ||
113 | #ifdef CONFIG_HOTPLUG_CPU | ||
114 | .cpu_die = socfpga_cpu_die, | ||
115 | #endif | ||
116 | }; | ||
diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c index f01e1ebf5396..6732924a5fee 100644 --- a/arch/arm/mach-socfpga/socfpga.c +++ b/arch/arm/mach-socfpga/socfpga.c | |||
@@ -15,23 +15,73 @@ | |||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | */ | 16 | */ |
17 | #include <linux/dw_apb_timer.h> | 17 | #include <linux/dw_apb_timer.h> |
18 | #include <linux/of_address.h> | ||
18 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
19 | #include <linux/of_platform.h> | 20 | #include <linux/of_platform.h> |
20 | 21 | ||
21 | #include <asm/hardware/cache-l2x0.h> | 22 | #include <asm/hardware/cache-l2x0.h> |
22 | #include <asm/hardware/gic.h> | 23 | #include <asm/hardware/gic.h> |
23 | #include <asm/mach/arch.h> | 24 | #include <asm/mach/arch.h> |
25 | #include <asm/mach/map.h> | ||
24 | 26 | ||
25 | extern void socfpga_init_clocks(void); | 27 | #include "core.h" |
28 | |||
29 | void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE)); | ||
30 | void __iomem *sys_manager_base_addr; | ||
31 | void __iomem *rst_manager_base_addr; | ||
32 | |||
33 | static struct map_desc scu_io_desc __initdata = { | ||
34 | .virtual = SOCFPGA_SCU_VIRT_BASE, | ||
35 | .pfn = 0, /* run-time */ | ||
36 | .length = SZ_8K, | ||
37 | .type = MT_DEVICE, | ||
38 | }; | ||
39 | |||
40 | static struct map_desc uart_io_desc __initdata = { | ||
41 | .virtual = 0xfec02000, | ||
42 | .pfn = __phys_to_pfn(0xffc02000), | ||
43 | .length = SZ_8K, | ||
44 | .type = MT_DEVICE, | ||
45 | }; | ||
46 | |||
47 | static void __init socfpga_scu_map_io(void) | ||
48 | { | ||
49 | unsigned long base; | ||
50 | |||
51 | /* Get SCU base */ | ||
52 | asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base)); | ||
53 | |||
54 | scu_io_desc.pfn = __phys_to_pfn(base); | ||
55 | iotable_init(&scu_io_desc, 1); | ||
56 | } | ||
57 | |||
58 | static void __init socfpga_map_io(void) | ||
59 | { | ||
60 | socfpga_scu_map_io(); | ||
61 | iotable_init(&uart_io_desc, 1); | ||
62 | early_printk("Early printk initialized\n"); | ||
63 | } | ||
26 | 64 | ||
27 | const static struct of_device_id irq_match[] = { | 65 | const static struct of_device_id irq_match[] = { |
28 | { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, | 66 | { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, |
29 | {} | 67 | {} |
30 | }; | 68 | }; |
31 | 69 | ||
70 | void __init socfpga_sysmgr_init(void) | ||
71 | { | ||
72 | struct device_node *np; | ||
73 | |||
74 | np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr"); | ||
75 | sys_manager_base_addr = of_iomap(np, 0); | ||
76 | |||
77 | np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr"); | ||
78 | rst_manager_base_addr = of_iomap(np, 0); | ||
79 | } | ||
80 | |||
32 | static void __init gic_init_irq(void) | 81 | static void __init gic_init_irq(void) |
33 | { | 82 | { |
34 | of_irq_init(irq_match); | 83 | of_irq_init(irq_match); |
84 | socfpga_sysmgr_init(); | ||
35 | } | 85 | } |
36 | 86 | ||
37 | static void socfpga_cyclone5_restart(char mode, const char *cmd) | 87 | static void socfpga_cyclone5_restart(char mode, const char *cmd) |
@@ -53,6 +103,8 @@ static const char *altera_dt_match[] = { | |||
53 | }; | 103 | }; |
54 | 104 | ||
55 | DT_MACHINE_START(SOCFPGA, "Altera SOCFPGA") | 105 | DT_MACHINE_START(SOCFPGA, "Altera SOCFPGA") |
106 | .smp = smp_ops(socfpga_smp_ops), | ||
107 | .map_io = socfpga_map_io, | ||
56 | .init_irq = gic_init_irq, | 108 | .init_irq = gic_init_irq, |
57 | .handle_irq = gic_handle_irq, | 109 | .handle_irq = gic_handle_irq, |
58 | .timer = &dw_apb_timer, | 110 | .timer = &dw_apb_timer, |
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c index 012bbd0b8d81..47c9fad43f00 100644 --- a/arch/arm/plat-samsung/clock.c +++ b/arch/arm/plat-samsung/clock.c | |||
@@ -389,6 +389,72 @@ int __init s3c24xx_register_baseclocks(unsigned long xtal) | |||
389 | 389 | ||
390 | static struct dentry *clk_debugfs_root; | 390 | static struct dentry *clk_debugfs_root; |
391 | 391 | ||
392 | static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level) | ||
393 | { | ||
394 | struct clk *child; | ||
395 | const char *state; | ||
396 | char buf[255] = { 0 }; | ||
397 | int n = 0; | ||
398 | |||
399 | if (c->name) | ||
400 | n = snprintf(buf, sizeof(buf) - 1, "%s", c->name); | ||
401 | |||
402 | if (c->devname) | ||
403 | n += snprintf(buf + n, sizeof(buf) - 1 - n, ":%s", c->devname); | ||
404 | |||
405 | state = (c->usage > 0) ? "on" : "off"; | ||
406 | |||
407 | seq_printf(s, "%*s%-*s %-6s %-3d %-10lu\n", | ||
408 | level * 3 + 1, "", | ||
409 | 50 - level * 3, buf, | ||
410 | state, c->usage, clk_get_rate(c)); | ||
411 | |||
412 | list_for_each_entry(child, &clocks, list) { | ||
413 | if (child->parent != c) | ||
414 | continue; | ||
415 | |||
416 | clock_tree_show_one(s, child, level + 1); | ||
417 | } | ||
418 | } | ||
419 | |||
420 | static int clock_tree_show(struct seq_file *s, void *data) | ||
421 | { | ||
422 | struct clk *c; | ||
423 | unsigned long flags; | ||
424 | |||
425 | seq_printf(s, " clock state ref rate\n"); | ||
426 | seq_printf(s, "----------------------------------------------------\n"); | ||
427 | |||
428 | spin_lock_irqsave(&clocks_lock, flags); | ||
429 | |||
430 | list_for_each_entry(c, &clocks, list) | ||
431 | if (c->parent == NULL) | ||
432 | clock_tree_show_one(s, c, 0); | ||
433 | |||
434 | spin_unlock_irqrestore(&clocks_lock, flags); | ||
435 | return 0; | ||
436 | } | ||
437 | |||
438 | static int clock_tree_open(struct inode *inode, struct file *file) | ||
439 | { | ||
440 | return single_open(file, clock_tree_show, inode->i_private); | ||
441 | } | ||
442 | |||
443 | static const struct file_operations clock_tree_fops = { | ||
444 | .open = clock_tree_open, | ||
445 | .read = seq_read, | ||
446 | .llseek = seq_lseek, | ||
447 | .release = single_release, | ||
448 | }; | ||
449 | |||
450 | static int clock_rate_show(void *data, u64 *val) | ||
451 | { | ||
452 | struct clk *c = data; | ||
453 | *val = clk_get_rate(c); | ||
454 | return 0; | ||
455 | } | ||
456 | DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_rate_show, NULL, "%llu\n"); | ||
457 | |||
392 | static int clk_debugfs_register_one(struct clk *c) | 458 | static int clk_debugfs_register_one(struct clk *c) |
393 | { | 459 | { |
394 | int err; | 460 | int err; |
@@ -411,7 +477,7 @@ static int clk_debugfs_register_one(struct clk *c) | |||
411 | goto err_out; | 477 | goto err_out; |
412 | } | 478 | } |
413 | 479 | ||
414 | d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate); | 480 | d = debugfs_create_file("rate", S_IRUGO, c->dent, c, &clock_rate_fops); |
415 | if (!d) { | 481 | if (!d) { |
416 | err = -ENOMEM; | 482 | err = -ENOMEM; |
417 | goto err_out; | 483 | goto err_out; |
@@ -446,13 +512,18 @@ static int __init clk_debugfs_init(void) | |||
446 | { | 512 | { |
447 | struct clk *c; | 513 | struct clk *c; |
448 | struct dentry *d; | 514 | struct dentry *d; |
449 | int err; | 515 | int err = -ENOMEM; |
450 | 516 | ||
451 | d = debugfs_create_dir("clock", NULL); | 517 | d = debugfs_create_dir("clock", NULL); |
452 | if (!d) | 518 | if (!d) |
453 | return -ENOMEM; | 519 | return -ENOMEM; |
454 | clk_debugfs_root = d; | 520 | clk_debugfs_root = d; |
455 | 521 | ||
522 | d = debugfs_create_file("clock_tree", S_IRUGO, clk_debugfs_root, NULL, | ||
523 | &clock_tree_fops); | ||
524 | if (!d) | ||
525 | goto err_out; | ||
526 | |||
456 | list_for_each_entry(c, &clocks, list) { | 527 | list_for_each_entry(c, &clocks, list) { |
457 | err = clk_debugfs_register(c); | 528 | err = clk_debugfs_register(c); |
458 | if (err) | 529 | if (err) |
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index b3dc44146ca0..5aedcdf4ac5c 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c | |||
@@ -401,7 +401,6 @@ static int fsidiv_enable(struct clk *clk) | |||
401 | 401 | ||
402 | static int fsidiv_set_rate(struct clk *clk, unsigned long rate) | 402 | static int fsidiv_set_rate(struct clk *clk, unsigned long rate) |
403 | { | 403 | { |
404 | u32 val; | ||
405 | int idx; | 404 | int idx; |
406 | 405 | ||
407 | idx = (clk->parent->rate / rate) & 0xffff; | 406 | idx = (clk->parent->rate / rate) & 0xffff; |