123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * Copyright 2016 Freescale Semiconductor, Inc.
- */
- #include <common.h>
- #include <command.h>
- #include <fdt_support.h>
- #include <hang.h>
- #include <i2c.h>
- #include <asm/cache.h>
- #include <init.h>
- #include <asm/global_data.h>
- #include <asm/io.h>
- #include <asm/arch/clock.h>
- #include <asm/arch/fsl_serdes.h>
- #ifdef CONFIG_FSL_LS_PPA
- #include <asm/arch/ppa.h>
- #endif
- #include <asm/arch/mmu.h>
- #include <asm/arch/soc.h>
- #include <hwconfig.h>
- #include <ahci.h>
- #include <mmc.h>
- #include <scsi.h>
- #include <fsl_esdhc.h>
- #include <env_internal.h>
- #include <fsl_mmdc.h>
- #include <netdev.h>
- #include <fsl_sec.h>
- DECLARE_GLOBAL_DATA_PTR;
- #define BOOT_FROM_UPPER_BANK 0x2
- #define BOOT_FROM_LOWER_BANK 0x1
- int checkboard(void)
- {
- #ifdef CONFIG_TARGET_LS1012ARDB
- u8 in1;
- int ret, bus_num = 0;
- puts("Board: LS1012ARDB ");
- /* Initialize i2c early for Serial flash bank information */
- #if CONFIG_IS_ENABLED(DM_I2C)
- struct udevice *dev;
- ret = i2c_get_chip_for_busnum(bus_num, I2C_MUX_IO_ADDR,
- 1, &dev);
- if (ret) {
- printf("%s: Cannot find udev for a bus %d\n", __func__,
- bus_num);
- return -ENXIO;
- }
- ret = dm_i2c_read(dev, I2C_MUX_IO_1, &in1, 1);
- #else /* Non DM I2C support - will be removed */
- i2c_set_bus_num(bus_num);
- ret = i2c_read(I2C_MUX_IO_ADDR, I2C_MUX_IO_1, 1, &in1, 1);
- #endif
- if (ret < 0) {
- printf("Error reading i2c boot information!\n");
- return 0; /* Don't want to hang() on this error */
- }
- puts("Version");
- switch (in1 & SW_REV_MASK) {
- case SW_REV_A:
- puts(": RevA");
- break;
- case SW_REV_B:
- puts(": RevB");
- break;
- case SW_REV_C:
- puts(": RevC");
- break;
- case SW_REV_C1:
- puts(": RevC1");
- break;
- case SW_REV_C2:
- puts(": RevC2");
- break;
- case SW_REV_D:
- puts(": RevD");
- break;
- case SW_REV_E:
- puts(": RevE");
- break;
- default:
- puts(": unknown");
- break;
- }
- printf(", boot from QSPI");
- if ((in1 & SW_BOOT_MASK) == SW_BOOT_EMU)
- puts(": emu\n");
- else if ((in1 & SW_BOOT_MASK) == SW_BOOT_BANK1)
- puts(": bank1\n");
- else if ((in1 & SW_BOOT_MASK) == SW_BOOT_BANK2)
- puts(": bank2\n");
- else
- puts("unknown\n");
- #else
- puts("Board: LS1012A2G5RDB ");
- #endif
- return 0;
- }
- #ifdef CONFIG_TFABOOT
- int dram_init(void)
- {
- gd->ram_size = tfa_get_dram_size();
- if (!gd->ram_size)
- gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
- return 0;
- }
- #else
- int dram_init(void)
- {
- #ifndef CONFIG_TFABOOT
- static const struct fsl_mmdc_info mparam = {
- 0x05180000, /* mdctl */
- 0x00030035, /* mdpdc */
- 0x12554000, /* mdotc */
- 0xbabf7954, /* mdcfg0 */
- 0xdb328f64, /* mdcfg1 */
- 0x01ff00db, /* mdcfg2 */
- 0x00001680, /* mdmisc */
- 0x0f3c8000, /* mdref */
- 0x00002000, /* mdrwd */
- 0x00bf1023, /* mdor */
- 0x0000003f, /* mdasp */
- 0x0000022a, /* mpodtctrl */
- 0xa1390003, /* mpzqhwctrl */
- };
- mmdc_init(&mparam);
- #endif
- gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
- #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
- /* This will break-before-make MMU for DDR */
- update_early_mmu_table();
- #endif
- return 0;
- }
- #endif
- int board_early_init_f(void)
- {
- fsl_lsch2_early_init_f();
- return 0;
- }
- int board_init(void)
- {
- struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR +
- CONFIG_SYS_CCI400_OFFSET);
- /*
- * Set CCI-400 control override register to enable barrier
- * transaction
- */
- if (current_el() == 3)
- out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
- #ifdef CONFIG_SYS_FSL_ERRATUM_A010315
- erratum_a010315();
- #endif
- #ifdef CONFIG_ENV_IS_NOWHERE
- gd->env_addr = (ulong)&default_environment[0];
- #endif
- #ifdef CONFIG_FSL_CAAM
- sec_init();
- #endif
- #ifdef CONFIG_FSL_LS_PPA
- ppa_init();
- #endif
- return 0;
- }
- #ifdef CONFIG_TARGET_LS1012ARDB
- int esdhc_status_fixup(void *blob, const char *compat)
- {
- char esdhc1_path[] = "/soc/esdhc@1580000";
- bool sdhc2_en = false;
- u8 mux_sdhc2;
- u8 io = 0;
- int ret, bus_num = 0;
- #if CONFIG_IS_ENABLED(DM_I2C)
- struct udevice *dev;
- ret = i2c_get_chip_for_busnum(bus_num, I2C_MUX_IO_ADDR,
- 1, &dev);
- if (ret) {
- printf("%s: Cannot find udev for a bus %d\n", __func__,
- bus_num);
- return -ENXIO;
- }
- ret = dm_i2c_read(dev, I2C_MUX_IO_1, &io, 1);
- #else
- i2c_set_bus_num(bus_num);
- /* IO1[7:3] is the field of board revision info. */
- ret = i2c_read(I2C_MUX_IO_ADDR, I2C_MUX_IO_1, 1, &io, 1);
- #endif
- if (ret < 0) {
- printf("Error reading i2c boot information!\n");
- return 0;
- }
- /* hwconfig method is used for RevD and later versions. */
- if ((io & SW_REV_MASK) <= SW_REV_D) {
- #ifdef CONFIG_HWCONFIG
- if (hwconfig("esdhc1"))
- sdhc2_en = true;
- #endif
- } else {
- /*
- * The I2C IO-expander for mux select is used to control
- * the muxing of various onboard interfaces.
- *
- * IO0[3:2] indicates SDHC2 interface demultiplexer
- * select lines.
- * 00 - SDIO wifi
- * 01 - GPIO (to Arduino)
- * 10 - eMMC Memory
- * 11 - SPI
- */
- #if CONFIG_IS_ENABLED(DM_I2C)
- ret = dm_i2c_read(dev, I2C_MUX_IO_0, &io, 1);
- #else
- ret = i2c_read(I2C_MUX_IO_ADDR, I2C_MUX_IO_0, 1, &io, 1);
- #endif
- if (ret < 0) {
- printf("Error reading i2c boot information!\n");
- return 0;
- }
- mux_sdhc2 = (io & 0x0c) >> 2;
- /* Enable SDHC2 only when use SDIO wifi and eMMC */
- if (mux_sdhc2 == 2 || mux_sdhc2 == 0)
- sdhc2_en = true;
- }
- if (sdhc2_en)
- do_fixup_by_path(blob, esdhc1_path, "status", "okay",
- sizeof("okay"), 1);
- else
- do_fixup_by_path(blob, esdhc1_path, "status", "disabled",
- sizeof("disabled"), 1);
- return 0;
- }
- #endif
- int ft_board_setup(void *blob, struct bd_info *bd)
- {
- arch_fixup_fdt(blob);
- ft_cpu_setup(blob, bd);
- return 0;
- }
- static int switch_to_bank1(void)
- {
- u8 data = 0xf4, chip_addr = 0x24, offset_addr = 0x03;
- int ret, bus_num = 0;
- #if CONFIG_IS_ENABLED(DM_I2C)
- struct udevice *dev;
- ret = i2c_get_chip_for_busnum(bus_num, chip_addr,
- 1, &dev);
- if (ret) {
- printf("%s: Cannot find udev for a bus %d\n", __func__,
- bus_num);
- return -ENXIO;
- }
- /*
- * --------------------------------------------------------------------
- * |bus |I2C address| Device | Notes |
- * --------------------------------------------------------------------
- * |I2C1|0x24, 0x25,| IO expander (CFG,| Provides 16bits of General |
- * | |0x26 | RESET, and INT/ | Purpose parallel Input/Output|
- * | | | KW41GPIO) - NXP | (GPIO) expansion for the |
- * | | | PCAL9555AHF | I2C bus |
- * ----- --------------------------------------------------------------
- * - mount three IO expander(PCAL9555AHF) on I2C1
- *
- * PCAL9555A device address
- * slave address
- * --------------------------------------
- * | 0 | 1 | 0 | 0 | A2 | A1 | A0 | R/W |
- * --------------------------------------
- * | fixed | hardware selectable|
- *
- * Output port 1(Pinter register bits = 0x03)
- *
- * P1_[7~0] = 0xf4
- * P1_0 <---> CFG_MUX_QSPI_S0
- * P1_1 <---> CFG_MUX_QSPI_S1
- * CFG_MUX_QSPI_S[1:0] = 0b00
- *
- * QSPI chip-select demultiplexer select
- * ---------------------------------------------------------------------
- * CFG_MUX_QSPI_S1|CFG_MUX_QSPI_S0| Values
- * ---------------------------------------------------------------------
- * 0 | 0 |CS routed to SPI memory bank1(default)
- * ---------------------------------------------------------------------
- * 0 | 1 |CS routed to SPI memory bank2
- * ---------------------------------------------------------------------
- *
- */
- ret = dm_i2c_write(dev, offset_addr, &data, 1);
- #else /* Non DM I2C support - will be removed */
- i2c_set_bus_num(bus_num);
- ret = i2c_write(chip_addr, offset_addr, 1, &data, 1);
- #endif
- if (ret) {
- printf("i2c write error to chip : %u, addr : %u, data : %u\n",
- chip_addr, offset_addr, data);
- }
- return ret;
- }
- static int switch_to_bank2(void)
- {
- u8 data[2] = {0xfc, 0xf5}, offset_addr[2] = {0x7, 0x3};
- u8 chip_addr = 0x24;
- int ret, i, bus_num = 0;
- #if CONFIG_IS_ENABLED(DM_I2C)
- struct udevice *dev;
- ret = i2c_get_chip_for_busnum(bus_num, chip_addr,
- 1, &dev);
- if (ret) {
- printf("%s: Cannot find udev for a bus %d\n", __func__,
- bus_num);
- return -ENXIO;
- }
- #else /* Non DM I2C support - will be removed */
- i2c_set_bus_num(bus_num);
- #endif
- /*
- * 1th step: config port 1
- * - the port 1 pin is enabled as an output
- * 2th step: output port 1
- * - P1_[7:0] output 0xf5,
- * then CFG_MUX_QSPI_S[1:0] equal to 0b01,
- * CS routed to SPI memory bank2
- */
- for (i = 0; i < sizeof(data); i++) {
- #if CONFIG_IS_ENABLED(DM_I2C)
- ret = dm_i2c_write(dev, offset_addr[i], &data[i], 1);
- #else /* Non DM I2C support - will be removed */
- ret = i2c_write(chip_addr, offset_addr[i], 1, &data[i], 1);
- #endif
- if (ret) {
- printf("i2c write error to chip : %u, addr : %u, data : %u\n",
- chip_addr, offset_addr[i], data[i]);
- goto err;
- }
- }
- err:
- return ret;
- }
- static int convert_flash_bank(int bank)
- {
- int ret = 0;
- switch (bank) {
- case BOOT_FROM_UPPER_BANK:
- ret = switch_to_bank2();
- break;
- case BOOT_FROM_LOWER_BANK:
- ret = switch_to_bank1();
- break;
- default:
- ret = CMD_RET_USAGE;
- break;
- };
- return ret;
- }
- static int flash_bank_cmd(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
- {
- if (argc != 2)
- return CMD_RET_USAGE;
- if (strcmp(argv[1], "1") == 0)
- convert_flash_bank(BOOT_FROM_LOWER_BANK);
- else if (strcmp(argv[1], "2") == 0)
- convert_flash_bank(BOOT_FROM_UPPER_BANK);
- else
- return CMD_RET_USAGE;
- return 0;
- }
- U_BOOT_CMD(
- boot_bank, 2, 0, flash_bank_cmd,
- "Flash bank Selection Control",
- "bank[1-lower bank/2-upper bank] (e.g. boot_bank 1)"
- );
|