]> git.sur5r.net Git - u-boot/blobdiff - arch/arm/cpu/armv8/fsl-layerscape/soc.c
fsl-layerscape: Consolidate registers space defination for CCI-400 bus
[u-boot] / arch / arm / cpu / armv8 / fsl-layerscape / soc.c
index 5a4dd39a6173e785348bb65c7ddd30f303dcaab6..339ff0c4c708e6047da60d718f54e341a24b3402 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <fsl_immap.h>
 #include <fsl_ifc.h>
 #include <ahci.h>
 #include <scsi.h>
@@ -31,8 +32,10 @@ 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_LS2085A)
+       /* LS2085A, LS2088A, LS2048A has DP_DDR */
+       if ((SVR_SOC_VER(svr) == SVR_LS2085A) ||
+           (SVR_SOC_VER(svr) == SVR_LS2088A) ||
+           (SVR_SOC_VER(svr) == SVR_LS2048A))
                return true;
 
        return false;
@@ -93,7 +96,7 @@ static void erratum_a008514(void)
 
 static unsigned long get_internval_val_mhz(void)
 {
-       char *interval = getenv(PLATFORM_CYCLE_ENV_VAR);
+       char *interval = env_get(PLATFORM_CYCLE_ENV_VAR);
        /*
         *  interval is the number of platform cycles(MHz) between
         *  wake up events generated by EPU.
@@ -132,7 +135,7 @@ void erratum_a009635(void)
 
 static void erratum_rcw_src(void)
 {
-#if defined(CONFIG_SPL)
+#if defined(CONFIG_SPL) && defined(CONFIG_NAND_BOOT)
        u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
        u32 __iomem *dcfg_dcsr = (u32 __iomem *)DCFG_DCSR_BASE;
        u32 val;
@@ -150,6 +153,7 @@ static void erratum_rcw_src(void)
  * This erratum requires setting glitch_en bit to enable
  * digital glitch filter to improve clock stability.
  */
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009203
 static void erratum_a009203(void)
 {
        u8 __iomem *ptr;
@@ -176,6 +180,7 @@ static void erratum_a009203(void)
 #endif
 #endif
 }
+#endif
 
 void bypass_smmu(void)
 {
@@ -189,7 +194,9 @@ void fsl_lsch3_early_init_f(void)
 {
        erratum_rcw_src();
        init_early_memctl_regs();       /* tighten IFC timing */
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009203
        erratum_a009203();
+#endif
        erratum_a008514();
        erratum_a008336();
 #ifdef CONFIG_CHAIN_OF_TRUST
@@ -211,13 +218,15 @@ int sata_init(void)
        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);
+       out_le32(&ccsr_ahci->axicc, AHCI_PORT_AXICC_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);
+       out_le32(&ccsr_ahci->axicc, AHCI_PORT_AXICC_CFG);
 
        ahci_init((void __iomem *)CONFIG_SYS_SATA1);
-       scsi_scan(0);
+       scsi_scan(false);
 
        return 0;
 }
@@ -229,16 +238,14 @@ int sata_init(void)
 {
        struct ccsr_ahci __iomem *ccsr_ahci = (void *)CONFIG_SYS_SATA;
 
-#ifdef CONFIG_ARCH_LS1046A
        /* Disable SATA ECC */
        out_le32((void *)CONFIG_SYS_DCSR_DCFG_ADDR + 0x520, 0x80000000);
-#endif
        out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG);
        out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG);
        out_le32(&ccsr_ahci->axicc, AHCI_PORT_AXICC_CFG);
 
        ahci_init((void __iomem *)CONFIG_SYS_SATA);
-       scsi_scan(0);
+       scsi_scan(false);
 
        return 0;
 }
@@ -279,9 +286,14 @@ static void erratum_a008850_early(void)
 {
 #ifdef CONFIG_SYS_FSL_ERRATUM_A008850
        /* part 1 of 2 */
-       struct ccsr_cci400 __iomem *cci = (void *)CONFIG_SYS_CCI400_ADDR;
+       struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR +
+                                               CONFIG_SYS_CCI400_OFFSET);
        struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
 
+       /* Skip if running at lower exception level */
+       if (current_el() < 3)
+               return;
+
        /* disables propagation of barrier transactions to DDRC from CCI400 */
        out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER);
 
@@ -294,10 +306,15 @@ void erratum_a008850_post(void)
 {
 #ifdef CONFIG_SYS_FSL_ERRATUM_A008850
        /* part 2 of 2 */
-       struct ccsr_cci400 __iomem *cci = (void *)CONFIG_SYS_CCI400_ADDR;
+       struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR +
+                                               CONFIG_SYS_CCI400_OFFSET);
        struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
        u32 tmp;
 
+       /* Skip if running at lower exception level */
+       if (current_el() < 3)
+               return;
+
        /* enable propagation of barrier transactions to DDRC from CCI400 */
        out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
 
@@ -334,9 +351,99 @@ static void erratum_a010539(void)
 #endif
 }
 
