From 76cc23644bb9f951e644e12951d77df3edd2639a Mon Sep 17 00:00:00 2001 From: XiaoDong Huang Date: Mon, 11 Dec 2023 19:19:25 +0800 Subject: [PATCH] ARM: rockchip: rv1106: sleep: support pm config Signed-off-by: XiaoDong Huang Change-Id: I0901947b0f978a985e50be34d42c9e63f19649dd --- arch/arm/mach-rockchip/rv1106_pm.c | 98 +++++++++++++++++------------- 1 file changed, 55 insertions(+), 43 deletions(-) diff --git a/arch/arm/mach-rockchip/rv1106_pm.c b/arch/arm/mach-rockchip/rv1106_pm.c index ce0edb7743f5..2d2b3213ed0f 100644 --- a/arch/arm/mach-rockchip/rv1106_pm.c +++ b/arch/arm/mach-rockchip/rv1106_pm.c @@ -15,12 +15,13 @@ #include #include #include +#include #include +#include #include "rkpm_gicv2.h" #include "rkpm_helpers.h" #include "rkpm_uart.h" - #include "rv1106_pm.h" #define RV1106_PM_REG_REGION_MEM_SIZE SZ_4K @@ -57,6 +58,8 @@ struct rv1106_sleep_ddr_data { static struct rv1106_sleep_ddr_data ddr_data; +static const struct rk_sleep_config *slp_cfg; + static void __iomem *pmucru_base; static void __iomem *cru_base; static void __iomem *pvtpllcru_base; @@ -916,64 +919,71 @@ static void gpio0_set_direct(u32 pin_id, int out) gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H); } +static void gpio0_set_lvl(u32 pin_id, int lvl) +{ + u32 sft = (pin_id % 16); + + if (pin_id < 16) + writel_relaxed(BITS_WITH_WMASK(lvl, 0x1, sft), + gpio_base[0] + RV1106_GPIO_SWPORT_DR_L); + else + writel_relaxed(BITS_WITH_WMASK(lvl, 0x1, sft), + gpio_base[0] + RV1106_GPIO_SWPORT_DR_H); +} + static void gpio_config(void) { + u32 iomux, dir, lvl, pull, id; + u32 cfg, i; + + if (slp_cfg == NULL) + return; + ddr_data.gpio0a_iomux_l = readl_relaxed(ioc_base[0] + 0); ddr_data.gpio0a_iomux_h = readl_relaxed(ioc_base[0] + 0x4); ddr_data.gpio0a0_pull = readl_relaxed(ioc_base[0] + 0x38); ddr_data.gpio0_ddr_l = readl_relaxed(gpio_base[0] + RV1106_GPIO_SWPORT_DDR_L); ddr_data.gpio0_ddr_h = readl_relaxed(gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H); - /* gpio0_a0, input, pulldown */ - gpio0_set_iomux(0, 0); - gpio0_set_pull(0, RV1106_GPIO_PULL_DOWN); - gpio0_set_direct(0, 0); + for (i = 0; i < slp_cfg->sleep_io_config_cnt; i++) { + cfg = slp_cfg->sleep_io_config[i]; + iomux = RKPM_IO_CFG_GET_IOMUX(cfg); + dir = RKPM_IO_CFG_GET_GPIO_DIR(cfg); + lvl = RKPM_IO_CFG_GET_GPIO_LVL(cfg); + pull = RKPM_IO_CFG_GET_PULL(cfg); + id = RKPM_IO_CFG_GET_ID(cfg); - /* gpio0_a1, input, pulldown */ - gpio0_set_iomux(1, 0); - gpio0_set_pull(1, RV1106_GPIO_PULL_DOWN); - gpio0_set_direct(1, 0); + if (is_rv1106 && id == 3) { + /* gpio0_a3, pullnone */ + gpio0_set_iomux(3, 1); + gpio0_set_pull(3, RV1106_GPIO_PULL_NONE); + continue; + } - /* gpio0_a2, input, pulldown */ - gpio0_set_iomux(2, 0); - gpio0_set_pull(2, RV1106_GPIO_PULL_DOWN); - gpio0_set_direct(2, 0); + if (is_rv1103 && id == 4) { + /* gpio0_a4, pullnone */ + gpio0_set_iomux(4, 1); + gpio0_set_pull(4, RV1106_GPIO_PULL_NONE); + continue; + } - if (is_rv1106) { - /* gpio0_a3, pullnone */ - gpio0_set_iomux(3, 1); - gpio0_set_pull(3, RV1106_GPIO_PULL_NONE); - } else { - /* gpio0_a3, input, pullup */ - gpio0_set_iomux(3, 0); - gpio0_set_pull(3, RV1106_GPIO_PULL_UP); - gpio0_set_direct(3, 0); + if (iomux == RKPM_IO_CFG_IOMUX_GPIO_VAL) { + if (dir == RKPM_IO_CFG_GPIO_DIR_INPUT_VAL) + gpio0_set_lvl(id, lvl); + + gpio0_set_direct(id, dir); + } + + gpio0_set_iomux(id, iomux); + gpio0_set_pull(id, pull); } - - if (is_rv1103) { - /* gpio0_a4, pullnone */ - gpio0_set_iomux(4, 1); - gpio0_set_pull(4, RV1106_GPIO_PULL_NONE); - } else { - /* gpio0_a4, input, pullup */ - gpio0_set_iomux(4, 0); - gpio0_set_pull(4, RV1106_GPIO_PULL_UP); - gpio0_set_direct(4, 0); - } - - /* gpio0_a5, input, pullnone */ - gpio0_set_iomux(5, 0); - gpio0_set_pull(5, RV1106_GPIO_PULL_NONE); - gpio0_set_direct(5, 0); - - /* gpio0_a6, input, pullnone */ - gpio0_set_iomux(6, 0); - gpio0_set_pull(6, RV1106_GPIO_PULL_NONE); - gpio0_set_direct(6, 0); } static void gpio_restore(void) { + if (slp_cfg == NULL) + return; + writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_l), ioc_base[0] + 0); writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_h), ioc_base[0] + 0x4); @@ -1067,6 +1077,8 @@ static int rv1106_suspend_enter(suspend_state_t state) { rkpm_printstr("rv1106 enter sleep\n"); + slp_cfg = rockchip_get_cur_sleep_config(); + local_fiq_disable(); rv1106_dbg_irq_prepare();