xref: /openbmc/u-boot/board/xilinx/zynqmp/zynqmp.c (revision cd1cc31f)
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, "zu", 2);
264 		zynqmppl.name = strncat(version,
265 					zynqmp_get_silicon_idcode_name(),
266 					ZYNQMP_VERSION_SIZE - 3);
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 	if (current_el() != 3)
281 		return 0;
282 
283 	val = readl(&crlapb_base->timestamp_ref_ctrl);
284 	val &= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
285 
286 	if (!val) {
287 		val = readl(&crlapb_base->timestamp_ref_ctrl);
288 		val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
289 		writel(val, &crlapb_base->timestamp_ref_ctrl);
290 
291 		/* Program freq register in System counter */
292 		writel(zynqmp_get_system_timer_freq(),
293 		       &iou_scntr_secure->base_frequency_id_register);
294 		/* And enable system counter */
295 		writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
296 		       &iou_scntr_secure->counter_control_register);
297 	}
298 	return 0;
299 }
300 
301 int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
302 {
303 #if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \
304     defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET) && \
305     defined(CONFIG_ZYNQ_EEPROM_BUS)
306 	i2c_set_bus_num(CONFIG_ZYNQ_EEPROM_BUS);
307 
308 	if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR,
309 			CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET,
310 			ethaddr, 6))
311 		printf("I2C EEPROM MAC address read failed\n");
312 #endif
313 
314 	return 0;
315 }
316 
317 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
318 int dram_init_banksize(void)
319 {
320 	return fdtdec_setup_memory_banksize();
321 }
322 
323 int dram_init(void)
324 {
325 	if (fdtdec_setup_memory_size() != 0)
326 		return -EINVAL;
327 
328 	return 0;
329 }
330 #else
331 int dram_init(void)
332 {
333 	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
334 
335 	return 0;
336 }
337 #endif
338 
339 void reset_cpu(ulong addr)
340 {
341 }
342 
343 int board_late_init(void)
344 {
345 	u32 reg = 0;
346 	u8 bootmode;
347 	const char *mode;
348 	char *new_targets;
349 	int ret;
350 
351 	if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
352 		debug("Saved variables - Skipping\n");
353 		return 0;
354 	}
355 
356 	ret = zynqmp_mmio_read((ulong)&crlapb_base->boot_mode, &reg);
357 	if (ret)
358 		return -EINVAL;
359 
360 	if (reg >> BOOT_MODE_ALT_SHIFT)
361 		reg >>= BOOT_MODE_ALT_SHIFT;
362 
363 	bootmode = reg & BOOT_MODES_MASK;
364 
365 	puts("Bootmode: ");
366 	switch (bootmode) {
367 	case USB_MODE:
368 		puts("USB_MODE\n");
369 		mode = "usb";
370 		env_set("modeboot", "usb_dfu_spl");
371 		break;
372 	case JTAG_MODE:
373 		puts("JTAG_MODE\n");
374 		mode = "pxe dhcp";
375 		env_set("modeboot", "jtagboot");
376 		break;
377 	case QSPI_MODE_24BIT:
378 	case QSPI_MODE_32BIT:
379 		mode = "qspi0";
380 		puts("QSPI_MODE\n");
381 		env_set("modeboot", "qspiboot");
382 		break;
383 	case EMMC_MODE:
384 		puts("EMMC_MODE\n");
385 		mode = "mmc0";
386 		env_set("modeboot", "emmcboot");
387 		break;
388 	case SD_MODE:
389 		puts("SD_MODE\n");
390 		mode = "mmc0";
391 		env_set("modeboot", "sdboot");
392 		break;
393 	case SD1_LSHFT_MODE:
394 		puts("LVL_SHFT_");
395 		/* fall through */
396 	case SD_MODE1:
397 		puts("SD_MODE1\n");
398 #if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1)
399 		mode = "mmc1";
400 		env_set("sdbootdev", "1");
401 #else
402 		mode = "mmc0";
403 #endif
404 		env_set("modeboot", "sdboot");
405 		break;
406 	case NAND_MODE:
407 		puts("NAND_MODE\n");
408 		mode = "nand0";
409 		env_set("modeboot", "nandboot");
410 		break;
411 	default:
412 		mode = "";
413 		printf("Invalid Boot Mode:0x%x\n", bootmode);
414 		break;
415 	}
416 
417 	/*
418 	 * One terminating char + one byte for space between mode
419 	 * and default boot_targets
420 	 */
421 	new_targets = calloc(1, strlen(mode) +
422 				strlen(env_get("boot_targets")) + 2);
423 
424 	sprintf(new_targets, "%s %s", mode, env_get("boot_targets"));
425 	env_set("boot_targets", new_targets);
426 
427 	return 0;
428 }
429 
430 int checkboard(void)
431 {
432 	puts("Board: Xilinx ZynqMP\n");
433 	return 0;
434 }
435 
436 #ifdef CONFIG_USB_DWC3
437 static struct dwc3_device dwc3_device_data0 = {
438 	.maximum_speed = USB_SPEED_HIGH,
439 	.base = ZYNQMP_USB0_XHCI_BASEADDR,
440 	.dr_mode = USB_DR_MODE_PERIPHERAL,
441 	.index = 0,
442 };
443 
444 static struct dwc3_device dwc3_device_data1 = {
445 	.maximum_speed = USB_SPEED_HIGH,
446 	.base = ZYNQMP_USB1_XHCI_BASEADDR,
447 	.dr_mode = USB_DR_MODE_PERIPHERAL,
448 	.index = 1,
449 };
450 
451 int usb_gadget_handle_interrupts(int index)
452 {
453 	dwc3_uboot_handle_interrupt(index);
454 	return 0;
455 }
456 
457 int board_usb_init(int index, enum usb_init_type init)
458 {
459 	debug("%s: index %x\n", __func__, index);
460 
461 #if defined(CONFIG_USB_GADGET_DOWNLOAD)
462 	g_dnl_set_serialnumber(CONFIG_SYS_CONFIG_NAME);
463 #endif
464 
465 	switch (index) {
466 	case 0:
467 		return dwc3_uboot_init(&dwc3_device_data0);
468 	case 1:
469 		return dwc3_uboot_init(&dwc3_device_data1);
470 	};
471 
472 	return -1;
473 }
474 
475 int board_usb_cleanup(int index, enum usb_init_type init)
476 {
477 	dwc3_uboot_exit(index);
478 	return 0;
479 }
480 #endif
481