xref: /openbmc/u-boot/board/xilinx/zynqmp/zynqmp.c (revision 014a953c)
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 <malloc.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 #include <zynqmppl.h>
20 #include <i2c.h>
21 #include <g_dnl.h>
22 
23 DECLARE_GLOBAL_DATA_PTR;
24 
25 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
26     !defined(CONFIG_SPL_BUILD)
27 static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
28 
29 static const struct {
30 	u32 id;
31 	u32 ver;
32 	char *name;
33 } zynqmp_devices[] = {
34 	{
35 		.id = 0x10,
36 		.name = "3eg",
37 	},
38 	{
39 		.id = 0x10,
40 		.ver = 0x2c,
41 		.name = "3cg",
42 	},
43 	{
44 		.id = 0x11,
45 		.name = "2eg",
46 	},
47 	{
48 		.id = 0x11,
49 		.ver = 0x2c,
50 		.name = "2cg",
51 	},
52 	{
53 		.id = 0x20,
54 		.name = "5ev",
55 	},
56 	{
57 		.id = 0x20,
58 		.ver = 0x100,
59 		.name = "5eg",
60 	},
61 	{
62 		.id = 0x20,
63 		.ver = 0x12c,
64 		.name = "5cg",
65 	},
66 	{
67 		.id = 0x21,
68 		.name = "4ev",
69 	},
70 	{
71 		.id = 0x21,
72 		.ver = 0x100,
73 		.name = "4eg",
74 	},
75 	{
76 		.id = 0x21,
77 		.ver = 0x12c,
78 		.name = "4cg",
79 	},
80 	{
81 		.id = 0x30,
82 		.name = "7ev",
83 	},
84 	{
85 		.id = 0x30,
86 		.ver = 0x100,
87 		.name = "7eg",
88 	},
89 	{
90 		.id = 0x30,
91 		.ver = 0x12c,
92 		.name = "7cg",
93 	},
94 	{
95 		.id = 0x38,
96 		.name = "9eg",
97 	},
98 	{
99 		.id = 0x38,
100 		.ver = 0x2c,
101 		.name = "9cg",
102 	},
103 	{
104 		.id = 0x39,
105 		.name = "6eg",
106 	},
107 	{
108 		.id = 0x39,
109 		.ver = 0x2c,
110 		.name = "6cg",
111 	},
112 	{
113 		.id = 0x40,
114 		.name = "11eg",
115 	},
116 	{ /* For testing purpose only */
117 		.id = 0x50,
118 		.ver = 0x2c,
119 		.name = "15cg",
120 	},
121 	{
122 		.id = 0x50,
123 		.name = "15eg",
124 	},
125 	{
126 		.id = 0x58,
127 		.name = "19eg",
128 	},
129 	{
130 		.id = 0x59,
131 		.name = "17eg",
132 	},
133 	{
134 		.id = 0x61,
135 		.name = "21dr",
136 	},
137 	{
138 		.id = 0x63,
139 		.name = "23dr",
140 	},
141 	{
142 		.id = 0x65,
143 		.name = "25dr",
144 	},
145 	{
146 		.id = 0x64,
147 		.name = "27dr",
148 	},
149 	{
150 		.id = 0x60,
151 		.name = "28dr",
152 	},
153 	{
154 		.id = 0x62,
155 		.name = "29dr",
156 	},
157 };
158 #endif
159 
160 int chip_id(unsigned char id)
161 {
162 	struct pt_regs regs;
163 	int val = -EINVAL;
164 
165 	if (current_el() != 3) {
166 		regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID;
167 		regs.regs[1] = 0;
168 		regs.regs[2] = 0;
169 		regs.regs[3] = 0;
170 
171 		smc_call(&regs);
172 
173 		/*
174 		 * SMC returns:
175 		 * regs[0][31:0]  = status of the operation
176 		 * regs[0][63:32] = CSU.IDCODE register
177 		 * regs[1][31:0]  = CSU.version register
178 		 * regs[1][63:32] = CSU.IDCODE2 register
179 		 */
180 		switch (id) {
181 		case IDCODE:
182 			regs.regs[0] = upper_32_bits(regs.regs[0]);
183 			regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
184 					ZYNQMP_CSU_IDCODE_SVD_MASK;
185 			regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
186 			val = regs.regs[0];
187 			break;
188 		case VERSION:
189 			regs.regs[1] = lower_32_bits(regs.regs[1]);
190 			regs.regs[1] &= ZYNQMP_CSU_SILICON_VER_MASK;
191 			val = regs.regs[1];
192 			break;
193 		case IDCODE2:
194 			regs.regs[1] = lower_32_bits(regs.regs[1]);
195 			regs.regs[1] >>= ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
196 			val = regs.regs[1];
197 			break;
198 		default:
199 			printf("%s, Invalid Req:0x%x\n", __func__, id);
200 		}
201 	} else {
202 		switch (id) {
203 		case IDCODE:
204 			val = readl(ZYNQMP_CSU_IDCODE_ADDR);
205 			val &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
206 			       ZYNQMP_CSU_IDCODE_SVD_MASK;
207 			val >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
208 			break;
209 		case VERSION:
210 			val = readl(ZYNQMP_CSU_VER_ADDR);
211 			val &= ZYNQMP_CSU_SILICON_VER_MASK;
212 			break;
213 		default:
214 			printf("%s, Invalid Req:0x%x\n", __func__, id);
215 		}
216 	}
217 
218 	return val;
219 }
220 
221 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
222 	!defined(CONFIG_SPL_BUILD)
223 static char *zynqmp_get_silicon_idcode_name(void)
224 {
225 	u32 i, id, ver;
226 
227 	id = chip_id(IDCODE);
228 	ver = chip_id(IDCODE2);
229 
230 	for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
231 		if (zynqmp_devices[i].id == id && zynqmp_devices[i].ver == ver)
232 			return zynqmp_devices[i].name;
233 	}
234 	return "unknown";
235 }
236 #endif
237 
238 int board_early_init_f(void)
239 {
240 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_CLK_ZYNQMP)
241 	zynqmp_pmufw_version();
242 #endif
243 
244 #if defined(CONFIG_SPL_BUILD) || defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED)
245 	psu_init();
246 #endif
247 
248 	return 0;
249 }
250 
251 #define ZYNQMP_VERSION_SIZE	9
252 
253 int board_init(void)
254 {
255 	printf("EL Level:\tEL%d\n", current_el());
256 
257 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
258     !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
259     defined(CONFIG_SPL_BUILD))
260 	if (current_el() != 3) {
261 		static char version[ZYNQMP_VERSION_SIZE];
262 
263 		strncat(version, "xczu", 4);
264 		zynqmppl.name = strncat(version,
265 					zynqmp_get_silicon_idcode_name(),
266 					ZYNQMP_VERSION_SIZE - 5);
267 		printf("Chip ID:\t%s\n", zynqmppl.name);
268 		fpga_init();
269 		fpga_add(fpga_xilinx, &zynqmppl);
270 	}
271 #endif
272 
273 	return 0;
274 }
275 
276 int board_early_init_r(void)
277 {
278 	u32 val;
279 
280 	val = readl(&crlapb_base->timestamp_ref_ctrl);
281 	val &= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
282 
283 	if (current_el() == 3 && !val) {
284 		val = readl(&crlapb_base->timestamp_ref_ctrl);
285 		val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
286 		writel(val, &crlapb_base->timestamp_ref_ctrl);
287 
288 		/* Program freq register in System counter */
289 		writel(zynqmp_get_system_timer_freq(),
290 		       &iou_scntr_secure->base_frequency_id_register);
291 		/* And enable system counter */
292 		writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
293 		       &iou_scntr_secure->counter_control_register);
294 	}
295 	return 0;
296 }
297 
298 int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
299 {
300 #if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \
301     defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET) && \
302     defined(CONFIG_ZYNQ_EEPROM_BUS)
303 	i2c_set_bus_num(CONFIG_ZYNQ_EEPROM_BUS);
304 
305 	if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR,
306 			CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET,
307 			ethaddr, 6))
308 		printf("I2C EEPROM MAC address read failed\n");
309 #endif
310 
311 	return 0;
312 }
313 
314 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
315 int dram_init_banksize(void)
316 {
317 	return fdtdec_setup_memory_banksize();
318 }
319 
320 int dram_init(void)
321 {
322 	if (fdtdec_setup_memory_size() != 0)
323 		return -EINVAL;
324 
325 	return 0;
326 }
327 #else
328 int dram_init(void)
329 {
330 	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
331 
332 	return 0;
333 }
334 #endif
335 
336 void reset_cpu(ulong addr)
337 {
338 }
339 
340 int board_late_init(void)
341 {
342 	u32 reg = 0;
343 	u8 bootmode;
344 	const char *mode;
345 	char *new_targets;
346 
347 	if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
348 		debug("Saved variables - Skipping\n");
349 		return 0;
350 	}
351 
352 	reg = readl(&crlapb_base->boot_mode);
353 	if (reg >> BOOT_MODE_ALT_SHIFT)
354 		reg >>= BOOT_MODE_ALT_SHIFT;
355 
356 	bootmode = reg & BOOT_MODES_MASK;
357 
358 	puts("Bootmode: ");
359 	switch (bootmode) {
360 	case USB_MODE:
361 		puts("USB_MODE\n");
362 		mode = "usb";
363 		break;
364 	case JTAG_MODE:
365 		puts("JTAG_MODE\n");
366 		mode = "pxe dhcp";
367 		break;
368 	case QSPI_MODE_24BIT:
369 	case QSPI_MODE_32BIT:
370 		mode = "qspi0";
371 		puts("QSPI_MODE\n");
372 		break;
373 	case EMMC_MODE:
374 		puts("EMMC_MODE\n");
375 		mode = "mmc0";
376 		break;
377 	case SD_MODE:
378 		puts("SD_MODE\n");
379 		mode = "mmc0";
380 		break;
381 	case SD1_LSHFT_MODE:
382 		puts("LVL_SHFT_");
383 		/* fall through */
384 	case SD_MODE1:
385 		puts("SD_MODE1\n");
386 #if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1)
387 		mode = "mmc1";
388 #else
389 		mode = "mmc0";
390 #endif
391 		break;
392 	case NAND_MODE:
393 		puts("NAND_MODE\n");
394 		mode = "nand0";
395 		break;
396 	default:
397 		mode = "";
398 		printf("Invalid Boot Mode:0x%x\n", bootmode);
399 		break;
400 	}
401 
402 	/*
403 	 * One terminating char + one byte for space between mode
404 	 * and default boot_targets
405 	 */
406 	new_targets = calloc(1, strlen(mode) +
407 				strlen(env_get("boot_targets")) + 2);
408 
409 	sprintf(new_targets, "%s %s", mode, env_get("boot_targets"));
410 	env_set("boot_targets", new_targets);
411 
412 	return 0;
413 }
414 
415 int checkboard(void)
416 {
417 	puts("Board: Xilinx ZynqMP\n");
418 	return 0;
419 }
420 
421 #ifdef CONFIG_USB_DWC3
422 static struct dwc3_device dwc3_device_data0 = {
423 	.maximum_speed = USB_SPEED_HIGH,
424 	.base = ZYNQMP_USB0_XHCI_BASEADDR,
425 	.dr_mode = USB_DR_MODE_PERIPHERAL,
426 	.index = 0,
427 };
428 
429 static struct dwc3_device dwc3_device_data1 = {
430 	.maximum_speed = USB_SPEED_HIGH,
431 	.base = ZYNQMP_USB1_XHCI_BASEADDR,
432 	.dr_mode = USB_DR_MODE_PERIPHERAL,
433 	.index = 1,
434 };
435 
436 int usb_gadget_handle_interrupts(int index)
437 {
438 	dwc3_uboot_handle_interrupt(index);
439 	return 0;
440 }
441 
442 int board_usb_init(int index, enum usb_init_type init)
443 {
444 	debug("%s: index %x\n", __func__, index);
445 
446 #if defined(CONFIG_USB_GADGET_DOWNLOAD)
447 	g_dnl_set_serialnumber(CONFIG_SYS_CONFIG_NAME);
448 #endif
449 
450 	switch (index) {
451 	case 0:
452 		return dwc3_uboot_init(&dwc3_device_data0);
453 	case 1:
454 		return dwc3_uboot_init(&dwc3_device_data1);
455 	};
456 
457 	return -1;
458 }
459 
460 int board_usb_cleanup(int index, enum usb_init_type init)
461 {
462 	dwc3_uboot_exit(index);
463 	return 0;
464 }
465 #endif
466