diff --git a/plat/rockchip/common/plat_pm.c b/plat/rockchip/common/plat_pm.c index 43558b65afd10de065ce9892785ded1de68390b8..d20a683b3b569652bd32125f1bd3d7a3a5fa07d8 100644 --- a/plat/rockchip/common/plat_pm.c +++ b/plat/rockchip/common/plat_pm.c @@ -252,6 +252,16 @@ static void __dead2 rockchip_system_reset(void) rockchip_ops->sys_gbl_soft_reset(); } +/******************************************************************************* + * RockChip handlers to power off the system + ******************************************************************************/ +static void __dead2 rockchip_system_poweroff(void) +{ + assert(rockchip_ops && rockchip_ops->system_off); + + rockchip_ops->system_off(); +} + /******************************************************************************* * Export the platform handlers via plat_rockchip_psci_pm_ops. The rockchip * standard @@ -265,6 +275,7 @@ const plat_psci_ops_t plat_rockchip_psci_pm_ops = { .pwr_domain_on_finish = rockchip_pwr_domain_on_finish, .pwr_domain_suspend_finish = rockchip_pwr_domain_suspend_finish, .system_reset = rockchip_system_reset, + .system_off = rockchip_system_poweroff, .validate_power_state = rockchip_validate_power_state, .get_sys_suspend_power_state = rockchip_get_sys_suspend_power_state }; diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c index c5b281ae9da2dc838db09212d131138622bf7251..9b95621f5d208cf516bd36f97224227e135f7ed9 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c @@ -403,6 +403,31 @@ void __dead2 soc_soft_reset(void) ; } +void __dead2 soc_system_off(void) +{ + struct gpio_info *poweroff_gpio; + + poweroff_gpio = (struct gpio_info *)plat_get_rockchip_gpio_poweroff(); + + if (poweroff_gpio) { + /* + * if use tsadc over temp pin(GPIO1A6) as shutdown gpio, + * need to set this pin iomux back to gpio function + */ + if (poweroff_gpio->index == TSADC_INT_PIN) { + mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO1A_IOMUX, + GPIO1A6_IOMUX); + } + gpio_set_direction(poweroff_gpio->index, GPIO_DIR_OUT); + gpio_set_value(poweroff_gpio->index, poweroff_gpio->polarity); + } else { + WARN("Do nothing when system off\n"); + } + + while (1) + ; +} + static struct rockchip_pm_ops_cb pm_ops = { .cores_pwr_dm_on = cores_pwr_domain_on, .cores_pwr_dm_off = cores_pwr_domain_off, @@ -412,6 +437,7 @@ static struct rockchip_pm_ops_cb pm_ops = { .sys_pwr_dm_suspend = sys_pwr_domain_suspend, .sys_pwr_dm_resume = sys_pwr_domain_resume, .sys_gbl_soft_reset = soc_soft_reset, + .system_off = soc_system_off, }; void plat_rockchip_pmu_init(void) diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.h b/plat/rockchip/rk3399/drivers/pmu/pmu.h index d5ff8ce095a286a812c02c39dec27daa1fe6004d..8f935e98d98019a04e644f9ba104f084cac37c03 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.h +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.h @@ -810,6 +810,8 @@ enum pmu_core_pwr_st { #define PMUGRF_GPIO1A_IOMUX 0x10 #define AP_PWROFF 0x0a +#define GPIO1A6_IOMUX BITS_WITH_WMASK(0, 3, 12) +#define TSADC_INT_PIN 38 #define CORES_PM_DISABLE 0x0 #define PD_CTR_LOOP 500