select HAVE_S3C_RTC if RTC_CLASS
select NEED_MACH_MEMORY_H
select SPARSE_IRQ
+ select SRAM
select USE_OF
help
Support for SAMSUNG's EXYNOS SoCs (EXYNOS4/5)
bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rw rootwait earlyprintk panic=5 maxcpus=1";
};
+ sysram@02020000 {
+ smp-sysram@0 {
+ status = "disabled";
+ };
+
+ smp-sysram@5000 {
+ compatible = "samsung,exynos4210-sysram";
+ reg = <0x5000 0x1000>;
+ };
+
+ smp-sysram@1f000 {
+ status = "disabled";
+ };
+ };
+
mct@10050000 {
compatible = "none";
};
pinctrl2 = &pinctrl_2;
};
+ sysram@02020000 {
+ compatible = "mmio-sram";
+ reg = <0x02020000 0x20000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x02020000 0x20000>;
+
+ smp-sysram@0 {
+ compatible = "samsung,exynos4210-sysram";
+ reg = <0x0 0x1000>;
+ };
+
+ smp-sysram@1f000 {
+ compatible = "samsung,exynos4210-sysram-ns";
+ reg = <0x1f000 0x1000>;
+ };
+ };
+
pd_lcd1: lcd1-power-domain@10023CA0 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023CA0 0x20>;
interrupts = <2 2>, <3 2>, <18 2>, <19 2>;
};
+ sysram@02020000 {
+ compatible = "mmio-sram";
+ reg = <0x02020000 0x40000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x02020000 0x40000>;
+
+ smp-sysram@0 {
+ compatible = "samsung,exynos4210-sysram";
+ reg = <0x0 0x1000>;
+ };
+
+ smp-sysram@2f000 {
+ compatible = "samsung,exynos4210-sysram-ns";
+ reg = <0x2f000 0x1000>;
+ };
+ };
+
pd_isp: isp-power-domain@10023CA0 {
compatible = "samsung,exynos4210-pd";
reg = <0x10023CA0 0x20>;
};
};
+ sysram@02020000 {
+ compatible = "mmio-sram";
+ reg = <0x02020000 0x30000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x02020000 0x30000>;
+
+ smp-sysram@0 {
+ compatible = "samsung,exynos4210-sysram";
+ reg = <0x0 0x1000>;
+ };
+
+ smp-sysram@2f000 {
+ compatible = "samsung,exynos4210-sysram-ns";
+ reg = <0x2f000 0x1000>;
+ };
+ };
+
pd_gsc: gsc-power-domain@10044000 {
compatible = "samsung,exynos4210-pd";
reg = <0x10044000 0x20>;
};
};
+ sysram@02020000 {
+ compatible = "mmio-sram";
+ reg = <0x02020000 0x54000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x02020000 0x54000>;
+
+ smp-sysram@0 {
+ compatible = "samsung,exynos4210-sysram";
+ reg = <0x0 0x1000>;
+ };
+
+ smp-sysram@53000 {
+ compatible = "samsung,exynos4210-sysram-ns";
+ reg = <0x53000 0x1000>;
+ };
+ };
+
clock: clock-controller@10010000 {
compatible = "samsung,exynos5420-clock";
reg = <0x10010000 0x30000>;
void mct_init(void __iomem *base, int irq_g0, int irq_l0, int irq_l1);
struct map_desc;
+extern void __iomem *sysram_ns_base_addr;
void exynos_init_io(void);
void exynos_restart(enum reboot_mode mode, const char *cmd);
void exynos_cpuidle_init(void);
},
};
-static struct map_desc exynos4_iodesc0[] __initdata = {
- {
- .virtual = (unsigned long)S5P_VA_SYSRAM,
- .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM0),
- .length = SZ_4K,
- .type = MT_DEVICE,
- },
-};
-
-static struct map_desc exynos4_iodesc1[] __initdata = {
- {
- .virtual = (unsigned long)S5P_VA_SYSRAM,
- .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM1),
- .length = SZ_4K,
- .type = MT_DEVICE,
- },
-};
-
-static struct map_desc exynos4210_iodesc[] __initdata = {
- {
- .virtual = (unsigned long)S5P_VA_SYSRAM_NS,
- .pfn = __phys_to_pfn(EXYNOS4210_PA_SYSRAM_NS),
- .length = SZ_4K,
- .type = MT_DEVICE,
- },
-};
-
-static struct map_desc exynos4x12_iodesc[] __initdata = {
- {
- .virtual = (unsigned long)S5P_VA_SYSRAM_NS,
- .pfn = __phys_to_pfn(EXYNOS4x12_PA_SYSRAM_NS),
- .length = SZ_4K,
- .type = MT_DEVICE,
- },
-};
-
-static struct map_desc exynos5250_iodesc[] __initdata = {
- {
- .virtual = (unsigned long)S5P_VA_SYSRAM_NS,
- .pfn = __phys_to_pfn(EXYNOS5250_PA_SYSRAM_NS),
- .length = SZ_4K,
- .type = MT_DEVICE,
- },
-};
-
static struct map_desc exynos5_iodesc[] __initdata = {
{
.virtual = (unsigned long)S3C_VA_SYS,
.pfn = __phys_to_pfn(EXYNOS5_PA_SROMC),
.length = SZ_4K,
.type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S5P_VA_SYSRAM,
- .pfn = __phys_to_pfn(EXYNOS5_PA_SYSRAM),
- .length = SZ_4K,
- .type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_CMU,
.pfn = __phys_to_pfn(EXYNOS5_PA_CMU),
if (soc_is_exynos5())
iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
-
- if (soc_is_exynos4210()) {
- if (samsung_rev() == EXYNOS4210_REV_0)
- iotable_init(exynos4_iodesc0,
- ARRAY_SIZE(exynos4_iodesc0));
- else
- iotable_init(exynos4_iodesc1,
- ARRAY_SIZE(exynos4_iodesc1));
- iotable_init(exynos4210_iodesc, ARRAY_SIZE(exynos4210_iodesc));
- }
- if (soc_is_exynos4212() || soc_is_exynos4412())
- iotable_init(exynos4x12_iodesc, ARRAY_SIZE(exynos4x12_iodesc));
- if (soc_is_exynos5250())
- iotable_init(exynos5250_iodesc, ARRAY_SIZE(exynos5250_iodesc));
}
void __init exynos_init_io(void)
#include <mach/map.h>
+#include "common.h"
#include "smc.h"
static int exynos_do_idle(void)
static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
{
- void __iomem *boot_reg = S5P_VA_SYSRAM_NS + 0x1c + 4*cpu;
+ void __iomem *boot_reg;
+
+ if (!sysram_ns_base_addr)
+ return -ENODEV;
+
+ boot_reg = sysram_ns_base_addr + 0x1c + 4*cpu;
__raw_writel(boot_addr, boot_reg);
return 0;
#include <plat/map-s5p.h>
-#define EXYNOS4_PA_SYSRAM0 0x02025000
-#define EXYNOS4_PA_SYSRAM1 0x02020000
-#define EXYNOS5_PA_SYSRAM 0x02020000
-#define EXYNOS4210_PA_SYSRAM_NS 0x0203F000
-#define EXYNOS4x12_PA_SYSRAM_NS 0x0204F000
-#define EXYNOS5250_PA_SYSRAM_NS 0x0204F000
-
#define EXYNOS_PA_CHIPID 0x10000000
#define EXYNOS4_PA_SYSCON 0x10010000
#include <linux/jiffies.h>
#include <linux/smp.h>
#include <linux/io.h>
+#include <linux/of_address.h>
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
extern void exynos4_secondary_startup(void);
+static void __iomem *sysram_base_addr;
+void __iomem *sysram_ns_base_addr;
+
+static void __init exynos_smp_prepare_sysram(void)
+{
+ struct device_node *node;
+
+ for_each_compatible_node(node, NULL, "samsung,exynos4210-sysram") {
+ if (!of_device_is_available(node))
+ continue;
+ sysram_base_addr = of_iomap(node, 0);
+ break;
+ }
+
+ for_each_compatible_node(node, NULL, "samsung,exynos4210-sysram-ns") {
+ if (!of_device_is_available(node))
+ continue;
+ sysram_ns_base_addr = of_iomap(node, 0);
+ break;
+ }
+}
+
static inline void __iomem *cpu_boot_reg_base(void)
{
if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
return S5P_INFORM5;
- return S5P_VA_SYSRAM;
+ return sysram_base_addr;
}
static inline void __iomem *cpu_boot_reg(int cpu)
void __iomem *boot_reg;
boot_reg = cpu_boot_reg_base();
+ if (!boot_reg)
+ return ERR_PTR(-ENODEV);
if (soc_is_exynos4412())
boot_reg += 4*cpu;
else if (soc_is_exynos5420())
{
unsigned long timeout;
unsigned long phys_cpu = cpu_logical_map(cpu);
+ int ret = -ENOSYS;
/*
* Set synchronisation state between this boot processor
* Try to set boot address using firmware first
* and fall back to boot register if it fails.
*/
- if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr))
+ ret = call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr);
+ if (ret && ret != -ENOSYS)
+ goto fail;
+ if (ret == -ENOSYS) {
+ void __iomem *boot_reg = cpu_boot_reg(phys_cpu);
+
+ if (IS_ERR(boot_reg)) {
+ ret = PTR_ERR(boot_reg);
+ goto fail;
+ }
__raw_writel(boot_addr, cpu_boot_reg(phys_cpu));
+ }
call_firmware_op(cpu_boot, phys_cpu);
* now the secondary core is starting up let it run its
* calibrations, then wait for it to finish
*/
+fail:
spin_unlock(&boot_lock);
- return pen_release != -1 ? -ENOSYS : 0;
+ return pen_release != -1 ? ret : 0;
}
/*
if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9)
scu_enable(scu_base_addr());
+ exynos_smp_prepare_sysram();
+
/*
* Write the address of secondary startup into the
* system-wide flags register. The boot monitor waits
for (i = 1; i < max_cpus; ++i) {
unsigned long phys_cpu;
unsigned long boot_addr;
+ int ret;
phys_cpu = cpu_logical_map(i);
boot_addr = virt_to_phys(exynos4_secondary_startup);
- if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr))
+ ret = call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr);
+ if (ret && ret != -ENOSYS)
+ break;
+ if (ret == -ENOSYS) {
+ void __iomem *boot_reg = cpu_boot_reg(phys_cpu);
+
+ if (IS_ERR(boot_reg))
+ break;
__raw_writel(boot_addr, cpu_boot_reg(phys_cpu));
+ }
}
}