]> git.sur5r.net Git - u-boot/blob - board/xilinx/zynqmp/zynqmp.c
Merge branch 'master' of git://git.denx.de/u-boot-net
[u-boot] / board / xilinx / zynqmp / zynqmp.c
1 /*
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 <sata.h>
10 #include <ahci.h>
11 #include <scsi.h>
12 #include <asm/arch/clk.h>
13 #include <asm/arch/hardware.h>
14 #include <asm/arch/sys_proto.h>
15 #include <asm/io.h>
16 #include <usb.h>
17 #include <dwc3-uboot.h>
18 #include <i2c.h>
19
20 DECLARE_GLOBAL_DATA_PTR;
21
22 int board_init(void)
23 {
24         printf("EL Level:\tEL%d\n", current_el());
25
26         return 0;
27 }
28
29 int board_early_init_r(void)
30 {
31         u32 val;
32
33         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);
37
38                 /* 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         }
45         /* 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
54 int 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
70 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
71 /*
72  * fdt_get_reg - Fill buffer by information from DT
73  */
74 static 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;
82         u64 val;
83         u64 vals;
84
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 */
145 static u8 tmp[CONFIG_NR_DRAM_BANKS * 16];
146
147 void 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
161 int 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
185         debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size);
186
187         return 0;
188 }
189 #else
190 int dram_init(void)
191 {
192         gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
193
194         return 0;
195 }
196 #endif
197
198 void reset_cpu(ulong addr)
199 {
200 }
201
202 #ifdef CONFIG_SCSI_AHCI_PLAT
203 void scsi_init(void)
204 {
205 #if defined(CONFIG_SATA_CEVA)
206         init_sata(0);
207 #endif
208         ahci_init((void __iomem *)ZYNQMP_SATA_BASEADDR);
209         scsi_scan(1);
210 }
211 #endif
212
213 int 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
221         puts("Bootmode: ");
222         switch (bootmode) {
223         case JTAG_MODE:
224                 puts("JTAG_MODE\n");
225                 setenv("modeboot", "jtagboot");
226                 break;
227         case QSPI_MODE_24BIT:
228         case QSPI_MODE_32BIT:
229                 setenv("modeboot", "qspiboot");
230                 puts("QSPI_MODE\n");
231                 break;
232         case EMMC_MODE:
233                 puts("EMMC_MODE\n");
234                 setenv("modeboot", "sdboot");
235                 break;
236         case SD_MODE:
237                 puts("SD_MODE\n");
238                 setenv("modeboot", "sdboot");
239                 break;
240         case SD_MODE1:
241                 puts("SD_MODE1\n");
242 #if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1)
243                 setenv("sdbootdev", "1");
244 #endif
245                 setenv("modeboot", "sdboot");
246                 break;
247         case NAND_MODE:
248                 puts("NAND_MODE\n");
249                 setenv("modeboot", "nandboot");
250                 break;
251         default:
252                 printf("Invalid Boot Mode:0x%x\n", bootmode);
253                 break;
254         }
255
256         return 0;
257 }
258
259 int checkboard(void)
260 {
261         puts("Board: Xilinx ZynqMP\n");
262         return 0;
263 }
264
265 #ifdef CONFIG_USB_DWC3
266 static 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
273 int usb_gadget_handle_interrupts(void)
274 {
275         dwc3_uboot_handle_interrupt(0);
276         return 0;
277 }
278
279 int board_usb_init(int index, enum usb_init_type init)
280 {
281         return dwc3_uboot_init(&dwc3_device_data);
282 }
283
284 int board_usb_cleanup(int index, enum usb_init_type init)
285 {
286         dwc3_uboot_exit(index);
287         return 0;
288 }
289 #endif