aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-exynos
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-exynos')
-rw-r--r--arch/arm/mach-exynos/Kconfig13
-rw-r--r--arch/arm/mach-exynos/common.h18
-rw-r--r--arch/arm/mach-exynos/exynos.c42
-rw-r--r--arch/arm/mach-exynos/firmware.c14
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h2
-rw-r--r--arch/arm/mach-exynos/platsmp.c27
-rw-r--r--arch/arm/mach-exynos/pm.c12
-rw-r--r--arch/arm/mach-exynos/suspend.c41
8 files changed, 72 insertions, 97 deletions
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 647c319f9f5f..b40963cf91c7 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -8,7 +8,6 @@
menuconfig ARCH_EXYNOS
bool "Samsung EXYNOS"
depends on ARCH_MULTI_V7
- select ARCH_HAS_BANDGAP
select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_AMBA
@@ -108,18 +107,6 @@ config SOC_EXYNOS5420
default y
depends on ARCH_EXYNOS5
-config SOC_EXYNOS5440
- bool "SAMSUNG EXYNOS5440"
- default y
- depends on ARCH_EXYNOS5
- select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
- select HAVE_ARM_ARCH_TIMER
- select AUTO_ZRELADDR
- select PINCTRL_EXYNOS5440
- select PM_OPP
- help
- Enable EXYNOS5440 SoC support
-
config SOC_EXYNOS5800
bool "SAMSUNG EXYNOS5800"
default y
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 098f84a149a3..f96730cce6e8 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -21,7 +21,6 @@
#define EXYNOS5250_SOC_ID 0x43520000
#define EXYNOS5410_SOC_ID 0xE5410000
#define EXYNOS5420_SOC_ID 0xE5420000
-#define EXYNOS5440_SOC_ID 0xE5440000
#define EXYNOS5800_SOC_ID 0xE5422000
#define EXYNOS5_SOC_MASK 0xFFFFF000
@@ -39,7 +38,6 @@ IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK)
IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_SOC_ID, EXYNOS5_SOC_MASK)
IS_SAMSUNG_CPU(exynos5410, EXYNOS5410_SOC_ID, EXYNOS5_SOC_MASK)
IS_SAMSUNG_CPU(exynos5420, EXYNOS5420_SOC_ID, EXYNOS5_SOC_MASK)
-IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
#if defined(CONFIG_SOC_EXYNOS3250)
@@ -82,22 +80,12 @@ IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
# define soc_is_exynos5420() 0
#endif
-#if defined(CONFIG_SOC_EXYNOS5440)
-# define soc_is_exynos5440() is_samsung_exynos5440()
-#else
-# define soc_is_exynos5440() 0
-#endif
-
#if defined(CONFIG_SOC_EXYNOS5800)
# define soc_is_exynos5800() is_samsung_exynos5800()
#else
# define soc_is_exynos5800() 0
#endif
-#define soc_is_exynos4() (soc_is_exynos4210() || soc_is_exynos4412())
-#define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \
- soc_is_exynos5420() || soc_is_exynos5800())
-
extern u32 cp15_save_diag;
extern u32 cp15_save_power;
@@ -122,6 +110,7 @@ void exynos_firmware_init(void);
#define EXYNOS_SLEEP_MAGIC 0x00000bad
#define EXYNOS_AFTR_MAGIC 0xfcba0d10
+bool __init exynos_secure_firmware_available(void);
void exynos_set_boot_flag(unsigned int cpu, unsigned int mode);
void exynos_clear_boot_flag(unsigned int cpu, unsigned int mode);
@@ -149,6 +138,11 @@ extern void exynos_cpu_restore_register(void);
extern void exynos_pm_central_suspend(void);
extern int exynos_pm_central_resume(void);
extern void exynos_enter_aftr(void);
+#ifdef CONFIG_SMP
+extern void exynos_scu_enable(void);
+#else
+static inline void exynos_scu_enable(void) { }
+#endif
extern struct cpuidle_exynos_data cpuidle_coupled_exynos_data;
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index fbd108ce8745..865dcc4c3181 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -24,15 +24,6 @@
#include "common.h"
-static struct map_desc exynos4_iodesc[] __initdata = {
- {
- .virtual = (unsigned long)S5P_VA_COREPERI_BASE,
- .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI),
- .length = SZ_8K,
- .type = MT_DEVICE,
- },
-};
-
static struct platform_device exynos_cpuidle = {
.name = "exynos_cpuidle",
#ifdef CONFIG_ARM_EXYNOS_CPUIDLE
@@ -63,15 +54,6 @@ void __init exynos_sysram_init(void)
}
}
-static void __init exynos_init_late(void)
-{
- if (of_machine_is_compatible("samsung,exynos5440"))
- /* to be supported later */
- return;
-
- exynos_pm_init();
-}
-
static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
int depth, void *data)
{
@@ -79,8 +61,7 @@ static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
const __be32 *reg;
int len;
- if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
- !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
+ if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid"))
return 0;
reg = of_get_flat_dt_prop(node, "reg", &len);
@@ -95,17 +76,6 @@ static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
return 1;
}
-/*
- * exynos_map_io
- *
- * register the standard cpu IO areas
- */
-static void __init exynos_map_io(void)
-{
- if (soc_is_exynos4())
- iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
-}
-
static void __init exynos_init_io(void)
{
debug_ll_io_init();
@@ -114,8 +84,6 @@ static void __init exynos_init_io(void)
/* detect cpu id and rev. */
s5p_init_cpu(S5P_VA_CHIPID);
-
- exynos_map_io();
}
/*
@@ -192,7 +160,8 @@ static void __init exynos_dt_machine_init(void)
#endif
if (of_machine_is_compatible("samsung,exynos4210") ||
(of_machine_is_compatible("samsung,exynos4412") &&
- of_machine_is_compatible("samsung,trats2")) ||
+ (of_machine_is_compatible("samsung,trats2") ||
+ of_machine_is_compatible("samsung,midas"))) ||
of_machine_is_compatible("samsung,exynos3250") ||
of_machine_is_compatible("samsung,exynos5250"))
platform_device_register(&exynos_cpuidle);
@@ -208,7 +177,6 @@ static char const *const exynos_dt_compat[] __initconst = {
"samsung,exynos5250",
"samsung,exynos5260",
"samsung,exynos5420",
- "samsung,exynos5440",
NULL
};
@@ -222,8 +190,6 @@ static void __init exynos_dt_fixup(void)
}
DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
- /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
- /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
.l2c_aux_val = 0x3c400001,
.l2c_aux_mask = 0xc20fffff,
.smp = smp_ops(exynos_smp_ops),
@@ -231,7 +197,7 @@ DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
.init_early = exynos_firmware_init,
.init_irq = exynos_init_irq,
.init_machine = exynos_dt_machine_init,
- .init_late = exynos_init_late,
+ .init_late = exynos_pm_init,
.dt_compat = exynos_dt_compat,
.dt_fixup = exynos_dt_fixup,
MACHINE_END
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index be1f20fe28f4..d602e3bf3f96 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -185,7 +185,7 @@ static void exynos_l2_configure(const struct l2x0_regs *regs)
exynos_smc(SMC_CMD_L2X0SETUP2, regs->pwr_ctrl, regs->aux_ctrl, 0);
}
-void __init exynos_firmware_init(void)
+bool __init exynos_secure_firmware_available(void)
{
struct device_node *nd;
const __be32 *addr;
@@ -193,14 +193,22 @@ void __init exynos_firmware_init(void)
nd = of_find_compatible_node(NULL, NULL,
"samsung,secure-firmware");
if (!nd)
- return;
+ return false;
addr = of_get_address(nd, 0, NULL, NULL);
if (!addr) {
pr_err("%s: No address specified.\n", __func__);
- return;
+ return false;
}
+ return true;
+}
+
+void __init exynos_firmware_init(void)
+{
+ if (!exynos_secure_firmware_available())
+ return;
+
pr_info("Running under secure firmware.\n");
register_firmware_ops(&exynos_firmware_ops);
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 37a5ea5e2602..22ebe3654633 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -15,6 +15,4 @@
#define EXYNOS_PA_CHIPID 0x10000000
-#define EXYNOS4_PA_COREPERI 0x10500000
-
#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 5156fe70e030..6a1e682371b3 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -163,6 +163,26 @@ int exynos_cluster_power_state(int cluster)
S5P_CORE_LOCAL_PWR_EN);
}
+/**
+ * exynos_scu_enable : enables SCU for Cortex-A9 based system
+ */
+void exynos_scu_enable(void)
+{
+ struct device_node *np;
+ static void __iomem *scu_base;
+
+ if (!scu_base) {
+ np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+ if (np) {
+ scu_base = of_iomap(np, 0);
+ of_node_put(np);
+ } else {
+ scu_base = ioremap(scu_a9_get_base(), SZ_4K);
+ }
+ }
+ scu_enable(scu_base);
+}
+
static void __iomem *cpu_boot_reg_base(void)
{
if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
@@ -219,11 +239,6 @@ static void write_pen_release(int val)
sync_cache_w(&pen_release);
}
-static void __iomem *scu_base_addr(void)
-{
- return (void __iomem *)(S5P_VA_SCU);
-}
-
static DEFINE_SPINLOCK(boot_lock);
static void exynos_secondary_init(unsigned int cpu)
@@ -389,7 +404,7 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
exynos_set_delayed_reset_assertion(true);
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
- scu_enable(scu_base_addr());
+ exynos_scu_enable();
/*
* Write the address of secondary startup into the
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index dc4346ecf16d..48e7fb38613e 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -22,8 +22,6 @@
#include <asm/suspend.h>
#include <asm/cacheflush.h>
-#include <mach/map.h>
-
#include "common.h"
static inline void __iomem *exynos_boot_vector_addr(void)
@@ -163,7 +161,7 @@ void exynos_enter_aftr(void)
exynos_pm_central_suspend();
- if (of_machine_is_compatible("samsung,exynos4412")) {
+ if (soc_is_exynos4412()) {
/* Setting SEQ_OPTION register */
pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0,
S5P_CENTRAL_SEQ_OPTION);
@@ -172,7 +170,7 @@ void exynos_enter_aftr(void)
cpu_suspend(0, exynos_aftr_finisher);
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
- scu_enable(S5P_VA_SCU);
+ exynos_scu_enable();
if (call_firmware_op(resume) == -ENOSYS)
exynos_cpu_restore_register();
}
@@ -271,11 +269,7 @@ abort:
goto fail;
call_firmware_op(cpu_boot, 1);
-
- if (soc_is_exynos3250())
- dsb_sev();
- else
- arch_send_wakeup_ipi_mask(cpumask_of(1));
+ dsb_sev();
}
}
fail:
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
index c2ed997fedef..bb8e3985acdb 100644
--- a/arch/arm/mach-exynos/suspend.c
+++ b/arch/arm/mach-exynos/suspend.c
@@ -30,8 +30,6 @@
#include <asm/smp_scu.h>
#include <asm/suspend.h>
-#include <mach/map.h>
-
#include <plat/pm-common.h>
#include "common.h"
@@ -61,10 +59,15 @@ struct exynos_pm_data {
int (*cpu_suspend)(unsigned long);
};
-static const struct exynos_pm_data *pm_data __ro_after_init;
+/* Used only on Exynos542x/5800 */
+struct exynos_pm_state {
+ int cpu_state;
+ unsigned int pmu_spare3;
+ void __iomem *sysram_base;
+};
-static int exynos5420_cpu_state;
-static unsigned int exynos_pmu_spare3;
+static const struct exynos_pm_data *pm_data __ro_after_init;
+static struct exynos_pm_state pm_state;
/*
* GIC wake-up support
@@ -205,6 +208,7 @@ static int __init exynos_pmu_irq_init(struct device_node *node,
NULL);
if (!domain) {
iounmap(pmu_base_addr);
+ pmu_base_addr = NULL;
return -ENOMEM;
}
@@ -258,7 +262,7 @@ static int exynos5420_cpu_suspend(unsigned long arg)
unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
- writel_relaxed(0x0, sysram_base_addr + EXYNOS5420_CPU_STATE);
+ writel_relaxed(0x0, pm_state.sysram_base + EXYNOS5420_CPU_STATE);
if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) {
mcpm_set_entry_vector(cpu, cluster, exynos_cpu_resume);
@@ -274,7 +278,7 @@ static int exynos5420_cpu_suspend(unsigned long arg)
static void exynos_pm_set_wakeup_mask(void)
{
/* Set wake-up mask registers */
- pmu_raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
+ pmu_raw_writel(exynos_get_eint_wake_mask(), EXYNOS_EINT_WAKEUP_MASK);
pmu_raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
}
@@ -322,7 +326,7 @@ static void exynos5420_pm_prepare(void)
/* Set wake-up mask registers */
exynos_pm_set_wakeup_mask();
- exynos_pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3);
+ pm_state.pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3);
/*
* The cpu state needs to be saved and restored so that the
* secondary CPUs will enter low power start. Though the U-Boot
@@ -330,8 +334,8 @@ static void exynos5420_pm_prepare(void)
* needs to restore it back in case, the primary cpu fails to
* suspend for any reason.
*/
- exynos5420_cpu_state = readl_relaxed(sysram_base_addr +
- EXYNOS5420_CPU_STATE);
+ pm_state.cpu_state = readl_relaxed(pm_state.sysram_base +
+ EXYNOS5420_CPU_STATE);
exynos_pm_enter_sleep_mode();
@@ -401,7 +405,7 @@ static void exynos_pm_resume(void)
goto early_wakeup;
if (cpuid == ARM_CPU_PART_CORTEX_A9)
- scu_enable(S5P_VA_SCU);
+ exynos_scu_enable();
if (call_firmware_op(resume) == -ENOSYS
&& cpuid == ARM_CPU_PART_CORTEX_A9)
@@ -449,8 +453,8 @@ static void exynos5420_pm_resume(void)
EXYNOS5_ARM_CORE0_SYS_PWR_REG);
/* Restore the sysram cpu state register */
- writel_relaxed(exynos5420_cpu_state,
- sysram_base_addr + EXYNOS5420_CPU_STATE);
+ writel_relaxed(pm_state.cpu_state,
+ pm_state.sysram_base + EXYNOS5420_CPU_STATE);
pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL,
S5P_CENTRAL_SEQ_OPTION);
@@ -458,7 +462,7 @@ static void exynos5420_pm_resume(void)
if (exynos_pm_central_resume())
goto early_wakeup;
- pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3);
+ pmu_raw_writel(pm_state.pmu_spare3, S5P_PMU_SPARE3);
early_wakeup:
@@ -655,4 +659,13 @@ void __init exynos_pm_init(void)
register_syscore_ops(&exynos_pm_syscore_ops);
suspend_set_ops(&exynos_suspend_ops);
+
+ /*
+ * Applicable as of now only to Exynos542x. If booted under secure
+ * firmware, the non-secure region of sysram should be used.
+ */
+ if (exynos_secure_firmware_available())
+ pm_state.sysram_base = sysram_ns_base_addr;
+ else
+ pm_state.sysram_base = sysram_base_addr;
}