Am Freitag, 10. Oktober 2014, 14:26:09 schrieb Kever Yang:
> This patch add basic rk3288 smp support.
> 
> Only cortex-A9 need invalid L1, A7/A12/A15/A17 should not invalid L1, since
> for A7/A12/A15, the invalidation would be taken as clean and invalidate.
> 
> If you use the software manual invalidation instead of hardware invalidation
> (assert l1/l2rstdisable during reset) after reset, there is tiny change
> that some cachelines would be in dirty and valid state after reset(since
> the ram content would be random value after reset), then the unexpected
> clean might lead to system crash.
> 
> Signed-off-by: Heiko Stuebner <he...@sntech.de>
> Signed-off-by: Kever Yang <kever.y...@rock-chips.com>
> ---
> 
> Changes in v3:
> - use one ops and secondary_starup for all rockchip SOCs
> - pick back the power domain operation for cpu hotplug
> 
> Changes in v2:
> - use rk3288_boot_secondary instead ofsmp_boot_secondary
> - discards the power domain operation
> - handle the per cpu starup when actived by 'sev'
> 
>  arch/arm/mach-rockchip/headsmp.S |  5 ++-
>  arch/arm/mach-rockchip/platsmp.c | 81
> ++++++++++++++++++++++++++++------------ 2 files changed, 61 insertions(+),
> 25 deletions(-)
> 
> diff --git a/arch/arm/mach-rockchip/headsmp.S
> b/arch/arm/mach-rockchip/headsmp.S index 73206e3..46c22de 100644
> --- a/arch/arm/mach-rockchip/headsmp.S
> +++ b/arch/arm/mach-rockchip/headsmp.S
> @@ -16,7 +16,10 @@
>  #include <linux/init.h>
> 
>  ENTRY(rockchip_secondary_startup)
> -     bl      v7_invalidate_l1
> +     mrc     p15, 0, r0, c0, c0, 0   @ read main ID register
> +     ldr     r1, =0x00000c09         @ Cortex-A9 primary part number
> +     teq     r0, r1
> +     beq     v7_invalidate_l1
>       b       secondary_startup
>  ENDPROC(rockchip_secondary_startup)
> 
> diff --git a/arch/arm/mach-rockchip/platsmp.c
> b/arch/arm/mach-rockchip/platsmp.c index 57b53b3..d1f858e 100644
> --- a/arch/arm/mach-rockchip/platsmp.c
> +++ b/arch/arm/mach-rockchip/platsmp.c
> @@ -84,6 +84,8 @@ static int pmu_set_power_domain(int pd, bool on)
>  static int __cpuinit rockchip_boot_secondary(unsigned int cpu,
>                                            struct task_struct *idle)
>  {
> +     int ret;
> +
>       if (!sram_base_addr || !pmu) {
>               pr_err("%s: sram or pmu missing for cpu boot\n", __func__);
>               return -ENXIO;
> @@ -96,7 +98,26 @@ static int __cpuinit rockchip_boot_secondary(unsigned int
> cpu, }
> 
>       /* start the core */
> -     return pmu_set_power_domain(0 + cpu, true);
> +     ret = pmu_set_power_domain(0 + cpu, true);
> +     if (ret < 0)
> +             return ret;
> +
> +     if (read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
> +             /* We communicate with the bootrom to active the cpus other
> +              * than cpu0, after a blob of initialize code, they will
> +              * stay at wfe state, once they are actived, they will check
> +              * the mailbox:
> +              * sram_base_addr + 4: 0xdeadbeaf
> +              * sram_base_addr + 8: start address for pc
> +              * */
> +             udelay(10);
> +             writel(virt_to_phys(rockchip_secondary_startup),
> +                     sram_base_addr + 8);
> +             writel(0xDEADBEAF, sram_base_addr + 4);
> +             dsb_sev();
> +     }
> +
> +     return 0;
>  }
> 
>  /**
> @@ -129,8 +150,6 @@ static int __init rockchip_smp_prepare_sram(struct
> device_node *node) return -EINVAL;
>       }
> 
> -     sram_base_addr = of_iomap(node, 0);
> -
>       /* set the boot function for the sram code */
>       rockchip_boot_fn = virt_to_phys(rockchip_secondary_startup);
> 
> @@ -203,18 +222,7 @@ static void __init rockchip_smp_prepare_cpus(unsigned
> int max_cpus) {
>       struct device_node *node;
>       unsigned int i;
> -
> -     node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
> -     if (!node) {
> -             pr_err("%s: missing scu\n", __func__);
> -             return;
> -     }
> -
> -     scu_base_addr = of_iomap(node, 0);
> -     if (!scu_base_addr) {
> -             pr_err("%s: could not map scu registers\n", __func__);
> -             return;
> -     }
> +     unsigned int l2ctlr;

please move this l2ctlr below inside the else branch - as it's only used 
there.


> 
>       node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-smp-sram");
>       if (!node) {
> @@ -222,22 +230,47 @@ static void __init rockchip_smp_prepare_cpus(unsigned
> int max_cpus) return;
>       }
> 
> -     if (rockchip_smp_prepare_sram(node))
> +     sram_base_addr = of_iomap(node, 0);
> +     if (!sram_base_addr) {
> +             pr_err("%s: could not map sram registers\n", __func__);
>               return;
> +     }
> 
>       if (rockchip_smp_prepare_pmu())
>               return;
> 
> -     /* enable the SCU power domain */
> -     pmu_set_power_domain(PMU_PWRDN_SCU, true);
> +     if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
> +             if (rockchip_smp_prepare_sram(node))
> +                     return;
> 
> -     /*
> -      * While the number of cpus is gathered from dt, also get the number
> -      * of cores from the scu to verify this value when booting the cores.
> -      */
> -     ncores = scu_get_core_count(scu_base_addr);
> +             /* enable the SCU power domain */
> +             pmu_set_power_domain(PMU_PWRDN_SCU, true);
> +
> +             node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
> +             if (!node) {
> +                     pr_err("%s: missing scu\n", __func__);
> +                     return;
> +             }
> 
> -     scu_enable(scu_base_addr);
> +             scu_base_addr = of_iomap(node, 0);
> +             if (!scu_base_addr) {
> +                     pr_err("%s: could not map scu registers\n", __func__);
> +                     return;
> +             }
> +
> +             /*
> +              * While the number of cpus is gathered from dt, also get the
> +              * number of cores from the scu to verify this value when
> +              * booting the cores.
> +              */
> +             ncores = scu_get_core_count(scu_base_addr);
> +             pr_err("%s: ncores %d\n", __func__, ncores);
> +
> +             scu_enable(scu_base_addr);
> +     } else {

-> here

> +             asm ("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr));
> +             ncores = ((l2ctlr >> 24) & 0x3) + 1;
> +     }
> 
>       /* Make sure that all cores except the first are really off */
>       for (i = 1; i < ncores; i++)

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to