]> git.sur5r.net Git - u-boot/blobdiff - arch/arm/cpu/armv8/fsl-layerscape/soc.c
Merge branch 'master' of git://git.denx.de/u-boot-net
[u-boot] / arch / arm / cpu / armv8 / fsl-layerscape / soc.c
index a0de4becd1a33cbfec318bf65d6eccca7ceb8a75..0cb010012e7add46e725741cbcb535e2bb9047f4 100644 (file)
@@ -6,14 +6,43 @@
 
 #include <common.h>
 #include <fsl_ifc.h>
+#include <ahci.h>
+#include <scsi.h>
 #include <asm/arch/soc.h>
 #include <asm/io.h>
 #include <asm/global_data.h>
 #include <asm/arch-fsl-layerscape/config.h>
+#ifdef CONFIG_CHAIN_OF_TRUST
+#include <fsl_validate.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A)
+bool soc_has_dp_ddr(void)
+{
+       struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+       u32 svr = gur_in32(&gur->svr);
+
+       /* LS2085A has DP_DDR */
+       if (SVR_SOC_VER(svr) == SVR_LS2085)
+               return true;
+
+       return false;
+}
+
+bool soc_has_aiop(void)
+{
+       struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+       u32 svr = gur_in32(&gur->svr);
+
+       /* LS2085A has AIOP */
+       if (SVR_SOC_VER(svr) == SVR_LS2085)
+               return true;
+
+       return false;
+}
+
+#ifdef CONFIG_LS2080A
 /*
  * This erratum requires setting a value to eddrtqcr1 to
  * optimal the DDR performance.
@@ -146,7 +175,14 @@ static void erratum_a009203(void)
 #endif
 #endif
 }
-
+void bypass_smmu(void)
+{
+       u32 val;
+       val = (in_le32(SMMU_SCR0) | SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK);
+       out_le32(SMMU_SCR0, val);
+       val = (in_le32(SMMU_NSCR0) | SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK);
+       out_le32(SMMU_NSCR0, val);
+}
 void fsl_lsch3_early_init_f(void)
 {
        erratum_a008751();
@@ -155,29 +191,125 @@ void fsl_lsch3_early_init_f(void)
        erratum_a009203();
        erratum_a008514();
        erratum_a008336();
+#ifdef CONFIG_CHAIN_OF_TRUST
+       /* In case of Secure Boot, the IBR configures the SMMU
+       * to allow only Secure transactions.
+       * SMMU must be reset in bypass mode.
+       * Set the ClientPD bit and Clear the USFCFG Bit
+       */
+       if (fsl_check_boot_mode_secure() == 1)
+               bypass_smmu();
+#endif
 }
 
+#ifdef CONFIG_SCSI_AHCI_PLAT
+int sata_init(void)
+{
+       struct ccsr_ahci __iomem *ccsr_ahci;
+
+       ccsr_ahci  = (void *)CONFIG_SYS_SATA2;
+       out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG);
+       out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG);
+
+       ccsr_ahci  = (void *)CONFIG_SYS_SATA1;
+       out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG);
+       out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG);
+
+       ahci_init((void __iomem *)CONFIG_SYS_SATA1);
+       scsi_scan(0);
+
+       return 0;
+}
+#endif
+
 #elif defined(CONFIG_LS1043A)
+#ifdef CONFIG_SCSI_AHCI_PLAT
+int sata_init(void)
+{
+       struct ccsr_ahci __iomem *ccsr_ahci = (void *)CONFIG_SYS_SATA;
+
+       out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG);
+       out_le32(&ccsr_ahci->pp2c, AHCI_PORT_PHY_2_CFG);
+       out_le32(&ccsr_ahci->pp3c, AHCI_PORT_PHY_3_CFG);
+       out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG);
+
+       ahci_init((void __iomem *)CONFIG_SYS_SATA);
+       scsi_scan(0);
+
+       return 0;
+}
+#endif
+
+static void erratum_a009929(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009929
+       struct ccsr_gur *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+       u32 __iomem *dcsr_cop_ccp = (void *)CONFIG_SYS_DCSR_COP_CCP_ADDR;
+       u32 rstrqmr1 = gur_in32(&gur->rstrqmr1);
+
+       rstrqmr1 |= 0x00000400;
+       gur_out32(&gur->rstrqmr1, rstrqmr1);
+       writel(0x01000000, dcsr_cop_ccp);
+#endif
+}
+
+/*
+ * This erratum requires setting a value to eddrtqcr1 to optimal
+ * the DDR performance. The eddrtqcr1 register is in SCFG space
+ * of LS1043A and the offset is 0x157_020c.
+ */
+#if defined(CONFIG_SYS_FSL_ERRATUM_A009660) \
+       && defined(CONFIG_SYS_FSL_ERRATUM_A008514)
+#error A009660 and A008514 can not be both enabled.
+#endif
+
+static void erratum_a009660(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009660
+       u32 *eddrtqcr1 = (void *)CONFIG_SYS_FSL_SCFG_ADDR + 0x20c;
+       out_be32(eddrtqcr1, 0x63b20042);
+#endif
+}
+
 void fsl_lsch2_early_init_f(void)
 {
        struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR;
+       struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
 
 #ifdef CONFIG_FSL_IFC
        init_early_memctl_regs();       /* tighten IFC timing */
 #endif
 
+#if defined(CONFIG_FSL_QSPI) && !defined(CONFIG_QSPI_BOOT)
+       out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
+#endif
+       /* Make SEC reads and writes snoopable */
+       setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP |
+                    SCFG_SNPCNFGCR_SECWRSNP);
+
        /*
         * Enable snoop requests and DVM message requests for
         * Slave insterface S4 (A53 core cluster)
         */
        out_le32(&cci->slave[4].snoop_ctrl,
                 CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN);
+
+       /* Erratum */
+       erratum_a009929();
+       erratum_a009660();
 }
 #endif
 
 #ifdef CONFIG_BOARD_LATE_INIT
 int board_late_init(void)
 {
+#ifdef CONFIG_SCSI_AHCI_PLAT
+       sata_init();
+#endif
+#ifdef CONFIG_CHAIN_OF_TRUST
+       fsl_setenv_chain_of_trust();
+#endif
+
        return 0;
 }
 #endif