blob: 4623cd49e9c797f309540fb618e5076a2bee82a8 [file] [log] [blame]
Michal Simek84c72042015-01-15 10:01:51 +01001/*
2 * (C) Copyright 2014 - 2015 Xilinx, Inc.
3 * Michal Simek <michal.simek@xilinx.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#include <common.h>
Michal Simek679b9942015-09-30 17:26:55 +02009#include <sata.h>
Michal Simek6fe6f132015-07-23 13:27:40 +020010#include <ahci.h>
11#include <scsi.h>
Michal Simek0785dfd2015-11-05 08:34:35 +010012#include <asm/arch/clk.h>
Michal Simek84c72042015-01-15 10:01:51 +010013#include <asm/arch/hardware.h>
14#include <asm/arch/sys_proto.h>
15#include <asm/io.h>
Siva Durga Prasad Paladugu16fa00a2015-08-04 13:03:26 +053016#include <usb.h>
17#include <dwc3-uboot.h>
Michal Simek6919b4b2016-04-22 11:48:49 +020018#include <i2c.h>
Michal Simek84c72042015-01-15 10:01:51 +010019
20DECLARE_GLOBAL_DATA_PTR;
21
22int board_init(void)
23{
Michal Simeka0736ef2015-06-22 14:31:06 +020024 printf("EL Level:\tEL%d\n", current_el());
25
Michal Simek84c72042015-01-15 10:01:51 +010026 return 0;
27}
28
29int board_early_init_r(void)
30{
31 u32 val;
32
Michal Simek0785dfd2015-11-05 08:34:35 +010033 if (current_el() == 3) {
34 val = readl(&crlapb_base->timestamp_ref_ctrl);
35 val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
36 writel(val, &crlapb_base->timestamp_ref_ctrl);
Michal Simek84c72042015-01-15 10:01:51 +010037
Michal Simek0785dfd2015-11-05 08:34:35 +010038 /* Program freq register in System counter */
39 writel(zynqmp_get_system_timer_freq(),
40 &iou_scntr_secure->base_frequency_id_register);
41 /* And enable system counter */
42 writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
43 &iou_scntr_secure->counter_control_register);
44 }
Michal Simek84c72042015-01-15 10:01:51 +010045 /* Program freq register in System counter and enable system counter */
46 writel(gd->cpu_clk, &iou_scntr->base_frequency_id_register);
47 writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_HDBG |
48 ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
49 &iou_scntr->counter_control_register);
50
51 return 0;
52}
53
Michal Simek6919b4b2016-04-22 11:48:49 +020054int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
55{
56#if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \
57 defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET) && \
58 defined(CONFIG_ZYNQ_EEPROM_BUS)
59 i2c_set_bus_num(CONFIG_ZYNQ_EEPROM_BUS);
60
61 if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR,
62 CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET,
63 ethaddr, 6))
64 printf("I2C EEPROM MAC address read failed\n");
65#endif
66
67 return 0;
68}
69
Michal Simek8d59d7f2016-02-08 09:34:53 +010070#if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
71/*
72 * fdt_get_reg - Fill buffer by information from DT
73 */
74static phys_size_t fdt_get_reg(const void *fdt, int nodeoffset, void *buf,
75 const u32 *cell, int n)
76{
77 int i = 0, b, banks;
78 int parent_offset = fdt_parent_offset(fdt, nodeoffset);
79 int address_cells = fdt_address_cells(fdt, parent_offset);
80 int size_cells = fdt_size_cells(fdt, parent_offset);
81 char *p = buf;
Michal Simek658b3a52016-04-01 15:55:47 +020082 u64 val;
83 u64 vals;
Michal Simek8d59d7f2016-02-08 09:34:53 +010084
85 debug("%s: addr_cells=%x, size_cell=%x, buf=%p, cell=%p\n",
86 __func__, address_cells, size_cells, buf, cell);
87
88 /* Check memory bank setup */
89 banks = n % (address_cells + size_cells);
90 if (banks)
91 panic("Incorrect memory setup cells=%d, ac=%d, sc=%d\n",
92 n, address_cells, size_cells);
93
94 banks = n / (address_cells + size_cells);
95
96 for (b = 0; b < banks; b++) {
97 debug("%s: Bank #%d:\n", __func__, b);
98 if (address_cells == 2) {
99 val = cell[i + 1];
100 val <<= 32;
101 val |= cell[i];
102 val = fdt64_to_cpu(val);
103 debug("%s: addr64=%llx, ptr=%p, cell=%p\n",
104 __func__, val, p, &cell[i]);
105 *(phys_addr_t *)p = val;
106 } else {
107 debug("%s: addr32=%x, ptr=%p\n",
108 __func__, fdt32_to_cpu(cell[i]), p);
109 *(phys_addr_t *)p = fdt32_to_cpu(cell[i]);
110 }
111 p += sizeof(phys_addr_t);
112 i += address_cells;
113
114 debug("%s: pa=%p, i=%x, size=%zu\n", __func__, p, i,
115 sizeof(phys_addr_t));
116
117 if (size_cells == 2) {
118 vals = cell[i + 1];
119 vals <<= 32;
120 vals |= cell[i];
121 vals = fdt64_to_cpu(vals);
122
123 debug("%s: size64=%llx, ptr=%p, cell=%p\n",
124 __func__, vals, p, &cell[i]);
125 *(phys_size_t *)p = vals;
126 } else {
127 debug("%s: size32=%x, ptr=%p\n",
128 __func__, fdt32_to_cpu(cell[i]), p);
129 *(phys_size_t *)p = fdt32_to_cpu(cell[i]);
130 }
131 p += sizeof(phys_size_t);
132 i += size_cells;
133
134 debug("%s: ps=%p, i=%x, size=%zu\n",
135 __func__, p, i, sizeof(phys_size_t));
136 }
137
138 /* Return the first address size */
139 return *(phys_size_t *)((char *)buf + sizeof(phys_addr_t));
140}
141
142#define FDT_REG_SIZE sizeof(u32)
143/* Temp location for sharing data for storing */
144/* Up to 64-bit address + 64-bit size */
145static u8 tmp[CONFIG_NR_DRAM_BANKS * 16];
146
147void dram_init_banksize(void)
148{
149 int bank;
150
151 memcpy(&gd->bd->bi_dram[0], &tmp, sizeof(tmp));
152
153 for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
154 debug("Bank #%d: start %llx\n", bank,
155 (unsigned long long)gd->bd->bi_dram[bank].start);
156 debug("Bank #%d: size %llx\n", bank,
157 (unsigned long long)gd->bd->bi_dram[bank].size);
158 }
159}
160
161int dram_init(void)
162{
163 int node, len;
164 const void *blob = gd->fdt_blob;
165 const u32 *cell;
166
167 memset(&tmp, 0, sizeof(tmp));
168
169 /* find or create "/memory" node. */
170 node = fdt_subnode_offset(blob, 0, "memory");
171 if (node < 0) {
172 printf("%s: Can't get memory node\n", __func__);
173 return node;
174 }
175
176 /* Get pointer to cells and lenght of it */
177 cell = fdt_getprop(blob, node, "reg", &len);
178 if (!cell) {
179 printf("%s: Can't get reg property\n", __func__);
180 return -1;
181 }
182
183 gd->ram_size = fdt_get_reg(blob, node, &tmp, cell, len / FDT_REG_SIZE);
184
Michal Simek658b3a52016-04-01 15:55:47 +0200185 debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size);
Michal Simek8d59d7f2016-02-08 09:34:53 +0100186
187 return 0;
188}
189#else
Michal Simek84c72042015-01-15 10:01:51 +0100190int dram_init(void)
191{
192 gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
193
194 return 0;
195}
Michal Simek8d59d7f2016-02-08 09:34:53 +0100196#endif
Michal Simek84c72042015-01-15 10:01:51 +0100197
Michal Simek84c72042015-01-15 10:01:51 +0100198void reset_cpu(ulong addr)
199{
200}
201
Michal Simek6fe6f132015-07-23 13:27:40 +0200202#ifdef CONFIG_SCSI_AHCI_PLAT
203void scsi_init(void)
204{
Michal Simek679b9942015-09-30 17:26:55 +0200205#if defined(CONFIG_SATA_CEVA)
206 init_sata(0);
207#endif
Michal Simek6fe6f132015-07-23 13:27:40 +0200208 ahci_init((void __iomem *)ZYNQMP_SATA_BASEADDR);
209 scsi_scan(1);
210}
211#endif
212
Michal Simek84c72042015-01-15 10:01:51 +0100213int board_late_init(void)
214{
215 u32 reg = 0;
216 u8 bootmode;
217
218 reg = readl(&crlapb_base->boot_mode);
219 bootmode = reg & BOOT_MODES_MASK;
220
Michal Simekfb909172015-09-20 17:20:42 +0200221 puts("Bootmode: ");
Michal Simek84c72042015-01-15 10:01:51 +0100222 switch (bootmode) {
Siva Durga Prasad Paladugu0a5bcc82015-03-13 11:10:26 +0530223 case JTAG_MODE:
Michal Simekfb909172015-09-20 17:20:42 +0200224 puts("JTAG_MODE\n");
225 setenv("modeboot", "jtagboot");
Siva Durga Prasad Paladugu0a5bcc82015-03-13 11:10:26 +0530226 break;
227 case QSPI_MODE_24BIT:
228 case QSPI_MODE_32BIT:
229 setenv("modeboot", "qspiboot");
Michal Simekfb909172015-09-20 17:20:42 +0200230 puts("QSPI_MODE\n");
Siva Durga Prasad Paladugu0a5bcc82015-03-13 11:10:26 +0530231 break;
Michal Simek39c56f52015-04-15 15:02:28 +0200232 case EMMC_MODE:
Michal Simek78678fe2015-10-05 15:59:38 +0200233 puts("EMMC_MODE\n");
234 setenv("modeboot", "sdboot");
235 break;
236 case SD_MODE:
Michal Simekfb909172015-09-20 17:20:42 +0200237 puts("SD_MODE\n");
Michal Simek84c72042015-01-15 10:01:51 +0100238 setenv("modeboot", "sdboot");
239 break;
Michal Simekaf813ac2015-10-05 10:51:12 +0200240 case SD_MODE1:
Michal Simekfb909172015-09-20 17:20:42 +0200241 puts("SD_MODE1\n");
Michal Simek2d9925b2015-11-06 10:22:37 +0100242#if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1)
243 setenv("sdbootdev", "1");
244#endif
245 setenv("modeboot", "sdboot");
Michal Simekaf813ac2015-10-05 10:51:12 +0200246 break;
247 case NAND_MODE:
Michal Simekfb909172015-09-20 17:20:42 +0200248 puts("NAND_MODE\n");
Michal Simekaf813ac2015-10-05 10:51:12 +0200249 setenv("modeboot", "nandboot");
250 break;
Michal Simek84c72042015-01-15 10:01:51 +0100251 default:
252 printf("Invalid Boot Mode:0x%x\n", bootmode);
253 break;
254 }
255
256 return 0;
257}
Siva Durga Prasad Paladugu84696ff2015-08-04 13:01:05 +0530258
259int checkboard(void)
260{
Michal Simek5af08552016-01-25 11:04:21 +0100261 puts("Board: Xilinx ZynqMP\n");
Siva Durga Prasad Paladugu84696ff2015-08-04 13:01:05 +0530262 return 0;
263}
Siva Durga Prasad Paladugu16fa00a2015-08-04 13:03:26 +0530264
265#ifdef CONFIG_USB_DWC3
266static struct dwc3_device dwc3_device_data = {
267 .maximum_speed = USB_SPEED_HIGH,
268 .base = ZYNQMP_USB0_XHCI_BASEADDR,
269 .dr_mode = USB_DR_MODE_PERIPHERAL,
270 .index = 0,
271};
272
273int usb_gadget_handle_interrupts(void)
274{
275 dwc3_uboot_handle_interrupt(0);
276 return 0;
277}
278
279int board_usb_init(int index, enum usb_init_type init)
280{
281 return dwc3_uboot_init(&dwc3_device_data);
282}
283
284int board_usb_cleanup(int index, enum usb_init_type init)
285{
286 dwc3_uboot_exit(index);
287 return 0;
288}
289#endif