^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * OMAP4 SMP source file. It contains platform specific functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * needed for the linux smp kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2009 Texas Instruments, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Author:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Santosh Shilimkar <santosh.shilimkar@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Platform file needed for the OMAP4 SMP. This file is based on arm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * realview smp platform.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * * Copyright (c) 2002 ARM Limited.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/irqchip/arm-gic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/sections.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/smp_scu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/virt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "omap-secure.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "omap-wakeupgen.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/cputype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "soc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "iomap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "clockdomain.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "pm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define CPU_MASK 0xff0ffff0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define CPU_CORTEX_A9 0x410FC090
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define CPU_CORTEX_A15 0x410FC0F0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define OMAP5_CORE_COUNT 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define AUX_CORE_BOOT0_GP_RELEASE 0x020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define AUX_CORE_BOOT0_HS_RELEASE 0x200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct omap_smp_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned long cpu1_rstctrl_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) void __iomem *cpu1_rstctrl_va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) void __iomem *scu_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) void __iomem *wakeupgen_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) void *startup_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static struct omap_smp_config cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static const struct omap_smp_config omap443x_cfg __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .cpu1_rstctrl_pa = 0x4824380c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .startup_addr = omap4_secondary_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static const struct omap_smp_config omap446x_cfg __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .cpu1_rstctrl_pa = 0x4824380c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .startup_addr = omap4460_secondary_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static const struct omap_smp_config omap5_cfg __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .cpu1_rstctrl_pa = 0x48243810,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .startup_addr = omap5_secondary_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) void __iomem *omap4_get_scu_base(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return cfg.scu_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #ifdef CONFIG_OMAP5_ERRATA_801819
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static void omap5_erratum_workaround_801819(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) u32 acr, revidr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u32 acr_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* REVIDR[3] indicates erratum fix available on silicon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) asm volatile ("mrc p15, 0, %0, c0, c0, 6" : "=r" (revidr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (revidr & (0x1 << 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * BIT(27) - Disables streaming. All write-allocate lines allocate in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * the L1 or L2 cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * BIT(25) - Disables streaming. All write-allocate lines allocate in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * the L1 cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) acr_mask = (0x3 << 25) | (0x3 << 27);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* do we already have it done.. if yes, skip expensive smc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if ((acr & acr_mask) == acr_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) acr |= acr_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) omap_smc1(OMAP5_DRA7_MON_SET_ACR_INDEX, acr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) pr_debug("%s: ARM erratum workaround 801819 applied on CPU%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) __func__, smp_processor_id());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static inline void omap5_erratum_workaround_801819(void) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * Configure ACR and enable ACTLR[0] (Enable invalidates of BTB with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * ICIALLU) to activate the workaround for secondary Core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * NOTE: it is assumed that the primary core's configuration is done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * by the boot loader (kernel will detect a misconfiguration and complain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * if this is not done).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * In General Purpose(GP) devices, ACR bit settings can only be done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * by ROM code in "secure world" using the smc call and there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * option to update the "firmware" on such devices. This also works for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * High security(HS) devices, as a backup option in case the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * "update" is not done in the "security firmware".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static void omap5_secondary_harden_predictor(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u32 acr, acr_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * ACTLR[0] (Enable invalidates of BTB with ICIALLU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) acr_mask = BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Do we already have it done.. if yes, skip expensive smc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if ((acr & acr_mask) == acr_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) acr |= acr_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) omap_smc1(OMAP5_DRA7_MON_SET_ACR_INDEX, acr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) pr_debug("%s: ARM ACR setup for CVE_2017_5715 applied on CPU%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) __func__, smp_processor_id());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static inline void omap5_secondary_harden_predictor(void) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static void omap4_secondary_init(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * init and for CPU1, a secure PPA API provided. CPU0 must be ON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * OMAP443X GP devices- SMP bit isn't accessible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * OMAP446X GP devices - SMP bit access is enabled on both CPUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (soc_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 4, 0, 0, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (soc_is_omap54xx() || soc_is_dra7xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * Configure the CNTFRQ register for the secondary cpu's which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * indicates the frequency of the cpu local timers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) set_cntfreq();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* Configure ACR to disable streaming WA for 801819 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) omap5_erratum_workaround_801819();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* Enable ACR to allow for ICUALLU workaround */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) omap5_secondary_harden_predictor();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static struct clockdomain *cpu1_clkdm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static bool booted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static struct powerdomain *cpu1_pwrdm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * Update the AuxCoreBoot0 with boot state for secondary core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * omap4_secondary_startup() routine will hold the secondary core till
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * the AuxCoreBoot1 register is updated with cpu state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * A barrier is added to ensure that write buffer is drained
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (omap_secure_apis_support())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) omap_modify_auxcoreboot0(AUX_CORE_BOOT0_HS_RELEASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 0xfffffdff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) writel_relaxed(AUX_CORE_BOOT0_GP_RELEASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) cfg.wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (!cpu1_clkdm && !cpu1_pwrdm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) cpu1_pwrdm = pwrdm_lookup("cpu1_pwrdm");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * The SGI(Software Generated Interrupts) are not wakeup capable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * from low power states. This is known limitation on OMAP4 and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * needs to be worked around by using software forced clockdomain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * wake-up. To wakeup CPU1, CPU0 forces the CPU1 clockdomain to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * software force wakeup. The clockdomain is then put back to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * hardware supervised mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * More details can be found in OMAP4430 TRM - Version J
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * Section :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * 4.3.4.2 Power States of CPU0 and CPU1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (booted && cpu1_pwrdm && cpu1_clkdm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * GIC distributor control register has changed between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * CortexA9 r1pX and r2pX. The Control Register secure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * banked version is now composed of 2 bits:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * bit 0 == Secure Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * bit 1 == Non-Secure Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * The Non-Secure banked register has not changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * Because the ROM Code is based on the r1pX GIC, the CPU1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * GIC restoration will cause a problem to CPU0 Non-Secure SW.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * The workaround must be:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * 1) Before doing the CPU1 wakeup, CPU0 must disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * the GIC distributor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * 2) CPU1 must re-enable the GIC distributor on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * it's wakeup path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) gic_dist_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * Ensure that CPU power state is set to ON to avoid CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * powerdomain transition on wfi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) clkdm_deny_idle_nolock(cpu1_clkdm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) pwrdm_set_next_pwrst(cpu1_pwrdm, PWRDM_POWER_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) clkdm_allow_idle_nolock(cpu1_clkdm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) while (gic_dist_disabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) gic_timer_retrigger();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) dsb_sev();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) booted = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) arch_send_wakeup_ipi_mask(cpumask_of(cpu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * Initialise the CPU possible map early - this describes the CPUs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * which may be present or become present in the system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static void __init omap4_smp_init_cpus(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) unsigned int i = 0, ncores = 1, cpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* Use ARM cpuid check here, as SoC detection will not work so early */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) cpu_id = read_cpuid_id() & CPU_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (cpu_id == CPU_CORTEX_A9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * Currently we can't call ioremap here because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * SoC detection won't work until after init_early.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) cfg.scu_base = OMAP2_L4_IO_ADDRESS(scu_a9_get_base());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) BUG_ON(!cfg.scu_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ncores = scu_get_core_count(cfg.scu_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) } else if (cpu_id == CPU_CORTEX_A15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ncores = OMAP5_CORE_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (ncores > nr_cpu_ids) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ncores, nr_cpu_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) ncores = nr_cpu_ids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) for (i = 0; i < ncores; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) set_cpu_possible(i, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * For now, just make sure the start-up address is not within the booting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * kernel space as that means we just overwrote whatever secondary_startup()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * code there was.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static bool __init omap4_smp_cpu1_startup_valid(unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if ((addr >= __pa(PAGE_OFFSET)) && (addr <= __pa(__bss_start)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * We may need to reset CPU1 before configuring, otherwise kexec boot can end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * up trying to use old kernel startup address or suspend-resume will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * occasionally fail to bring up CPU1 on 4430 if CPU1 fails to enter deeper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * idle states.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static void __init omap4_smp_maybe_reset_cpu1(struct omap_smp_config *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) unsigned long cpu1_startup_pa, cpu1_ns_pa_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) bool needs_reset = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) u32 released;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (omap_secure_apis_support())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) released = omap_read_auxcoreboot0() & AUX_CORE_BOOT0_HS_RELEASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) released = readl_relaxed(cfg.wakeupgen_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) OMAP_AUX_CORE_BOOT_0) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) AUX_CORE_BOOT0_GP_RELEASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (released) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) pr_warn("smp: CPU1 not parked?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) cpu1_startup_pa = readl_relaxed(cfg.wakeupgen_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) OMAP_AUX_CORE_BOOT_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* Did the configured secondary_startup() get overwritten? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (!omap4_smp_cpu1_startup_valid(cpu1_startup_pa))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) needs_reset = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * If omap4 or 5 has NS_PA_ADDR configured, CPU1 may be in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * deeper idle state in WFI and will wake to an invalid address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if ((soc_is_omap44xx() || soc_is_omap54xx())) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) cpu1_ns_pa_addr = omap4_get_cpu1_ns_pa_addr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (!omap4_smp_cpu1_startup_valid(cpu1_ns_pa_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) needs_reset = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) cpu1_ns_pa_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (!needs_reset || !c->cpu1_rstctrl_va)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) pr_info("smp: CPU1 parked within kernel, needs reset (0x%lx 0x%lx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) cpu1_startup_pa, cpu1_ns_pa_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) writel_relaxed(1, c->cpu1_rstctrl_va);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) readl_relaxed(c->cpu1_rstctrl_va);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) writel_relaxed(0, c->cpu1_rstctrl_va);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) const struct omap_smp_config *c = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (soc_is_omap443x())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) c = &omap443x_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) else if (soc_is_omap446x())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) c = &omap446x_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) else if (soc_is_dra74x() || soc_is_omap54xx() || soc_is_dra76x())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) c = &omap5_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (!c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) pr_err("%s Unknown SMP SoC?\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* Must preserve cfg.scu_base set earlier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) cfg.cpu1_rstctrl_pa = c->cpu1_rstctrl_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) cfg.startup_addr = c->startup_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) cfg.wakeupgen_base = omap_get_wakeupgen_base();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (soc_is_dra74x() || soc_is_omap54xx() || soc_is_dra76x()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) cfg.startup_addr = omap5_secondary_hyp_startup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) omap5_erratum_workaround_801819();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) cfg.cpu1_rstctrl_va = ioremap(cfg.cpu1_rstctrl_pa, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (!cfg.cpu1_rstctrl_va)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * Initialise the SCU and wake up the secondary core using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * wakeup_secondary().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (cfg.scu_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) scu_enable(cfg.scu_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) omap4_smp_maybe_reset_cpu1(&cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * Write the address of secondary startup routine into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * AuxCoreBoot1 where ROM code will jump and start executing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * on secondary core once out of WFE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * A barrier is added to ensure that write buffer is drained
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (omap_secure_apis_support())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) omap_auxcoreboot_addr(__pa_symbol(cfg.startup_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) writel_relaxed(__pa_symbol(cfg.startup_addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) cfg.wakeupgen_base + OMAP_AUX_CORE_BOOT_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) const struct smp_operations omap4_smp_ops __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .smp_init_cpus = omap4_smp_init_cpus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) .smp_prepare_cpus = omap4_smp_prepare_cpus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .smp_secondary_init = omap4_secondary_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .smp_boot_secondary = omap4_boot_secondary,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) #ifdef CONFIG_HOTPLUG_CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) .cpu_die = omap4_cpu_die,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .cpu_kill = omap4_cpu_kill,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) };