diff --git a/src/soc/nvidia/tegra124/bootblock.c b/src/soc/nvidia/tegra124/bootblock.c index 59001491ff..aec914532e 100644 --- a/src/soc/nvidia/tegra124/bootblock.c +++ b/src/soc/nvidia/tegra124/bootblock.c @@ -79,6 +79,10 @@ void main(void) clock_cpu0_config(entry); power_enable_and_ungate_cpu(); + + /* Repair ram on cluster0 and cluster1 after CPU is powered on. */ + ram_repair(); + clock_cpu0_remove_reset(); clock_halt_avp(); diff --git a/src/soc/nvidia/tegra124/flow.h b/src/soc/nvidia/tegra124/flow.h index 531278c402..416681ac8f 100644 --- a/src/soc/nvidia/tegra124/flow.h +++ b/src/soc/nvidia/tegra124/flow.h @@ -35,8 +35,14 @@ 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 */ }; -check_member(flow_ctlr, ram_repair, 0x40); +check_member(flow_ctlr, ram_repair_cluster1, 0x58); enum { FLOW_MODE_SHIFT = 29, @@ -76,4 +82,10 @@ enum { FLOW_EVENT_JTAG = 1 << 28 }; +/* RAM_REPAIR, 0x40, 0x58 */ +enum { + RAM_REPAIR_REQ = 0x1 << 0, + RAM_REPAIR_STS = 0x1 << 1, +}; + #endif /* _TEGRA124_FLOW_H_ */ diff --git a/src/soc/nvidia/tegra124/power.c b/src/soc/nvidia/tegra124/power.c index ec44a0fb02..75f04942b9 100644 --- a/src/soc/nvidia/tegra124/power.c +++ b/src/soc/nvidia/tegra124/power.c @@ -25,8 +25,10 @@ #include "pmc.h" #include "power.h" +#include "flow.h" static struct tegra_pmc_regs * const pmc = (void *)TEGRA_PMC_BASE; +static struct flow_ctlr * const flow = (void *)TEGRA_FLOW_BASE; static int partition_powered(int id) { @@ -92,3 +94,17 @@ int power_reset_status(void) { return read32(&pmc->rst_status) & 0x7; } + +void ram_repair(void) +{ + // Request RAM repair for cluster 0 + setbits_le32(&flow->ram_repair, RAM_REPAIR_REQ); + // Poll for completion + while (!(read32(&flow->ram_repair) & RAM_REPAIR_STS)) + ; + // Request RAM repair for cluster 1 + setbits_le32(&flow->ram_repair_cluster1, RAM_REPAIR_REQ); + // Poll for completion + while (!(read32(&flow->ram_repair_cluster1) & RAM_REPAIR_STS)) + ; +} diff --git a/src/soc/nvidia/tegra124/power.h b/src/soc/nvidia/tegra124/power.h index bce6faf9ec..889dede2dd 100644 --- a/src/soc/nvidia/tegra124/power.h +++ b/src/soc/nvidia/tegra124/power.h @@ -35,4 +35,6 @@ enum { }; int power_reset_status(void); +void ram_repair(void); + #endif /* __SOC_NVIDIA_TEGRA124_POWER_H__ */