Re: [PATCH v3 6/8] ARM: rockchip: add support smp for rk3036
From: Heiko Stübner
Date: Fri Oct 02 2015 - 05:20:00 EST
Hi,
Am Dienstag, 29. September 2015, 10:13:51 schrieb Xing Zheng:
> The rk3036 is dual-core soc, we can use this patch to enable cpu1
> enter boot secondary, and hotplug(online/offline).
>
> Signed-off-by: Xing Zheng <zhengxing@xxxxxxxxxxxxxx>
> Reviewed-by: Heiko Stuebner <heiko@xxxxxxxxx>
> ---
>
> Changes in v3: None
>
> arch/arm/mach-rockchip/platsmp.c | 142
> ++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+)
>
> diff --git a/arch/arm/mach-rockchip/platsmp.c
> b/arch/arm/mach-rockchip/platsmp.c index 3e7a4b7..7864bf3 100644
> --- a/arch/arm/mach-rockchip/platsmp.c
> +++ b/arch/arm/mach-rockchip/platsmp.c
> @@ -34,6 +34,8 @@
>
> static void __iomem *scu_base_addr;
> static void __iomem *sram_base_addr;
> +static void __iomem *cru_base_addr;
> +
> static int ncores;
>
> #define PMU_PWRDN_CON 0x08
> @@ -41,6 +43,8 @@ static int ncores;
>
> #define PMU_PWRDN_SCU 4
>
> +#define RK3036_SOFTRST_CON(x) ((x) * 0x4 + 0x110)
> +
> static struct regmap *pmu;
>
> static int pmu_power_domain_is_on(int pd)
> @@ -350,3 +354,141 @@ static struct smp_operations rockchip_smp_ops
> __initdata = { };
>
> CPU_METHOD_OF_DECLARE(rk3066_smp, "rockchip,rk3066-smp",
> &rockchip_smp_ops); +
> +/* for RK3036 */
> +
> +static int rk3036_set_power_domain(int pd, bool on)
> +{
> + struct reset_control *rstc = rockchip_get_core_reset(pd);
> + u32 val;
> +
> + /* there are 2cpus on rk3036 soc, we just need to be care cpu1 */
> + if (pd != 1)
> + return 0;
> +
> + if (IS_ERR(rstc) && read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
> + pr_err("%s: could not get reset control for core %d\n",
> + __func__, pd);
> + return PTR_ERR(rstc);
> + }
> +
> + /*
> + * We need to soft reset the cpu when we turn off the cpu power domain,
> + * or else the active processors might be stalled when the individual
> + * processor is powered down.
> + */
> + if (!IS_ERR(rstc) && !on)
> + reset_control_assert(rstc);
> +
> + val = (on) ? 0 : 1;
> + val = (val << pd) | BIT(pd + 16);
> + writel_relaxed(val, cru_base_addr + RK3036_SOFTRST_CON(0));
simply mapping the CRU in some arbitary part and then writing to the raw
reset register is just a no-go. Even more, as it also conflicts with the
reset-control handling directly above and below.
> +
> + dsb();
> +
> + if (!IS_ERR(rstc)) {
> + if (on)
> + reset_control_deassert(rstc);
> + reset_control_put(rstc);
> + }
> +
> + return 0;
> +}
In general you are duplicating a lot of code for the simple case of not being
able to control the power domains. The following should do the trick as well
I'd think and produce a lot less code duplication?
[of course adapting the dts slightly for the sram now old name]
Heiko
-------------- 8< --------------