Merge https://gitlab.denx.de/u-boot/custodians/u-boot-fsl-qoriq
[oweals/u-boot.git] / arch / arm / cpu / armv8 / fsl-layerscape / soc.c
index 54fb0745f903ad93b0cca8dfc5d3a5ddbef0fb5c..d0e10cb007be5a2be1ac91dce616470ae77ca7f9 100644 (file)
@@ -1,11 +1,15 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2014-2015 Freescale Semiconductor
+ * Copyright 2019 NXP
  */
 
 #include <common.h>
+#include <clock_legacy.h>
+#include <env.h>
 #include <fsl_immap.h>
 #include <fsl_ifc.h>
+#include <init.h>
 #include <asm/arch/fsl_serdes.h>
 #include <asm/arch/soc.h>
 #include <asm/io.h>
 #include <fsl_validate.h>
 #endif
 #include <fsl_immap.h>
+#ifdef CONFIG_TFABOOT
+#include <env_internal.h>
+DECLARE_GLOBAL_DATA_PTR;
+#endif
 
 bool soc_has_dp_ddr(void)
 {
@@ -122,6 +130,10 @@ static void erratum_a008997(void)
        set_usb_pcstxswingfull(scfg, SCFG_USB3PRM2CR_USB2);
        set_usb_pcstxswingfull(scfg, SCFG_USB3PRM2CR_USB3);
 #endif
+#elif defined(CONFIG_ARCH_LS1028A)
+       clrsetbits_le32(DCSR_BASE +  DCSR_USB_IOCR1,
+                       0x7F << 11,
+                       DCSR_USB_PCSTXSWINGFULL << 11);
 #endif
 #endif /* CONFIG_SYS_FSL_ERRATUM_A008997 */
 }
@@ -135,7 +147,8 @@ static void erratum_a008997(void)
        out_be16((phy) + SCFG_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_3);      \
        out_be16((phy) + SCFG_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_4)
 
-#elif defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1088A)
+#elif defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1088A) || \
+       defined(CONFIG_ARCH_LS1028A) || defined(CONFIG_ARCH_LX2160A)
 
 #define PROGRAM_USB_PHY_RX_OVRD_IN_HI(phy)     \
        out_le16((phy) + DCSR_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_1); \
@@ -159,7 +172,8 @@ static void erratum_a009007(void)
        usb_phy = (void __iomem *)SCFG_USB_PHY3;
        PROGRAM_USB_PHY_RX_OVRD_IN_HI(usb_phy);
 #endif
-#elif defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1088A)
+#elif defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1088A) || \
+       defined(CONFIG_ARCH_LS1028A)
        void __iomem *dcsr = (void __iomem *)DCSR_BASE;
 
        PROGRAM_USB_PHY_RX_OVRD_IN_HI(dcsr + DCSR_USB_PHY1);
@@ -168,6 +182,15 @@ static void erratum_a009007(void)
 }
 
 #if defined(CONFIG_FSL_LSCH3)
+static void erratum_a050106(void)
+{
+#if defined(CONFIG_ARCH_LX2160A)
+       void __iomem *dcsr = (void __iomem *)DCSR_BASE;
+
+       PROGRAM_USB_PHY_RX_OVRD_IN_HI(dcsr + DCSR_USB_PHY1);
+       PROGRAM_USB_PHY_RX_OVRD_IN_HI(dcsr + DCSR_USB_PHY2);
+#endif
+}
 /*
  * This erratum requires setting a value to eddrtqcr1 to
  * optimal the DDR performance.
@@ -319,6 +342,7 @@ void fsl_lsch3_early_init_f(void)
        erratum_a009798();
        erratum_a008997();
        erratum_a009007();
+       erratum_a050106();
 #ifdef CONFIG_CHAIN_OF_TRUST
        /* In case of Secure Boot, the IBR configures the SMMU
        * to allow only Secure transactions.
@@ -328,6 +352,11 @@ void fsl_lsch3_early_init_f(void)
        if (fsl_check_boot_mode_secure() == 1)
                bypass_smmu();
 #endif
+
+#if defined(CONFIG_ARCH_LS1088A) || defined(CONFIG_ARCH_LS1028A) || \
+       defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LX2160A)
+       set_icids();
+#endif
 }
 
 /* Get VDD in the unit mV from voltage ID */
@@ -589,6 +618,9 @@ void fsl_lsch2_early_init_f(void)
        struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR +
                                        CONFIG_SYS_CCI400_OFFSET);
        struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
+#if defined(CONFIG_FSL_QSPI) && defined(CONFIG_TFABOOT)
+       enum boot_src src;
+#endif
 
 #ifdef CONFIG_LAYERSCAPE_NS_ACCESS
        enable_layerscape_ns_access();
@@ -598,14 +630,34 @@ void fsl_lsch2_early_init_f(void)
        init_early_memctl_regs();       /* tighten IFC timing */
 #endif
 
