blob: 087578cb6b9c0cf823378f27b415b2b8fe54c2af [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>
9#include <netdev.h>
Michal Simek679b9942015-09-30 17:26:55 +020010#include <sata.h>
Michal Simek6fe6f132015-07-23 13:27:40 +020011#include <ahci.h>
12#include <scsi.h>
Michal Simek0785dfd2015-11-05 08:34:35 +010013#include <asm/arch/clk.h>
Michal Simek84c72042015-01-15 10:01:51 +010014#include <asm/arch/hardware.h>
15#include <asm/arch/sys_proto.h>
16#include <asm/io.h>
Siva Durga Prasad Paladugu16fa00a2015-08-04 13:03:26 +053017#include <usb.h>
18#include <dwc3-uboot.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 Simek8d59d7f2016-02-08 09:34:53 +010054#if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
55/*
56 * fdt_get_reg - Fill buffer by information from DT
57 */
58static phys_size_t fdt_get_reg(const void *fdt, int nodeoffset, void *buf,
59 const u32 *cell, int n)
60{
61 int i = 0, b, banks;
62 int parent_offset = fdt_parent_offset(fdt, nodeoffset);
63 int address_cells = fdt_address_cells(fdt, parent_offset);
64 int size_cells = fdt_size_cells(fdt, parent_offset);
65 char *p = buf;
66 phys_addr_t val;
67 phys_size_t vals;
68
69 debug("%s: addr_cells=%x, size_cell=%x, buf=%p, cell=%p\n",
70 __func__, address_cells, size_cells, buf, cell);
71
72 /* Check memory bank setup */
73 banks = n % (address_cells + size_cells);
74 if (banks)
75 panic("Incorrect memory setup cells=%d, ac=%d, sc=%d\n",
76 n, address_cells, size_cells);
77
78 banks = n / (address_cells + size_cells);
79
80 for (b = 0; b < banks; b++) {
81 debug("%s: Bank #%d:\n", __func__, b);
82 if (address_cells == 2) {
83 val = cell[i + 1];
84 val <<= 32;
85 val |= cell[i];
86 val = fdt64_to_cpu(val);
87 debug("%s: addr64=%llx, ptr=%p, cell=%p\n",
88 __func__, val, p, &cell[i]);
89 *(phys_addr_t *)p = val;
90 } else {
91 debug("%s: addr32=%x, ptr=%p\n",
92 __func__, fdt32_to_cpu(cell[i]), p);
93 *(phys_addr_t *)p = fdt32_to_cpu(cell[i]);
94 }
95 p += sizeof(phys_addr_t);
96 i += address_cells;
97
98 debug("%s: pa=%p, i=%x, size=%zu\n", __func__, p, i,
99 sizeof(phys_addr_t));
100
101 if (size_cells == 2) {
102 vals = cell[i + 1];
103 vals <<= 32;
104 vals |= cell[i];
105 vals = fdt64_to_cpu(vals);
106
107 debug("%s: size64=%llx, ptr=%p, cell=%p\n",
108 __func__, vals, p, &cell[i]);
109 *(phys_size_t *)p = vals;
110 } else {
111 debug("%s: size32=%x, ptr=%p\n",
112 __func__, fdt32_to_cpu(cell[i]), p);
113 *(phys_size_t *)p = fdt32_to_cpu(cell[i]);
114 }
115 p += sizeof(phys_size_t);
116 i += size_cells;
117
118 debug("%s: ps=%p, i=%x, size=%zu\n",
119 __func__, p, i, sizeof(phys_size_t));
120 }
121
122 /* Return the first address size */
123 return *(phys_size_t *)((char *)buf + sizeof(phys_addr_t));
124}
125
126#define FDT_REG_SIZE sizeof(u32)
127/* Temp location for sharing data for storing */
128/* Up to 64-bit address + 64-bit size */
129static u8 tmp[CONFIG_NR_DRAM_BANKS * 16];
130
131void dram_init_banksize(void)
132{
133 int bank;
134
135 memcpy(&gd->bd->bi_dram[0], &tmp, sizeof(tmp));
136
137 for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
138 debug("Bank #%d: start %llx\n", bank,
139 (unsigned long long)gd->bd->bi_dram[bank].start);
140 debug("Bank #%d: size %llx\n", bank,
141 (unsigned long long)gd->bd->bi_dram[bank].size);
142 }
143}
144
145int dram_init(void)
146{
147 int node, len;
148 const void *blob = gd->fdt_blob;
149 const u32 *cell;
150
151 memset(&tmp, 0, sizeof(tmp));
152
153 /* find or create "/memory" node. */
154 node = fdt_subnode_offset(blob, 0, "memory");
155 if (node < 0) {
156 printf("%s: Can't get memory node\n", __func__);
157 return node;
158 }
159
160 /* Get pointer to cells and lenght of it */
161 cell = fdt_getprop(blob, node, "reg", &len);
162 if (!cell) {
163 printf("%s: Can't get reg property\n", __func__);
164 return -1;
165 }
166
167 gd->ram_size = fdt_get_reg(blob, node, &tmp, cell, len / FDT_REG_SIZE);
168
169 debug("%s: Initial DRAM size %llx\n", __func__, gd->ram_size);
170
171 return 0;
172}
173#else
Michal Simek84c72042015-01-15 10:01:51 +0100174int dram_init(void)
175{
176 gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
177
178 return 0;
179}
Michal Simek8d59d7f2016-02-08 09:34:53 +0100180#endif
Michal Simek84c72042015-01-15 10:01:51 +0100181
Michal Simek84c72042015-01-15 10:01:51 +0100182void reset_cpu(ulong addr)
183{
184}
185
Michal Simek6fe6f132015-07-23 13:27:40 +0200186#ifdef CONFIG_SCSI_AHCI_PLAT
187void scsi_init(void)
188{
Michal Simek679b9942015-09-30 17:26:55 +0200189#if defined(CONFIG_SATA_CEVA)
190 init_sata(0);
191#endif
Michal Simek6fe6f132015-07-23 13:27:40 +0200192 ahci_init((void __iomem *)ZYNQMP_SATA_BASEADDR);
193 scsi_scan(1);
194}
195#endif
196
Michal Simek84c72042015-01-15 10:01:51 +0100197int board_late_init(void)
198{
199 u32 reg = 0;
200 u8 bootmode;
201
202 reg = readl(&crlapb_base->boot_mode);
203 bootmode = reg & BOOT_MODES_MASK;
204
Michal Simekfb909172015-09-20 17:20:42 +0200205 puts("Bootmode: ");
Michal Simek84c72042015-01-15 10:01:51 +0100206 switch (bootmode) {
Siva Durga Prasad Paladugu0a5bcc82015-03-13 11:10:26 +0530207 case JTAG_MODE:
Michal Simekfb909172015-09-20 17:20:42 +0200208 puts("JTAG_MODE\n");
209 setenv("modeboot", "jtagboot");
Siva Durga Prasad Paladugu0a5bcc82015-03-13 11:10:26 +0530210 break;
211 case QSPI_MODE_24BIT:
212 case QSPI_MODE_32BIT:
213 setenv("modeboot", "qspiboot");
Michal Simekfb909172015-09-20 17:20:42 +0200214 puts("QSPI_MODE\n");
Siva Durga Prasad Paladugu0a5bcc82015-03-13 11:10:26 +0530215 break;
Michal Simek39c56f52015-04-15 15:02:28 +0200216 case EMMC_MODE:
Michal Simek78678fe2015-10-05 15:59:38 +0200217 puts("EMMC_MODE\n");
218 setenv("modeboot", "sdboot");
219 break;
220 case SD_MODE:
Michal Simekfb909172015-09-20 17:20:42 +0200221 puts("SD_MODE\n");
Michal Simek84c72042015-01-15 10:01:51 +0100222 setenv("modeboot", "sdboot");
223 break;
Michal Simekaf813ac2015-10-05 10:51:12 +0200224 case SD_MODE1:
Michal Simekfb909172015-09-20 17:20:42 +0200225 puts("SD_MODE1\n");
Michal Simek2d9925b2015-11-06 10:22:37 +0100226#if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1)
227 setenv("sdbootdev", "1");
228#endif
229 setenv("modeboot", "sdboot");
Michal Simekaf813ac2015-10-05 10:51:12 +0200230 break;
231 case NAND_MODE:
Michal Simekfb909172015-09-20 17:20:42 +0200232 puts("NAND_MODE\n");
Michal Simekaf813ac2015-10-05 10:51:12 +0200233 setenv("modeboot", "nandboot");
234 break;
Michal Simek84c72042015-01-15 10:01:51 +0100235 default:
236 printf("Invalid Boot Mode:0x%x\n", bootmode);
237 break;
238 }
239
240 return 0;
241}
Siva Durga Prasad Paladugu84696ff2015-08-04 13:01:05 +0530242
243int checkboard(void)
244{
Michal Simek5af08552016-01-25 11:04:21 +0100245 puts("Board: Xilinx ZynqMP\n");
Siva Durga Prasad Paladugu84696ff2015-08-04 13:01:05 +0530246 return 0;
247}
Siva Durga Prasad Paladugu16fa00a2015-08-04 13:03:26 +0530248
249#ifdef CONFIG_USB_DWC3
250static struct dwc3_device dwc3_device_data = {
251 .maximum_speed = USB_SPEED_HIGH,
252 .base = ZYNQMP_USB0_XHCI_BASEADDR,
253 .dr_mode = USB_DR_MODE_PERIPHERAL,
254 .index = 0,
255};
256
257int usb_gadget_handle_interrupts(void)
258{
259 dwc3_uboot_handle_interrupt(0);
260 return 0;
261}
262
263int board_usb_init(int index, enum usb_init_type init)
264{
265 return dwc3_uboot_init(&dwc3_device_data);
266}
267
268int board_usb_cleanup(int index, enum usb_init_type init)
269{
270 dwc3_uboot_exit(index);
271 return 0;
272}
273#endif