123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- #include <common.h>
- #include <linux/bitops.h>
- #include <linux/io.h>
- #include <linux/kernel.h>
- #include <linux/psci.h>
- #include <linux/sizes.h>
- #include <asm/processor.h>
- #include <asm/psci.h>
- #include <asm/secure.h>
- #include "../debug.h"
- #include "../soc-info.h"
- #include "arm-mpcore.h"
- #include "cache-uniphier.h"
- #define UNIPHIER_SMPCTRL_ROM_RSV2 0x59801208
- void uniphier_smp_trampoline(void);
- void uniphier_smp_trampoline_end(void);
- u32 uniphier_smp_booted[CONFIG_ARMV7_PSCI_NR_CPUS];
- static int uniphier_get_nr_cpus(void)
- {
- switch (uniphier_get_soc_type()) {
- case SOC_UNIPHIER_SLD3:
- case SOC_UNIPHIER_PRO4:
- case SOC_UNIPHIER_PRO5:
- return 2;
- case SOC_UNIPHIER_PXS2:
- case SOC_UNIPHIER_LD6B:
- return 4;
- default:
- return 1;
- }
- }
- static void uniphier_smp_kick_all_cpus(void)
- {
- const u32 target_ways = BIT(0);
- size_t trmp_size;
- u32 trmp_src = (unsigned long)uniphier_smp_trampoline;
- u32 trmp_src_end = (unsigned long)uniphier_smp_trampoline_end;
- u32 trmp_dest, trmp_dest_end;
- int nr_cpus, i;
- int timeout = 1000;
- nr_cpus = uniphier_get_nr_cpus();
- if (nr_cpus == 1)
- return;
- for (i = 0; i < nr_cpus; i++)
- uniphier_cache_set_active_ways(i, 0);
- uniphier_cache_inv_way(target_ways);
- uniphier_cache_enable();
-
- uniphier_cache_prefetch_range(trmp_src, trmp_src_end, target_ways);
- trmp_size = trmp_src_end - trmp_src;
- trmp_dest = trmp_src & (SZ_64K - 1);
- trmp_dest += SZ_1M - SZ_64K * 2;
- trmp_dest_end = trmp_dest + trmp_size;
- uniphier_cache_touch_range(trmp_dest, trmp_dest_end, target_ways);
- writel(trmp_dest, UNIPHIER_SMPCTRL_ROM_RSV2);
- asm("dsb ishst\n"
- "sev");
- while (--timeout) {
- int all_booted = 1;
- for (i = 1; i < nr_cpus; i++)
- if (!uniphier_smp_booted[i])
- all_booted = 0;
- if (all_booted)
- break;
- udelay(1);
-
- cpu_relax();
- }
- if (!timeout)
- printf("warning: some of secondary CPUs may not boot\n");
- uniphier_cache_disable();
- }
- void psci_board_init(void)
- {
- unsigned long scu_base;
- u32 scu_ctrl, tmp;
- asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (scu_base));
- scu_ctrl = readl(scu_base + 0x30);
- if (!(scu_ctrl & 1))
- writel(scu_ctrl | 0x1, scu_base + 0x30);
- scu_ctrl = readl(scu_base + SCU_CTRL);
- scu_ctrl |= SCU_ENABLE | SCU_STANDBY_ENABLE;
- writel(scu_ctrl, scu_base + SCU_CTRL);
- tmp = readl(scu_base + SCU_SNSAC);
- tmp |= 0xfff;
- writel(tmp, scu_base + SCU_SNSAC);
- uniphier_smp_kick_all_cpus();
- }
- void psci_arch_init(void)
- {
- u32 actlr;
- asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (actlr));
- actlr |= 0x41;
- asm("mcr p15, 0, %0, c1, c0, 1" : : "r" (actlr));
- }
- u32 uniphier_psci_holding_pen_release __secure_data = 0xffffffff;
- int __secure psci_cpu_on(u32 function_id, u32 cpuid, u32 entry_point)
- {
- u32 cpu = cpuid & 0xff;
- debug_puts("[U-Boot PSCI] psci_cpu_on: cpuid=");
- debug_puth(cpuid);
- debug_puts(", entry_point=");
- debug_puth(entry_point);
- debug_puts("\n");
- psci_save_target_pc(cpu, entry_point);
-
- uniphier_psci_holding_pen_release = cpu;
-
- asm("dsb ishst\n"
- "sev");
- return PSCI_RET_SUCCESS;
- }
- void __secure psci_system_reset(u32 function_id)
- {
- reset_cpu(0);
- }
|