hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/arch/arm/mach-rockchip/rv1106_pm.c
....@@ -15,12 +15,14 @@
1515 #include <asm/fiq_glue.h>
1616 #include <asm/tlbflush.h>
1717 #include <asm/suspend.h>
18
+#include <dt-bindings/suspend/rockchip-rv1106.h>
1819 #include <linux/irqchip/arm-gic.h>
20
+#include <linux/rockchip/rockchip_pm_config.h>
1921
2022 #include "rkpm_gicv2.h"
2123 #include "rkpm_helpers.h"
2224 #include "rkpm_uart.h"
23
-
25
+#include "rockchip_hptimer.h"
2426 #include "rv1106_pm.h"
2527
2628 #define RV1106_PM_REG_REGION_MEM_SIZE SZ_4K
....@@ -57,8 +59,11 @@
5759
5860 static struct rv1106_sleep_ddr_data ddr_data;
5961
62
+static const struct rk_sleep_config *slp_cfg;
63
+
6064 static void __iomem *pmucru_base;
6165 static void __iomem *cru_base;
66
+static void __iomem *pvtpllcru_base;
6267 static void __iomem *pericru_base;
6368 static void __iomem *vicru_base;
6469 static void __iomem *npucru_base;
....@@ -87,6 +92,7 @@
8792 static void __iomem *pmu_base;
8893 static void __iomem *gicd_base;
8994 static void __iomem *gicc_base;
95
+static void __iomem *hptimer_base;
9096 static void __iomem *firewall_ddr_base;
9197 static void __iomem *firewall_syssram_base;
9298 static void __iomem *pmu_base;
....@@ -104,6 +110,10 @@
104110 /* core_cru */
105111 { REG_REGION(0x300, 0x310, 4, &corecru_base, WMSK_VAL)},
106112 { REG_REGION(0x800, 0x804, 4, &corecru_base, WMSK_VAL)},
113
+
114
+ /* pvtpll_cru */
115
+ { REG_REGION(0x00, 0x24, 4, &pvtpllcru_base, WMSK_VAL)},
116
+ { REG_REGION(0x30, 0x54, 4, &pvtpllcru_base, WMSK_VAL)},
107117
108118 /* core_sgrf */
109119 { REG_REGION(0x004, 0x014, 4, &coresgrf_base, 0)},
....@@ -276,6 +286,8 @@
276286 { REG_REGION(0x30, 0x30, 4, &stimer_base, 0)},
277287 };
278288
289
+static int is_rv1103, is_rv1106;
290
+
279291 #define PLL_LOCKED_TIMEOUT 600000U
280292
281293 static void pm_pll_wait_lock(u32 pll_id)
....@@ -382,7 +394,7 @@
382394 if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_USBDEV_EN))
383395 rkpm_printstr("USBDEV detect wakeup\n");
384396
385
- if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_TIMEROUT_EN))
397
+ if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_TIMEOUT_EN))
386398 rkpm_printstr("TIMEOUT interrupt wakeup\n");
387399
388400 rkpm_printch('\n');
....@@ -646,6 +658,9 @@
646658 {
647659 writel_relaxed(WITH_16BITS_WMSK(ddr_data.pmucru_sel_con7),
648660 pmucru_base + RV1106_PMUCRU_CLKSEL_CON(7));
661
+
662
+ if (rk_hptimer_get_mode(hptimer_base) == RK_HPTIMER_SOFT_ADJUST_MODE)
663
+ rk_hptimer_do_soft_adjust_no_wait(hptimer_base);
649664 }
650665
651666 static void ddr_sleep_config(void)
....@@ -705,8 +720,8 @@
705720 /* BIT(RV1106_PMU_WAKEUP_CPU_INT_EN) | */
706721 BIT(RV1106_PMU_WAKEUP_GPIO_INT_EN) |
707722 0;
708
- if (IS_ENABLED(CONFIG_RV1106_HPMCU_FAST_WAKEUP))
709
- pmu_wkup_con |= BIT(RV1106_PMU_WAKEUP_TIMEROUT_EN);
723
+ if (IS_ENABLED(CONFIG_RV1106_PMU_WAKEUP_TIMEOUT))
724
+ pmu_wkup_con |= BIT(RV1106_PMU_WAKEUP_TIMEOUT_EN);
710725
711726 pmu_pwr_con =
712727 BIT(RV1106_PMU_PWRMODE_EN) |
....@@ -772,30 +787,21 @@
772787 BIT(RV1106_PMU_GPLL_PD_ENA) |
773788 0;
774789
775
- /* pmic_sleep */
776
- /* gpio0_a3 activelow, gpio0_a4 active high */
777
- writel_relaxed(BITS_WITH_WMASK(0x4, 0x7, 0), pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
778
- /* select sleep func */
779
- writel_relaxed(BITS_WITH_WMASK(0x1, 0x1, 0), pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
780
- /* gpio0_a3 iomux */
781
- writel_relaxed(BITS_WITH_WMASK(0x1, 0xf, 12), ioc_base[0] + 0);
782
-
783790 /* pmu_debug */
784791 writel_relaxed(0xffffff01, pmu_base + RV1106_PMU_INFO_TX_CON);
785792 writel_relaxed(BITS_WITH_WMASK(0x1, 0xf, 4), ioc_base[1] + 0);
786793
787794 /* pmu count */
788
- writel_relaxed(clk_freq_khz * 32, pmu_base + RV1106_PMU_OSC_STABLE_CNT);
789
- writel_relaxed(clk_freq_khz * 32, pmu_base + RV1106_PMU_PMIC_STABLE_CNT);
790
- writel_relaxed(clk_freq_khz * 3000, pmu_base + RV1106_PMU_WAKEUP_TIMEOUT_CNT);
795
+ writel_relaxed(clk_freq_khz * 10, pmu_base + RV1106_PMU_OSC_STABLE_CNT);
796
+ writel_relaxed(clk_freq_khz * 5, pmu_base + RV1106_PMU_PMIC_STABLE_CNT);
791797
792798 /* Pmu's clk has switched to 24M back When pmu FSM counts
793799 * the follow counters, so we should use 24M to calculate
794800 * these counters.
795801 */
796
- writel_relaxed(24000 * 2, pmu_base + RV1106_PMU_WAKEUP_RSTCLR_CNT);
797
- writel_relaxed(24000 * 5, pmu_base + RV1106_PMU_PLL_LOCK_CNT);
798
- writel_relaxed(24000 * 5, pmu_base + RV1106_PMU_PWM_SWITCH_CNT);
802
+ writel_relaxed(12000, pmu_base + RV1106_PMU_WAKEUP_RSTCLR_CNT);
803
+ writel_relaxed(12000, pmu_base + RV1106_PMU_PLL_LOCK_CNT);
804
+ writel_relaxed(24000 * 2, pmu_base + RV1106_PMU_PWM_SWITCH_CNT);
799805
800806 /* pmu reset hold */
801807 writel_relaxed(0xffffffff, pmugrf_base + RV1106_PMUGRF_SOC_CON(4));
....@@ -918,51 +924,71 @@
918924 gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H);
919925 }
920926
927
+static void gpio0_set_lvl(u32 pin_id, int lvl)
928
+{
929
+ u32 sft = (pin_id % 16);
930
+
931
+ if (pin_id < 16)
932
+ writel_relaxed(BITS_WITH_WMASK(lvl, 0x1, sft),
933
+ gpio_base[0] + RV1106_GPIO_SWPORT_DR_L);
934
+ else
935
+ writel_relaxed(BITS_WITH_WMASK(lvl, 0x1, sft),
936
+ gpio_base[0] + RV1106_GPIO_SWPORT_DR_H);
937
+}
938
+
921939 static void gpio_config(void)
922940 {
941
+ u32 iomux, dir, lvl, pull, id;
942
+ u32 cfg, i;
943
+
944
+ if (slp_cfg == NULL)
945
+ return;
946
+
923947 ddr_data.gpio0a_iomux_l = readl_relaxed(ioc_base[0] + 0);
924948 ddr_data.gpio0a_iomux_h = readl_relaxed(ioc_base[0] + 0x4);
925949 ddr_data.gpio0a0_pull = readl_relaxed(ioc_base[0] + 0x38);
926950 ddr_data.gpio0_ddr_l = readl_relaxed(gpio_base[0] + RV1106_GPIO_SWPORT_DDR_L);
927951 ddr_data.gpio0_ddr_h = readl_relaxed(gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H);
928952
929
- /* gpio0_a0, input, pulldown */
930
- gpio0_set_iomux(0, 0);
931
- gpio0_set_pull(0, RV1106_GPIO_PULL_DOWN);
932
- gpio0_set_direct(0, 0);
953
+ for (i = 0; i < slp_cfg->sleep_io_config_cnt; i++) {
954
+ cfg = slp_cfg->sleep_io_config[i];
955
+ iomux = RKPM_IO_CFG_GET_IOMUX(cfg);
956
+ dir = RKPM_IO_CFG_GET_GPIO_DIR(cfg);
957
+ lvl = RKPM_IO_CFG_GET_GPIO_LVL(cfg);
958
+ pull = RKPM_IO_CFG_GET_PULL(cfg);
959
+ id = RKPM_IO_CFG_GET_ID(cfg);
933960
934
-#ifdef RV1106_GPIO0_A1_LOWPOWER
935
- /* gpio0_a1, input, pulldown */
936
- gpio0_set_iomux(1, 0);
937
- gpio0_set_pull(1, RV1106_GPIO_PULL_DOWN);
938
- gpio0_set_direct(1, 0);
939
-#endif
940
- /* gpio0_a2, input, pulldown */
941
- gpio0_set_iomux(2, 0);
942
- gpio0_set_pull(2, RV1106_GPIO_PULL_DOWN);
943
- gpio0_set_direct(2, 0);
961
+ if (is_rv1106 && id == 3) {
962
+ /* gpio0_a3, pullnone */
963
+ gpio0_set_iomux(3, 1);
964
+ gpio0_set_pull(3, RV1106_GPIO_PULL_NONE);
965
+ continue;
966
+ }
944967
945
- /* gpio0_a3, pullnone */
946
- gpio0_set_pull(3, RV1106_GPIO_PULL_NONE);
968
+ if (is_rv1103 && id == 4) {
969
+ /* gpio0_a4, pullnone */
970
+ gpio0_set_iomux(4, 1);
971
+ gpio0_set_pull(4, RV1106_GPIO_PULL_NONE);
972
+ continue;
973
+ }
947974
948
- /* gpio0_a4, input, pulldown */
949
- gpio0_set_iomux(4, 0);
950
- gpio0_set_pull(4, RV1106_GPIO_PULL_DOWN);
951
- gpio0_set_direct(4, 0);
975
+ if (iomux == RKPM_IO_CFG_IOMUX_GPIO_VAL) {
976
+ if (dir == RKPM_IO_CFG_GPIO_DIR_INPUT_VAL)
977
+ gpio0_set_lvl(id, lvl);
952978
953
- /* gpio0_a5, input, pullnone */
954
- gpio0_set_iomux(5, 0);
955
- gpio0_set_pull(5, RV1106_GPIO_PULL_NONE);
956
- gpio0_set_direct(5, 0);
979
+ gpio0_set_direct(id, dir);
980
+ }
957981
958
- /* gpio0_a6, input, pullnone */
959
- gpio0_set_iomux(6, 0);
960
- gpio0_set_pull(6, RV1106_GPIO_PULL_NONE);
961
- gpio0_set_direct(6, 0);
982
+ gpio0_set_iomux(id, iomux);
983
+ gpio0_set_pull(id, pull);
984
+ }
962985 }
963986
964987 static void gpio_restore(void)
965988 {
989
+ if (slp_cfg == NULL)
990
+ return;
991
+
966992 writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_l), ioc_base[0] + 0);
967993 writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_h), ioc_base[0] + 0x4);
968994
....@@ -1056,6 +1082,8 @@
10561082 {
10571083 rkpm_printstr("rv1106 enter sleep\n");
10581084
1085
+ slp_cfg = rockchip_get_cur_sleep_config();
1086
+
10591087 local_fiq_disable();
10601088
10611089 rv1106_dbg_irq_prepare();
....@@ -1101,7 +1129,7 @@
11011129 rkpm_printch('-');
11021130
11031131 /* Check whether it's time_out wakeup */
1104
- if (IS_ENABLED(CONFIG_RV1106_HPMCU_FAST_WAKEUP) && ddr_data.pmu_wkup_int_st == 0) {
1132
+ if (IS_ENABLED(CONFIG_RV1106_HPMCU_FAST_WAKEUP)) {
11051133 if (hpmcu_fast_wkup()) {
11061134 rkpm_gicv2_dist_restore(gicd_base, &gicd_ctx_save);
11071135 goto RE_ENTER_SLEEP;
....@@ -1109,6 +1137,12 @@
11091137 rkpm_gicv2_dist_restore(gicd_base, &gicd_ctx_save);
11101138 rkpm_gicv2_cpu_restore(gicd_base, gicc_base, &gicc_ctx_save);
11111139 }
1140
+ }
1141
+
1142
+ if (rk_hptimer_get_mode(hptimer_base) == RK_HPTIMER_SOFT_ADJUST_MODE) {
1143
+ if (rk_hptimer_wait_mode(hptimer_base,
1144
+ RK_HPTIMER_SOFT_ADJUST_MODE))
1145
+ rkpm_printstr("WARN: can't wait hptimer soft adjust mode!\n");
11121146 }
11131147
11141148 fiq_glue_resume();
....@@ -1125,6 +1159,11 @@
11251159 {
11261160 void __iomem *dev_reg_base;
11271161
1162
+ if (of_machine_is_compatible("rockchip,rv1103"))
1163
+ is_rv1103 = 1;
1164
+ else if (of_machine_is_compatible("rockchip,rv1106"))
1165
+ is_rv1106 = 1;
1166
+
11281167 dev_reg_base = ioremap(RV1106_DEV_REG_BASE, RV1106_DEV_REG_SIZE);
11291168 if (dev_reg_base)
11301169 pr_info("%s map dev_reg 0x%x -> 0x%x\n",
....@@ -1134,6 +1173,8 @@
11341173
11351174 gicd_base = dev_reg_base + RV1106_GIC_OFFSET + 0x1000;
11361175 gicc_base = dev_reg_base + RV1106_GIC_OFFSET + 0x2000;
1176
+
1177
+ hptimer_base = dev_reg_base + RV1106_HPTIMER_OFFSET;
11371178
11381179 firewall_ddr_base = dev_reg_base + RV1106_FW_DDR_OFFSET;
11391180 firewall_syssram_base = dev_reg_base + RV1106_FW_SRAM_OFFSET;
....@@ -1166,6 +1207,7 @@
11661207
11671208 pmucru_base = dev_reg_base + RV1106_PMUCRU_OFFSET;
11681209 cru_base = dev_reg_base + RV1106_CRU_OFFSET;
1210
+ pvtpllcru_base = dev_reg_base + RV1106_PVTPLLCRU_OFFSET;
11691211 pericru_base = dev_reg_base + RV1106_PERICRU_OFFSET;
11701212 vicru_base = dev_reg_base + RV1106_VICRU_OFFSET;
11711213 npucru_base = dev_reg_base + RV1106_NPUCRU_OFFSET;
....@@ -1203,6 +1245,10 @@
12031245 /* biu auto con */
12041246 writel_relaxed(0x07ff07ff, pmu_base + RV1106_PMU_BIU_AUTO_CON);
12051247
1248
+ /* gpio0_a3 activelow, gpio0_a4 active high, select sleep func */
1249
+ writel_relaxed(BITS_WITH_WMASK(0x5, 0x7, 0),
1250
+ pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
1251
+
12061252 rkpm_region_mem_init(RV1106_PM_REG_REGION_MEM_SIZE);
12071253 rkpm_reg_rgns_init();
12081254