rockchip: support system off function for rk3399
if define power off gpio, BL31 will do system power off through
gpio control.
diff --git a/plat/rockchip/common/plat_pm.c b/plat/rockchip/common/plat_pm.c
index 43558b6..d20a683 100644
--- a/plat/rockchip/common/plat_pm.c
+++ b/plat/rockchip/common/plat_pm.c
@@ -253,6 +253,16 @@
}
/*******************************************************************************
+ * 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
* platform layer will take care of registering the handlers with PSCI.
@@ -265,6 +275,7 @@
.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 c5b281a..9b95621 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c
@@ -403,6 +403,31 @@
;
}
+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 @@
.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 d5ff8ce..8f935e9 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu.h
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu.h
@@ -810,6 +810,8 @@
#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