| .. | .. |
|---|
| 26 | 26 | #define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30) |
|---|
| 27 | 27 | |
|---|
| 28 | 28 | static void __iomem *ns_sram_base_addr __ro_after_init; |
|---|
| 29 | +static bool secure_firmware __ro_after_init; |
|---|
| 29 | 30 | |
|---|
| 30 | 31 | /* |
|---|
| 31 | 32 | * The common v7_exit_coherency_flush API could not be used because of the |
|---|
| .. | .. |
|---|
| 58 | 59 | static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster) |
|---|
| 59 | 60 | { |
|---|
| 60 | 61 | unsigned int cpunr = cpu + (cluster * EXYNOS5420_CPUS_PER_CLUSTER); |
|---|
| 62 | + bool state; |
|---|
| 61 | 63 | |
|---|
| 62 | 64 | pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster); |
|---|
| 63 | 65 | if (cpu >= EXYNOS5420_CPUS_PER_CLUSTER || |
|---|
| 64 | 66 | cluster >= EXYNOS5420_NR_CLUSTERS) |
|---|
| 65 | 67 | return -EINVAL; |
|---|
| 66 | 68 | |
|---|
| 67 | | - if (!exynos_cpu_power_state(cpunr)) { |
|---|
| 68 | | - exynos_cpu_power_up(cpunr); |
|---|
| 69 | | - |
|---|
| 69 | + state = exynos_cpu_power_state(cpunr); |
|---|
| 70 | + exynos_cpu_power_up(cpunr); |
|---|
| 71 | + if (!state && secure_firmware) { |
|---|
| 70 | 72 | /* |
|---|
| 71 | 73 | * This assumes the cluster number of the big cores(Cortex A15) |
|---|
| 72 | 74 | * is 0 and the Little cores(Cortex A7) is 1. |
|---|
| .. | .. |
|---|
| 75 | 77 | */ |
|---|
| 76 | 78 | if (cluster && |
|---|
| 77 | 79 | cluster == MPIDR_AFFINITY_LEVEL(cpu_logical_map(0), 1)) { |
|---|
| 80 | + unsigned int timeout = 16; |
|---|
| 81 | + |
|---|
| 78 | 82 | /* |
|---|
| 79 | 83 | * Before we reset the Little cores, we should wait |
|---|
| 80 | 84 | * the SPARE2 register is set to 1 because the init |
|---|
| 81 | 85 | * codes of the iROM will set the register after |
|---|
| 82 | 86 | * initialization. |
|---|
| 83 | 87 | */ |
|---|
| 84 | | - while (!pmu_raw_readl(S5P_PMU_SPARE2)) |
|---|
| 88 | + while (timeout && !pmu_raw_readl(S5P_PMU_SPARE2)) { |
|---|
| 89 | + timeout--; |
|---|
| 85 | 90 | udelay(10); |
|---|
| 91 | + } |
|---|
| 92 | + |
|---|
| 93 | + if (timeout == 0) { |
|---|
| 94 | + pr_err("cpu %u cluster %u powerup failed\n", |
|---|
| 95 | + cpu, cluster); |
|---|
| 96 | + exynos_cpu_power_down(cpunr); |
|---|
| 97 | + return -ETIMEDOUT; |
|---|
| 98 | + } |
|---|
| 86 | 99 | |
|---|
| 87 | 100 | pmu_raw_writel(EXYNOS5420_KFC_CORE_RESET(cpu), |
|---|
| 88 | 101 | EXYNOS_SWRESET); |
|---|
| .. | .. |
|---|
| 247 | 260 | return -ENOMEM; |
|---|
| 248 | 261 | } |
|---|
| 249 | 262 | |
|---|
| 263 | + secure_firmware = exynos_secure_firmware_available(); |
|---|
| 264 | + |
|---|
| 250 | 265 | /* |
|---|
| 251 | 266 | * To increase the stability of KFC reset we need to program |
|---|
| 252 | 267 | * the PMU SPARE3 register |
|---|