block: Add support for Ceva sata
[platform/kernel/u-boot.git] / 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 <netdev.h>
10 #include <sata.h>
11 #include <ahci.h>
12 #include <scsi.h>
13 #include <asm/arch/clk.h>
14 #include <asm/arch/hardware.h>
15 #include <asm/arch/sys_proto.h>
16 #include <asm/io.h>
17 #include <usb.h>
18 #include <dwc3-uboot.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 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
55 /*
56  * fdt_get_reg - Fill buffer by information from DT
57  */
58 static 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 */
129 static u8 tmp[CONFIG_NR_DRAM_BANKS * 16];
130
131 void 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
145 int 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
174 int dram_init(void)
175 {
176         gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
177
178         return 0;
179 }
180 #endif
181
182 void reset_cpu(ulong addr)
183 {
184 }
185
186 #ifdef CONFIG_SCSI_AHCI_PLAT
187 void scsi_init(void)
188 {
189 #if defined(CONFIG_SATA_CEVA)
190         init_sata(0);
191 #endif
192         ahci_init((void __iomem *)ZYNQMP_SATA_BASEADDR);
193         scsi_scan(1);
194 }
195 #endif
196
197 int 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
205         puts("Bootmode: ");
206         switch (bootmode) {
207         case JTAG_MODE:
208                 puts("JTAG_MODE\n");
209                 setenv("modeboot", "jtagboot");
210                 break;
211         case QSPI_MODE_24BIT:
212         case QSPI_MODE_32BIT:
213                 setenv("modeboot", "qspiboot");
214                 puts("QSPI_MODE\n");
215                 break;
216         case EMMC_MODE:
217                 puts("EMMC_MODE\n");
218                 setenv("modeboot", "sdboot");
219                 break;
220         case SD_MODE:
221                 puts("SD_MODE\n");
222                 setenv("modeboot", "sdboot");
223                 break;
224         case SD_MODE1:
225                 puts("SD_MODE1\n");
226 #if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1)
227                 setenv("sdbootdev", "1");
228 #endif
229                 setenv("modeboot", "sdboot");
230                 break;
231         case NAND_MODE:
232                 puts("NAND_MODE\n");
233                 setenv("modeboot", "nandboot");
234                 break;
235         default:
236                 printf("Invalid Boot Mode:0x%x\n", bootmode);
237                 break;
238         }
239
240         return 0;
241 }
242
243 int checkboard(void)
244 {
245         puts("Board: Xilinx ZynqMP\n");
246         return 0;
247 }
248
249 #ifdef CONFIG_USB_DWC3
250 static 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
257 int usb_gadget_handle_interrupts(void)
258 {
259         dwc3_uboot_handle_interrupt(0);
260         return 0;
261 }
262
263 int board_usb_init(int index, enum usb_init_type init)
264 {
265         return dwc3_uboot_init(&dwc3_device_data);
266 }
267
268 int board_usb_cleanup(int index, enum usb_init_type init)
269 {
270         dwc3_uboot_exit(index);
271         return 0;
272 }
273 #endif