blob: 132d724fbdf8a9638dbe21a8d95d867fe8fb186d [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 Simek84c72042015-01-15 10:01:51 +010018
19DECLARE_GLOBAL_DATA_PTR;
20
21int board_init(void)
22{
Michal Simeka0736ef2015-06-22 14:31:06 +020023 printf("EL Level:\tEL%d\n", current_el());
24
Michal Simek84c72042015-01-15 10:01:51 +010025 return 0;
26}
27
28int board_early_init_r(void)
29{
30 u32 val;
31
Michal Simek0785dfd2015-11-05 08:34:35 +010032 if (current_el() == 3) {
33 val = readl(&crlapb_base->timestamp_ref_ctrl);
34 val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
35 writel(val, &crlapb_base->timestamp_ref_ctrl);
Michal Simek84c72042015-01-15 10:01:51 +010036
Michal Simek0785dfd2015-11-05 08:34:35 +010037 /* Program freq register in System counter */
38 writel(zynqmp_get_system_timer_freq(),
39 &iou_scntr_secure->base_frequency_id_register);
40 /* And enable system counter */
41 writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
42 &iou_scntr_secure->counter_control_register);
43 }
Michal Simek84c72042015-01-15 10:01:51 +010044 /* Program freq register in System counter and enable system counter */
45 writel(gd->cpu_clk, &iou_scntr->base_frequency_id_register);
46 writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_HDBG |
47 ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
48 &iou_scntr->counter_control_register);
49
50 return 0;
51}
52
Michal Simek8d59d7f2016-02-08 09:34:53 +010053#if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
54/*
55 * fdt_get_reg - Fill buffer by information from DT
56 */
57static phys_size_t fdt_get_reg(const void *fdt, int nodeoffset, void *buf,
58 const u32 *cell, int n)
59{
60 int i = 0, b, banks;
61 int parent_offset = fdt_parent_offset(fdt, nodeoffset);
62 int address_cells = fdt_address_cells(fdt, parent_offset);
63 int size_cells = fdt_size_cells(fdt, parent_offset);
64 char *p = buf;
Michal Simek658b3a52016-04-01 15:55:47 +020065 u64 val;
66 u64 vals;
Michal Simek8d59d7f2016-02-08 09:34:53 +010067
68 debug("%s: addr_cells=%x, size_cell=%x, buf=%p, cell=%p\n",
69 __func__, address_cells, size_cells, buf, cell);
70
71 /* Check memory bank setup */
72 banks = n % (address_cells + size_cells);
73 if (banks)
74 panic("Incorrect memory setup cells=%d, ac=%d, sc=%d\n",
75 n, address_cells, size_cells);
76
77 banks = n / (address_cells + size_cells);
78
79 for (b = 0; b < banks; b++) {
80 debug("%s: Bank #%d:\n", __func__, b);
81 if (address_cells == 2) {
82 val = cell[i + 1];
83 val <<= 32;
84 val |= cell[i];
85 val = fdt64_to_cpu(val);
86 debug("%s: addr64=%llx, ptr=%p, cell=%p\n",
87 __func__, val, p, &cell[i]);
88 *(phys_addr_t *)p = val;
89 } else {
90 debug("%s: addr32=%x, ptr=%p\n",
91 __func__, fdt32_to_cpu(cell[i]), p);
92 *(phys_addr_t *)p = fdt32_to_cpu(cell[i]);
93 }
94 p += sizeof(phys_addr_t);
95 i += address_cells;
96
97 debug("%s: pa=%p, i=%x, size=%zu\n", __func__, p, i,
98 sizeof(phys_addr_t));
99
100 if (size_cells == 2) {
101 vals = cell[i + 1];
102 vals <<= 32;
103 vals |= cell[i];
104 vals = fdt64_to_cpu(vals);
105
106 debug("%s: size64=%llx, ptr=%p, cell=%p\n",
107 __func__, vals, p, &cell[i]);
108 *(phys_size_t *)p = vals;
109 } else {
110 debug("%s: size32=%x, ptr=%p\n",
111 __func__, fdt32_to_cpu(cell[i]), p);
112 *(phys_size_t *)p = fdt32_to_cpu(cell[i]);
113 }
114 p += sizeof(phys_size_t);
115 i += size_cells;
116
117 debug("%s: ps=%p, i=%x, size=%zu\n",
118 __func__, p, i, sizeof(phys_size_t));
119 }
120
121 /* Return the first address size */
122 return *(phys_size_t *)((char *)buf + sizeof(phys_addr_t));
123}
124
125#define FDT_REG_SIZE sizeof(u32)
126/* Temp location for sharing data for storing */
127/* Up to 64-bit address + 64-bit size */
128static u8 tmp[CONFIG_NR_DRAM_BANKS * 16];
129
130void dram_init_banksize(void)
131{
132 int bank;
133
134 memcpy(&gd->bd->bi_dram[0], &tmp, sizeof(tmp));
135
136 for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
137 debug("Bank #%d: start %llx\n", bank,
138 (unsigned long long)gd->bd->bi_dram[bank].start);
139 debug("Bank #%d: size %llx\n", bank,
140 (unsigned long long)gd->bd->bi_dram[bank].size);
141 }
142}
143
144int dram_init(void)
145{
146 int node, len;
147 const void *blob = gd->fdt_blob;
148 const u32 *cell;
149
150 memset(&tmp, 0, sizeof(tmp));
151
152 /* find or create "/memory" node. */
153 node = fdt_subnode_offset(blob, 0, "memory");
154 if (node < 0) {
155 printf("%s: Can't get memory node\n", __func__);
156 return node;
157 }
158
159 /* Get pointer to cells and lenght of it */
160 cell = fdt_getprop(blob, node, "reg", &len);
161 if (!cell) {
162 printf("%s: Can't get reg property\n", __func__);
163 return -1;
164 }
165
166 gd->ram_size = fdt_get_reg(blob, node, &tmp, cell, len / FDT_REG_SIZE);
167
Michal Simek658b3a52016-04-01 15:55:47 +0200168 debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size);
Michal Simek8d59d7f2016-02-08 09:34:53 +0100169
170 return 0;
171}
172#else
Michal Simek84c72042015-01-15 10:01:51 +0100173int dram_init(void)
174{
175 gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
176
177 return 0;
178}
Michal Simek8d59d7f2016-02-08 09:34:53 +0100179#endif
Michal Simek84c72042015-01-15 10:01:51 +0100180
Michal Simek84c72042015-01-15 10:01:51 +0100181void reset_cpu(ulong addr)
182{
183}
184
Michal Simek6fe6f132015-07-23 13:27:40 +0200185#ifdef CONFIG_SCSI_AHCI_PLAT
186void scsi_init(void)
187{
Michal Simek679b9942015-09-30 17:26:55 +0200188#if defined(CONFIG_SATA_CEVA)
189 init_sata(0);
190#endif
Michal Simek6fe6f132015-07-23 13:27:40 +0200191 ahci_init((void __iomem *)ZYNQMP_SATA_BASEADDR);
192 scsi_scan(1);
193}
194#endif
195
Michal Simek84c72042015-01-15 10:01:51 +0100196int board_late_init(void)
197{
198 u32 reg = 0;
199 u8 bootmode;
200
201 reg = readl(&crlapb_base->boot_mode);
202 bootmode = reg & BOOT_MODES_MASK;
203
Michal Simekfb909172015-09-20 17:20:42 +0200204 puts("Bootmode: ");
Michal Simek84c72042015-01-15 10:01:51 +0100205 switch (bootmode) {
Siva Durga Prasad Paladugu0a5bcc82015-03-13 11:10:26 +0530206 case JTAG_MODE:
Michal Simekfb909172015-09-20 17:20:42 +0200207 puts("JTAG_MODE\n");
208 setenv("modeboot", "jtagboot");
Siva Durga Prasad Paladugu0a5bcc82015-03-13 11:10:26 +0530209 break;
210 case QSPI_MODE_24BIT:
211 case QSPI_MODE_32BIT:
212 setenv("modeboot", "qspiboot");
Michal Simekfb909172015-09-20 17:20:42 +0200213 puts("QSPI_MODE\n");
Siva Durga Prasad Paladugu0a5bcc82015-03-13 11:10:26 +0530214 break;
Michal Simek39c56f52015-04-15 15:02:28 +0200215 case EMMC_MODE:
Michal Simek78678fe2015-10-05 15:59:38 +0200216 puts("EMMC_MODE\n");
217 setenv("modeboot", "sdboot");
218 break;
219 case SD_MODE:
Michal Simekfb909172015-09-20 17:20:42 +0200220 puts("SD_MODE\n");
Michal Simek84c72042015-01-15 10:01:51 +0100221 setenv("modeboot", "sdboot");
222 break;
Michal Simekaf813ac2015-10-05 10:51:12 +0200223 case SD_MODE1:
Michal Simekfb909172015-09-20 17:20:42 +0200224 puts("SD_MODE1\n");
Michal Simek2d9925b2015-11-06 10:22:37 +0100225#if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1)
226 setenv("sdbootdev", "1");
227#endif
228 setenv("modeboot", "sdboot");
Michal Simekaf813ac2015-10-05 10:51:12 +0200229 break;
230 case NAND_MODE:
Michal Simekfb909172015-09-20 17:20:42 +0200231 puts("NAND_MODE\n");
Michal Simekaf813ac2015-10-05 10:51:12 +0200232 setenv("modeboot", "nandboot");
233 break;
Michal Simek84c72042015-01-15 10:01:51 +0100234 default:
235 printf("Invalid Boot Mode:0x%x\n", bootmode);
236 break;
237 }
238
239 return 0;
240}
Siva Durga Prasad Paladugu84696ff2015-08-04 13:01:05 +0530241
242int checkboard(void)
243{
Michal Simek5af08552016-01-25 11:04:21 +0100244 puts("Board: Xilinx ZynqMP\n");
Siva Durga Prasad Paladugu84696ff2015-08-04 13:01:05 +0530245 return 0;
246}
Siva Durga Prasad Paladugu16fa00a2015-08-04 13:03:26 +0530247
248#ifdef CONFIG_USB_DWC3
249static struct dwc3_device dwc3_device_data = {
250 .maximum_speed = USB_SPEED_HIGH,
251 .base = ZYNQMP_USB0_XHCI_BASEADDR,
252 .dr_mode = USB_DR_MODE_PERIPHERAL,
253 .index = 0,
254};
255
256int usb_gadget_handle_interrupts(void)
257{
258 dwc3_uboot_handle_interrupt(0);
259 return 0;
260}
261
262int board_usb_init(int index, enum usb_init_type init)
263{
264 return dwc3_uboot_init(&dwc3_device_data);
265}
266
267int board_usb_cleanup(int index, enum usb_init_type init)
268{
269 dwc3_uboot_exit(index);
270 return 0;
271}
272#endif