common: Drop log.h from common header
[platform/kernel/u-boot.git] / board / xilinx / zynqmp / zynqmp.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2014 - 2015 Xilinx, Inc.
4  * Michal Simek <michal.simek@xilinx.com>
5  */
6
7 #include <common.h>
8 #include <command.h>
9 #include <cpu_func.h>
10 #include <debug_uart.h>
11 #include <env.h>
12 #include <init.h>
13 #include <log.h>
14 #include <net.h>
15 #include <sata.h>
16 #include <ahci.h>
17 #include <scsi.h>
18 #include <malloc.h>
19 #include <wdt.h>
20 #include <asm/arch/clk.h>
21 #include <asm/arch/hardware.h>
22 #include <asm/arch/sys_proto.h>
23 #include <asm/arch/psu_init_gpl.h>
24 #include <asm/cache.h>
25 #include <asm/io.h>
26 #include <dm/device.h>
27 #include <dm/uclass.h>
28 #include <usb.h>
29 #include <dwc3-uboot.h>
30 #include <zynqmppl.h>
31 #include <zynqmp_firmware.h>
32 #include <g_dnl.h>
33 #include "../common/board.h"
34
35 #include "pm_cfg_obj.h"
36
37 DECLARE_GLOBAL_DATA_PTR;
38
39 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
40     !defined(CONFIG_SPL_BUILD)
41 static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
42
43 static const struct {
44         u32 id;
45         u32 ver;
46         char *name;
47         bool evexists;
48 } zynqmp_devices[] = {
49         {
50                 .id = 0x10,
51                 .name = "3eg",
52         },
53         {
54                 .id = 0x10,
55                 .ver = 0x2c,
56                 .name = "3cg",
57         },
58         {
59                 .id = 0x11,
60                 .name = "2eg",
61         },
62         {
63                 .id = 0x11,
64                 .ver = 0x2c,
65                 .name = "2cg",
66         },
67         {
68                 .id = 0x20,
69                 .name = "5ev",
70                 .evexists = 1,
71         },
72         {
73                 .id = 0x20,
74                 .ver = 0x100,
75                 .name = "5eg",
76                 .evexists = 1,
77         },
78         {
79                 .id = 0x20,
80                 .ver = 0x12c,
81                 .name = "5cg",
82                 .evexists = 1,
83         },
84         {
85                 .id = 0x21,
86                 .name = "4ev",
87                 .evexists = 1,
88         },
89         {
90                 .id = 0x21,
91                 .ver = 0x100,
92                 .name = "4eg",
93                 .evexists = 1,
94         },
95         {
96                 .id = 0x21,
97                 .ver = 0x12c,
98                 .name = "4cg",
99                 .evexists = 1,
100         },
101         {
102                 .id = 0x30,
103                 .name = "7ev",
104                 .evexists = 1,
105         },
106         {
107                 .id = 0x30,
108                 .ver = 0x100,
109                 .name = "7eg",
110                 .evexists = 1,
111         },
112         {
113                 .id = 0x30,
114                 .ver = 0x12c,
115                 .name = "7cg",
116                 .evexists = 1,
117         },
118         {
119                 .id = 0x38,
120                 .name = "9eg",
121         },
122         {
123                 .id = 0x38,
124                 .ver = 0x2c,
125                 .name = "9cg",
126         },
127         {
128                 .id = 0x39,
129                 .name = "6eg",
130         },
131         {
132                 .id = 0x39,
133                 .ver = 0x2c,
134                 .name = "6cg",
135         },
136         {
137                 .id = 0x40,
138                 .name = "11eg",
139         },
140         { /* For testing purpose only */
141                 .id = 0x50,
142                 .ver = 0x2c,
143                 .name = "15cg",
144         },
145         {
146                 .id = 0x50,
147                 .name = "15eg",
148         },
149         {
150                 .id = 0x58,
151                 .name = "19eg",
152         },
153         {
154                 .id = 0x59,
155                 .name = "17eg",
156         },
157         {
158                 .id = 0x61,
159                 .name = "21dr",
160         },
161         {
162                 .id = 0x63,
163                 .name = "23dr",
164         },
165         {
166                 .id = 0x65,
167                 .name = "25dr",
168         },
169         {
170                 .id = 0x64,
171                 .name = "27dr",
172         },
173         {
174                 .id = 0x60,
175                 .name = "28dr",
176         },
177         {
178                 .id = 0x62,
179                 .name = "29dr",
180         },
181         {
182                 .id = 0x66,
183                 .name = "39dr",
184         },
185         {
186                 .id = 0x7b,
187                 .name = "48dr",
188         },
189         {
190                 .id = 0x7e,
191                 .name = "49dr",
192         },
193 };
194 #endif
195
196 int chip_id(unsigned char id)
197 {
198         struct pt_regs regs;
199         int val = -EINVAL;
200
201         if (current_el() != 3) {
202                 regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID;
203                 regs.regs[1] = 0;
204                 regs.regs[2] = 0;
205                 regs.regs[3] = 0;
206
207                 smc_call(&regs);
208
209                 /*
210                  * SMC returns:
211                  * regs[0][31:0]  = status of the operation
212                  * regs[0][63:32] = CSU.IDCODE register
213                  * regs[1][31:0]  = CSU.version register
214                  * regs[1][63:32] = CSU.IDCODE2 register
215                  */
216                 switch (id) {
217                 case IDCODE:
218                         regs.regs[0] = upper_32_bits(regs.regs[0]);
219                         regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
220                                         ZYNQMP_CSU_IDCODE_SVD_MASK;
221                         regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
222                         val = regs.regs[0];
223                         break;
224                 case VERSION:
225                         regs.regs[1] = lower_32_bits(regs.regs[1]);
226                         regs.regs[1] &= ZYNQMP_CSU_SILICON_VER_MASK;
227                         val = regs.regs[1];
228                         break;
229                 case IDCODE2:
230                         regs.regs[1] = lower_32_bits(regs.regs[1]);
231                         regs.regs[1] >>= ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
232                         val = regs.regs[1];
233                         break;
234                 default:
235                         printf("%s, Invalid Req:0x%x\n", __func__, id);
236                 }
237         } else {
238                 switch (id) {
239                 case IDCODE:
240                         val = readl(ZYNQMP_CSU_IDCODE_ADDR);
241                         val &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
242                                ZYNQMP_CSU_IDCODE_SVD_MASK;
243                         val >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
244                         break;
245                 case VERSION:
246                         val = readl(ZYNQMP_CSU_VER_ADDR);
247                         val &= ZYNQMP_CSU_SILICON_VER_MASK;
248                         break;
249                 default:
250                         printf("%s, Invalid Req:0x%x\n", __func__, id);
251                 }
252         }
253
254         return val;
255 }
256
257 #define ZYNQMP_VERSION_SIZE             9
258 #define ZYNQMP_PL_STATUS_BIT            9
259 #define ZYNQMP_IPDIS_VCU_BIT            8
260 #define ZYNQMP_PL_STATUS_MASK           BIT(ZYNQMP_PL_STATUS_BIT)
261 #define ZYNQMP_CSU_VERSION_MASK         ~(ZYNQMP_PL_STATUS_MASK)
262 #define ZYNQMP_CSU_VCUDIS_VER_MASK      ZYNQMP_CSU_VERSION_MASK & \
263                                         ~BIT(ZYNQMP_IPDIS_VCU_BIT)
264 #define MAX_VARIANTS_EV                 3
265
266 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
267         !defined(CONFIG_SPL_BUILD)
268 static char *zynqmp_get_silicon_idcode_name(void)
269 {
270         u32 i, id, ver, j;
271         char *buf;
272         static char name[ZYNQMP_VERSION_SIZE];
273
274         id = chip_id(IDCODE);
275         ver = chip_id(IDCODE2);
276
277         for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
278                 if (zynqmp_devices[i].id == id) {
279                         if (zynqmp_devices[i].evexists &&
280                             !(ver & ZYNQMP_PL_STATUS_MASK))
281                                 break;
282                         if (zynqmp_devices[i].ver == (ver &
283                             ZYNQMP_CSU_VERSION_MASK))
284                                 break;
285                 }
286         }
287
288         if (i >= ARRAY_SIZE(zynqmp_devices))
289                 return "unknown";
290
291         strncat(name, "zu", 2);
292         if (!zynqmp_devices[i].evexists ||
293             (ver & ZYNQMP_PL_STATUS_MASK)) {
294                 strncat(name, zynqmp_devices[i].name,
295                         ZYNQMP_VERSION_SIZE - 3);
296                 return name;
297         }
298
299         /*
300          * Here we are means, PL not powered up and ev variant
301          * exists. So, we need to ignore VCU disable bit(8) in
302          * version and findout if its CG or EG/EV variant.
303          */
304         for (j = 0; j < MAX_VARIANTS_EV; j++, i++) {
305                 if ((zynqmp_devices[i].ver & ~BIT(ZYNQMP_IPDIS_VCU_BIT)) ==
306                     (ver & ZYNQMP_CSU_VCUDIS_VER_MASK)) {
307                         strncat(name, zynqmp_devices[i].name,
308                                 ZYNQMP_VERSION_SIZE - 3);
309                         break;
310                 }
311         }
312
313         if (j >= MAX_VARIANTS_EV)
314                 return "unknown";
315
316         if (strstr(name, "eg") || strstr(name, "ev")) {
317                 buf = strstr(name, "e");
318                 *buf = '\0';
319         }
320
321         return name;
322 }
323 #endif
324
325 int board_early_init_f(void)
326 {
327 #if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED)
328         int ret;
329
330         ret = psu_init();
331         if (ret)
332                 return ret;
333
334         /* Delay is required for clocks to be propagated */
335         udelay(1000000);
336 #endif
337
338 #ifdef CONFIG_DEBUG_UART
339         /* Uart debug for sure */
340         debug_uart_init();
341         puts("Debug uart enabled\n"); /* or printch() */
342 #endif
343
344         return 0;
345 }
346
347 static int multi_boot(void)
348 {
349         u32 multiboot;
350
351         multiboot = readl(&csu_base->multi_boot);
352
353         printf("Multiboot:\t%x\n", multiboot);
354
355         return 0;
356 }
357
358 int board_init(void)
359 {
360 #if defined(CONFIG_ZYNQMP_FIRMWARE)
361         struct udevice *dev;
362
363         uclass_get_device_by_name(UCLASS_FIRMWARE, "zynqmp-power", &dev);
364         if (!dev)
365                 panic("PMU Firmware device not found - Enable it");
366 #endif
367
368 #if defined(CONFIG_SPL_BUILD)
369         /* Check *at build time* if the filename is an non-empty string */
370         if (sizeof(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE) > 1)
371                 zynqmp_pmufw_load_config_object(zynqmp_pm_cfg_obj,
372                                                 zynqmp_pm_cfg_obj_size);
373 #endif
374
375         printf("EL Level:\tEL%d\n", current_el());
376
377 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
378     !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
379     defined(CONFIG_SPL_BUILD))
380         if (current_el() != 3) {
381                 zynqmppl.name = zynqmp_get_silicon_idcode_name();
382                 printf("Chip ID:\t%s\n", zynqmppl.name);
383                 fpga_init();
384                 fpga_add(fpga_xilinx, &zynqmppl);
385         }
386 #endif
387
388         if (current_el() == 3)
389                 multi_boot();
390
391         return 0;
392 }
393
394 int board_early_init_r(void)
395 {
396         u32 val;
397
398         if (current_el() != 3)
399                 return 0;
400
401         val = readl(&crlapb_base->timestamp_ref_ctrl);
402         val &= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
403
404         if (!val) {
405                 val = readl(&crlapb_base->timestamp_ref_ctrl);
406                 val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
407                 writel(val, &crlapb_base->timestamp_ref_ctrl);
408
409                 /* Program freq register in System counter */
410                 writel(zynqmp_get_system_timer_freq(),
411                        &iou_scntr_secure->base_frequency_id_register);
412                 /* And enable system counter */
413                 writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
414                        &iou_scntr_secure->counter_control_register);
415         }
416         return 0;
417 }
418
419 unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
420                          char *const argv[])
421 {
422         int ret = 0;
423
424         if (current_el() > 1) {
425                 smp_kick_all_cpus();
426                 dcache_disable();
427                 armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry,
428                                     ES_TO_AARCH64);
429         } else {
430                 printf("FAIL: current EL is not above EL1\n");
431                 ret = EINVAL;
432         }
433         return ret;
434 }
435
436 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
437 int dram_init_banksize(void)
438 {
439         int ret;
440
441         ret = fdtdec_setup_memory_banksize();
442         if (ret)
443                 return ret;
444
445         mem_map_fill();
446
447         return 0;
448 }
449
450 int dram_init(void)
451 {
452         if (fdtdec_setup_mem_size_base() != 0)
453                 return -EINVAL;
454
455         return 0;
456 }
457 #else
458 int dram_init_banksize(void)
459 {
460 #if defined(CONFIG_NR_DRAM_BANKS)
461         gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
462         gd->bd->bi_dram[0].size = get_effective_memsize();
463 #endif
464
465         mem_map_fill();
466
467         return 0;
468 }
469
470 int dram_init(void)
471 {
472         gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
473                                     CONFIG_SYS_SDRAM_SIZE);
474
475         return 0;
476 }
477 #endif
478
479 void reset_cpu(ulong addr)
480 {
481 }
482
483 #if defined(CONFIG_BOARD_LATE_INIT)
484 static const struct {
485         u32 bit;
486         const char *name;
487 } reset_reasons[] = {
488         { RESET_REASON_DEBUG_SYS, "DEBUG" },
489         { RESET_REASON_SOFT, "SOFT" },
490         { RESET_REASON_SRST, "SRST" },
491         { RESET_REASON_PSONLY, "PS-ONLY" },
492         { RESET_REASON_PMU, "PMU" },
493         { RESET_REASON_INTERNAL, "INTERNAL" },
494         { RESET_REASON_EXTERNAL, "EXTERNAL" },
495         {}
496 };
497
498 static int reset_reason(void)
499 {
500         u32 reg;
501         int i, ret;
502         const char *reason = NULL;
503
504         ret = zynqmp_mmio_read((ulong)&crlapb_base->reset_reason, &reg);
505         if (ret)
506                 return -EINVAL;
507
508         puts("Reset reason:\t");
509
510         for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) {
511                 if (reg & reset_reasons[i].bit) {
512                         reason = reset_reasons[i].name;
513                         printf("%s ", reset_reasons[i].name);
514                         break;
515                 }
516         }
517
518         puts("\n");
519
520         env_set("reset_reason", reason);
521
522         ret = zynqmp_mmio_write((ulong)&crlapb_base->reset_reason, ~0, ~0);
523         if (ret)
524                 return -EINVAL;
525
526         return ret;
527 }
528
529 static int set_fdtfile(void)
530 {
531         char *compatible, *fdtfile;
532         const char *suffix = ".dtb";
533         const char *vendor = "xilinx/";
534
535         if (env_get("fdtfile"))
536                 return 0;
537
538         compatible = (char *)fdt_getprop(gd->fdt_blob, 0, "compatible", NULL);
539         if (compatible) {
540                 debug("Compatible: %s\n", compatible);
541
542                 /* Discard vendor prefix */
543                 strsep(&compatible, ",");
544
545                 fdtfile = calloc(1, strlen(vendor) + strlen(compatible) +
546                                  strlen(suffix) + 1);
547                 if (!fdtfile)
548                         return -ENOMEM;
549
550                 sprintf(fdtfile, "%s%s%s", vendor, compatible, suffix);
551
552                 env_set("fdtfile", fdtfile);
553                 free(fdtfile);
554         }
555
556         return 0;
557 }
558
559 static u8 zynqmp_get_bootmode(void)
560 {
561         u8 bootmode;
562         u32 reg = 0;
563         int ret;
564
565         ret = zynqmp_mmio_read((ulong)&crlapb_base->boot_mode, &reg);
566         if (ret)
567                 return -EINVAL;
568
569         if (reg >> BOOT_MODE_ALT_SHIFT)
570                 reg >>= BOOT_MODE_ALT_SHIFT;
571
572         bootmode = reg & BOOT_MODES_MASK;
573
574         return bootmode;
575 }
576
577 int board_late_init(void)
578 {
579         u8 bootmode;
580         struct udevice *dev;
581         int bootseq = -1;
582         int bootseq_len = 0;
583         int env_targets_len = 0;
584         const char *mode;
585         char *new_targets;
586         char *env_targets;
587         int ret;
588
589 #if defined(CONFIG_USB_ETHER) && !defined(CONFIG_USB_GADGET_DOWNLOAD)
590         usb_ether_init();
591 #endif
592
593         if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
594                 debug("Saved variables - Skipping\n");
595                 return 0;
596         }
597
598         ret = set_fdtfile();
599         if (ret)
600                 return ret;
601
602         bootmode = zynqmp_get_bootmode();
603
604         puts("Bootmode: ");
605         switch (bootmode) {
606         case USB_MODE:
607                 puts("USB_MODE\n");
608                 mode = "usb";
609                 env_set("modeboot", "usb_dfu_spl");
610                 break;
611         case JTAG_MODE:
612                 puts("JTAG_MODE\n");
613                 mode = "jtag pxe dhcp";
614                 env_set("modeboot", "jtagboot");
615                 break;
616         case QSPI_MODE_24BIT:
617         case QSPI_MODE_32BIT:
618                 mode = "qspi0";
619                 puts("QSPI_MODE\n");
620                 env_set("modeboot", "qspiboot");
621                 break;
622         case EMMC_MODE:
623                 puts("EMMC_MODE\n");
624                 if (uclass_get_device_by_name(UCLASS_MMC,
625                                               "mmc@ff160000", &dev) &&
626                     uclass_get_device_by_name(UCLASS_MMC,
627                                               "sdhci@ff160000", &dev)) {
628                         puts("Boot from EMMC but without SD0 enabled!\n");
629                         return -1;
630                 }
631                 debug("mmc0 device found at %p, seq %d\n", dev, dev->seq);
632
633                 mode = "mmc";
634                 bootseq = dev->seq;
635                 break;
636         case SD_MODE:
637                 puts("SD_MODE\n");
638                 if (uclass_get_device_by_name(UCLASS_MMC,
639                                               "mmc@ff160000", &dev) &&
640                     uclass_get_device_by_name(UCLASS_MMC,
641                                               "sdhci@ff160000", &dev)) {
642                         puts("Boot from SD0 but without SD0 enabled!\n");
643                         return -1;
644                 }
645                 debug("mmc0 device found at %p, seq %d\n", dev, dev->seq);
646
647                 mode = "mmc";
648                 bootseq = dev->seq;
649                 env_set("modeboot", "sdboot");
650                 break;
651         case SD1_LSHFT_MODE:
652                 puts("LVL_SHFT_");
653                 /* fall through */
654         case SD_MODE1:
655                 puts("SD_MODE1\n");
656                 if (uclass_get_device_by_name(UCLASS_MMC,
657                                               "mmc@ff170000", &dev) &&
658                     uclass_get_device_by_name(UCLASS_MMC,
659                                               "sdhci@ff170000", &dev)) {
660                         puts("Boot from SD1 but without SD1 enabled!\n");
661                         return -1;
662                 }
663                 debug("mmc1 device found at %p, seq %d\n", dev, dev->seq);
664
665                 mode = "mmc";
666                 bootseq = dev->seq;
667                 env_set("modeboot", "sdboot");
668                 break;
669         case NAND_MODE:
670                 puts("NAND_MODE\n");
671                 mode = "nand0";
672                 env_set("modeboot", "nandboot");
673                 break;
674         default:
675                 mode = "";
676                 printf("Invalid Boot Mode:0x%x\n", bootmode);
677                 break;
678         }
679
680         if (bootseq >= 0) {
681                 bootseq_len = snprintf(NULL, 0, "%i", bootseq);
682                 debug("Bootseq len: %x\n", bootseq_len);
683         }
684
685         /*
686          * One terminating char + one byte for space between mode
687          * and default boot_targets
688          */
689         env_targets = env_get("boot_targets");
690         if (env_targets)
691                 env_targets_len = strlen(env_targets);
692
693         new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
694                              bootseq_len);
695         if (!new_targets)
696                 return -ENOMEM;
697
698         if (bootseq >= 0)
699                 sprintf(new_targets, "%s%x %s", mode, bootseq,
700                         env_targets ? env_targets : "");
701         else
702                 sprintf(new_targets, "%s %s", mode,
703                         env_targets ? env_targets : "");
704
705         env_set("boot_targets", new_targets);
706
707         reset_reason();
708
709         return board_late_init_xilinx();
710 }
711 #endif
712
713 int checkboard(void)
714 {
715         puts("Board: Xilinx ZynqMP\n");
716         return 0;
717 }