+/* Get VDD in the unit mV from voltage ID */
+int get_core_volt_from_fuse(void)
+{
+       struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+       int vdd;
+       u32 fusesr;
+       u8 vid;
+
+       fusesr = in_be32(&gur->dcfg_fusesr);
+       debug("%s: fusesr = 0x%x\n", __func__, fusesr);
+       vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_ALTVID_SHIFT) &
+               FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK;
+       if ((vid == 0) || (vid == FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK)) {
+               vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_VID_SHIFT) &
+                       FSL_CHASSIS2_DCFG_FUSESR_VID_MASK;
+       }
+       debug("%s: VID = 0x%x\n", __func__, vid);
+       switch (vid) {
+       case 0x00: /* VID isn't supported */
+               vdd = -EINVAL;
+               debug("%s: The VID feature is not supported\n", __func__);
+               break;
+       case 0x08: /* 0.9V silicon */
+               vdd = 900;
+               break;
+       case 0x10: /* 1.0V silicon */
+               vdd = 1000;
+               break;
+       default:  /* Other core voltage */
+               vdd = -EINVAL;
+               printf("%s: The VID(%x) isn't supported\n", __func__, vid);
+               break;
+       }
+       debug("%s: The required minimum volt of CORE is %dmV\n", __func__, vdd);
+
+       return vdd;
+}
+
+__weak int board_switch_core_volt(u32 vdd)
+{
+       return 0;
+}
+
+static int setup_core_volt(u32 vdd)
+{
+       return board_setup_core_volt(vdd);
+}
+
+#ifdef CONFIG_SYS_FSL_DDR
+static void ddr_enable_0v9_volt(bool en)
+{
+       struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+       u32 tmp;
+
+       tmp = ddr_in32(&ddr->ddr_cdr1);
+
+       if (en)
+               tmp |= DDR_CDR1_V0PT9_EN;
+       else
+               tmp &= ~DDR_CDR1_V0PT9_EN;
+
+       ddr_out32(&ddr->ddr_cdr1, tmp);
+}
+#endif
+
+int setup_chip_volt(void)
+{
+       int vdd;
+
+       vdd = get_core_volt_from_fuse();
+       /* Nothing to do for silicons doesn't support VID */
+       if (vdd < 0)
+               return vdd;
+
+       if (setup_core_volt(vdd))
+               printf("%s: Switch core VDD to %dmV failed\n", __func__, vdd);
+#ifdef CONFIG_SYS_HAS_SERDES
+       if (setup_serdes_volt(vdd))
+               printf("%s: Switch SVDD to %dmV failed\n", __func__, vdd);
+#endif
+
+#ifdef CONFIG_SYS_FSL_DDR
+       if (vdd == 900)
+               ddr_enable_0v9_volt(true);
+#endif
+
+       return 0;
+}
+
 void fsl_lsch2_early_init_f(void)
 {
-       struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR;
+       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;
 
 #ifdef CONFIG_LAYERSCAPE_NS_ACCESS
@@ -360,8 +467,10 @@ void fsl_lsch2_early_init_f(void)
         * 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);
+       if (current_el() == 3) {
+               out_le32(&cci->slave[4].snoop_ctrl,
+                        CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN);
+       }
 
        /* Erratum */
        erratum_a008850_early(); /* part 1 of 2 */
@@ -371,6 +480,45 @@ void fsl_lsch2_early_init_f(void)
 }
 #endif
 
+#ifdef CONFIG_QSPI_AHB_INIT
+/* Enable 4bytes address support and fast read */
+int qspi_ahb_init(void)
+{
+       u32 *qspi_lut, lut_key, *qspi_key;
+
+       qspi_key = (void *)SYS_FSL_QSPI_ADDR + 0x300;
+       qspi_lut = (void *)SYS_FSL_QSPI_ADDR + 0x310;
+
+       lut_key = in_be32(qspi_key);
+
+       if (lut_key == 0x5af05af0) {
+               /* That means the register is BE */
+               out_be32(qspi_key, 0x5af05af0);
+               /* Unlock the lut table */
+               out_be32(qspi_key + 1, 0x00000002);
+               out_be32(qspi_lut, 0x0820040c);
+               out_be32(qspi_lut + 1, 0x1c080c08);
+               out_be32(qspi_lut + 2, 0x00002400);
+               /* Lock the lut table */
+               out_be32(qspi_key, 0x5af05af0);
+               out_be32(qspi_key + 1, 0x00000001);
+       } else {
+               /* That means the register is LE */
+               out_le32(qspi_key, 0x5af05af0);
+               /* Unlock the lut table */
+               out_le32(qspi_key + 1, 0x00000002);
+               out_le32(qspi_lut, 0x0820040c);
+               out_le32(qspi_lut + 1, 0x1c080c08);
+               out_le32(qspi_lut + 2, 0x00002400);
+               /* Lock the lut table */
+               out_le32(qspi_key, 0x5af05af0);
+               out_le32(qspi_key + 1, 0x00000001);
+       }
+
+       return 0;
+}
+#endif
+
 #ifdef CONFIG_BOARD_LATE_INIT
 int board_late_init(void)
 {
@@ -380,6 +528,9 @@ int board_late_init(void)
 #ifdef CONFIG_CHAIN_OF_TRUST
        fsl_setenv_chain_of_trust();
 #endif
+#ifdef CONFIG_QSPI_AHB_INIT
+       qspi_ahb_init();
+#endif
 
        return 0;
 }