Merge tag 'xilinx-for-v2020.01' of https://gitlab.denx.de/u-boot/custodians/u-boot...
[platform/kernel/u-boot.git] / board / xilinx / versal / board.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2014 - 2018 Xilinx, Inc.
4  * Michal Simek <michal.simek@xilinx.com>
5  */
6
7 #include <common.h>
8 #include <fdtdec.h>
9 #include <malloc.h>
10 #include <asm/io.h>
11 #include <asm/arch/hardware.h>
12 #include <asm/arch/sys_proto.h>
13 #include <dm/device.h>
14 #include <dm/uclass.h>
15 #include <versalpl.h>
16 #include <linux/sizes.h>
17
18 DECLARE_GLOBAL_DATA_PTR;
19
20 #if defined(CONFIG_FPGA_VERSALPL)
21 static xilinx_desc versalpl = XILINX_VERSAL_DESC;
22 #endif
23
24 int board_init(void)
25 {
26         printf("EL Level:\tEL%d\n", current_el());
27
28 #if defined(CONFIG_FPGA_VERSALPL)
29         fpga_init();
30         fpga_add(fpga_xilinx, &versalpl);
31 #endif
32
33         return 0;
34 }
35
36 int board_early_init_r(void)
37 {
38         u32 val;
39
40         if (current_el() != 3)
41                 return 0;
42
43         debug("iou_switch ctrl div0 %x\n",
44               readl(&crlapb_base->iou_switch_ctrl));
45
46         writel(IOU_SWITCH_CTRL_CLKACT_BIT |
47                (CONFIG_IOU_SWITCH_DIVISOR0 << IOU_SWITCH_CTRL_DIVISOR0_SHIFT),
48                &crlapb_base->iou_switch_ctrl);
49
50         /* Global timer init - Program time stamp reference clk */
51         val = readl(&crlapb_base->timestamp_ref_ctrl);
52         val |= CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT;
53         writel(val, &crlapb_base->timestamp_ref_ctrl);
54
55         debug("ref ctrl 0x%x\n",
56               readl(&crlapb_base->timestamp_ref_ctrl));
57
58         /* Clear reset of timestamp reg */
59         writel(0, &crlapb_base->rst_timestamp);
60
61         /*
62          * Program freq register in System counter and
63          * enable system counter.
64          */
65         writel(COUNTER_FREQUENCY,
66                &iou_scntr_secure->base_frequency_id_register);
67
68         debug("counter val 0x%x\n",
69               readl(&iou_scntr_secure->base_frequency_id_register));
70
71         writel(IOU_SCNTRS_CONTROL_EN,
72                &iou_scntr_secure->counter_control_register);
73
74         debug("scntrs control 0x%x\n",
75               readl(&iou_scntr_secure->counter_control_register));
76         debug("timer 0x%llx\n", get_ticks());
77         debug("timer 0x%llx\n", get_ticks());
78
79         return 0;
80 }
81
82 int board_late_init(void)
83 {
84         u32 reg = 0;
85         u8 bootmode;
86         struct udevice *dev;
87         int bootseq = -1;
88         int bootseq_len = 0;
89         int env_targets_len = 0;
90         const char *mode;
91         char *new_targets;
92         char *env_targets;
93         ulong initrd_hi;
94
95         if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
96                 debug("Saved variables - Skipping\n");
97                 return 0;
98         }
99
100         reg = readl(&crp_base->boot_mode_usr);
101
102         if (reg >> BOOT_MODE_ALT_SHIFT)
103                 reg >>= BOOT_MODE_ALT_SHIFT;
104
105         bootmode = reg & BOOT_MODES_MASK;
106
107         puts("Bootmode: ");
108         switch (bootmode) {
109         case USB_MODE:
110                 puts("USB_MODE\n");
111                 mode = "dfu_usb";
112                 break;
113         case JTAG_MODE:
114                 puts("JTAG_MODE\n");
115                 mode = "jtag pxe dhcp";
116                 break;
117         case QSPI_MODE_24BIT:
118                 puts("QSPI_MODE_24\n");
119                 mode = "xspi0";
120                 break;
121         case QSPI_MODE_32BIT:
122                 puts("QSPI_MODE_32\n");
123                 mode = "xspi0";
124                 break;
125         case OSPI_MODE:
126                 puts("OSPI_MODE\n");
127                 mode = "xspi0";
128                 break;
129         case EMMC_MODE:
130                 puts("EMMC_MODE\n");
131                 mode = "mmc0";
132                 break;
133         case SD_MODE:
134                 puts("SD_MODE\n");
135                 if (uclass_get_device_by_name(UCLASS_MMC,
136                                               "sdhci@f1040000", &dev)) {
137                         puts("Boot from SD0 but without SD0 enabled!\n");
138                         return -1;
139                 }
140                 debug("mmc0 device found at %p, seq %d\n", dev, dev->seq);
141
142                 mode = "mmc";
143                 bootseq = dev->seq;
144                 break;
145         case SD1_LSHFT_MODE:
146                 puts("LVL_SHFT_");
147                 /* fall through */
148         case SD_MODE1:
149                 puts("SD_MODE1\n");
150                 if (uclass_get_device_by_name(UCLASS_MMC,
151                                               "sdhci@f1050000", &dev)) {
152                         puts("Boot from SD1 but without SD1 enabled!\n");
153                         return -1;
154                 }
155                 debug("mmc1 device found at %p, seq %d\n", dev, dev->seq);
156
157                 mode = "mmc";
158                 bootseq = dev->seq;
159                 break;
160         default:
161                 mode = "";
162                 printf("Invalid Boot Mode:0x%x\n", bootmode);
163                 break;
164         }
165
166         if (bootseq >= 0) {
167                 bootseq_len = snprintf(NULL, 0, "%i", bootseq);
168                 debug("Bootseq len: %x\n", bootseq_len);
169         }
170
171         /*
172          * One terminating char + one byte for space between mode
173          * and default boot_targets
174          */
175         env_targets = env_get("boot_targets");
176         if (env_targets)
177                 env_targets_len = strlen(env_targets);
178
179         new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
180                              bootseq_len);
181         if (!new_targets)
182                 return -ENOMEM;
183
184         if (bootseq >= 0)
185                 sprintf(new_targets, "%s%x %s", mode, bootseq,
186                         env_targets ? env_targets : "");
187         else
188                 sprintf(new_targets, "%s %s", mode,
189                         env_targets ? env_targets : "");
190
191         env_set("boot_targets", new_targets);
192
193         initrd_hi = gd->start_addr_sp - CONFIG_STACK_SIZE;
194         initrd_hi = round_down(initrd_hi, SZ_16M);
195         env_set_addr("initrd_high", (void *)initrd_hi);
196
197         return 0;
198 }
199
200 int dram_init_banksize(void)
201 {
202         int ret;
203
204         ret = fdtdec_setup_memory_banksize();
205         if (ret)
206                 return ret;
207
208         mem_map_fill();
209
210         return 0;
211 }
212
213 int dram_init(void)
214 {
215         if (fdtdec_setup_mem_size_base() != 0)
216                 return -EINVAL;
217
218         return 0;
219 }
220
221 void reset_cpu(ulong addr)
222 {
223 }