2 * (C) Copyright 2014 - 2015 Xilinx, Inc.
3 * Michal Simek <michal.simek@xilinx.com>
5 * SPDX-License-Identifier: GPL-2.0+
13 #include <asm/arch/clk.h>
14 #include <asm/arch/hardware.h>
15 #include <asm/arch/sys_proto.h>
18 #include <dwc3-uboot.h>
23 DECLARE_GLOBAL_DATA_PTR;
25 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
26 !defined(CONFIG_SPL_BUILD)
27 static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
32 } zynqmp_devices[] = {
79 static int chip_id(void)
82 regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID;
92 static char *zynqmp_get_silicon_idcode_name(void)
97 for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
98 if (zynqmp_devices[i].id == id)
99 return zynqmp_devices[i].name;
105 #define ZYNQMP_VERSION_SIZE 9
109 printf("EL Level:\tEL%d\n", current_el());
111 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
112 !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
113 defined(CONFIG_SPL_BUILD))
114 if (current_el() != 3) {
115 static char version[ZYNQMP_VERSION_SIZE];
117 strncat(version, "xczu", ZYNQMP_VERSION_SIZE);
118 zynqmppl.name = strncat(version,
119 zynqmp_get_silicon_idcode_name(),
120 ZYNQMP_VERSION_SIZE);
121 printf("Chip ID:\t%s\n", zynqmppl.name);
123 fpga_add(fpga_xilinx, &zynqmppl);
130 int board_early_init_r(void)
134 if (current_el() == 3) {
135 val = readl(&crlapb_base->timestamp_ref_ctrl);
136 val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
137 writel(val, &crlapb_base->timestamp_ref_ctrl);
139 /* Program freq register in System counter */
140 writel(zynqmp_get_system_timer_freq(),
141 &iou_scntr_secure->base_frequency_id_register);
142 /* And enable system counter */
143 writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
144 &iou_scntr_secure->counter_control_register);
146 /* Program freq register in System counter and enable system counter */
147 writel(gd->cpu_clk, &iou_scntr->base_frequency_id_register);
148 writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_HDBG |
149 ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
150 &iou_scntr->counter_control_register);
155 int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
157 #if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \
158 defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET) && \
159 defined(CONFIG_ZYNQ_EEPROM_BUS)
160 i2c_set_bus_num(CONFIG_ZYNQ_EEPROM_BUS);
162 if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR,
163 CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET,
165 printf("I2C EEPROM MAC address read failed\n");
171 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
173 * fdt_get_reg - Fill buffer by information from DT
175 static phys_size_t fdt_get_reg(const void *fdt, int nodeoffset, void *buf,
176 const u32 *cell, int n)
179 int parent_offset = fdt_parent_offset(fdt, nodeoffset);
180 int address_cells = fdt_address_cells(fdt, parent_offset);
181 int size_cells = fdt_size_cells(fdt, parent_offset);
186 debug("%s: addr_cells=%x, size_cell=%x, buf=%p, cell=%p\n",
187 __func__, address_cells, size_cells, buf, cell);
189 /* Check memory bank setup */
190 banks = n % (address_cells + size_cells);
192 panic("Incorrect memory setup cells=%d, ac=%d, sc=%d\n",
193 n, address_cells, size_cells);
195 banks = n / (address_cells + size_cells);
197 for (b = 0; b < banks; b++) {
198 debug("%s: Bank #%d:\n", __func__, b);
199 if (address_cells == 2) {
203 val = fdt64_to_cpu(val);
204 debug("%s: addr64=%llx, ptr=%p, cell=%p\n",
205 __func__, val, p, &cell[i]);
206 *(phys_addr_t *)p = val;
208 debug("%s: addr32=%x, ptr=%p\n",
209 __func__, fdt32_to_cpu(cell[i]), p);
210 *(phys_addr_t *)p = fdt32_to_cpu(cell[i]);
212 p += sizeof(phys_addr_t);
215 debug("%s: pa=%p, i=%x, size=%zu\n", __func__, p, i,
216 sizeof(phys_addr_t));
218 if (size_cells == 2) {
222 vals = fdt64_to_cpu(vals);
224 debug("%s: size64=%llx, ptr=%p, cell=%p\n",
225 __func__, vals, p, &cell[i]);
226 *(phys_size_t *)p = vals;
228 debug("%s: size32=%x, ptr=%p\n",
229 __func__, fdt32_to_cpu(cell[i]), p);
230 *(phys_size_t *)p = fdt32_to_cpu(cell[i]);
232 p += sizeof(phys_size_t);
235 debug("%s: ps=%p, i=%x, size=%zu\n",
236 __func__, p, i, sizeof(phys_size_t));
239 /* Return the first address size */
240 return *(phys_size_t *)((char *)buf + sizeof(phys_addr_t));
243 #define FDT_REG_SIZE sizeof(u32)
244 /* Temp location for sharing data for storing */
245 /* Up to 64-bit address + 64-bit size */
246 static u8 tmp[CONFIG_NR_DRAM_BANKS * 16];
248 void dram_init_banksize(void)
252 memcpy(&gd->bd->bi_dram[0], &tmp, sizeof(tmp));
254 for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
255 debug("Bank #%d: start %llx\n", bank,
256 (unsigned long long)gd->bd->bi_dram[bank].start);
257 debug("Bank #%d: size %llx\n", bank,
258 (unsigned long long)gd->bd->bi_dram[bank].size);
265 const void *blob = gd->fdt_blob;
268 memset(&tmp, 0, sizeof(tmp));
270 /* find or create "/memory" node. */
271 node = fdt_subnode_offset(blob, 0, "memory");
273 printf("%s: Can't get memory node\n", __func__);
277 /* Get pointer to cells and lenght of it */
278 cell = fdt_getprop(blob, node, "reg", &len);
280 printf("%s: Can't get reg property\n", __func__);
284 gd->ram_size = fdt_get_reg(blob, node, &tmp, cell, len / FDT_REG_SIZE);
286 debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size);
293 gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
299 void reset_cpu(ulong addr)
303 #ifdef CONFIG_SCSI_AHCI_PLAT
306 #if defined(CONFIG_SATA_CEVA)
309 ahci_init((void __iomem *)ZYNQMP_SATA_BASEADDR);
314 int board_late_init(void)
321 if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
322 debug("Saved variables - Skipping\n");
326 reg = readl(&crlapb_base->boot_mode);
327 bootmode = reg & BOOT_MODES_MASK;
339 case QSPI_MODE_24BIT:
340 case QSPI_MODE_32BIT:
354 #if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1)
366 printf("Invalid Boot Mode:0x%x\n", bootmode);
371 * One terminating char + one byte for space between mode
372 * and default boot_targets
374 new_targets = calloc(1, strlen(mode) +
375 strlen(getenv("boot_targets")) + 2);
377 sprintf(new_targets, "%s %s", mode, getenv("boot_targets"));
378 setenv("boot_targets", new_targets);
385 puts("Board: Xilinx ZynqMP\n");
389 #ifdef CONFIG_USB_DWC3
390 static struct dwc3_device dwc3_device_data0 = {
391 .maximum_speed = USB_SPEED_HIGH,
392 .base = ZYNQMP_USB0_XHCI_BASEADDR,
393 .dr_mode = USB_DR_MODE_PERIPHERAL,
397 static struct dwc3_device dwc3_device_data1 = {
398 .maximum_speed = USB_SPEED_HIGH,
399 .base = ZYNQMP_USB1_XHCI_BASEADDR,
400 .dr_mode = USB_DR_MODE_PERIPHERAL,
404 int usb_gadget_handle_interrupts(int index)
406 dwc3_uboot_handle_interrupt(index);
410 int board_usb_init(int index, enum usb_init_type init)
412 debug("%s: index %x\n", __func__, index);
416 return dwc3_uboot_init(&dwc3_device_data0);
418 return dwc3_uboot_init(&dwc3_device_data1);
424 int board_usb_cleanup(int index, enum usb_init_type init)
426 dwc3_uboot_exit(index);