Skip to content

Commit

Permalink
ARM: EXYNOS: Map SYSRAM through generic DT bindings
Browse files Browse the repository at this point in the history
Instead of hardcoding the SYSRAM details for each SoC,
pass this information through device tree (DT) and make
the code SoC agnostic. Generic DT SRAM bindings are
used for achieving this.

Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
  • Loading branch information
Sachin Kamat authored and kgene committed May 14, 2014
1 parent 3528dd3 commit b3205de
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 76 deletions.
1 change: 1 addition & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,7 @@ config ARCH_EXYNOS
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)
Expand Down
15 changes: 15 additions & 0 deletions arch/arm/boot/dts/exynos4210-universal_c210.dts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@
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";
};
Expand Down
18 changes: 18 additions & 0 deletions arch/arm/boot/dts/exynos4210.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,24 @@
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>;
Expand Down
18 changes: 18 additions & 0 deletions arch/arm/boot/dts/exynos4x12.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,24 @@
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>;
Expand Down
18 changes: 18 additions & 0 deletions arch/arm/boot/dts/exynos5250.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,24 @@
};
};

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>;
Expand Down
18 changes: 18 additions & 0 deletions arch/arm/boot/dts/exynos5420.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,24 @@
};
};

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>;
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-exynos/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
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);
Expand Down
64 changes: 0 additions & 64 deletions arch/arm/mach-exynos/exynos.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,51 +114,6 @@ static struct map_desc exynos4_iodesc[] __initdata = {
},
};

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,
Expand All @@ -180,11 +135,6 @@ static struct map_desc exynos5_iodesc[] __initdata = {
.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),
Expand Down Expand Up @@ -280,20 +230,6 @@ static void __init exynos_map_io(void)

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)
Expand Down
8 changes: 7 additions & 1 deletion arch/arm/mach-exynos/firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include <mach/map.h>

#include "common.h"
#include "smc.h"

static int exynos_do_idle(void)
Expand All @@ -34,7 +35,12 @@ static int exynos_cpu_boot(int cpu)

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;
Expand Down
7 changes: 0 additions & 7 deletions arch/arm/mach-exynos/include/mach/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,6 @@

#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
Expand Down
56 changes: 52 additions & 4 deletions arch/arm/mach-exynos/platsmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#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>
Expand All @@ -33,18 +34,42 @@

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())
Expand Down Expand Up @@ -90,6 +115,7 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;
unsigned long phys_cpu = cpu_logical_map(cpu);
int ret = -ENOSYS;

/*
* Set synchronisation state between this boot processor
Expand Down Expand Up @@ -146,8 +172,18 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
* 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);

Expand All @@ -163,9 +199,10 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
* 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;
}

/*
Expand Down Expand Up @@ -205,6 +242,8 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
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
Expand All @@ -217,12 +256,21 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
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));
}
}
}

Expand Down

0 comments on commit b3205de

Please sign in to comment.