1 /* 2 * (C) Copyright 2012 Michal Simek <monstr@monstr.eu> 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <fdtdec.h> 9 #include <fpga.h> 10 #include <mmc.h> 11 #include <zynqpl.h> 12 #include <asm/arch/hardware.h> 13 #include <asm/arch/sys_proto.h> 14 15 DECLARE_GLOBAL_DATA_PTR; 16 17 #if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \ 18 (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD)) 19 static xilinx_desc fpga; 20 21 /* It can be done differently */ 22 static xilinx_desc fpga010 = XILINX_XC7Z010_DESC(0x10); 23 static xilinx_desc fpga015 = XILINX_XC7Z015_DESC(0x15); 24 static xilinx_desc fpga020 = XILINX_XC7Z020_DESC(0x20); 25 static xilinx_desc fpga030 = XILINX_XC7Z030_DESC(0x30); 26 static xilinx_desc fpga035 = XILINX_XC7Z035_DESC(0x35); 27 static xilinx_desc fpga045 = XILINX_XC7Z045_DESC(0x45); 28 static xilinx_desc fpga100 = XILINX_XC7Z100_DESC(0x100); 29 #endif 30 31 int board_init(void) 32 { 33 #if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \ 34 (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD)) 35 u32 idcode; 36 37 idcode = zynq_slcr_get_idcode(); 38 39 switch (idcode) { 40 case XILINX_ZYNQ_7010: 41 fpga = fpga010; 42 break; 43 case XILINX_ZYNQ_7015: 44 fpga = fpga015; 45 break; 46 case XILINX_ZYNQ_7020: 47 fpga = fpga020; 48 break; 49 case XILINX_ZYNQ_7030: 50 fpga = fpga030; 51 break; 52 case XILINX_ZYNQ_7035: 53 fpga = fpga035; 54 break; 55 case XILINX_ZYNQ_7045: 56 fpga = fpga045; 57 break; 58 case XILINX_ZYNQ_7100: 59 fpga = fpga100; 60 break; 61 } 62 #endif 63 64 #if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \ 65 (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD)) 66 fpga_init(); 67 fpga_add(fpga_xilinx, &fpga); 68 #endif 69 70 return 0; 71 } 72 73 int board_late_init(void) 74 { 75 switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) { 76 case ZYNQ_BM_NOR: 77 setenv("modeboot", "norboot"); 78 break; 79 case ZYNQ_BM_SD: 80 setenv("modeboot", "sdboot"); 81 break; 82 case ZYNQ_BM_JTAG: 83 setenv("modeboot", "jtagboot"); 84 break; 85 default: 86 setenv("modeboot", ""); 87 break; 88 } 89 90 return 0; 91 } 92 93 #ifdef CONFIG_DISPLAY_BOARDINFO 94 int checkboard(void) 95 { 96 puts("Board: Xilinx Zynq\n"); 97 return 0; 98 } 99 #endif 100 101 int zynq_board_read_rom_ethaddr(unsigned char *ethaddr) 102 { 103 #if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \ 104 defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET) 105 if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR, 106 CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET, 107 ethaddr, 6)) 108 printf("I2C EEPROM MAC address read failed\n"); 109 #endif 110 111 return 0; 112 } 113 114 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE) 115 /* 116 * fdt_get_reg - Fill buffer by information from DT 117 */ 118 static phys_size_t fdt_get_reg(const void *fdt, int nodeoffset, void *buf, 119 const u32 *cell, int n) 120 { 121 int i = 0, b, banks; 122 int parent_offset = fdt_parent_offset(fdt, nodeoffset); 123 int address_cells = fdt_address_cells(fdt, parent_offset); 124 int size_cells = fdt_size_cells(fdt, parent_offset); 125 char *p = buf; 126 u64 val; 127 u64 vals; 128 129 debug("%s: addr_cells=%x, size_cell=%x, buf=%p, cell=%p\n", 130 __func__, address_cells, size_cells, buf, cell); 131 132 /* Check memory bank setup */ 133 banks = n % (address_cells + size_cells); 134 if (banks) 135 panic("Incorrect memory setup cells=%d, ac=%d, sc=%d\n", 136 n, address_cells, size_cells); 137 138 banks = n / (address_cells + size_cells); 139 140 for (b = 0; b < banks; b++) { 141 debug("%s: Bank #%d:\n", __func__, b); 142 if (address_cells == 2) { 143 val = cell[i + 1]; 144 val <<= 32; 145 val |= cell[i]; 146 val = fdt64_to_cpu(val); 147 debug("%s: addr64=%llx, ptr=%p, cell=%p\n", 148 __func__, val, p, &cell[i]); 149 *(phys_addr_t *)p = val; 150 } else { 151 debug("%s: addr32=%x, ptr=%p\n", 152 __func__, fdt32_to_cpu(cell[i]), p); 153 *(phys_addr_t *)p = fdt32_to_cpu(cell[i]); 154 } 155 p += sizeof(phys_addr_t); 156 i += address_cells; 157 158 debug("%s: pa=%p, i=%x, size=%zu\n", __func__, p, i, 159 sizeof(phys_addr_t)); 160 161 if (size_cells == 2) { 162 vals = cell[i + 1]; 163 vals <<= 32; 164 vals |= cell[i]; 165 vals = fdt64_to_cpu(vals); 166 167 debug("%s: size64=%llx, ptr=%p, cell=%p\n", 168 __func__, vals, p, &cell[i]); 169 *(phys_size_t *)p = vals; 170 } else { 171 debug("%s: size32=%x, ptr=%p\n", 172 __func__, fdt32_to_cpu(cell[i]), p); 173 *(phys_size_t *)p = fdt32_to_cpu(cell[i]); 174 } 175 p += sizeof(phys_size_t); 176 i += size_cells; 177 178 debug("%s: ps=%p, i=%x, size=%zu\n", 179 __func__, p, i, sizeof(phys_size_t)); 180 } 181 182 /* Return the first address size */ 183 return *(phys_size_t *)((char *)buf + sizeof(phys_addr_t)); 184 } 185 186 #define FDT_REG_SIZE sizeof(u32) 187 /* Temp location for sharing data for storing */ 188 /* Up to 64-bit address + 64-bit size */ 189 static u8 tmp[CONFIG_NR_DRAM_BANKS * 16]; 190 191 void dram_init_banksize(void) 192 { 193 int bank; 194 195 memcpy(&gd->bd->bi_dram[0], &tmp, sizeof(tmp)); 196 197 for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { 198 debug("Bank #%d: start %llx\n", bank, 199 (unsigned long long)gd->bd->bi_dram[bank].start); 200 debug("Bank #%d: size %llx\n", bank, 201 (unsigned long long)gd->bd->bi_dram[bank].size); 202 } 203 } 204 205 int dram_init(void) 206 { 207 int node, len; 208 const void *blob = gd->fdt_blob; 209 const u32 *cell; 210 211 memset(&tmp, 0, sizeof(tmp)); 212 213 /* find or create "/memory" node. */ 214 node = fdt_subnode_offset(blob, 0, "memory"); 215 if (node < 0) { 216 printf("%s: Can't get memory node\n", __func__); 217 return node; 218 } 219 220 /* Get pointer to cells and lenght of it */ 221 cell = fdt_getprop(blob, node, "reg", &len); 222 if (!cell) { 223 printf("%s: Can't get reg property\n", __func__); 224 return -1; 225 } 226 227 gd->ram_size = fdt_get_reg(blob, node, &tmp, cell, len / FDT_REG_SIZE); 228 229 debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size); 230 231 zynq_ddrc_init(); 232 233 return 0; 234 } 235 #else 236 int dram_init(void) 237 { 238 gd->ram_size = CONFIG_SYS_SDRAM_SIZE; 239 240 zynq_ddrc_init(); 241 242 return 0; 243 } 244 #endif 245