blob: 5b814f7abf53f0cc42414611c7c8fca4365f1cdd [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +05302/*
3 * Copyright 2016 Freescale Semiconductor, Inc.
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +05304 */
5
6#include <common.h>
Simon Glassed38aef2020-05-10 11:40:03 -06007#include <command.h>
Simon Glass3bbe70c2019-12-28 10:44:54 -07008#include <fdt_support.h>
Simon Glassf11478f2019-12-28 10:45:07 -07009#include <hang.h>
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053010#include <i2c.h>
Simon Glass274e0b02020-05-10 11:39:56 -060011#include <asm/cache.h>
Simon Glass97589732020-05-10 11:40:02 -060012#include <init.h>
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053013#include <asm/io.h>
14#include <asm/arch/clock.h>
15#include <asm/arch/fsl_serdes.h>
Prabhakar Kushwaha74d129b2017-01-30 17:05:35 +053016#ifdef CONFIG_FSL_LS_PPA
17#include <asm/arch/ppa.h>
18#endif
York Sun729f2d12017-03-06 09:02:34 -080019#include <asm/arch/mmu.h>
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053020#include <asm/arch/soc.h>
21#include <hwconfig.h>
22#include <ahci.h>
23#include <mmc.h>
24#include <scsi.h>
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053025#include <fsl_esdhc.h>
Simon Glass9d1f6192019-08-02 09:44:25 -060026#include <env_internal.h>
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053027#include <fsl_mmdc.h>
28#include <netdev.h>
Vinitha Pillai-B57223eea4a322017-03-23 13:48:20 +053029#include <fsl_sec.h>
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053030
31DECLARE_GLOBAL_DATA_PTR;
32
Jagdish Gediyaf9cb31e2018-04-13 00:18:22 +053033#define BOOT_FROM_UPPER_BANK 0x2
34#define BOOT_FROM_LOWER_BANK 0x1
35
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053036int checkboard(void)
37{
Bhaskar Upadhaya7fff22a2018-01-11 20:03:31 +053038#ifdef CONFIG_TARGET_LS1012ARDB
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053039 u8 in1;
Biwen Li0a759bb2019-12-31 15:33:41 +080040 int ret, bus_num = 0;
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053041
42 puts("Board: LS1012ARDB ");
43
44 /* Initialize i2c early for Serial flash bank information */
Biwen Li0a759bb2019-12-31 15:33:41 +080045#if defined(CONFIG_DM_I2C)
46 struct udevice *dev;
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053047
Biwen Li0a759bb2019-12-31 15:33:41 +080048 ret = i2c_get_chip_for_busnum(bus_num, I2C_MUX_IO_ADDR,
49 1, &dev);
50 if (ret) {
51 printf("%s: Cannot find udev for a bus %d\n", __func__,
52 bus_num);
53 return -ENXIO;
54 }
55 ret = dm_i2c_read(dev, I2C_MUX_IO_1, &in1, 1);
56#else /* Non DM I2C support - will be removed */
57 i2c_set_bus_num(bus_num);
58 ret = i2c_read(I2C_MUX_IO_ADDR, I2C_MUX_IO_1, 1, &in1, 1);
59#endif
60 if (ret < 0) {
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053061 printf("Error reading i2c boot information!\n");
62 return 0; /* Don't want to hang() on this error */
63 }
64
65 puts("Version");
Yangbo Lu13acb0d2017-12-08 15:35:36 +080066 switch (in1 & SW_REV_MASK) {
67 case SW_REV_A:
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053068 puts(": RevA");
Yangbo Lu13acb0d2017-12-08 15:35:36 +080069 break;
70 case SW_REV_B:
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053071 puts(": RevB");
Yangbo Lu13acb0d2017-12-08 15:35:36 +080072 break;
73 case SW_REV_C:
74 puts(": RevC");
75 break;
76 case SW_REV_C1:
77 puts(": RevC1");
78 break;
79 case SW_REV_C2:
80 puts(": RevC2");
81 break;
82 case SW_REV_D:
83 puts(": RevD");
84 break;
85 case SW_REV_E:
86 puts(": RevE");
87 break;
88 default:
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053089 puts(": unknown");
Yangbo Lu13acb0d2017-12-08 15:35:36 +080090 break;
91 }
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053092
93 printf(", boot from QSPI");
Yangbo Lu2786f902017-12-08 15:35:35 +080094 if ((in1 & SW_BOOT_MASK) == SW_BOOT_EMU)
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053095 puts(": emu\n");
Yangbo Lu2786f902017-12-08 15:35:35 +080096 else if ((in1 & SW_BOOT_MASK) == SW_BOOT_BANK1)
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053097 puts(": bank1\n");
Yangbo Lu2786f902017-12-08 15:35:35 +080098 else if ((in1 & SW_BOOT_MASK) == SW_BOOT_BANK2)
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +053099 puts(": bank2\n");
100 else
101 puts("unknown\n");
Bhaskar Upadhaya7fff22a2018-01-11 20:03:31 +0530102#else
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +0530103
Bhaskar Upadhaya7fff22a2018-01-11 20:03:31 +0530104 puts("Board: LS1012A2G5RDB ");
105#endif
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +0530106 return 0;
107}
108
Rajesh Bhagatfcafef62018-11-05 18:02:53 +0000109#ifdef CONFIG_TFABOOT
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +0530110int dram_init(void)
111{
Rajesh Bhagatfcafef62018-11-05 18:02:53 +0000112 gd->ram_size = tfa_get_dram_size();
113 if (!gd->ram_size)
114 gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
115
116 return 0;
117}
118#else
119int dram_init(void)
120{
121#ifndef CONFIG_TFABOOT
York Sunc1e979b2016-09-26 08:09:25 -0700122 static const struct fsl_mmdc_info mparam = {
123 0x05180000, /* mdctl */
124 0x00030035, /* mdpdc */
125 0x12554000, /* mdotc */
126 0xbabf7954, /* mdcfg0 */
127 0xdb328f64, /* mdcfg1 */
128 0x01ff00db, /* mdcfg2 */
129 0x00001680, /* mdmisc */
130 0x0f3c8000, /* mdref */
131 0x00002000, /* mdrwd */
132 0x00bf1023, /* mdor */
133 0x0000003f, /* mdasp */
134 0x0000022a, /* mpodtctrl */
135 0xa1390003, /* mpzqhwctrl */
136 };
137
138 mmdc_init(&mparam);
Rajesh Bhagatfcafef62018-11-05 18:02:53 +0000139#endif
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +0530140
141 gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
York Sun729f2d12017-03-06 09:02:34 -0800142#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
143 /* This will break-before-make MMU for DDR */
144 update_early_mmu_table();
145#endif
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +0530146
147 return 0;
148}
Rajesh Bhagatfcafef62018-11-05 18:02:53 +0000149#endif
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +0530150
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +0530151
152int board_early_init_f(void)
153{
154 fsl_lsch2_early_init_f();
155
156 return 0;
157}
158
159int board_init(void)
160{
Ashish Kumar11234062017-08-11 11:09:14 +0530161 struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR +
162 CONFIG_SYS_CCI400_OFFSET);
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +0530163 /*
164 * Set CCI-400 control override register to enable barrier
165 * transaction
166 */
Rajesh Bhagatfcafef62018-11-05 18:02:53 +0000167 if (current_el() == 3)
168 out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +0530169
Hou Zhiqiang4b23ca82016-08-02 19:03:27 +0800170#ifdef CONFIG_SYS_FSL_ERRATUM_A010315
171 erratum_a010315();
172#endif
173
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +0530174#ifdef CONFIG_ENV_IS_NOWHERE
175 gd->env_addr = (ulong)&default_environment[0];
176#endif
177
Vinitha Pillai-B57223eea4a322017-03-23 13:48:20 +0530178#ifdef CONFIG_FSL_CAAM
179 sec_init();
180#endif
181
Prabhakar Kushwaha74d129b2017-01-30 17:05:35 +0530182#ifdef CONFIG_FSL_LS_PPA
183 ppa_init();
184#endif
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +0530185 return 0;
186}
187
Bhaskar Upadhaya7fff22a2018-01-11 20:03:31 +0530188#ifdef CONFIG_TARGET_LS1012ARDB
Yangbo Lub2495c02017-01-17 10:43:56 +0800189int esdhc_status_fixup(void *blob, const char *compat)
190{
Yangbo Lub2495c02017-01-17 10:43:56 +0800191 char esdhc1_path[] = "/soc/esdhc@1580000";
Yangbo Lu878c9782017-12-08 15:35:37 +0800192 bool sdhc2_en = false;
Yangbo Lub2495c02017-01-17 10:43:56 +0800193 u8 mux_sdhc2;
Yangbo Lu878c9782017-12-08 15:35:37 +0800194 u8 io = 0;
Biwen Li0a759bb2019-12-31 15:33:41 +0800195 int ret, bus_num = 0;
Yangbo Lub2495c02017-01-17 10:43:56 +0800196
Biwen Li0a759bb2019-12-31 15:33:41 +0800197#if defined(CONFIG_DM_I2C)
198 struct udevice *dev;
Yangbo Lub2495c02017-01-17 10:43:56 +0800199
Biwen Li0a759bb2019-12-31 15:33:41 +0800200 ret = i2c_get_chip_for_busnum(bus_num, I2C_MUX_IO_ADDR,
201 1, &dev);
202 if (ret) {
203 printf("%s: Cannot find udev for a bus %d\n", __func__,
204 bus_num);
205 return -ENXIO;
206 }
207 ret = dm_i2c_read(dev, I2C_MUX_IO_1, &io, 1);
208#else
209 i2c_set_bus_num(bus_num);
Yangbo Lu878c9782017-12-08 15:35:37 +0800210 /* IO1[7:3] is the field of board revision info. */
Biwen Li0a759bb2019-12-31 15:33:41 +0800211 ret = i2c_read(I2C_MUX_IO_ADDR, I2C_MUX_IO_1, 1, &io, 1);
212#endif
213 if (ret < 0) {
Yangbo Lub2495c02017-01-17 10:43:56 +0800214 printf("Error reading i2c boot information!\n");
Yangbo Lu878c9782017-12-08 15:35:37 +0800215 return 0;
Yangbo Lub2495c02017-01-17 10:43:56 +0800216 }
217
Yangbo Lu878c9782017-12-08 15:35:37 +0800218 /* hwconfig method is used for RevD and later versions. */
219 if ((io & SW_REV_MASK) <= SW_REV_D) {
220#ifdef CONFIG_HWCONFIG
221 if (hwconfig("esdhc1"))
222 sdhc2_en = true;
223#endif
224 } else {
225 /*
226 * The I2C IO-expander for mux select is used to control
227 * the muxing of various onboard interfaces.
228 *
229 * IO0[3:2] indicates SDHC2 interface demultiplexer
230 * select lines.
231 * 00 - SDIO wifi
232 * 01 - GPIO (to Arduino)
233 * 10 - eMMC Memory
234 * 11 - SPI
235 */
Biwen Li0a759bb2019-12-31 15:33:41 +0800236#if defined(CONFIG_DM_I2C)
237 ret = dm_i2c_read(dev, I2C_MUX_IO_0, &io, 1);
238#else
239 ret = i2c_read(I2C_MUX_IO_ADDR, I2C_MUX_IO_0, 1, &io, 1);
240#endif
241 if (ret < 0) {
Yangbo Lu878c9782017-12-08 15:35:37 +0800242 printf("Error reading i2c boot information!\n");
243 return 0;
244 }
245
246 mux_sdhc2 = (io & 0x0c) >> 2;
247 /* Enable SDHC2 only when use SDIO wifi and eMMC */
248 if (mux_sdhc2 == 2 || mux_sdhc2 == 0)
249 sdhc2_en = true;
250 }
Yangbo Lu878c9782017-12-08 15:35:37 +0800251 if (sdhc2_en)
Yangbo Lub2495c02017-01-17 10:43:56 +0800252 do_fixup_by_path(blob, esdhc1_path, "status", "okay",
253 sizeof("okay"), 1);
254 else
255 do_fixup_by_path(blob, esdhc1_path, "status", "disabled",
256 sizeof("disabled"), 1);
257 return 0;
258}
Bhaskar Upadhaya7fff22a2018-01-11 20:03:31 +0530259#endif
Yangbo Lub2495c02017-01-17 10:43:56 +0800260
Prabhakar Kushwahaa315c662016-06-03 18:41:35 +0530261int ft_board_setup(void *blob, bd_t *bd)
262{
263 arch_fixup_fdt(blob);
264
265 ft_cpu_setup(blob, bd);
266
267 return 0;
268}
Jagdish Gediyaf9cb31e2018-04-13 00:18:22 +0530269
270static int switch_to_bank1(void)
271{
Biwen Li0a759bb2019-12-31 15:33:41 +0800272 u8 data = 0xf4, chip_addr = 0x24, offset_addr = 0x03;
273 int ret, bus_num = 0;
Jagdish Gediyaf9cb31e2018-04-13 00:18:22 +0530274
Biwen Li0a759bb2019-12-31 15:33:41 +0800275#if defined(CONFIG_DM_I2C)
276 struct udevice *dev;
277
278 ret = i2c_get_chip_for_busnum(bus_num, chip_addr,
279 1, &dev);
280 if (ret) {
281 printf("%s: Cannot find udev for a bus %d\n", __func__,
282 bus_num);
283 return -ENXIO;
284 }
285 /*
286 * --------------------------------------------------------------------
287 * |bus |I2C address| Device | Notes |
288 * --------------------------------------------------------------------
289 * |I2C1|0x24, 0x25,| IO expander (CFG,| Provides 16bits of General |
290 * | |0x26 | RESET, and INT/ | Purpose parallel Input/Output|
291 * | | | KW41GPIO) - NXP | (GPIO) expansion for the |
292 * | | | PCAL9555AHF | I2C bus |
293 * ----- --------------------------------------------------------------
294 * - mount three IO expander(PCAL9555AHF) on I2C1
295 *
296 * PCAL9555A device address
297 * slave address
298 * --------------------------------------
299 * | 0 | 1 | 0 | 0 | A2 | A1 | A0 | R/W |
300 * --------------------------------------
301 * | fixed | hardware selectable|
302 *
303 * Output port 1(Pinter register bits = 0x03)
304 *
305 * P1_[7~0] = 0xf4
306 * P1_0 <---> CFG_MUX_QSPI_S0
307 * P1_1 <---> CFG_MUX_QSPI_S1
308 * CFG_MUX_QSPI_S[1:0] = 0b00
309 *
310 * QSPI chip-select demultiplexer select
311 * ---------------------------------------------------------------------
312 * CFG_MUX_QSPI_S1|CFG_MUX_QSPI_S0| Values
313 * ---------------------------------------------------------------------
314 * 0 | 0 |CS routed to SPI memory bank1(default)
315 * ---------------------------------------------------------------------
316 * 0 | 1 |CS routed to SPI memory bank2
317 * ---------------------------------------------------------------------
318 *
319 */
320 ret = dm_i2c_write(dev, offset_addr, &data, 1);
321#else /* Non DM I2C support - will be removed */
322 i2c_set_bus_num(bus_num);
323 ret = i2c_write(chip_addr, offset_addr, 1, &data, 1);
324#endif
Jagdish Gediyaf9cb31e2018-04-13 00:18:22 +0530325
Jagdish Gediyaf9cb31e2018-04-13 00:18:22 +0530326 if (ret) {
327 printf("i2c write error to chip : %u, addr : %u, data : %u\n",
Biwen Li0a759bb2019-12-31 15:33:41 +0800328 chip_addr, offset_addr, data);
Jagdish Gediyaf9cb31e2018-04-13 00:18:22 +0530329 }
330
331 return ret;
332}
333
334static int switch_to_bank2(void)
335{
Biwen Li0a759bb2019-12-31 15:33:41 +0800336 u8 data[2] = {0xfc, 0xf5}, offset_addr[2] = {0x7, 0x3};
337 u8 chip_addr = 0x24;
338 int ret, i, bus_num = 0;
Jagdish Gediyaf9cb31e2018-04-13 00:18:22 +0530339
Biwen Li0a759bb2019-12-31 15:33:41 +0800340#if defined(CONFIG_DM_I2C)
341 struct udevice *dev;
Jagdish Gediyaf9cb31e2018-04-13 00:18:22 +0530342
Biwen Li0a759bb2019-12-31 15:33:41 +0800343 ret = i2c_get_chip_for_busnum(bus_num, chip_addr,
344 1, &dev);
Jagdish Gediyaf9cb31e2018-04-13 00:18:22 +0530345 if (ret) {
Biwen Li0a759bb2019-12-31 15:33:41 +0800346 printf("%s: Cannot find udev for a bus %d\n", __func__,
347 bus_num);
348 return -ENXIO;
Jagdish Gediyaf9cb31e2018-04-13 00:18:22 +0530349 }
Biwen Li0a759bb2019-12-31 15:33:41 +0800350#else /* Non DM I2C support - will be removed */
351 i2c_set_bus_num(bus_num);
352#endif
Jagdish Gediyaf9cb31e2018-04-13 00:18:22 +0530353
Biwen Li0a759bb2019-12-31 15:33:41 +0800354 /*
355 * 1th step: config port 1
356 * - the port 1 pin is enabled as an output
357 * 2th step: output port 1
358 * - P1_[7:0] output 0xf5,
359 * then CFG_MUX_QSPI_S[1:0] equal to 0b01,
360 * CS routed to SPI memory bank2
361 */
362 for (i = 0; i < sizeof(data); i++) {
363#if defined(CONFIG_DM_I2C)
364 ret = dm_i2c_write(dev, offset_addr[i], &data[i], 1);
365#else /* Non DM I2C support - will be removed */
366 ret = i2c_write(chip_addr, offset_addr[i], 1, &data[i], 1);
367#endif
368 if (ret) {
369 printf("i2c write error to chip : %u, addr : %u, data : %u\n",
370 chip_addr, offset_addr[i], data[i]);
371 goto err;
372 }
Jagdish Gediyaf9cb31e2018-04-13 00:18:22 +0530373 }
Biwen Li0a759bb2019-12-31 15:33:41 +0800374
Jagdish Gediyaf9cb31e2018-04-13 00:18:22 +0530375err:
376 return ret;
377}
378
379static int convert_flash_bank(int bank)
380{
381 int ret = 0;
382
383 switch (bank) {
384 case BOOT_FROM_UPPER_BANK:
385 ret = switch_to_bank2();
386 break;
387 case BOOT_FROM_LOWER_BANK:
388 ret = switch_to_bank1();
389 break;
390 default:
391 ret = CMD_RET_USAGE;
392 break;
393 };
394
395 return ret;
396}
397
Simon Glassed38aef2020-05-10 11:40:03 -0600398static int flash_bank_cmd(struct cmd_tbl *cmdtp, int flag, int argc,
399 char *const argv[])
Jagdish Gediyaf9cb31e2018-04-13 00:18:22 +0530400{
401 if (argc != 2)
402 return CMD_RET_USAGE;
403 if (strcmp(argv[1], "1") == 0)
404 convert_flash_bank(BOOT_FROM_LOWER_BANK);
405 else if (strcmp(argv[1], "2") == 0)
406 convert_flash_bank(BOOT_FROM_UPPER_BANK);
407 else
408 return CMD_RET_USAGE;
409
410 return 0;
411}
412
413U_BOOT_CMD(
414 boot_bank, 2, 0, flash_bank_cmd,
415 "Flash bank Selection Control",
416 "bank[1-lower bank/2-upper bank] (e.g. boot_bank 1)"
417);