0001
0002
0003
0004
0005
0006
0007 #include <linux/kernel.h>
0008 #include <linux/io.h>
0009 #include <linux/init.h>
0010 #include <linux/of.h>
0011 #include <linux/of_address.h>
0012
0013 #include <asm/cacheflush.h>
0014 #include <asm/cputype.h>
0015 #include <asm/firmware.h>
0016 #include <asm/hardware/cache-l2x0.h>
0017 #include <asm/suspend.h>
0018
0019 #include "common.h"
0020 #include "smc.h"
0021
0022 #define EXYNOS_BOOT_ADDR 0x8
0023 #define EXYNOS_BOOT_FLAG 0xc
0024
0025 static void exynos_save_cp15(void)
0026 {
0027
0028 asm ("mrc p15, 0, %0, c15, c0, 0\n"
0029 "mrc p15, 0, %1, c15, c0, 1\n"
0030 : "=r" (cp15_save_power), "=r" (cp15_save_diag)
0031 : : "cc");
0032 }
0033
0034 static int exynos_do_idle(unsigned long mode)
0035 {
0036 switch (mode) {
0037 case FW_DO_IDLE_AFTR:
0038 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
0039 exynos_save_cp15();
0040 writel_relaxed(__pa_symbol(exynos_cpu_resume_ns),
0041 sysram_ns_base_addr + 0x24);
0042 writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
0043 if (soc_is_exynos3250()) {
0044 flush_cache_all();
0045 exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
0046 SMC_POWERSTATE_IDLE, 0);
0047 exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
0048 SMC_POWERSTATE_IDLE, 0);
0049 } else
0050 exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
0051 break;
0052 case FW_DO_IDLE_SLEEP:
0053 exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
0054 }
0055 return 0;
0056 }
0057
0058 static int exynos_cpu_boot(int cpu)
0059 {
0060
0061
0062
0063
0064
0065
0066 if (!soc_is_exynos4210() && !soc_is_exynos4412())
0067 return 0;
0068
0069
0070
0071
0072 exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
0073 return 0;
0074 }
0075
0076 static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
0077 {
0078 void __iomem *boot_reg;
0079
0080 if (!sysram_ns_base_addr)
0081 return -ENODEV;
0082
0083 boot_reg = sysram_ns_base_addr + 0x1c;
0084
0085
0086
0087
0088
0089
0090 if (soc_is_exynos4412())
0091 boot_reg += 4 * cpu;
0092
0093 writel_relaxed(boot_addr, boot_reg);
0094 return 0;
0095 }
0096
0097 static int exynos_get_cpu_boot_addr(int cpu, unsigned long *boot_addr)
0098 {
0099 void __iomem *boot_reg;
0100
0101 if (!sysram_ns_base_addr)
0102 return -ENODEV;
0103
0104 boot_reg = sysram_ns_base_addr + 0x1c;
0105
0106 if (soc_is_exynos4412())
0107 boot_reg += 4 * cpu;
0108
0109 *boot_addr = readl_relaxed(boot_reg);
0110 return 0;
0111 }
0112
0113 static int exynos_cpu_suspend(unsigned long arg)
0114 {
0115 flush_cache_all();
0116 outer_flush_all();
0117
0118 exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
0119
0120 pr_info("Failed to suspend the system\n");
0121 writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
0122 return 1;
0123 }
0124
0125 static int exynos_suspend(void)
0126 {
0127 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
0128 exynos_save_cp15();
0129
0130 writel(EXYNOS_SLEEP_MAGIC, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
0131 writel(__pa_symbol(exynos_cpu_resume_ns),
0132 sysram_ns_base_addr + EXYNOS_BOOT_ADDR);
0133
0134 return cpu_suspend(0, exynos_cpu_suspend);
0135 }
0136
0137 static int exynos_resume(void)
0138 {
0139 writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
0140
0141 return 0;
0142 }
0143
0144 static const struct firmware_ops exynos_firmware_ops = {
0145 .do_idle = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL,
0146 .set_cpu_boot_addr = exynos_set_cpu_boot_addr,
0147 .get_cpu_boot_addr = exynos_get_cpu_boot_addr,
0148 .cpu_boot = exynos_cpu_boot,
0149 .suspend = IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL,
0150 .resume = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,
0151 };
0152
0153 static void exynos_l2_write_sec(unsigned long val, unsigned reg)
0154 {
0155 static int l2cache_enabled;
0156
0157 switch (reg) {
0158 case L2X0_CTRL:
0159 if (val & L2X0_CTRL_EN) {
0160
0161
0162
0163
0164 if (!l2cache_enabled) {
0165 exynos_smc(SMC_CMD_L2X0INVALL, 0, 0, 0);
0166 l2cache_enabled = 1;
0167 }
0168 } else {
0169 l2cache_enabled = 0;
0170 }
0171 exynos_smc(SMC_CMD_L2X0CTRL, val, 0, 0);
0172 break;
0173
0174 case L2X0_DEBUG_CTRL:
0175 exynos_smc(SMC_CMD_L2X0DEBUG, val, 0, 0);
0176 break;
0177
0178 default:
0179 WARN_ONCE(1, "%s: ignoring write to reg 0x%x\n", __func__, reg);
0180 }
0181 }
0182
0183 static void exynos_l2_configure(const struct l2x0_regs *regs)
0184 {
0185 exynos_smc(SMC_CMD_L2X0SETUP1, regs->tag_latency, regs->data_latency,
0186 regs->prefetch_ctrl);
0187 exynos_smc(SMC_CMD_L2X0SETUP2, regs->pwr_ctrl, regs->aux_ctrl, 0);
0188 }
0189
0190 bool __init exynos_secure_firmware_available(void)
0191 {
0192 struct device_node *nd;
0193 const __be32 *addr;
0194
0195 nd = of_find_compatible_node(NULL, NULL,
0196 "samsung,secure-firmware");
0197 if (!nd)
0198 return false;
0199
0200 addr = of_get_address(nd, 0, NULL, NULL);
0201 of_node_put(nd);
0202 if (!addr) {
0203 pr_err("%s: No address specified.\n", __func__);
0204 return false;
0205 }
0206
0207 return true;
0208 }
0209
0210 void __init exynos_firmware_init(void)
0211 {
0212 if (!exynos_secure_firmware_available())
0213 return;
0214
0215 pr_info("Running under secure firmware.\n");
0216
0217 register_firmware_ops(&exynos_firmware_ops);
0218
0219
0220
0221
0222
0223
0224
0225 if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
0226 read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
0227 outer_cache.write_sec = exynos_l2_write_sec;
0228 outer_cache.configure = exynos_l2_configure;
0229 }
0230 }
0231
0232 #define REG_CPU_STATE_ADDR (sysram_ns_base_addr + 0x28)
0233 #define BOOT_MODE_MASK 0x1f
0234
0235 void exynos_set_boot_flag(unsigned int cpu, unsigned int mode)
0236 {
0237 unsigned int tmp;
0238
0239 tmp = readl_relaxed(REG_CPU_STATE_ADDR + cpu * 4);
0240
0241 if (mode & BOOT_MODE_MASK)
0242 tmp &= ~BOOT_MODE_MASK;
0243
0244 tmp |= mode;
0245 writel_relaxed(tmp, REG_CPU_STATE_ADDR + cpu * 4);
0246 }
0247
0248 void exynos_clear_boot_flag(unsigned int cpu, unsigned int mode)
0249 {
0250 unsigned int tmp;
0251
0252 tmp = readl_relaxed(REG_CPU_STATE_ADDR + cpu * 4);
0253 tmp &= ~mode;
0254 writel_relaxed(tmp, REG_CPU_STATE_ADDR + cpu * 4);
0255 }