Browse Source

MIPS: Netlogic: Read memory from DRAM BARs

Read the memory from the Bridge DRAM BARs, if it is not passed in
from the device tree. This will allow us to remove memory configuration
from built in device trees.

Signed-off-by: Jayachandran C <jchandra@broadcom.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/5743/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Jayachandran C 12 years ago
parent
commit
a2ba6cd6e6

+ 4 - 0
arch/mips/include/asm/netlogic/xlp-hal/bridge.h

@@ -88,6 +88,7 @@
 #define BRIDGE_DRAM_LIMIT6		0x22
 #define BRIDGE_DRAM_LIMIT7		0x23
 
+#define BRIDGE_DRAM_NODE_TRANSLN(i)	(0x24 + (i))
 #define BRIDGE_DRAM_NODE_TRANSLN0	0x24
 #define BRIDGE_DRAM_NODE_TRANSLN1	0x25
 #define BRIDGE_DRAM_NODE_TRANSLN2	0x26
@@ -96,6 +97,8 @@
 #define BRIDGE_DRAM_NODE_TRANSLN5	0x29
 #define BRIDGE_DRAM_NODE_TRANSLN6	0x2a
 #define BRIDGE_DRAM_NODE_TRANSLN7	0x2b
+
+#define BRIDGE_DRAM_CHNL_TRANSLN(i)	(0x2c + (i))
 #define BRIDGE_DRAM_CHNL_TRANSLN0	0x2c
 #define BRIDGE_DRAM_CHNL_TRANSLN1	0x2d
 #define BRIDGE_DRAM_CHNL_TRANSLN2	0x2e
@@ -104,6 +107,7 @@
 #define BRIDGE_DRAM_CHNL_TRANSLN5	0x31
 #define BRIDGE_DRAM_CHNL_TRANSLN6	0x32
 #define BRIDGE_DRAM_CHNL_TRANSLN7	0x33
+
 #define BRIDGE_PCIEMEM_BASE0		0x34
 #define BRIDGE_PCIEMEM_BASE1		0x35
 #define BRIDGE_PCIEMEM_BASE2		0x36

+ 3 - 0
arch/mips/include/asm/netlogic/xlp-hal/xlp.h

@@ -59,6 +59,9 @@ void xlp_wakeup_secondary_cpus(void);
 
 void xlp_mmu_init(void);
 void nlm_hal_init(void);
+int xlp_get_dram_map(int n, uint64_t *dram_map);
+
+/* Device tree related */
 void *xlp_dt_init(void *fdtp);
 
 #endif /* !__ASSEMBLY__ */

+ 35 - 0
arch/mips/netlogic/xlp/nlm_hal.c

@@ -44,6 +44,7 @@
 #include <asm/netlogic/haldefs.h>
 #include <asm/netlogic/xlp-hal/iomap.h>
 #include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/bridge.h>
 #include <asm/netlogic/xlp-hal/pic.h>
 #include <asm/netlogic/xlp-hal/sys.h>
 
@@ -142,3 +143,37 @@ unsigned int nlm_get_cpu_frequency(void)
 {
 	return nlm_get_core_frequency(0, 0);
 }
+
+/*
+ * Fills upto 8 pairs of entries containing the DRAM map of a node
+ * if n < 0, get dram map for all nodes
+ */
+int xlp_get_dram_map(int n, uint64_t *dram_map)
+{
+	uint64_t bridgebase, base, lim;
+	uint32_t val;
+	int i, node, rv;
+
+	/* Look only at mapping on Node 0, we don't handle crazy configs */
+	bridgebase = nlm_get_bridge_regbase(0);
+	rv = 0;
+	for (i = 0; i < 8; i++) {
+		val = nlm_read_bridge_reg(bridgebase,
+					BRIDGE_DRAM_NODE_TRANSLN(i));
+		node = (val >> 1) & 0x3;
+		if (n >= 0 && n != node)
+			continue;
+		val = nlm_read_bridge_reg(bridgebase, BRIDGE_DRAM_BAR(i));
+		val = (val >>  12) & 0xfffff;
+		base = (uint64_t) val << 20;
+		val = nlm_read_bridge_reg(bridgebase, BRIDGE_DRAM_LIMIT(i));
+		val = (val >>  12) & 0xfffff;
+		if (val == 0)   /* BAR not used */
+			continue;
+		lim = ((uint64_t)val + 1) << 20;
+		dram_map[rv] = base;
+		dram_map[rv + 1] = lim;
+		rv += 2;
+	}
+	return rv;
+}

+ 23 - 0
arch/mips/netlogic/xlp/setup.c

@@ -73,6 +73,23 @@ static void nlm_fixup_mem(void)
 	}
 }
 
+static void __init xlp_init_mem_from_bars(void)
+{
+	uint64_t map[16];
+	int i, n;
+
+	n = xlp_get_dram_map(-1, map);	/* -1: info for all nodes */
+	for (i = 0; i < n; i += 2) {
+		/* exclude 0x1000_0000-0x2000_0000, u-boot device */
+		if (map[i] <= 0x10000000 && map[i+1] > 0x10000000)
+			map[i+1] = 0x10000000;
+		if (map[i] > 0x10000000 && map[i] < 0x20000000)
+			map[i] = 0x20000000;
+
+		add_memory_region(map[i], map[i+1] - map[i], BOOT_MEM_RAM);
+	}
+}
+
 void __init plat_mem_setup(void)
 {
 	panic_timeout	= 5;
@@ -82,6 +99,12 @@ void __init plat_mem_setup(void)
 
 	/* memory and bootargs from DT */
 	early_init_devtree(initial_boot_params);
+
+	if (boot_mem_map.nr_map == 0) {
+		pr_info("Using DRAM BARs for memory map.\n");
+		xlp_init_mem_from_bars();
+	}
+	/* Calculate and setup wired entries for mapped kernel */
 	nlm_fixup_mem();
 }