From 758f29d0f805ccd6ca1354a9562dab3bacf52310 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 1 Apr 2016 15:56:33 +0200 Subject: ARM: zynq: Support systems with more memory banks This is example how to change u-boot to support more memory banks read from DT. Signed-off-by: Michal Simek --- board/xilinx/zynq/board.c | 132 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 120 insertions(+), 12 deletions(-) (limited to 'board') diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 4c20450b63..183f642753 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -111,26 +111,134 @@ int zynq_board_read_rom_ethaddr(unsigned char *ethaddr) return 0; } +#if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE) +/* + * fdt_get_reg - Fill buffer by information from DT + */ +static phys_size_t fdt_get_reg(const void *fdt, int nodeoffset, void *buf, + const u32 *cell, int n) +{ + int i = 0, b, banks; + int parent_offset = fdt_parent_offset(fdt, nodeoffset); + int address_cells = fdt_address_cells(fdt, parent_offset); + int size_cells = fdt_size_cells(fdt, parent_offset); + char *p = buf; + u64 val; + u64 vals; + + debug("%s: addr_cells=%x, size_cell=%x, buf=%p, cell=%p\n", + __func__, address_cells, size_cells, buf, cell); + + /* Check memory bank setup */ + banks = n % (address_cells + size_cells); + if (banks) + panic("Incorrect memory setup cells=%d, ac=%d, sc=%d\n", + n, address_cells, size_cells); + + banks = n / (address_cells + size_cells); + + for (b = 0; b < banks; b++) { + debug("%s: Bank #%d:\n", __func__, b); + if (address_cells == 2) { + val = cell[i + 1]; + val <<= 32; + val |= cell[i]; + val = fdt64_to_cpu(val); + debug("%s: addr64=%llx, ptr=%p, cell=%p\n", + __func__, val, p, &cell[i]); + *(phys_addr_t *)p = val; + } else { + debug("%s: addr32=%x, ptr=%p\n", + __func__, fdt32_to_cpu(cell[i]), p); + *(phys_addr_t *)p = fdt32_to_cpu(cell[i]); + } + p += sizeof(phys_addr_t); + i += address_cells; + + debug("%s: pa=%p, i=%x, size=%zu\n", __func__, p, i, + sizeof(phys_addr_t)); + + if (size_cells == 2) { + vals = cell[i + 1]; + vals <<= 32; + vals |= cell[i]; + vals = fdt64_to_cpu(vals); + + debug("%s: size64=%llx, ptr=%p, cell=%p\n", + __func__, vals, p, &cell[i]); + *(phys_size_t *)p = vals; + } else { + debug("%s: size32=%x, ptr=%p\n", + __func__, fdt32_to_cpu(cell[i]), p); + *(phys_size_t *)p = fdt32_to_cpu(cell[i]); + } + p += sizeof(phys_size_t); + i += size_cells; + + debug("%s: ps=%p, i=%x, size=%zu\n", + __func__, p, i, sizeof(phys_size_t)); + } + + /* Return the first address size */ + return *(phys_size_t *)((char *)buf + sizeof(phys_addr_t)); +} + +#define FDT_REG_SIZE sizeof(u32) +/* Temp location for sharing data for storing */ +/* Up to 64-bit address + 64-bit size */ +static u8 tmp[CONFIG_NR_DRAM_BANKS * 16]; + +void dram_init_banksize(void) +{ + int bank; + + memcpy(&gd->bd->bi_dram[0], &tmp, sizeof(tmp)); + + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + debug("Bank #%d: start %llx\n", bank, + (unsigned long long)gd->bd->bi_dram[bank].start); + debug("Bank #%d: size %llx\n", bank, + (unsigned long long)gd->bd->bi_dram[bank].size); + } +} + int dram_init(void) { - int node; - fdt_addr_t addr; - fdt_size_t size; + int node, len; const void *blob = gd->fdt_blob; + const u32 *cell; - node = fdt_node_offset_by_prop_value(blob, -1, "device_type", - "memory", 7); - if (node == -FDT_ERR_NOTFOUND) { - debug("ZYNQ DRAM: Can't get memory node\n"); - return -1; + memset(&tmp, 0, sizeof(tmp)); + + /* find or create "/memory" node. */ + node = fdt_subnode_offset(blob, 0, "memory"); + if (node < 0) { + printf("%s: Can't get memory node\n", __func__); + return node; } - addr = fdtdec_get_addr_size(blob, node, "reg", &size); - if (addr == FDT_ADDR_T_NONE || size == 0) { - debug("ZYNQ DRAM: Can't get base address or size\n"); + + /* Get pointer to cells and lenght of it */ + cell = fdt_getprop(blob, node, "reg", &len); + if (!cell) { + printf("%s: Can't get reg property\n", __func__); return -1; } - gd->ram_size = size; + + gd->ram_size = fdt_get_reg(blob, node, &tmp, cell, len / FDT_REG_SIZE); + + debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size); + + zynq_ddrc_init(); + + return 0; +} +#else +int dram_init(void) +{ + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + zynq_ddrc_init(); return 0; } +#endif -- cgit v1.2.1 From 658b3a563983281b6617f57b6bf2aee2c92a2101 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 1 Apr 2016 15:55:47 +0200 Subject: ARM64: zynqmp: Make DDR detection code work on 32bit system Define u64 types to be usable on 32bit system because of 64bit address and size cells and 32bit shifts in the code. Signed-off-by: Michal Simek --- board/xilinx/zynqmp/zynqmp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'board') diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 087578cb6b..529476b082 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -63,8 +63,8 @@ static phys_size_t fdt_get_reg(const void *fdt, int nodeoffset, void *buf, int address_cells = fdt_address_cells(fdt, parent_offset); int size_cells = fdt_size_cells(fdt, parent_offset); char *p = buf; - phys_addr_t val; - phys_size_t vals; + u64 val; + u64 vals; debug("%s: addr_cells=%x, size_cell=%x, buf=%p, cell=%p\n", __func__, address_cells, size_cells, buf, cell); @@ -166,7 +166,7 @@ int dram_init(void) gd->ram_size = fdt_get_reg(blob, node, &tmp, cell, len / FDT_REG_SIZE); - debug("%s: Initial DRAM size %llx\n", __func__, gd->ram_size); + debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size); return 0; } -- cgit v1.2.1 From 52be5c05a06fc533655f63f1d1dd37b3b9e71231 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 11 Apr 2016 11:44:40 +0200 Subject: ARM64: zynqmp: Remove netdev.h from board file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Including netdev.h is causing compilation warning: + int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int)); + ^ w+In file included from ../board/xilinx/zynqmp/zynqmp.c:9:0: w+../include/netdev.h:204:41: warning: ‘struct eth_device’ declared inside parameter list [enabled by default] w+../include/netdev.h:204:41: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default] This patch removes it. Signed-off-by: Michal Simek --- board/xilinx/zynqmp/zynqmp.c | 1 - 1 file changed, 1 deletion(-) (limited to 'board') diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 529476b082..132d724fbd 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -6,7 +6,6 @@ */ #include -#include #include #include #include -- cgit v1.2.1