hc
2024-09-20 a36159eec6ca17402b0e146b86efaf76568dc353
kernel/arch/arm/mach-rockchip/rv1106_pm.c
....@@ -15,11 +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>
19
+#include <linux/irqchip/arm-gic.h>
20
+#include <linux/rockchip/rockchip_pm_config.h>
1821
1922 #include "rkpm_gicv2.h"
2023 #include "rkpm_helpers.h"
2124 #include "rkpm_uart.h"
22
-
25
+#include "rockchip_hptimer.h"
2326 #include "rv1106_pm.h"
2427
2528 #define RV1106_PM_REG_REGION_MEM_SIZE SZ_4K
....@@ -56,8 +59,11 @@
5659
5760 static struct rv1106_sleep_ddr_data ddr_data;
5861
62
+static const struct rk_sleep_config *slp_cfg;
63
+
5964 static void __iomem *pmucru_base;
6065 static void __iomem *cru_base;
66
+static void __iomem *pvtpllcru_base;
6167 static void __iomem *pericru_base;
6268 static void __iomem *vicru_base;
6369 static void __iomem *npucru_base;
....@@ -86,11 +92,13 @@
8692 static void __iomem *pmu_base;
8793 static void __iomem *gicd_base;
8894 static void __iomem *gicc_base;
95
+static void __iomem *hptimer_base;
8996 static void __iomem *firewall_ddr_base;
9097 static void __iomem *firewall_syssram_base;
9198 static void __iomem *pmu_base;
9299 static void __iomem *nstimer_base;
93100 static void __iomem *stimer_base;
101
+static void __iomem *mbox_base;
94102 static void __iomem *ddrc_base;
95103 static void __iomem *ioc_base[5];
96104 static void __iomem *gpio_base[5];
....@@ -102,6 +110,10 @@
102110 /* core_cru */
103111 { REG_REGION(0x300, 0x310, 4, &corecru_base, WMSK_VAL)},
104112 { 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)},
105117
106118 /* core_sgrf */
107119 { REG_REGION(0x004, 0x014, 4, &coresgrf_base, 0)},
....@@ -274,6 +286,8 @@
274286 { REG_REGION(0x30, 0x30, 4, &stimer_base, 0)},
275287 };
276288
289
+static int is_rv1103, is_rv1106;
290
+
277291 #define PLL_LOCKED_TIMEOUT 600000U
278292
279293 static void pm_pll_wait_lock(u32 pll_id)
....@@ -309,7 +323,10 @@
309323
310324 static void gic400_restore(void)
311325 {
312
- rkpm_gicv2_dist_restore(gicd_base, &gicd_ctx_save);
326
+ if (IS_ENABLED(CONFIG_RV1106_HPMCU_FAST_WAKEUP))
327
+ writel_relaxed(0x3, gicd_base + GIC_DIST_CTRL);
328
+ else
329
+ rkpm_gicv2_dist_restore(gicd_base, &gicd_ctx_save);
313330 rkpm_gicv2_cpu_restore(gicd_base, gicc_base, &gicc_ctx_save);
314331 }
315332
....@@ -377,7 +394,7 @@
377394 if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_USBDEV_EN))
378395 rkpm_printstr("USBDEV detect wakeup\n");
379396
380
- if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_TIMEROUT_EN))
397
+ if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_TIMEOUT_EN))
381398 rkpm_printstr("TIMEOUT interrupt wakeup\n");
382399
383400 rkpm_printch('\n');
....@@ -408,6 +425,87 @@
408425
409426 rkpm_bootdata_l2ctlr_f = 1;
410427 rkpm_bootdata_l2ctlr = rv1106_l2_config();
428
+}
429
+
430
+static void writel_clrset_bits(u32 clr, u32 set, void __iomem *addr)
431
+{
432
+ u32 val = readl_relaxed(addr);
433
+
434
+ val &= ~clr;
435
+ val |= set;
436
+ writel_relaxed(val, addr);
437
+}
438
+
439
+static void gic_irq_en(int irq)
440
+{
441
+ writel_clrset_bits(0xff << irq % 4 * 8, 0x1 << irq % 4 * 8,
442
+ gicd_base + GIC_DIST_TARGET + (irq >> 2 << 2));
443
+ writel_clrset_bits(0xff << irq % 4 * 8, 0xa0 << irq % 4 * 8,
444
+ gicd_base + GIC_DIST_PRI + (irq >> 2 << 2));
445
+ writel_clrset_bits(0x3 << irq % 16 * 2, 0x1 << irq % 16 * 2,
446
+ gicd_base + GIC_DIST_CONFIG + (irq >> 4 << 2));
447
+ writel_clrset_bits(BIT(irq % 32), BIT(irq % 32),
448
+ gicd_base + GIC_DIST_IGROUP + (irq >> 5 << 2));
449
+
450
+ dsb(sy);
451
+ writel_relaxed(0x1 << irq % 32, gicd_base + GIC_DIST_ENABLE_SET + (irq >> 5 << 2));
452
+ dsb(sy);
453
+}
454
+
455
+static int is_hpmcu_mbox_int(void)
456
+{
457
+ return !!(readl(mbox_base + RV1106_MBOX_B2A_STATUS) & BIT(0));
458
+}
459
+
460
+static void hpmcu_start(void)
461
+{
462
+ /* enable hpmcu mailbox AP irq */
463
+ gic_irq_en(RV1106_HPMCU_MBOX_IRQ_AP);
464
+
465
+ /* tell hpmcu that we are currently in system wake up. */
466
+ writel(RV1106_SYS_IS_WKUP, pmu_base + RV1106_PMU_SYS_REG(0));
467
+
468
+ /* set the mcu uncache area, usually set the devices address */
469
+ writel(0xff000, coregrf_base + RV1106_COREGRF_CACHE_PERI_ADDR_START);
470
+ writel(0xffc00, coregrf_base + RV1106_COREGRF_CACHE_PERI_ADDR_END);
471
+ /* Reset the hp mcu */
472
+ writel(0x1e001e, corecru_base + RV1106_COERCRU_SFTRST_CON(1));
473
+ /* set the mcu addr */
474
+ writel(RV1106_HPMCU_BOOT_ADDR,
475
+ coresgrf_base + RV1106_CORESGRF_HPMCU_BOOTADDR);
476
+ dsb(sy);
477
+
478
+ /* release the mcu */
479
+ writel(0x1e0000, corecru_base + RV1106_COERCRU_SFTRST_CON(1));
480
+ dsb(sy);
481
+}
482
+
483
+static int hpmcu_fast_wkup(void)
484
+{
485
+ u32 cmd;
486
+
487
+ hpmcu_start();
488
+
489
+ while (1) {
490
+ rkpm_printstr("-s-\n");
491
+ dsb(sy);
492
+ wfi();
493
+ rkpm_printstr("-w-\n");
494
+
495
+ if (is_hpmcu_mbox_int()) {
496
+ rkpm_printstr("-h-mbox-\n");
497
+ /* clear system wake up state */
498
+ writel(0, pmu_base + RV1106_PMU_SYS_REG(0));
499
+ writel(BIT(0), mbox_base + RV1106_MBOX_B2A_STATUS);
500
+ break;
501
+ }
502
+ }
503
+
504
+ cmd = readl(mbox_base + RV1106_MBOX_B2A_CMD_0);
505
+ if (cmd == RV1106_MBOX_CMD_AP_SUSPEND)
506
+ return 1;
507
+ else
508
+ return 0;
411509 }
412510
413511 static void clock_suspend(void)
....@@ -560,6 +658,9 @@
560658 {
561659 writel_relaxed(WITH_16BITS_WMSK(ddr_data.pmucru_sel_con7),
562660 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);
563664 }
564665
565666 static void ddr_sleep_config(void)
....@@ -616,10 +717,11 @@
616717 ddr_data.ioc1_1a_iomux_l = readl_relaxed(ioc_base[1] + 0);
617718
618719 pmu_wkup_con =
619
- /* BIT(RV1106_PMU_WAKEUP_TIMEROUT_EN) | */
620720 /* BIT(RV1106_PMU_WAKEUP_CPU_INT_EN) | */
621721 BIT(RV1106_PMU_WAKEUP_GPIO_INT_EN) |
622722 0;
723
+ if (IS_ENABLED(CONFIG_RV1106_PMU_WAKEUP_TIMEOUT))
724
+ pmu_wkup_con |= BIT(RV1106_PMU_WAKEUP_TIMEOUT_EN);
623725
624726 pmu_pwr_con =
625727 BIT(RV1106_PMU_PWRMODE_EN) |
....@@ -685,30 +787,21 @@
685787 BIT(RV1106_PMU_GPLL_PD_ENA) |
686788 0;
687789
688
- /* pmic_sleep */
689
- /* gpio0_a3 activelow, gpio0_a4 active high */
690
- writel_relaxed(BITS_WITH_WMASK(0x4, 0x7, 0), pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
691
- /* select sleep func */
692
- writel_relaxed(BITS_WITH_WMASK(0x1, 0x1, 0), pmugrf_base + RV1106_PMUGRF_SOC_CON(1));
693
- /* gpio0_a3 iomux */
694
- writel_relaxed(BITS_WITH_WMASK(0x1, 0xf, 12), ioc_base[0] + 0);
695
-
696790 /* pmu_debug */
697791 writel_relaxed(0xffffff01, pmu_base + RV1106_PMU_INFO_TX_CON);
698792 writel_relaxed(BITS_WITH_WMASK(0x1, 0xf, 4), ioc_base[1] + 0);
699793
700794 /* pmu count */
701
- writel_relaxed(clk_freq_khz * 32, pmu_base + RV1106_PMU_OSC_STABLE_CNT);
702
- writel_relaxed(clk_freq_khz * 32, pmu_base + RV1106_PMU_PMIC_STABLE_CNT);
703
- 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);
704797
705798 /* Pmu's clk has switched to 24M back When pmu FSM counts
706799 * the follow counters, so we should use 24M to calculate
707800 * these counters.
708801 */
709
- writel_relaxed(24000 * 2, pmu_base + RV1106_PMU_WAKEUP_RSTCLR_CNT);
710
- writel_relaxed(24000 * 5, pmu_base + RV1106_PMU_PLL_LOCK_CNT);
711
- 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);
712805
713806 /* pmu reset hold */
714807 writel_relaxed(0xffffffff, pmugrf_base + RV1106_PMUGRF_SOC_CON(4));
....@@ -831,51 +924,71 @@
831924 gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H);
832925 }
833926
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
+
834939 static void gpio_config(void)
835940 {
941
+ u32 iomux, dir, lvl, pull, id;
942
+ u32 cfg, i;
943
+
944
+ if (slp_cfg == NULL)
945
+ return;
946
+
836947 ddr_data.gpio0a_iomux_l = readl_relaxed(ioc_base[0] + 0);
837948 ddr_data.gpio0a_iomux_h = readl_relaxed(ioc_base[0] + 0x4);
838949 ddr_data.gpio0a0_pull = readl_relaxed(ioc_base[0] + 0x38);
839950 ddr_data.gpio0_ddr_l = readl_relaxed(gpio_base[0] + RV1106_GPIO_SWPORT_DDR_L);
840951 ddr_data.gpio0_ddr_h = readl_relaxed(gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H);
841952
842
- /* gpio0_a0, input, pulldown */
843
- gpio0_set_iomux(0, 0);
844
- gpio0_set_pull(0, RV1106_GPIO_PULL_DOWN);
845
- 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);
846960
847
-#ifdef RV1106_GPIO0_A1_LOWPOWER
848
- /* gpio0_a1, input, pulldown */
849
- gpio0_set_iomux(1, 0);
850
- gpio0_set_pull(1, RV1106_GPIO_PULL_DOWN);
851
- gpio0_set_direct(1, 0);
852
-#endif
853
- /* gpio0_a2, input, pulldown */
854
- gpio0_set_iomux(2, 0);
855
- gpio0_set_pull(2, RV1106_GPIO_PULL_DOWN);
856
- 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
+ }
857967
858
- /* gpio0_a3, pullnone */
859
- 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
+ }
860974
861
- /* gpio0_a4, input, pulldown */
862
- gpio0_set_iomux(4, 0);
863
- gpio0_set_pull(4, RV1106_GPIO_PULL_DOWN);
864
- 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);
865978
866
- /* gpio0_a5, input, pullnone */
867
- gpio0_set_iomux(5, 0);
868
- gpio0_set_pull(5, RV1106_GPIO_PULL_NONE);
869
- gpio0_set_direct(5, 0);
979
+ gpio0_set_direct(id, dir);
980
+ }
870981
871
- /* gpio0_a6, input, pullnone */
872
- gpio0_set_iomux(6, 0);
873
- gpio0_set_pull(6, RV1106_GPIO_PULL_NONE);
874
- gpio0_set_direct(6, 0);
982
+ gpio0_set_iomux(id, iomux);
983
+ gpio0_set_pull(id, pull);
984
+ }
875985 }
876986
877987 static void gpio_restore(void)
878988 {
989
+ if (slp_cfg == NULL)
990
+ return;
991
+
879992 writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_l), ioc_base[0] + 0);
880993 writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_h), ioc_base[0] + 0x4);
881994
....@@ -949,7 +1062,18 @@
9491062
9501063 cpu_do_idle();
9511064
952
- pr_err("%s: Failed to suspend\n", __func__);
1065
+#if RV1106_WAKEUP_TO_SYSTEM_RESET
1066
+ /* If reaches here, it means wakeup source cames before cpu enter wfi.
1067
+ * So we should do system reset if RV1106_WAKEUP_TO_SYSTEM_RESET.
1068
+ */
1069
+ writel_relaxed(0x000c000c, cru_base + RV1106_CRU_GLB_RST_CON);
1070
+ writel_relaxed(0xffff0000, pmugrf_base + RV1106_PMUGRF_SOC_CON(4));
1071
+ writel_relaxed(0xffff0000, pmugrf_base + RV1106_PMUGRF_SOC_CON(5));
1072
+ dsb(sy);
1073
+ writel_relaxed(0xfdb9, cru_base + RV1106_CRU_GLB_SRST_FST);
1074
+#endif
1075
+
1076
+ rkpm_printstr("Failed to suspend\n");
9531077
9541078 return 1;
9551079 }
....@@ -958,12 +1082,15 @@
9581082 {
9591083 rkpm_printstr("rv1106 enter sleep\n");
9601084
1085
+ slp_cfg = rockchip_get_cur_sleep_config();
1086
+
9611087 local_fiq_disable();
9621088
9631089 rv1106_dbg_irq_prepare();
9641090
9651091 rkpm_printch('-');
9661092
1093
+RE_ENTER_SLEEP:
9671094 clock_suspend();
9681095 rkpm_printch('0');
9691096
....@@ -1001,6 +1128,23 @@
10011128 clock_resume();
10021129 rkpm_printch('-');
10031130
1131
+ /* Check whether it's time_out wakeup */
1132
+ if (IS_ENABLED(CONFIG_RV1106_HPMCU_FAST_WAKEUP)) {
1133
+ if (hpmcu_fast_wkup()) {
1134
+ rkpm_gicv2_dist_restore(gicd_base, &gicd_ctx_save);
1135
+ goto RE_ENTER_SLEEP;
1136
+ } else {
1137
+ rkpm_gicv2_dist_restore(gicd_base, &gicd_ctx_save);
1138
+ rkpm_gicv2_cpu_restore(gicd_base, gicc_base, &gicc_ctx_save);
1139
+ }
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");
1146
+ }
1147
+
10041148 fiq_glue_resume();
10051149
10061150 rv1106_dbg_irq_finish();
....@@ -1015,6 +1159,11 @@
10151159 {
10161160 void __iomem *dev_reg_base;
10171161
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
+
10181167 dev_reg_base = ioremap(RV1106_DEV_REG_BASE, RV1106_DEV_REG_SIZE);
10191168 if (dev_reg_base)
10201169 pr_info("%s map dev_reg 0x%x -> 0x%x\n",
....@@ -1024,6 +1173,8 @@
10241173
10251174 gicd_base = dev_reg_base + RV1106_GIC_OFFSET + 0x1000;
10261175 gicc_base = dev_reg_base + RV1106_GIC_OFFSET + 0x2000;
1176
+
1177
+ hptimer_base = dev_reg_base + RV1106_HPTIMER_OFFSET;
10271178
10281179 firewall_ddr_base = dev_reg_base + RV1106_FW_DDR_OFFSET;
10291180 firewall_syssram_base = dev_reg_base + RV1106_FW_SRAM_OFFSET;
....@@ -1056,12 +1207,14 @@
10561207
10571208 pmucru_base = dev_reg_base + RV1106_PMUCRU_OFFSET;
10581209 cru_base = dev_reg_base + RV1106_CRU_OFFSET;
1210
+ pvtpllcru_base = dev_reg_base + RV1106_PVTPLLCRU_OFFSET;
10591211 pericru_base = dev_reg_base + RV1106_PERICRU_OFFSET;
10601212 vicru_base = dev_reg_base + RV1106_VICRU_OFFSET;
10611213 npucru_base = dev_reg_base + RV1106_NPUCRU_OFFSET;
10621214 corecru_base = dev_reg_base + RV1106_CORECRU_OFFSET;
10631215 venccru_base = dev_reg_base + RV1106_VENCCRU_OFFSET;
10641216 vocru_base = dev_reg_base + RV1106_VOCRU_OFFSET;
1217
+ mbox_base = dev_reg_base + RV1106_MBOX_OFFSET;
10651218
10661219 ioc_base[0] = dev_reg_base + RV1106_GPIO0IOC_OFFSET;
10671220 ioc_base[1] = dev_reg_base + RV1106_GPIO1IOC_OFFSET;
....@@ -1092,6 +1245,10 @@
10921245 /* biu auto con */
10931246 writel_relaxed(0x07ff07ff, pmu_base + RV1106_PMU_BIU_AUTO_CON);
10941247
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
+
10951252 rkpm_region_mem_init(RV1106_PM_REG_REGION_MEM_SIZE);
10961253 rkpm_reg_rgns_init();
10971254