board.c 5.9 KB
Newer Older
M
Michal Simek 已提交
1 2 3
/*
 * (C) Copyright 2012 Michal Simek <monstr@monstr.eu>
 *
4
 * SPDX-License-Identifier:	GPL-2.0+
M
Michal Simek 已提交
5 6 7
 */

#include <common.h>
8
#include <fdtdec.h>
M
Michal Simek 已提交
9 10
#include <fpga.h>
#include <mmc.h>
11
#include <zynqpl.h>
M
Michal Simek 已提交
12 13
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
M
Michal Simek 已提交
14 15 16

DECLARE_GLOBAL_DATA_PTR;

17 18
#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
    (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
M
Michal Simek 已提交
19
static xilinx_desc fpga;
20 21

/* It can be done differently */
22
static xilinx_desc fpga007s = XILINX_XC7Z007S_DESC(0x7);
M
Michal Simek 已提交
23
static xilinx_desc fpga010 = XILINX_XC7Z010_DESC(0x10);
24 25
static xilinx_desc fpga012s = XILINX_XC7Z012S_DESC(0x12);
static xilinx_desc fpga014s = XILINX_XC7Z014S_DESC(0x14);
M
Michal Simek 已提交
26 27 28
static xilinx_desc fpga015 = XILINX_XC7Z015_DESC(0x15);
static xilinx_desc fpga020 = XILINX_XC7Z020_DESC(0x20);
static xilinx_desc fpga030 = XILINX_XC7Z030_DESC(0x30);
29
static xilinx_desc fpga035 = XILINX_XC7Z035_DESC(0x35);
M
Michal Simek 已提交
30 31
static xilinx_desc fpga045 = XILINX_XC7Z045_DESC(0x45);
static xilinx_desc fpga100 = XILINX_XC7Z100_DESC(0x100);
32 33
#endif

M
Michal Simek 已提交
34 35
int board_init(void)
{
36 37
#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
    (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
38 39 40 41 42
	u32 idcode;

	idcode = zynq_slcr_get_idcode();

	switch (idcode) {
43 44 45
	case XILINX_ZYNQ_7007S:
		fpga = fpga007s;
		break;
46 47 48
	case XILINX_ZYNQ_7010:
		fpga = fpga010;
		break;
49 50 51 52 53 54
	case XILINX_ZYNQ_7012S:
		fpga = fpga012s;
		break;
	case XILINX_ZYNQ_7014S:
		fpga = fpga014s;
		break;
55 56 57
	case XILINX_ZYNQ_7015:
		fpga = fpga015;
		break;
58 59 60 61 62 63
	case XILINX_ZYNQ_7020:
		fpga = fpga020;
		break;
	case XILINX_ZYNQ_7030:
		fpga = fpga030;
		break;
64 65 66
	case XILINX_ZYNQ_7035:
		fpga = fpga035;
		break;
67 68 69
	case XILINX_ZYNQ_7045:
		fpga = fpga045;
		break;
70 71 72
	case XILINX_ZYNQ_7100:
		fpga = fpga100;
		break;
73 74 75
	}
#endif

76 77
#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
    (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
78 79 80 81
	fpga_init();
	fpga_add(fpga_xilinx, &fpga);
#endif

M
Michal Simek 已提交
82 83 84
	return 0;
}

85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
int board_late_init(void)
{
	switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
	case ZYNQ_BM_NOR:
		setenv("modeboot", "norboot");
		break;
	case ZYNQ_BM_SD:
		setenv("modeboot", "sdboot");
		break;
	case ZYNQ_BM_JTAG:
		setenv("modeboot", "jtagboot");
		break;
	default:
		setenv("modeboot", "");
		break;
	}

	return 0;
}
M
Michal Simek 已提交
104

105 106 107
#ifdef CONFIG_DISPLAY_BOARDINFO
int checkboard(void)
{
108
	puts("Board: Xilinx Zynq\n");
109 110 111 112
	return 0;
}
#endif

113 114 115 116 117 118 119 120 121 122 123 124 125
int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
{
#if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \
    defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET)
	if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR,
			CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET,
			ethaddr, 6))
		printf("I2C EEPROM MAC address read failed\n");
#endif

	return 0;
}

126
#if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
127 128 129 130 131
/*
 * 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)
132
{
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
	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));
	}
193

194 195
	/* Return the first address size */
	return *(phys_size_t *)((char *)buf + sizeof(phys_addr_t));
196
}
197

198 199 200 201
#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];
M
Michal Simek 已提交
202

203 204 205
void dram_init_banksize(void)
{
	int bank;
M
Michal Simek 已提交
206

207
	memcpy(&gd->bd->bi_dram[0], &tmp, sizeof(tmp));
M
Michal Simek 已提交
208

209 210 211 212 213 214 215
	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);
	}
}
M
Michal Simek 已提交
216

217 218 219 220 221
int dram_init(void)
{
	int node, len;
	const void *blob = gd->fdt_blob;
	const u32 *cell;
M
Michal Simek 已提交
222

223
	memset(&tmp, 0, sizeof(tmp));
M
Michal Simek 已提交
224

225 226 227 228 229 230
	/* 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;
	}
M
Michal Simek 已提交
231

232 233 234 235 236
	/* 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;
237
	}
238

239
	gd->ram_size = fdt_get_reg(blob, node, &tmp, cell, len / FDT_REG_SIZE);
240

241
	debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size);
242

243
	zynq_ddrc_init();
244

245
	return 0;
246 247 248 249 250 251
}
#else
int dram_init(void)
{
	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;

252 253
	zynq_ddrc_init();

M
Michal Simek 已提交
254 255
	return 0;
}
256
#endif