summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mvebu
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2017-02-14 11:53:58 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2017-02-16 08:16:27 +0100
commitf05c6e095cf8e8c97e1df5d79f65e4d7c30c788f (patch)
treee2bab6ef3587e0b78306465dd824a7382cca7a3b /arch/arm/mach-mvebu
parentdc904720553c6ddd80975cfc488a183d6d391dc5 (diff)
downloadbarebox-f05c6e095cf8e8c97e1df5d79f65e4d7c30c788f.tar.gz
barebox-f05c6e095cf8e8c97e1df5d79f65e4d7c30c788f.tar.xz
mvebu: rework how memory is detected
Status quo is that initially a size of 64 MiB is assumed (which is also used to determine the size of the malloc area) and then later the dtb is fixed up with the actually available RAM which is then used. Instead detect the real RAM size earlier and don't fixup the device tree. The device tree is fixed up instead by generic code. This way the malloc area is more appropriately sized and RAM detection is more similar to mach-imx which is both nice. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-mvebu')
-rw-r--r--arch/arm/mach-mvebu/Makefile3
-rw-r--r--arch/arm/mach-mvebu/armada-370-xp.c27
-rw-r--r--arch/arm/mach-mvebu/common.c153
-rw-r--r--arch/arm/mach-mvebu/dove.c31
-rw-r--r--arch/arm/mach-mvebu/include/mach/common.h2
-rw-r--r--arch/arm/mach-mvebu/include/mach/lowlevel.h3
-rw-r--r--arch/arm/mach-mvebu/kirkwood.c28
-rw-r--r--arch/arm/mach-mvebu/lowlevel.c59
8 files changed, 124 insertions, 182 deletions
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index 80b3947cc8..2cf0dfed47 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -1,5 +1,4 @@
-lwl-y += lowlevel.o
-obj-y += common.o
+obj-pbl-y += common.o
obj-$(CONFIG_ARCH_ARMADA_370) += armada-370-xp.o
obj-$(CONFIG_ARCH_ARMADA_XP) += armada-370-xp.o
obj-$(CONFIG_ARCH_DOVE) += dove.o
diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c
index cc0d7bd612..5fb207594f 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.c
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
@@ -25,29 +25,6 @@
#include <mach/armada-370-xp-regs.h>
#include <mach/socid.h>
-static inline void armada_370_xp_memory_find(unsigned long *phys_base,
- unsigned long *phys_size)
-{
- int cs;
-
- *phys_base = ~0;
- *phys_size = 0;
-
- for (cs = 0; cs < 4; cs++) {
- u32 base = readl(ARMADA_370_XP_SDRAM_BASE + DDR_BASE_CSn(cs));
- u32 ctrl = readl(ARMADA_370_XP_SDRAM_BASE + DDR_SIZE_CSn(cs));
-
- /* Skip non-enabled CS */
- if ((ctrl & DDR_SIZE_ENABLED) != DDR_SIZE_ENABLED)
- continue;
-
- base &= DDR_BASE_CS_LOW_MASK;
- if (base < *phys_base)
- *phys_base = base;
- *phys_size += (ctrl | ~DDR_SIZE_MASK) + 1;
- }
-}
-
static const struct of_device_id armada_370_xp_pcie_of_ids[] = {
{ .compatible = "marvell,armada-xp-pcie", },
{ .compatible = "marvell,armada-370-pcie", },
@@ -120,7 +97,6 @@ static int armada_xp_init_soc(struct device_node *root)
static int armada_370_xp_init_soc(struct device_node *root, void *context)
{
- unsigned long phys_base, phys_size;
u32 reg;
if (!of_machine_is_compatible("marvell,armada-370-xp"))
@@ -136,9 +112,6 @@ static int armada_370_xp_init_soc(struct device_node *root, void *context)
reg &= ~MBUS_ERR_PROP_EN;
writel(reg, ARMADA_370_XP_FABRIC_CTRL);
- armada_370_xp_memory_find(&phys_base, &phys_size);
-
- mvebu_set_memory(phys_base, phys_size);
mvebu_mbus_init();
armada_xp_soc_id_fixup();
diff --git a/arch/arm/mach-mvebu/common.c b/arch/arm/mach-mvebu/common.c
index cb40d0cb6f..7534d8dd01 100644
--- a/arch/arm/mach-mvebu/common.c
+++ b/arch/arm/mach-mvebu/common.c
@@ -23,6 +23,31 @@
#include <linux/clk.h>
#include <mach/common.h>
#include <mach/socid.h>
+#include <asm/barebox-arm.h>
+#include <asm/memory.h>
+
+/*
+ * The different SoC headers containing register definitions (mach/dove-regs.h,
+ * mach/kirkwood-regs.h and mach/armada-370-xp-regs.h) are pairwise
+ * incompatible. So some defines are reproduced here instead of just #included.
+ */
+
+#define DOVE_SDRAM_BASE IOMEM(0xf1800000)
+#define DOVE_SDRAM_MAPn(n) (0x100 + ((n) * 0x10))
+#define DOVE_SDRAM_MAP_VALID BIT(0)
+#define DOVE_SDRAM_LENGTH_SHIFT 16
+#define DOVE_SDRAM_LENGTH_MASK (0x00f << DOVE_SDRAM_LENGTH_SHIFT)
+
+#define KIRKWOOD_SDRAM_BASE (IOMEM(MVEBU_REMAP_INT_REG_BASE) + 0x00000)
+#define KIRKWOOD_DDR_BASE_CSn(n) (0x1500 + ((n) * 0x8))
+#define KIRKWOOD_DDR_SIZE_CSn(n) (0x1504 + ((n) * 0x8))
+#define KIRKWOOD_DDR_SIZE_ENABLED BIT(0)
+#define KIRKWOOD_DDR_SIZE_MASK 0xff000000
+
+#define ARMADA_370_XP_SDRAM_BASE (IOMEM(MVEBU_REMAP_INT_REG_BASE) + 0x20000)
+#define ARMADA_370_XP_DDR_SIZE_CSn(n) (0x184 + ((n) * 0x8))
+#define ARMADA_370_XP_DDR_SIZE_ENABLED BIT(0)
+#define ARMADA_370_XP_DDR_SIZE_MASK 0xff000000
/*
* Marvell MVEBU SoC id and revision can be read from any PCIe
@@ -78,48 +103,110 @@ static int mvebu_soc_id_init(void)
}
postcore_initcall(mvebu_soc_id_init);
-/*
- * Memory size is set up by BootROM and can be read from SoC's ram controller
- * registers. Fixup provided DTs to reflect accessible amount of directly
- * attached RAM. Removable RAM, e.g. SODIMM, should be added by a per-board
- * fixup.
- */
-int mvebu_set_memory(u64 phys_base, u64 phys_size)
+static unsigned long dove_memory_find(void)
{
- struct device_node *np, *root;
- __be32 reg[4];
- int na, ns;
+ int n;
+ unsigned long mem_size = 0;
- root = of_get_root_node();
- if (!root)
- return -EINVAL;
+ for (n = 0; n < 2; n++) {
+ uint32_t map = readl(DOVE_SDRAM_BASE + DOVE_SDRAM_MAPn(n));
+ uint32_t size;
- np = of_find_node_by_path("/memory");
- if (!np)
- np = of_create_node(root, "/memory");
- if (!np)
- return -EINVAL;
+ /* skip disabled areas */
+ if ((map & DOVE_SDRAM_MAP_VALID) != DOVE_SDRAM_MAP_VALID)
+ continue;
- na = of_n_addr_cells(np);
- ns = of_n_size_cells(np);
+ /* real size is encoded as ld(2^(16+length)) */
+ size = (map & DOVE_SDRAM_LENGTH_MASK) >> DOVE_SDRAM_LENGTH_SHIFT;
+ mem_size += 1 << (16 + size);
+ }
+
+ return mem_size;
+}
+
+static unsigned long kirkwood_memory_find(void)
+{
+ int cs;
+ unsigned long mem_size = 0;
+
+ for (cs = 0; cs < 4; cs++) {
+ u32 ctrl = readl(KIRKWOOD_SDRAM_BASE +
+ KIRKWOOD_DDR_SIZE_CSn(cs));
- if (na == 2) {
- reg[0] = cpu_to_be32(phys_base >> 32);
- reg[1] = cpu_to_be32(phys_base & 0xffffffff);
- } else {
- reg[0] = cpu_to_be32(phys_base & 0xffffffff);
+ /* Skip non-enabled CS */
+ if ((ctrl & KIRKWOOD_DDR_SIZE_ENABLED) !=
+ KIRKWOOD_DDR_SIZE_ENABLED)
+ continue;
+
+ mem_size += (ctrl | ~KIRKWOOD_DDR_SIZE_MASK) + 1;
}
- if (ns == 2) {
- reg[2] = cpu_to_be32(phys_size >> 32);
- reg[3] = cpu_to_be32(phys_size & 0xffffffff);
- } else {
- reg[1] = cpu_to_be32(phys_size & 0xffffffff);
+ return mem_size;
+}
+
+static unsigned long armada_370_xp_memory_find(void)
+{
+ int cs;
+ unsigned long mem_size = 0;
+
+ for (cs = 0; cs < 4; cs++) {
+ u32 ctrl = readl(ARMADA_370_XP_SDRAM_BASE + ARMADA_370_XP_DDR_SIZE_CSn(cs));
+
+ /* Skip non-enabled CS */
+ if ((ctrl & ARMADA_370_XP_DDR_SIZE_ENABLED) != ARMADA_370_XP_DDR_SIZE_ENABLED)
+ continue;
+
+ mem_size += (ctrl | ~ARMADA_370_XP_DDR_SIZE_MASK) + 1;
}
- if (of_set_property(np, "device_type", "memory", sizeof("memory"), 1) ||
- of_set_property(np, "reg", reg, sizeof(u32) * (na + ns), 1))
- pr_err("Unable to fixup memory node\n");
+ return mem_size;
+}
+
+static int mvebu_meminit(void)
+{
+ if (of_machine_is_compatible("marvell,armada-370-xp"))
+ arm_add_mem_device("ram0", 0, armada_370_xp_memory_find());
return 0;
}
+mem_initcall(mvebu_meminit);
+
+/*
+ * All MVEBU SoCs start with internal registers at 0xd0000000.
+ * To get more contiguous address space and as Linux expects them
+ * there, we remap them early to 0xf1000000.
+ *
+ * There no way to determine internal registers base address
+ * safely later on, as the remap register itself is within the
+ * internal registers.
+ */
+#define MVEBU_BOOTUP_INT_REG_BASE 0xd0000000
+#define MVEBU_BRIDGE_REG_BASE 0x20000
+#define DEVICE_INTERNAL_BASE_ADDR (MVEBU_BRIDGE_REG_BASE + 0x80)
+
+static void mvebu_remap_registers(void)
+{
+ writel(MVEBU_REMAP_INT_REG_BASE,
+ IOMEM(MVEBU_BOOTUP_INT_REG_BASE) + DEVICE_INTERNAL_BASE_ADDR);
+}
+
+void __naked __noreturn dove_barebox_entry(void *boarddata)
+{
+ mvebu_remap_registers();
+
+ barebox_arm_entry(0, dove_memory_find(), boarddata);
+}
+
+void __naked __noreturn kirkwood_barebox_entry(void *boarddata)
+{
+ mvebu_remap_registers();
+
+ barebox_arm_entry(0, kirkwood_memory_find(), boarddata);
+}
+
+void __naked __noreturn armada_370_xp_barebox_entry(void *boarddata)
+{
+ mvebu_remap_registers();
+
+ barebox_arm_entry(0, armada_370_xp_memory_find(), boarddata);
+}
diff --git a/arch/arm/mach-mvebu/dove.c b/arch/arm/mach-mvebu/dove.c
index ba4af3aae9..9a3b05d004 100644
--- a/arch/arm/mach-mvebu/dove.c
+++ b/arch/arm/mach-mvebu/dove.c
@@ -43,32 +43,6 @@ static inline void dove_remap_mc_regs(void)
writel(val, mcboot + SDRAM_REGS_BASE_DECODE);
}
-static inline void dove_memory_find(unsigned long *phys_base,
- unsigned long *phys_size)
-{
- int n;
-
- *phys_base = ~0;
- *phys_size = 0;
-
- for (n = 0; n < 2; n++) {
- uint32_t map = readl(DOVE_SDRAM_BASE + SDRAM_MAPn(n));
- uint32_t base, size;
-
- /* skip disabled areas */
- if ((map & SDRAM_MAP_VALID) != SDRAM_MAP_VALID)
- continue;
-
- base = map & SDRAM_START_MASK;
- if (base < *phys_base)
- *phys_base = base;
-
- /* real size is encoded as ld(2^(16+length)) */
- size = (map & SDRAM_LENGTH_MASK) >> SDRAM_LENGTH_SHIFT;
- *phys_size += 1 << (16 + size);
- }
-}
-
static void __noreturn dove_restart_soc(struct restart_handler *rst)
{
/* enable and assert RSTOUTn */
@@ -80,8 +54,6 @@ static void __noreturn dove_restart_soc(struct restart_handler *rst)
static int dove_init_soc(struct device_node *root, void *context)
{
- unsigned long phys_base, phys_size;
-
if (!of_machine_is_compatible("marvell,dove"))
return 0;
@@ -91,9 +63,6 @@ static int dove_init_soc(struct device_node *root, void *context)
barebox_set_hostname("dove");
dove_remap_mc_regs();
- dove_memory_find(&phys_base, &phys_size);
-
- mvebu_set_memory(phys_base, phys_size);
mvebu_mbus_init();
return 0;
diff --git a/arch/arm/mach-mvebu/include/mach/common.h b/arch/arm/mach-mvebu/include/mach/common.h
index 602af8f28f..3cc1bf71c0 100644
--- a/arch/arm/mach-mvebu/include/mach/common.h
+++ b/arch/arm/mach-mvebu/include/mach/common.h
@@ -20,6 +20,4 @@
#define MVEBU_REMAP_INT_REG_BASE 0xf1000000
-int mvebu_set_memory(u64 phys_base, u64 phys_size);
-
#endif
diff --git a/arch/arm/mach-mvebu/include/mach/lowlevel.h b/arch/arm/mach-mvebu/include/mach/lowlevel.h
index c922a27a7c..3e639fc1bd 100644
--- a/arch/arm/mach-mvebu/include/mach/lowlevel.h
+++ b/arch/arm/mach-mvebu/include/mach/lowlevel.h
@@ -19,5 +19,8 @@
#define __MACH_LOWLEVEL_H__
void mvebu_barebox_entry(void *boarddata);
+void dove_barebox_entry(void *boarddata);
+void kirkwood_barebox_entry(void *boarddata);
+void armada_370_xp_barebox_entry(void *boarddata);
#endif
diff --git a/arch/arm/mach-mvebu/kirkwood.c b/arch/arm/mach-mvebu/kirkwood.c
index 72a6b0db3c..d5ddf05e34 100644
--- a/arch/arm/mach-mvebu/kirkwood.c
+++ b/arch/arm/mach-mvebu/kirkwood.c
@@ -21,29 +21,6 @@
#include <linux/mbus.h>
#include <mach/kirkwood-regs.h>
-static inline void kirkwood_memory_find(unsigned long *phys_base,
- unsigned long *phys_size)
-{
- int cs;
-
- *phys_base = ~0;
- *phys_size = 0;
-
- for (cs = 0; cs < 4; cs++) {
- u32 base = readl(KIRKWOOD_SDRAM_BASE + DDR_BASE_CSn(cs));
- u32 ctrl = readl(KIRKWOOD_SDRAM_BASE + DDR_SIZE_CSn(cs));
-
- /* Skip non-enabled CS */
- if ((ctrl & DDR_SIZE_ENABLED) != DDR_SIZE_ENABLED)
- continue;
-
- base &= DDR_BASE_CS_LOW_MASK;
- if (base < *phys_base)
- *phys_base = base;
- *phys_size += (ctrl | ~DDR_SIZE_MASK) + 1;
- }
-}
-
static void __noreturn kirkwood_restart_soc(struct restart_handler *rst)
{
writel(SOFT_RESET_OUT_EN, KIRKWOOD_BRIDGE_BASE + BRIDGE_RSTOUT_MASK);
@@ -54,8 +31,6 @@ static void __noreturn kirkwood_restart_soc(struct restart_handler *rst)
static int kirkwood_init_soc(struct device_node *root, void *context)
{
- unsigned long phys_base, phys_size;
-
if (!of_machine_is_compatible("marvell,kirkwood"))
return 0;
@@ -64,9 +39,6 @@ static int kirkwood_init_soc(struct device_node *root, void *context)
barebox_set_model("Marvell Kirkwood");
barebox_set_hostname("kirkwood");
- kirkwood_memory_find(&phys_base, &phys_size);
-
- mvebu_set_memory(phys_base, phys_size);
mvebu_mbus_init();
return 0;
diff --git a/arch/arm/mach-mvebu/lowlevel.c b/arch/arm/mach-mvebu/lowlevel.c
deleted file mode 100644
index cf8f48e67b..0000000000
--- a/arch/arm/mach-mvebu/lowlevel.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2013
- * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <common.h>
-#include <io.h>
-#include <linux/sizes.h>
-#include <asm/barebox-arm.h>
-#include <asm/barebox-arm-head.h>
-#include <mach/common.h>
-#include <mach/lowlevel.h>
-
-/*
- * All MVEBU SoCs start with internal registers at 0xd0000000.
- * To get more contiguous address space and as Linux expects them
- * there, we remap them early to 0xf1000000.
- *
- * There is no way to determine internal registers base address
- * safely later on, as the remap register itself is within the
- * internal registers.
- */
-#define MVEBU_BOOTUP_INT_REG_BASE 0xd0000000
-#define MVEBU_BRIDGE_REG_BASE 0x20000
-#define DEVICE_INTERNAL_BASE_ADDR (MVEBU_BRIDGE_REG_BASE + 0x80)
-
-static void mvebu_remap_registers(void)
-{
- writel(MVEBU_REMAP_INT_REG_BASE,
- IOMEM(MVEBU_BOOTUP_INT_REG_BASE) + DEVICE_INTERNAL_BASE_ADDR);
-}
-
-/*
- * Determining the actual memory size is highly SoC dependent,
- * but for all SoCs RAM starts at 0x00000000. Therefore, we start
- * with a minimal memory setup of 64M and probe correct memory size
- * later.
- */
-#define MVEBU_BOOTUP_MEMORY_BASE 0x00000000
-#define MVEBU_BOOTUP_MEMORY_SIZE SZ_64M
-
-void __naked __noreturn mvebu_barebox_entry(void *boarddata)
-{
- mvebu_remap_registers();
- barebox_arm_entry(MVEBU_BOOTUP_MEMORY_BASE,
- MVEBU_BOOTUP_MEMORY_SIZE, boarddata);
-}