apalis-tk1: remove non-essential power rails on boot

When mainline kernels reboot TK1 they use SW_RESET,
that reset mode does not reset PMIC. Some rails
need to be off for RAM Re-repair to work correctly.

Reviewed-by: Oleksandr Suvorov <oleksandr.suvorov@toradex.com>
Signed-off-by: Dominik Sliwa <dominik.sliwa@toradex.com>
Signed-off-by: Igor Opaniuk <igor.opaniuk@toradex.com>
Signed-off-by: Tom Warren <twarren@nvidia.com>
This commit is contained in:
Dominik Sliwa 2019-08-01 11:06:39 +03:00 committed by Tom Warren
parent d415eab4f0
commit 5a20adf446
2 changed files with 68 additions and 0 deletions

View File

@ -238,6 +238,45 @@ static bool is_partition_powered(u32 partid)
return !!(reg & (1 << partid));
}
static void unpower_partition(u32 partid)
{
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
debug("%s: part ID = %08X\n", __func__, partid);
/* Is the partition on? */
if (is_partition_powered(partid)) {
/* Yes, toggle the partition power state (ON -> OFF) */
debug("power_partition, toggling state\n");
writel(START_CP | partid, &pmc->pmc_pwrgate_toggle);
/* Wait for the power to come down */
while (is_partition_powered(partid))
;
/* Give I/O signals time to stabilize */
udelay(IO_STABILIZATION_DELAY);
}
}
void unpower_cpus(void)
{
debug("%s entry: G cluster\n", __func__);
/* Power down the fast cluster rail partition */
debug("%s: CRAIL\n", __func__);
unpower_partition(CRAIL);
/* Power down the fast cluster non-CPU partition */
debug("%s: C0NC\n", __func__);
unpower_partition(C0NC);
/* Power down the fast cluster CPU0 partition */
debug("%s: CE0\n", __func__);
unpower_partition(CE0);
debug("%s: done\n", __func__);
}
static void power_partition(u32 partid)
{
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
@ -284,6 +323,12 @@ void start_cpu(u32 reset_vector)
debug("%s entry, reset_vector = %x\n", __func__, reset_vector);
/*
* High power clusters are on after software reset,
* it may interfere with tegra124_ram_repair.
* unpower them.
*/
unpower_cpus();
tegra124_init_clocks();
/* Set power-gating timer multiplier */

View File

@ -43,6 +43,29 @@ void pmic_enable_cpu_vdd(void)
udelay(10 * 1000);
#endif
/*
* Make sure all non-fused regulators are down.
* That way we're in known state after software reboot from linux
*/
tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2);
tegra_i2c_ll_write_data(0x0003, I2C_SEND_2_BYTES);
udelay(10 * 1000);
tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2);
tegra_i2c_ll_write_data(0x0004, I2C_SEND_2_BYTES);
udelay(10 * 1000);
tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2);
tegra_i2c_ll_write_data(0x001b, I2C_SEND_2_BYTES);
udelay(10 * 1000);
tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2);
tegra_i2c_ll_write_data(0x0014, I2C_SEND_2_BYTES);
udelay(10 * 1000);
tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2);
tegra_i2c_ll_write_data(0x001a, I2C_SEND_2_BYTES);
udelay(10 * 1000);
tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2);
tegra_i2c_ll_write_data(0x0019, I2C_SEND_2_BYTES);
udelay(10 * 1000);
debug("%s: Setting VDD_CPU to 1.0V via AS3722 reg 0/4D\n", __func__);
/*
* Bring up VDD_CPU via the AS3722 PMIC on the PWR I2C bus.