+#if defined(CONFIG_FSL_QSPI) && defined(CONFIG_TFABOOT)
+       src = get_boot_src();
+       if (src != BOOT_SOURCE_QSPI_NOR)
+               out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
+#else
 #if defined(CONFIG_FSL_QSPI) && !defined(CONFIG_QSPI_BOOT)
        out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
+#endif
 #endif
        /* Make SEC reads and writes snoopable */
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
+       setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP |
+                       SCFG_SNPCNFGCR_SECWRSNP | SCFG_SNPCNFGCR_USB1RDSNP |
+                       SCFG_SNPCNFGCR_USB1WRSNP | SCFG_SNPCNFGCR_USB2RDSNP |
+                       SCFG_SNPCNFGCR_USB2WRSNP | SCFG_SNPCNFGCR_USB3RDSNP |
+                       SCFG_SNPCNFGCR_USB3WRSNP | SCFG_SNPCNFGCR_SATARDSNP |
+                       SCFG_SNPCNFGCR_SATAWRSNP);
+#elif defined(CONFIG_ARCH_LS1012A)
+       setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP |
+                       SCFG_SNPCNFGCR_SECWRSNP | SCFG_SNPCNFGCR_USB1RDSNP |
+                       SCFG_SNPCNFGCR_USB1WRSNP | SCFG_SNPCNFGCR_SATARDSNP |
+                       SCFG_SNPCNFGCR_SATAWRSNP);
+#else
        setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP |
                     SCFG_SNPCNFGCR_SECWRSNP |
                     SCFG_SNPCNFGCR_SATARDSNP |
                     SCFG_SNPCNFGCR_SATAWRSNP);
+#endif
 
        /*
         * Enable snoop requests and DVM message requests for
@@ -640,6 +692,47 @@ void fsl_lsch2_early_init_f(void)
 }
 #endif
 
+#ifdef CONFIG_FSPI_AHB_EN_4BYTE
+int fspi_ahb_init(void)
+{
+       /* Enable 4bytes address support and fast read */
+       u32 *fspi_lut, lut_key, *fspi_key;
+
+       fspi_key = (void *)SYS_NXP_FSPI_ADDR + SYS_NXP_FSPI_LUTKEY_BASE_ADDR;
+       fspi_lut = (void *)SYS_NXP_FSPI_ADDR + SYS_NXP_FSPI_LUT_BASE_ADDR;
+
+       lut_key = in_be32(fspi_key);
+
+       if (lut_key == SYS_NXP_FSPI_LUTKEY) {
+               /* That means the register is BE */
+               out_be32(fspi_key, SYS_NXP_FSPI_LUTKEY);
+               /* Unlock the lut table */
+               out_be32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_UNLOCK);
+               /* Create READ LUT */
+               out_be32(fspi_lut, 0x0820040c);
+               out_be32(fspi_lut + 1, 0x24003008);
+               out_be32(fspi_lut + 2, 0x00000000);
+               /* Lock the lut table */
+               out_be32(fspi_key, SYS_NXP_FSPI_LUTKEY);
+               out_be32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_LOCK);
+       } else {
+               /* That means the register is LE */
+               out_le32(fspi_key, SYS_NXP_FSPI_LUTKEY);
+               /* Unlock the lut table */
+               out_le32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_UNLOCK);
+               /* Create READ LUT */
+               out_le32(fspi_lut, 0x0820040c);
+               out_le32(fspi_lut + 1, 0x24003008);
+               out_le32(fspi_lut + 2, 0x00000000);
+               /* Lock the lut table */
+               out_le32(fspi_key, SYS_NXP_FSPI_LUTKEY);
+               out_le32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_LOCK);
+       }
+
+       return 0;
+}
+#endif
+
 #ifdef CONFIG_QSPI_AHB_INIT
 /* Enable 4bytes address support and fast read */
 int qspi_ahb_init(void)
@@ -679,16 +772,163 @@ int qspi_ahb_init(void)
 }
 #endif
 
