diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c index 7907e46..7e176e6 100644 --- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c @@ -119,6 +119,13 @@ ret = tegra_bpmp_init(); if (ret != 0U) { + /* + * flag to indicate that BPMP firmware is not + * available and the CPU has to handle entry/exit + * for all power states + */ + tegra_bpmp_available = false; + /* Cluster idle not allowed */ target = PSCI_LOCAL_STATE_RUN; @@ -131,13 +138,6 @@ val = mmio_read_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_CTRL); if (val == ENABLE_CLOSED_LOOP) { /* - * flag to indicate that BPMP firmware is not - * available and the CPU has to handle entry/exit - * for all power states - */ - tegra_bpmp_available = false; - - /* * Acquire the cluster idle lock to stop * other CPUs from powering up. */ @@ -217,6 +217,15 @@ if (!tegra_bpmp_available) { + /* + * When disabled, DFLL loses its state. Enable + * open loop state for the DFLL as we dont want + * garbage values being written to the pmic + * when we enter cluster idle state. + */ + mmio_write_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_CTRL, + ENABLE_OPEN_LOOP); + /* Find if the platform uses OVR2/MAX77621 PMIC */ cfg = mmio_read_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_OUTPUT_CFG); if (cfg & DFLL_OUTPUT_CFG_CLK_EN_BIT) { @@ -481,8 +490,19 @@ val = mmio_read_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM); val &= ~PINMUX_PWM_TRISTATE; mmio_write_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM, val); + + /* make sure the setting took effect */ + val = mmio_read_32(TEGRA_MISC_BASE + PINMUX_AUX_DVFS_PWM); + assert((val & PINMUX_PWM_TRISTATE) == 0U); } + /* + * Restore operation mode for the DFLL ring + * oscillator + */ + mmio_write_32(TEGRA_CL_DVFS_BASE + DVFS_DFLL_CTRL, + ENABLE_CLOSED_LOOP); + /* release cluster idle lock */ tegra_fc_ccplex_pgexit_unlock(); }