On Sun, Jun 06, 2021 at 10:16:12PM +0200, Bartosz Dudziak wrote: > Implement support for Cortex-A7 CPU release sequence in MSM8226 SoC. > > Signed-off-by: Bartosz Dudziak <bartosz.dudziak@xxxxxxxx> > --- > arch/arm/mach-qcom/platsmp.c | 71 ++++++++++++++++++++++++++++++++++++ > 1 file changed, 71 insertions(+) > > diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c > index 630a038f45..60496554c6 100644 > --- a/arch/arm/mach-qcom/platsmp.c > +++ b/arch/arm/mach-qcom/platsmp.c > @@ -29,6 +29,7 @@ > #define COREPOR_RST BIT(5) > #define CORE_RST BIT(4) > #define L2DT_SLP BIT(3) > +#define CORE_MEM_CLAMP BIT(1) > #define CLAMP BIT(0) > > #define APC_PWR_GATE_CTL 0x14 > @@ -75,6 +76,62 @@ static int scss_release_secondary(unsigned int cpu) > return 0; > } > > +static int cortex_a7_release_secondary(unsigned int cpu) > +{ > + int ret = 0; > + void __iomem *reg; > + struct device_node *cpu_node, *acc_node; > + u32 reg_val; > + > + cpu_node = of_get_cpu_node(cpu, NULL); > + if (!cpu_node) > + return -ENODEV; > + > + acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0); > + if (!acc_node) { > + ret = -ENODEV; > + goto out_acc; > + } > + > + reg = of_iomap(acc_node, 0); > + if (!reg) { > + ret = -ENOMEM; > + goto out_acc_map; > + } > + > + /* Put the CPU into reset. */ > + reg_val = CORE_RST | COREPOR_RST | CLAMP | CORE_MEM_CLAMP; > + writel(reg_val, reg + APCS_CPU_PWR_CTL); > + > + /* Turn on the BHS and set the BHS_CNT to 16 XO clock cycles */ > + writel(BHS_EN | (0x10 << BHS_CNT_SHIFT), reg + APC_PWR_GATE_CTL); > + /* Wait for the BHS to settle */ > + udelay(2); > + > + reg_val &= ~CORE_MEM_CLAMP; > + writel(reg_val, reg + APCS_CPU_PWR_CTL); > + reg_val |= L2DT_SLP; > + writel(reg_val, reg + APCS_CPU_PWR_CTL); > + udelay(2); > + > + reg_val = (reg_val | BIT(17)) & ~CLAMP; > + writel(reg_val, reg + APCS_CPU_PWR_CTL); > + udelay(2); > + > + /* Release CPU out of reset and bring it to life. */ > + reg_val &= ~(CORE_RST | COREPOR_RST); > + writel(reg_val, reg + APCS_CPU_PWR_CTL); > + reg_val |= CORE_PWRD_UP; > + writel(reg_val, reg + APCS_CPU_PWR_CTL); > + > + iounmap(reg); > +out_acc_map: > + of_node_put(acc_node); > +out_acc: > + of_node_put(cpu_node); > + return ret; > +} > + > static int kpssv1_release_secondary(unsigned int cpu) > { > int ret = 0; > @@ -281,6 +338,11 @@ static int msm8660_boot_secondary(unsigned int cpu, struct task_struct *idle) > return qcom_boot_secondary(cpu, scss_release_secondary); > } > > +static int cortex_a7_boot_secondary(unsigned int cpu, struct task_struct *idle) > +{ > + return qcom_boot_secondary(cpu, cortex_a7_release_secondary); > +} > + > static int kpssv1_boot_secondary(unsigned int cpu, struct task_struct *idle) > { > return qcom_boot_secondary(cpu, kpssv1_release_secondary); > @@ -315,6 +377,15 @@ static const struct smp_operations smp_msm8660_ops __initconst = { > }; > CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops); > > +static const struct smp_operations qcom_smp_cortex_a7_ops __initconst = { > + .smp_prepare_cpus = qcom_smp_prepare_cpus, > + .smp_boot_secondary = cortex_a7_boot_secondary, > +#ifdef CONFIG_HOTPLUG_CPU > + .cpu_die = qcom_cpu_die, > +#endif > +}; > +CPU_METHOD_OF_DECLARE(qcom_smp_msm8226, "qcom,msm8226-smp", &qcom_smp_cortex_a7_ops); > + Looks good to me now. Actually this is also working well on MSM8916/Cortex-A53 on a rather unfortunate device where the firmware does not allow booting 64-bit kernels. I might upstream that now that it's mostly just adding a new compatible string with the same code. Assuming your change log is correct and you didn't change the initialization sequence in v1 -> v2 (didn't check it again): Reviewed-by: Stephan Gerhold <stephan@xxxxxxxxxxx> Thanks! Stephan