diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/boot/dts/sh73a0-kzm9g-reference.dts | 4 | ||||
-rw-r--r-- | arch/arm/boot/dts/sh73a0.dtsi | 358 | ||||
-rw-r--r-- | arch/arm/mach-exynos/common.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-exynos/exynos.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-exynos/platsmp.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-exynos/pm.c | 133 | ||||
-rw-r--r-- | arch/arm/mach-exynos/suspend.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/setup-sh73a0.c | 5 |
8 files changed, 508 insertions, 6 deletions
diff --git a/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts index 863dc4c7d7f6..6d32c87632d4 100644 --- a/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts +++ b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts @@ -182,6 +182,10 @@ status = "okay"; }; +&extal2_clk { + clock-frequency = <48000000>; +}; + &i2c0 { status = "okay"; as3711@40 { diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi index 37c8a761aeab..2dfd5b44255d 100644 --- a/arch/arm/boot/dts/sh73a0.dtsi +++ b/arch/arm/boot/dts/sh73a0.dtsi @@ -10,6 +10,7 @@ /include/ "skeleton.dtsi" +#include <dt-bindings/clock/sh73a0-clock.h> #include <dt-bindings/interrupt-controller/irq.h> / { @@ -71,6 +72,8 @@ renesas,channels-mask = <0x3f>; + clocks = <&mstp3_clks SH73A0_CLK_CMT1>; + clock-names = "fck"; status = "disabled"; }; @@ -160,6 +163,7 @@ 0 168 IRQ_TYPE_LEVEL_HIGH 0 169 IRQ_TYPE_LEVEL_HIGH 0 170 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp1_clks SH73A0_CLK_IIC0>; status = "disabled"; }; @@ -172,6 +176,7 @@ 0 52 IRQ_TYPE_LEVEL_HIGH 0 53 IRQ_TYPE_LEVEL_HIGH 0 54 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks SH73A0_CLK_IIC1>; status = "disabled"; }; @@ -184,6 +189,7 @@ 0 172 IRQ_TYPE_LEVEL_HIGH 0 173 IRQ_TYPE_LEVEL_HIGH 0 174 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp0_clks SH73A0_CLK_IIC2>; status = "disabled"; }; @@ -196,6 +202,7 @@ 0 184 IRQ_TYPE_LEVEL_HIGH 0 185 IRQ_TYPE_LEVEL_HIGH 0 186 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp4_clks SH73A0_CLK_IIC3>; status = "disabled"; }; @@ -208,6 +215,7 @@ 0 188 IRQ_TYPE_LEVEL_HIGH 0 189 IRQ_TYPE_LEVEL_HIGH 0 190 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp4_clks SH73A0_CLK_IIC4>; status = "disabled"; }; @@ -216,6 +224,7 @@ reg = <0xe6bd0000 0x100>; interrupts = <0 140 IRQ_TYPE_LEVEL_HIGH 0 141 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks SH73A0_CLK_MMCIF0>; reg-io-width = <4>; status = "disabled"; }; @@ -226,6 +235,7 @@ interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH 0 84 IRQ_TYPE_LEVEL_HIGH 0 85 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks SH73A0_CLK_SDHI0>; cap-sd-highspeed; status = "disabled"; }; @@ -236,6 +246,7 @@ reg = <0xee120000 0x100>; interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH 0 89 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks SH73A0_CLK_SDHI1>; toshiba,mmc-wrprotect-disable; cap-sd-highspeed; status = "disabled"; @@ -246,6 +257,7 @@ reg = <0xee140000 0x100>; interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH 0 105 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks SH73A0_CLK_SDHI2>; toshiba,mmc-wrprotect-disable; cap-sd-highspeed; status = "disabled"; @@ -255,6 +267,8 @@ compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c40000 0x100>; interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp2_clks SH73A0_CLK_SCIFA0>; + clock-names = "sci_ick"; status = "disabled"; }; @@ -262,6 +276,8 @@ compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c50000 0x100>; interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp2_clks SH73A0_CLK_SCIFA1>; + clock-names = "sci_ick"; status = "disabled"; }; @@ -269,6 +285,8 @@ compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c60000 0x100>; interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp2_clks SH73A0_CLK_SCIFA2>; + clock-names = "sci_ick"; status = "disabled"; }; @@ -276,6 +294,8 @@ compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c70000 0x100>; interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp2_clks SH73A0_CLK_SCIFA3>; + clock-names = "sci_ick"; status = "disabled"; }; @@ -283,6 +303,8 @@ compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c80000 0x100>; interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp2_clks SH73A0_CLK_SCIFA4>; + clock-names = "sci_ick"; status = "disabled"; }; @@ -290,6 +312,8 @@ compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6cb0000 0x100>; interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp2_clks SH73A0_CLK_SCIFA5>; + clock-names = "sci_ick"; status = "disabled"; }; @@ -297,6 +321,8 @@ compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6cc0000 0x100>; interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks SH73A0_CLK_SCIFA6>; + clock-names = "sci_ick"; status = "disabled"; }; @@ -304,6 +330,8 @@ compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6cd0000 0x100>; interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp2_clks SH73A0_CLK_SCIFA7>; + clock-names = "sci_ick"; status = "disabled"; }; @@ -311,6 +339,8 @@ compatible = "renesas,scifb-sh73a0", "renesas,scifb"; reg = <0xe6c30000 0x100>; interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp2_clks SH73A0_CLK_SCIFB>; + clock-names = "sci_ick"; status = "disabled"; }; @@ -338,4 +368,332 @@ interrupts = <0 146 0x4>; status = "disabled"; }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* External root clocks */ + extalr_clk: extalr_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "extalr"; + }; + extal1_clk: extal1_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + clock-output-names = "extal1"; + }; + extal2_clk: extal2_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "extal2"; + }; + extcki_clk: extcki_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "extcki"; + }; + fsiack_clk: fsiack_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + clock-output-names = "fsiack"; + }; + fsibck_clk: fsibck_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + clock-output-names = "fsibck"; + }; + + /* Special CPG clocks */ + cpg_clocks: cpg_clocks@e6150000 { + compatible = "renesas,sh73a0-cpg-clocks"; + reg = <0xe6150000 0x10000>; + clocks = <&extal1_clk>, <&extal2_clk>; + #clock-cells = <1>; + clock-output-names = "main", "pll0", "pll1", "pll2", + "pll3", "dsi0phy", "dsi1phy", + "zg", "m3", "b", "m1", "m2", + "z", "zx", "hp"; + }; + + /* Variable factor clocks (DIV6) */ + vclk1_clk: vclk1_clk@e6150008 { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe6150008 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "vclk1"; + }; + vclk2_clk: vclk2_clk@e615000c { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe615000c 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "vclk2"; + }; + vclk3_clk: vclk3_clk@e615001c { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe615001c 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "vclk3"; + }; + zb_clk: zb_clk@e6150010 { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe6150010 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "zb"; + }; + flctl_clk: flctl_clk@e6150014 { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe6150014 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "flctlck"; + }; + sdhi0_clk: sdhi0_clk@e6150074 { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe6150074 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "sdhi0ck"; + }; + sdhi1_clk: sdhi1_clk@e6150078 { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe6150078 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "sdhi1ck"; + }; + sdhi2_clk: sdhi2_clk@e615007c { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe615007c 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "sdhi2ck"; + }; + fsia_clk: fsia_clk@e6150018 { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe6150018 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "fsia"; + }; + fsib_clk: fsib_clk@e6150090 { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe6150090 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "fsib"; + }; + sub_clk: sub_clk@e6150080 { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe6150080 4>; + clocks = <&extal2_clk>; + #clock-cells = <0>; + clock-output-names = "sub"; + }; + spua_clk: spua_clk@e6150084 { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe6150084 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "spua"; + }; + spuv_clk: spuv_clk@e6150094 { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe6150094 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "spuv"; + }; + msu_clk: msu_clk@e6150088 { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe6150088 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "msu"; + }; + hsi_clk: hsi_clk@e615008c { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe615008c 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "hsi"; + }; + mfg1_clk: mfg1_clk@e6150098 { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe6150098 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "mfg1"; + }; + mfg2_clk: mfg2_clk@e615009c { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe615009c 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "mfg2"; + }; + dsit_clk: dsit_clk@e6150060 { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe6150060 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "dsit"; + }; + dsi0p_clk: dsi0p_clk@e6150064 { + compatible = "renesas,sh73a0-div6-clock", "renesas,cpg-div6-clock"; + reg = <0xe6150064 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "dsi0pck"; + }; + + /* Fixed factor clocks */ + main_div2_clk: main_div2_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks SH73A0_CLK_MAIN>; + #clock-cells = <0>; + clock-div = <2>; + clock-mult = <1>; + clock-output-names = "main_div2"; + }; + pll1_div2_clk: pll1_div2_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks SH73A0_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <2>; + clock-mult = <1>; + clock-output-names = "pll1_div2"; + }; + pll1_div7_clk: pll1_div7_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks SH73A0_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <7>; + clock-mult = <1>; + clock-output-names = "pll1_div7"; + }; + pll1_div13_clk: pll1_div13_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks SH73A0_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <13>; + clock-mult = <1>; + clock-output-names = "pll1_div13"; + }; + twd_clk: twd_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks SH73A0_CLK_Z>; + #clock-cells = <0>; + clock-div = <4>; + clock-mult = <1>; + clock-output-names = "twd"; + }; + + /* Gate clocks */ + mstp0_clks: mstp0_clks@e6150130 { + compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0xe6150130 4>, <0xe6150030 4>; + clocks = <&cpg_clocks SH73A0_CLK_HP>; + #clock-cells = <1>; + clock-indices = < + SH73A0_CLK_IIC2 + >; + clock-output-names = + "iic2"; + }; + mstp1_clks: mstp1_clks@e6150134 { + compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0xe6150134 4>, <0xe6150038 4>; + clocks = <&cpg_clocks SH73A0_CLK_B>, + <&cpg_clocks SH73A0_CLK_B>, + <&cpg_clocks SH73A0_CLK_B>, + <&cpg_clocks SH73A0_CLK_B>, + <&sub_clk>, <&cpg_clocks SH73A0_CLK_B>, + <&cpg_clocks SH73A0_CLK_HP>, + <&cpg_clocks SH73A0_CLK_ZG>, + <&cpg_clocks SH73A0_CLK_B>; + #clock-cells = <1>; + clock-indices = < + SH73A0_CLK_CEU1 SH73A0_CLK_CSI2_RX1 + SH73A0_CLK_CEU0 SH73A0_CLK_CSI2_RX0 + SH73A0_CLK_TMU0 SH73A0_CLK_DSITX0 + SH73A0_CLK_IIC0 SH73A0_CLK_SGX + SH73A0_CLK_LCDC0 + >; + clock-output-names = + "ceu1", "csi2_rx1", "ceu0", "csi2_rx0", + "tmu0", "dsitx0", "iic0", "sgx", "lcdc0"; + }; + mstp2_clks: mstp2_clks@e6150138 { + compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0xe6150138 4>, <0xe6150040 4>; + clocks = <&sub_clk>, <&cpg_clocks SH73A0_CLK_HP>, + <&cpg_clocks SH73A0_CLK_HP>, <&sub_clk>, + <&sub_clk>, <&sub_clk>, <&sub_clk>, <&sub_clk>, + <&sub_clk>, <&sub_clk>; + #clock-cells = <1>; + clock-indices = < + SH73A0_CLK_SCIFA7 SH73A0_CLK_SY_DMAC + SH73A0_CLK_MP_DMAC SH73A0_CLK_SCIFA5 + SH73A0_CLK_SCIFB SH73A0_CLK_SCIFA0 + SH73A0_CLK_SCIFA1 SH73A0_CLK_SCIFA2 + SH73A0_CLK_SCIFA3 SH73A0_CLK_SCIFA4 + >; + clock-output-names = + "scifa7", "sy_dmac", "mp_dmac", "scifa5", + "scifb", "scifa0", "scifa1", "scifa2", + "scifa3", "scifa4"; + }; + mstp3_clks: mstp3_clks@e615013c { + compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0xe615013c 4>, <0xe6150048 4>; + clocks = <&sub_clk>, <&extalr_clk>, + <&cpg_clocks SH73A0_CLK_HP>, <&sub_clk>, + <&cpg_clocks SH73A0_CLK_HP>, + <&cpg_clocks SH73A0_CLK_HP>, <&flctl_clk>, + <&sdhi0_clk>, <&sdhi1_clk>, + <&cpg_clocks SH73A0_CLK_HP>, <&sdhi2_clk>, + <&main_div2_clk>, <&main_div2_clk>, + <&main_div2_clk>, <&main_div2_clk>, + <&main_div2_clk>; + #clock-cells = <1>; + clock-indices = < + SH73A0_CLK_SCIFA6 SH73A0_CLK_CMT1 + SH73A0_CLK_FSI SH73A0_CLK_IRDA + SH73A0_CLK_IIC1 SH73A0_CLK_USB SH73A0_CLK_FLCTL + SH73A0_CLK_SDHI0 SH73A0_CLK_SDHI1 + SH73A0_CLK_MMCIF0 SH73A0_CLK_SDHI2 + SH73A0_CLK_TPU0 SH73A0_CLK_TPU1 + SH73A0_CLK_TPU2 SH73A0_CLK_TPU3 + SH73A0_CLK_TPU4 + >; + clock-output-names = + "scifa6", "cmt1", "fsi", "irda", "iic1", + "usb", "flctl", "sdhi0", "sdhi1", "mmcif0", "sdhi2", + "tpu0", "tpu1", "tpu2", "tpu3", "tpu4"; + }; + mstp4_clks: mstp4_clks@e6150140 { + compatible = "renesas,sh73a0-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0xe6150140 4>, <0xe615004c 4>; + clocks = <&cpg_clocks SH73A0_CLK_HP>, + <&cpg_clocks SH73A0_CLK_HP>, <&extalr_clk>; + #clock-cells = <1>; + clock-indices = < + SH73A0_CLK_IIC3 SH73A0_CLK_IIC4 + SH73A0_CLK_KEYSC + >; + clock-output-names = + "iic3", "iic4", "keysc"; + }; + }; }; diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index 865f878063cc..f70eca7ee705 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h @@ -13,6 +13,7 @@ #define __ARCH_ARM_MACH_EXYNOS_COMMON_H #include <linux/of.h> +#include <linux/platform_data/cpuidle-exynos.h> #define EXYNOS3250_SOC_ID 0xE3472000 #define EXYNOS3_SOC_MASK 0xFFFFF000 @@ -150,8 +151,11 @@ extern void exynos_pm_central_suspend(void); extern int exynos_pm_central_resume(void); extern void exynos_enter_aftr(void); +extern struct cpuidle_exynos_data cpuidle_coupled_exynos_data; + extern void s5p_init_cpu(void __iomem *cpuid_addr); extern unsigned int samsung_rev(void); +extern void __iomem *cpu_boot_reg_base(void); static inline void pmu_raw_writel(u32 val, u32 offset) { diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index 78eca99b98d1..2013f73797ed 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -211,6 +211,10 @@ static void __init exynos_dt_machine_init(void) if (!IS_ENABLED(CONFIG_SMP)) exynos_sysram_init(); +#ifdef CONFIG_ARM_EXYNOS_CPUIDLE + if (of_machine_is_compatible("samsung,exynos4210")) + exynos_cpuidle.dev.platform_data = &cpuidle_coupled_exynos_data; +#endif if (of_machine_is_compatible("samsung,exynos4210") || of_machine_is_compatible("samsung,exynos4212") || (of_machine_is_compatible("samsung,exynos4412") && diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 7a1ebfeeeeb8..3f32c47a6d74 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -194,7 +194,7 @@ int exynos_cluster_power_state(int cluster) S5P_CORE_LOCAL_PWR_EN); } -static inline void __iomem *cpu_boot_reg_base(void) +void __iomem *cpu_boot_reg_base(void) { if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1) return pmu_base_addr + S5P_INFORM5; diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index dfc8594e5b1f..e6209dadc00d 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -98,10 +98,6 @@ void exynos_pm_central_suspend(void) tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); tmp &= ~S5P_CENTRAL_LOWPWR_CFG; pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); - - /* Setting SEQ_OPTION register */ - pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0, - S5P_CENTRAL_SEQ_OPTION); } int exynos_pm_central_resume(void) @@ -165,6 +161,13 @@ void exynos_enter_aftr(void) exynos_pm_central_suspend(); + if (of_machine_is_compatible("samsung,exynos4212") || + of_machine_is_compatible("samsung,exynos4412")) { + /* Setting SEQ_OPTION register */ + pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0, + S5P_CENTRAL_SEQ_OPTION); + } + cpu_suspend(0, exynos_aftr_finisher); if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) { @@ -177,3 +180,125 @@ void exynos_enter_aftr(void) cpu_pm_exit(); } + +static atomic_t cpu1_wakeup = ATOMIC_INIT(0); + +static int exynos_cpu0_enter_aftr(void) +{ + int ret = -1; + + /* + * If the other cpu is powered on, we have to power it off, because + * the AFTR state won't work otherwise + */ + if (cpu_online(1)) { + /* + * We reach a sync point with the coupled idle state, we know + * the other cpu will power down itself or will abort the + * sequence, let's wait for one of these to happen + */ + while (exynos_cpu_power_state(1)) { + /* + * The other cpu may skip idle and boot back + * up again + */ + if (atomic_read(&cpu1_wakeup)) + goto abort; + + /* + * The other cpu may bounce through idle and + * boot back up again, getting stuck in the + * boot rom code + */ + if (__raw_readl(cpu_boot_reg_base()) == 0) + goto abort; + + cpu_relax(); + } + } + + exynos_enter_aftr(); + ret = 0; + +abort: + if (cpu_online(1)) { + /* + * Set the boot vector to something non-zero + */ + __raw_writel(virt_to_phys(exynos_cpu_resume), + cpu_boot_reg_base()); + dsb(); + + /* + * Turn on cpu1 and wait for it to be on + */ + exynos_cpu_power_up(1); + while (exynos_cpu_power_state(1) != S5P_CORE_LOCAL_PWR_EN) + cpu_relax(); + + while (!atomic_read(&cpu1_wakeup)) { + /* + * Poke cpu1 out of the boot rom + */ + __raw_writel(virt_to_phys(exynos_cpu_resume), + cpu_boot_reg_base()); + + arch_send_wakeup_ipi_mask(cpumask_of(1)); + } + } + + return ret; +} + +static int exynos_wfi_finisher(unsigned long flags) +{ + cpu_do_idle(); + + return -1; +} + +static int exynos_cpu1_powerdown(void) +{ + int ret = -1; + + /* + * Idle sequence for cpu1 + */ + if (cpu_pm_enter()) + goto cpu1_aborted; + + /* + * Turn off cpu 1 + */ + exynos_cpu_power_down(1); + + ret = cpu_suspend(0, exynos_wfi_finisher); + + cpu_pm_exit(); + +cpu1_aborted: + dsb(); + /* + * Notify cpu 0 that cpu 1 is awake + */ + atomic_set(&cpu1_wakeup, 1); + + return ret; +} + +static void exynos_pre_enter_aftr(void) +{ + __raw_writel(virt_to_phys(exynos_cpu_resume), cpu_boot_reg_base()); +} + +static void exynos_post_enter_aftr(void) +{ + atomic_set(&cpu1_wakeup, 0); +} + +struct cpuidle_exynos_data cpuidle_coupled_exynos_data = { + .cpu0_enter_aftr = exynos_cpu0_enter_aftr, + .cpu1_powerdown = exynos_cpu1_powerdown, + .pre_enter_aftr = exynos_pre_enter_aftr, + .post_enter_aftr = exynos_post_enter_aftr, +}; diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index 82e6b6fba23f..666ec3e5b03f 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -319,6 +319,10 @@ static int exynos_pm_suspend(void) { exynos_pm_central_suspend(); + /* Setting SEQ_OPTION register */ + pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0, + S5P_CENTRAL_SEQ_OPTION); + if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) exynos_cpu_save_register(); diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index a8593d1241be..faea74a2151b 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -766,7 +766,9 @@ void __init __weak sh73a0_register_twd(void) { } void __init sh73a0_earlytimer_init(void) { shmobile_init_delay(); +#ifndef CONFIG_COMMON_CLK sh73a0_clock_init(); +#endif shmobile_earlytimer_init(); sh73a0_register_twd(); } @@ -785,8 +787,9 @@ void __init sh73a0_add_early_devices(void) void __init sh73a0_add_standard_devices_dt(void) { /* clocks are setup late during boot in the case of DT */ +#ifndef CONFIG_COMMON_CLK sh73a0_clock_init(); - +#endif of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } |