]> git.sur5r.net Git - u-boot/blobdiff - arch/arm/cpu/armv8/fsl-layerscape/soc.c
SPDX: Convert all of our single license tags to Linux Kernel style
[u-boot] / arch / arm / cpu / armv8 / fsl-layerscape / soc.c
index d9d6e4fd962365420d4a3bb89ef9e2e629e47077..06fdd17604986151bee11b312da051af0c101ca2 100644 (file)
@@ -1,7 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2014-2015 Freescale Semiconductor
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
@@ -26,8 +25,6 @@
 #endif
 #include <fsl_immap.h>
 
-DECLARE_GLOBAL_DATA_PTR;
-
 bool soc_has_dp_ddr(void)
 {
        struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
@@ -66,10 +63,13 @@ static void erratum_a009008(void)
 #ifdef CONFIG_SYS_FSL_ERRATUM_A009008
        u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
 
-#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
+       defined(CONFIG_ARCH_LS1012A)
        set_usb_txvreftune(scfg, SCFG_USB3PRM1CR_USB1);
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
        set_usb_txvreftune(scfg, SCFG_USB3PRM1CR_USB2);
        set_usb_txvreftune(scfg, SCFG_USB3PRM1CR_USB3);
+#endif
 #elif defined(CONFIG_ARCH_LS2080A)
        set_usb_txvreftune(scfg, SCFG_USB3PRM1CR);
 #endif
@@ -87,16 +87,86 @@ static void erratum_a009798(void)
 #ifdef CONFIG_SYS_FSL_ERRATUM_A009798
        u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
 
-#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
+       defined(CONFIG_ARCH_LS1012A)
        set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR_USB1);
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
        set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR_USB2);
        set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR_USB3);
+#endif
 #elif defined(CONFIG_ARCH_LS2080A)
        set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR);
 #endif
 #endif /* CONFIG_SYS_FSL_ERRATUM_A009798 */
 }
 
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
+       defined(CONFIG_ARCH_LS1012A)
+static inline void set_usb_pcstxswingfull(u32 __iomem *scfg, u32 offset)
+{
+       scfg_clrsetbits32(scfg + offset / 4,
+                       0x7F << 9,
+                       SCFG_USB_PCSTXSWINGFULL << 9);
+}
+#endif
+
+static void erratum_a008997(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008997
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
+       defined(CONFIG_ARCH_LS1012A)
+       u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
+
+       set_usb_pcstxswingfull(scfg, SCFG_USB3PRM2CR_USB1);
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
+       set_usb_pcstxswingfull(scfg, SCFG_USB3PRM2CR_USB2);
+       set_usb_pcstxswingfull(scfg, SCFG_USB3PRM2CR_USB3);
+#endif
+#endif
+#endif /* CONFIG_SYS_FSL_ERRATUM_A008997 */
+}
+
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
+       defined(CONFIG_ARCH_LS1012A)
+
+#define PROGRAM_USB_PHY_RX_OVRD_IN_HI(phy)     \
+       out_be16((phy) + SCFG_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_1);      \
+       out_be16((phy) + SCFG_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_2);      \
+       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)
+
+#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); \
+       out_le16((phy) + DCSR_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_2); \
+       out_le16((phy) + DCSR_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_3); \
+       out_le16((phy) + DCSR_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_4)
+
+#endif
+
+static void erratum_a009007(void)
+{
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
+       defined(CONFIG_ARCH_LS1012A)
+       void __iomem *usb_phy = (void __iomem *)SCFG_USB_PHY1;
+
+       PROGRAM_USB_PHY_RX_OVRD_IN_HI(usb_phy);
+#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
+       usb_phy = (void __iomem *)SCFG_USB_PHY2;
+       PROGRAM_USB_PHY_RX_OVRD_IN_HI(usb_phy);
+
+       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)
+       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 /* CONFIG_SYS_FSL_ERRATUM_A009007 */
+}
+
 #if defined(CONFIG_FSL_LSCH3)
 /*
  * This erratum requires setting a value to eddrtqcr1 to
@@ -200,8 +270,8 @@ static void erratum_rcw_src(void)
 #ifdef CONFIG_SYS_FSL_ERRATUM_A009203
 static void erratum_a009203(void)
 {
-       u8 __iomem *ptr;
 #ifdef CONFIG_SYS_I2C
+       u8 __iomem *ptr;
 #ifdef I2C1_BASE_ADDR
        ptr = (u8 __iomem *)(I2C1_BASE_ADDR + I2C_DEBUG_REG);
 
@@ -237,7 +307,9 @@ void bypass_smmu(void)
 void fsl_lsch3_early_init_f(void)
 {
        erratum_rcw_src();
+#ifdef CONFIG_FSL_IFC
        init_early_memctl_regs();       /* tighten IFC timing */