+#ifdef CONFIG_TFABOOT
+#define MAX_BOOTCMD_SIZE       512
+
+int fsl_setenv_bootcmd(void)
+{
+       int ret;
+       enum boot_src src = get_boot_src();
+       char bootcmd_str[MAX_BOOTCMD_SIZE];
+
+       switch (src) {
+#ifdef IFC_NOR_BOOTCOMMAND
+       case BOOT_SOURCE_IFC_NOR:
+               sprintf(bootcmd_str, IFC_NOR_BOOTCOMMAND);
+               break;
+#endif
+#ifdef QSPI_NOR_BOOTCOMMAND
+       case BOOT_SOURCE_QSPI_NOR:
+               sprintf(bootcmd_str, QSPI_NOR_BOOTCOMMAND);
+               break;
+#endif
+#ifdef XSPI_NOR_BOOTCOMMAND
+       case BOOT_SOURCE_XSPI_NOR:
+               sprintf(bootcmd_str, XSPI_NOR_BOOTCOMMAND);
+               break;
+#endif
+#ifdef IFC_NAND_BOOTCOMMAND
+       case BOOT_SOURCE_IFC_NAND:
+               sprintf(bootcmd_str, IFC_NAND_BOOTCOMMAND);
+               break;
+#endif
+#ifdef QSPI_NAND_BOOTCOMMAND
+       case BOOT_SOURCE_QSPI_NAND:
+               sprintf(bootcmd_str, QSPI_NAND_BOOTCOMMAND);
+               break;
+#endif
+#ifdef XSPI_NAND_BOOTCOMMAND
+       case BOOT_SOURCE_XSPI_NAND:
+               sprintf(bootcmd_str, XSPI_NAND_BOOTCOMMAND);
+               break;
+#endif
+#ifdef SD_BOOTCOMMAND
+       case BOOT_SOURCE_SD_MMC:
+               sprintf(bootcmd_str, SD_BOOTCOMMAND);
+               break;
+#endif
+#ifdef SD2_BOOTCOMMAND
+       case BOOT_SOURCE_SD_MMC2:
+               sprintf(bootcmd_str, SD2_BOOTCOMMAND);
+               break;
+#endif
+       default:
+#ifdef QSPI_NOR_BOOTCOMMAND
+               sprintf(bootcmd_str, QSPI_NOR_BOOTCOMMAND);
+#endif
+               break;
+       }
+
+       ret = env_set("bootcmd", bootcmd_str);
+       if (ret) {
+               printf("Failed to set bootcmd: ret = %d\n", ret);
+               return ret;
+       }
+       return 0;
+}
+
+int fsl_setenv_mcinitcmd(void)
+{
+       int ret = 0;
+       enum boot_src src = get_boot_src();
+
+       switch (src) {
+#ifdef IFC_MC_INIT_CMD
+       case BOOT_SOURCE_IFC_NAND:
+       case BOOT_SOURCE_IFC_NOR:
+       ret = env_set("mcinitcmd", IFC_MC_INIT_CMD);
+               break;
+#endif
+#ifdef QSPI_MC_INIT_CMD
+       case BOOT_SOURCE_QSPI_NAND:
+       case BOOT_SOURCE_QSPI_NOR:
+       ret = env_set("mcinitcmd", QSPI_MC_INIT_CMD);
+               break;
+#endif
+#ifdef XSPI_MC_INIT_CMD
+       case BOOT_SOURCE_XSPI_NAND:
+       case BOOT_SOURCE_XSPI_NOR:
+       ret = env_set("mcinitcmd", XSPI_MC_INIT_CMD);
+               break;
+#endif
+#ifdef SD_MC_INIT_CMD
+       case BOOT_SOURCE_SD_MMC:
+       ret = env_set("mcinitcmd", SD_MC_INIT_CMD);
+               break;
+#endif
+#ifdef SD2_MC_INIT_CMD
+       case BOOT_SOURCE_SD_MMC2:
+       ret = env_set("mcinitcmd", SD2_MC_INIT_CMD);
+               break;
+#endif
+       default:
+#ifdef QSPI_MC_INIT_CMD
+       ret = env_set("mcinitcmd", QSPI_MC_INIT_CMD);
+#endif
+               break;
+       }
+
+       if (ret) {
+               printf("Failed to set mcinitcmd: ret = %d\n", ret);
+               return ret;
+       }
+       return 0;
+}
+#endif
+
 #ifdef CONFIG_BOARD_LATE_INIT
+__weak int fsl_board_late_init(void)
+{
+       return 0;
+}
+
 int board_late_init(void)
 {
 #ifdef CONFIG_CHAIN_OF_TRUST
        fsl_setenv_chain_of_trust();
 #endif
+#ifdef CONFIG_TFABOOT
+       /*
+        * check if gd->env_addr is default_environment; then setenv bootcmd
+        * and mcinitcmd.
+        */
+#ifdef CONFIG_SYS_RELOC_GD_ENV_ADDR
+       if (gd->env_addr == (ulong)&default_environment[0]) {
+#else
+       if (gd->env_addr + gd->reloc_off == (ulong)&default_environment[0]) {
+#endif
+               fsl_setenv_bootcmd();
+               fsl_setenv_mcinitcmd();
+       }
+
+       /*
+        * If the boot mode is secure, default environment is not present then
+        * setenv command needs to be run by default
+        */
+#ifdef CONFIG_CHAIN_OF_TRUST
+       if ((fsl_check_boot_mode_secure() == 1)) {
+               fsl_setenv_bootcmd();
+               fsl_setenv_mcinitcmd();
+       }
+#endif
+#endif
 #ifdef CONFIG_QSPI_AHB_INIT
        qspi_ahb_init();
 #endif
+#ifdef CONFIG_FSPI_AHB_EN_4BYTE
+       fspi_ahb_init();
+#endif
 
-       return 0;
+       return fsl_board_late_init();
 }
 #endif