summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-layerscape/errata.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-layerscape/errata.c')
-rw-r--r--arch/arm/mach-layerscape/errata.c144
1 files changed, 114 insertions, 30 deletions
diff --git a/arch/arm/mach-layerscape/errata.c b/arch/arm/mach-layerscape/errata.c
index 4f4b759ddb..deab584243 100644
--- a/arch/arm/mach-layerscape/errata.c
+++ b/arch/arm/mach-layerscape/errata.c
@@ -2,13 +2,12 @@
#include <common.h>
#include <io.h>
#include <soc/fsl/immap_lsch2.h>
+#include <soc/fsl/immap_lsch3.h>
#include <soc/fsl/fsl_ddr_sdram.h>
#include <asm/system.h>
-#include <mach/errata.h>
-#include <mach/lowlevel.h>
-
-#define scfg_clrsetbits32(addr, clear, set) clrsetbits_be32(addr, clear, set)
-#define scfg_clrbits32(addr, clear) clrbits_be32(addr, clear)
+#include <mach/layerscape/errata.h>
+#include <mach/layerscape/lowlevel.h>
+#include <soc/fsl/scfg.h>
static inline void set_usb_pcstxswingfull(u32 __iomem *scfg, u32 offset)
{
@@ -17,6 +16,22 @@ static inline void set_usb_pcstxswingfull(u32 __iomem *scfg, u32 offset)
SCFG_USB_PCSTXSWINGFULL << 9);
}
+static void erratum_a008997_ls1021a(void)
+{
+ u32 __iomem *scfg = (u32 __iomem *)LSCH2_SCFG_ADDR;
+
+ set_usb_pcstxswingfull(scfg, SCFG_USB3PRM2CR_USB1);
+}
+
+static void erratum_a008997_ls1028a(void)
+{
+ void __iomem *dcsr = IOMEM(LSCH3_DCSR_BASE);
+
+ clrsetbits_le32(dcsr + LSCH3_DCSR_USB_IOCR1,
+ 0x7f << 11,
+ LSCH3_DCSR_USB_PCSTXSWINGFULL << 11);
+}
+
static void erratum_a008997_ls1046a(void)
{
u32 __iomem *scfg = (u32 __iomem *)LSCH2_SCFG_ADDR;
@@ -26,22 +41,24 @@ static void erratum_a008997_ls1046a(void)
set_usb_pcstxswingfull(scfg, SCFG_USB3PRM2CR_USB3);
}
-#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)
+static void erratum_a009007(void __iomem *phy, u16 val1, u16 val2, u16 val3, u16 val4)
+{
+ scfg_out16(phy + SCFG_USB_PHY_RX_OVRD_IN_HI, val1);
+ scfg_out16(phy + SCFG_USB_PHY_RX_OVRD_IN_HI, val2);
+ scfg_out16(phy + SCFG_USB_PHY_RX_OVRD_IN_HI, val3);
+ scfg_out16(phy + SCFG_USB_PHY_RX_OVRD_IN_HI, val4);
+}
static void erratum_a009007_ls1046a(void)
{
- void __iomem *usb_phy = IOMEM(SCFG_USB_PHY1);
-
- PROGRAM_USB_PHY_RX_OVRD_IN_HI(usb_phy);
- usb_phy = (void __iomem *)SCFG_USB_PHY2;
- PROGRAM_USB_PHY_RX_OVRD_IN_HI(usb_phy);
+ erratum_a009007(IOMEM(SCFG_USB_PHY1), 0x0000, 0x0080, 0x0380, 0x0b80);
+ erratum_a009007(IOMEM(SCFG_USB_PHY2), 0x0000, 0x0080, 0x0380, 0x0b80);
+ erratum_a009007(IOMEM(SCFG_USB_PHY3), 0x0000, 0x0080, 0x0380, 0x0b80);
+}
- usb_phy = (void __iomem *)SCFG_USB_PHY3;
- PROGRAM_USB_PHY_RX_OVRD_IN_HI(usb_phy);
+static void erratum_a009007_ls1021a(void)
+{
+ erratum_a009007(IOMEM(SCFG_USB_PHY1), 0x0000, 0x8000, 0x8004, 0x800C);
}
static inline void set_usb_txvreftune(u32 __iomem *scfg, u32 offset)
@@ -49,6 +66,18 @@ static inline void set_usb_txvreftune(u32 __iomem *scfg, u32 offset)
scfg_clrsetbits32(scfg + offset / 4, 0xf << 6, SCFG_USB_TXVREFTUNE << 6);
}
+static void erratum_a009007_ls1028a(void)
+{
+ erratum_a009007(IOMEM(LSCH3_DCSR_BASE), 0x0000, 0x0080, 0x0380, 0x0b80);
+}
+
+static void erratum_a009008_ls1021a(void)
+{
+ u32 __iomem *scfg = IOMEM(LSCH2_SCFG_ADDR);
+
+ set_usb_txvreftune(scfg, SCFG_USB3PRM1CR_USB1);
+}
+
static void erratum_a009008_ls1046a(void)
{
u32 __iomem *scfg = IOMEM(LSCH2_SCFG_ADDR);
@@ -63,6 +92,13 @@ static inline void set_usb_sqrxtune(u32 __iomem *scfg, u32 offset)
scfg_clrbits32(scfg + offset / 4, SCFG_USB_SQRXTUNE_MASK << 23);
}
+static void erratum_a009798_ls1021a(void)
+{
+ u32 __iomem *scfg = IOMEM(LSCH2_SCFG_ADDR);
+
+ set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR_USB1);
+}
+
static void erratum_a009798_ls1046a(void)
{
u32 __iomem *scfg = IOMEM(LSCH2_SCFG_ADDR);
@@ -72,15 +108,16 @@ static void erratum_a009798_ls1046a(void)
set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR_USB3);
}
-static void erratum_a008850_early(void)
+static void erratum_a008850_early(struct ccsr_cci400 __iomem *cci,
+ struct ccsr_ddr __iomem *ddr)
{
/* part 1 of 2 */
- struct ccsr_cci400 __iomem *cci = IOMEM(LSCH2_CCI400_ADDR);
- struct ccsr_ddr __iomem *ddr = IOMEM(LSCH2_DDR_ADDR);
/* Skip if running at lower exception level */
- if (current_el() < 3)
- return;
+#if __LINUX_ARM_ARCH__ > 7
+ if (current_el() < 3)
+ return;
+#endif
/* disables propagation of barrier transactions to DDRC from CCI400 */
out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER);
@@ -89,27 +126,64 @@ static void erratum_a008850_early(void)
ddr_out32(&ddr->eor, DDR_EOR_RD_REOD_DIS | DDR_EOR_WD_REOD_DIS);
}
-/* erratum_a009942_check_cpo */
+/*
+ * This erratum requires a register write before being Memory
+ * controller 3 being enabled.
+ */
+static void erratum_a008514(void)
+{
+ u32 *eddrtqcr1;
+
+ eddrtqcr1 = IOMEM(LSCH3_DCSR_DDR3_ADDR) + 0x800;
+ out_le32(eddrtqcr1, 0x63b20002);
+}
+
+static void erratum_a009798(void)
+{
+ u32 __iomem *scfg = IOMEM(LSCH3_SCFG_BASE);
+
+ clrbits_be32(scfg + LSCH3_SCFG_USB3PRM1CR / 4,
+ LSCH3_SCFG_USB_SQRXTUNE_MASK << 23);
+}
void ls1046a_errata(void)
{
- erratum_a008850_early();
+ erratum_a008850_early(IOMEM(LSCH2_CCI400_ADDR), IOMEM(LSCH2_DDR_ADDR));
erratum_a009008_ls1046a();
erratum_a009798_ls1046a();
erratum_a008997_ls1046a();
erratum_a009007_ls1046a();
}
-static void erratum_a008850_post(void)
+void ls1021a_errata(void)
+{
+ erratum_a008850_early(IOMEM(LSCH2_CCI400_ADDR), IOMEM(LSCH2_DDR_ADDR));
+ erratum_a009008_ls1021a();
+ erratum_a009798_ls1021a();
+ erratum_a008997_ls1021a();
+ erratum_a009007_ls1021a();
+}
+
+void ls1028a_errata(void)
+{
+ erratum_a008850_early(IOMEM(LSCH3_CCI400_ADDR), IOMEM(LSCH3_DDR_ADDR));
+ erratum_a009007_ls1028a();
+ erratum_a008997_ls1028a();
+ erratum_a008514();
+ erratum_a009798();
+}
+
+static void erratum_a008850_post(struct ccsr_cci400 __iomem *cci,
+ struct ccsr_ddr __iomem *ddr)
{
/* part 2 of 2 */
- struct ccsr_cci400 __iomem *cci = IOMEM(LSCH2_CCI400_ADDR);
- struct ccsr_ddr __iomem *ddr = IOMEM(LSCH2_DDR_ADDR);
u32 tmp;
/* Skip if running at lower exception level */
- if (current_el() < 3)
- return;
+#if __LINUX_ARM_ARCH__ > 7
+ if (current_el() < 3)
+ return;
+#endif
/* enable propagation of barrier transactions to DDRC from CCI400 */
out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
@@ -190,6 +264,16 @@ static void erratum_a009942_check_cpo(void)
void ls1046a_errata_post_ddr(void)
{
- erratum_a008850_post();
+ erratum_a008850_post(IOMEM(LSCH2_CCI400_ADDR), IOMEM(LSCH2_DDR_ADDR));
erratum_a009942_check_cpo();
}
+
+void ls1021a_errata_post_ddr(void)
+{
+ erratum_a008850_post(IOMEM(LSCH2_CCI400_ADDR), IOMEM(LSCH2_DDR_ADDR));
+}
+
+void ls1028a_errata_post_ddr(void)
+{
+ erratum_a008850_post(IOMEM(LSCH3_CCI400_ADDR), IOMEM(LSCH3_DDR_ADDR));
+}