tegra: Introduce SRAM repair on tegra124
authorSimon Glass <sjg@chromium.org>
Fri, 5 Jun 2015 20:39:38 +0000 (14:39 -0600)
committerTom Warren <twarren@nvidia.com>
Tue, 9 Jun 2015 16:56:14 +0000 (09:56 -0700)
This is required in order to avoid instability when running from caches
after the kernel starts.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Tom Warren <twarren@nvidia.com>
arch/arm/include/asm/arch-tegra124/flow.h
arch/arm/mach-tegra/powergate.c

index d6f515f1e98703f488b2007ca371415a0d59c54a..7818b1bd3455b945b1471d1b25e8979f8c7d3b66 100644 (file)
@@ -26,6 +26,12 @@ struct flow_ctlr {
        u32 cpu_pwr_csr;        /* offset 0x38 */
        u32 mpid;               /* offset 0x3c */
        u32 ram_repair;         /* offset 0x40 */
+       u32 flow_dbg_sel;       /* offset 0x44 */
+       u32 flow_dbg_cnt0;      /* offset 0x48 */
+       u32 flow_dbg_cnt1;      /* offset 0x4c */
+       u32 flow_dbg_qual;      /* offset 0x50 */
+       u32 flow_ctlr_spare;    /* offset 0x54 */
+       u32 ram_repair_cluster1;/* offset 0x58 */
 };
 
 /* HALT_COP_EVENTS_0, 0x04 */
@@ -43,4 +49,10 @@ struct flow_ctlr {
 #define CSR_WAIT_WFI_SHIFT     8
 #define CSR_PWR_OFF_STS                (1 << 16)
 
+/* RAM_REPAIR, 0x40, 0x58 */
+enum {
+       RAM_REPAIR_REQ = 0x1 << 0,
+       RAM_REPAIR_STS = 0x1 << 1,
+};
+
 #endif /*  _TEGRA124_FLOW_H_ */
index 6331cd40fdb5c91da2b578060e8d85d47294e262..30ae036bff055fb5561d140fb1d4e04c17235045 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <asm/io.h>
 #include <asm/types.h>
-
+#include <asm/arch/flow.h>
 #include <asm/arch/powergate.h>
 #include <asm/arch/tegra.h>
 
@@ -75,11 +75,29 @@ static int tegra_powergate_remove_clamping(enum tegra_powergate id)
        return 0;
 }
 
+static void tegra_powergate_ram_repair(void)
+{
+#ifdef CONFIG_TEGRA124
+       struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;
+
+       /* Request RAM repair for cluster 0 and wait until complete */
+       setbits_le32(&flow->ram_repair, RAM_REPAIR_REQ);
+       while (!(readl(&flow->ram_repair) & RAM_REPAIR_STS))
+               ;
+
+       /* Same for cluster 1 */
+       setbits_le32(&flow->ram_repair_cluster1, RAM_REPAIR_REQ);
+       while (!(readl(&flow->ram_repair_cluster1) & RAM_REPAIR_STS))
+               ;
+#endif
+}
+
 int tegra_powergate_sequence_power_up(enum tegra_powergate id,
                                      enum periph_id periph)
 {
        int err;
 
+       tegra_powergate_ram_repair();
        reset_set_enable(periph, 1);
 
        err = tegra_powergate_power_on(id);