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