+#endif
 #ifdef CONFIG_SYS_FSL_ERRATUM_A009203
        erratum_a009203();
 #endif
@@ -245,6 +317,8 @@ void fsl_lsch3_early_init_f(void)
        erratum_a008336();
        erratum_a009008();
        erratum_a009798();
+       erratum_a008997();
+       erratum_a009007();
 #ifdef CONFIG_CHAIN_OF_TRUST
        /* In case of Secure Boot, the IBR configures the SMMU
        * to allow only Secure transactions.
@@ -261,23 +335,70 @@ int sata_init(void)
 {
        struct ccsr_ahci __iomem *ccsr_ahci;
 
+#ifdef CONFIG_SYS_SATA2
        ccsr_ahci  = (void *)CONFIG_SYS_SATA2;
        out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG);
+       out_le32(&ccsr_ahci->pp2c, AHCI_PORT_PHY2_CFG);
+       out_le32(&ccsr_ahci->pp3c, AHCI_PORT_PHY3_CFG);
        out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG);
        out_le32(&ccsr_ahci->axicc, AHCI_PORT_AXICC_CFG);
+#endif
 
+#ifdef CONFIG_SYS_SATA1
        ccsr_ahci  = (void *)CONFIG_SYS_SATA1;
        out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG);
+       out_le32(&ccsr_ahci->pp2c, AHCI_PORT_PHY2_CFG);
+       out_le32(&ccsr_ahci->pp3c, AHCI_PORT_PHY3_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(false);
+#endif
 
        return 0;
 }
 #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;
+
+       /* get the voltage ID from fuse status register */
+       fusesr = in_le32(&gur->dcfg_fusesr);
+       debug("%s: fusesr = 0x%x\n", __func__, fusesr);
+       vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT) &
+               FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK;
+       if ((vid == 0) || (vid == FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK)) {
+               vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT) &
+                       FSL_CHASSIS3_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;
+               debug("%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;
+}
+
 #elif defined(CONFIG_FSL_LSCH2)
 #ifdef CONFIG_SCSI_AHCI_PLAT
 int sata_init(void)
@@ -287,6 +408,8 @@ int sata_init(void)
        /* Disable SATA ECC */
        out_le32((void *)CONFIG_SYS_DCSR_DCFG_ADDR + 0x520, 0x80000000);
        out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG);
+       out_le32(&ccsr_ahci->pp2c, AHCI_PORT_PHY2_CFG);
+       out_le32(&ccsr_ahci->pp3c, AHCI_PORT_PHY3_CFG);
        out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG);
        out_le32(&ccsr_ahci->axicc, AHCI_PORT_AXICC_CFG);
 
@@ -486,6 +609,29 @@ int setup_chip_volt(void)
        return 0;
 }
 
+#ifdef CONFIG_FSL_PFE
+void init_pfe_scfg_dcfg_regs(void)
+{
+       struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
+       u32 ecccr2;
+
+       out_be32(&scfg->pfeasbcr,
+                in_be32(&scfg->pfeasbcr) | SCFG_PFEASBCR_AWCACHE0);
+       out_be32(&scfg->pfebsbcr,
+                in_be32(&scfg->pfebsbcr) | SCFG_PFEASBCR_AWCACHE0);
+
+       /* CCI-400 QoS settings for PFE */
+       out_be32(&scfg->wr_qos1, (unsigned int)(SCFG_WR_QOS1_PFE1_QOS
+                | SCFG_WR_QOS1_PFE2_QOS));
+       out_be32(&scfg->rd_qos1, (unsigned int)(SCFG_RD_QOS1_PFE1_QOS
+                | SCFG_RD_QOS1_PFE2_QOS));
+
+       ecccr2 = in_be32(CONFIG_SYS_DCSR_DCFG_ADDR + DCFG_DCSR_ECCCR2);
+       out_be32((void *)CONFIG_SYS_DCSR_DCFG_ADDR + DCFG_DCSR_ECCCR2,
+                ecccr2 | (unsigned int)DISABLE_PFE_ECC);
+}
+#endif
+
 void fsl_lsch2_early_init_f(void)
 {
        struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR +
@@ -525,6 +671,8 @@ void fsl_lsch2_early_init_f(void)
        erratum_a010539();
        erratum_a009008();
        erratum_a009798();
+       erratum_a008997();
+       erratum_a009007();
 }
 #endif