.. | .. |
---|
15 | 15 | #include <asm/fiq_glue.h> |
---|
16 | 16 | #include <asm/tlbflush.h> |
---|
17 | 17 | #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> |
---|
18 | 21 | |
---|
19 | 22 | #include "rkpm_gicv2.h" |
---|
20 | 23 | #include "rkpm_helpers.h" |
---|
21 | 24 | #include "rkpm_uart.h" |
---|
22 | | - |
---|
| 25 | +#include "rockchip_hptimer.h" |
---|
23 | 26 | #include "rv1106_pm.h" |
---|
24 | 27 | |
---|
25 | 28 | #define RV1106_PM_REG_REGION_MEM_SIZE SZ_4K |
---|
.. | .. |
---|
56 | 59 | |
---|
57 | 60 | static struct rv1106_sleep_ddr_data ddr_data; |
---|
58 | 61 | |
---|
| 62 | +static const struct rk_sleep_config *slp_cfg; |
---|
| 63 | + |
---|
59 | 64 | static void __iomem *pmucru_base; |
---|
60 | 65 | static void __iomem *cru_base; |
---|
| 66 | +static void __iomem *pvtpllcru_base; |
---|
61 | 67 | static void __iomem *pericru_base; |
---|
62 | 68 | static void __iomem *vicru_base; |
---|
63 | 69 | static void __iomem *npucru_base; |
---|
.. | .. |
---|
86 | 92 | static void __iomem *pmu_base; |
---|
87 | 93 | static void __iomem *gicd_base; |
---|
88 | 94 | static void __iomem *gicc_base; |
---|
| 95 | +static void __iomem *hptimer_base; |
---|
89 | 96 | static void __iomem *firewall_ddr_base; |
---|
90 | 97 | static void __iomem *firewall_syssram_base; |
---|
91 | 98 | static void __iomem *pmu_base; |
---|
92 | 99 | static void __iomem *nstimer_base; |
---|
93 | 100 | static void __iomem *stimer_base; |
---|
| 101 | +static void __iomem *mbox_base; |
---|
94 | 102 | static void __iomem *ddrc_base; |
---|
95 | 103 | static void __iomem *ioc_base[5]; |
---|
96 | 104 | static void __iomem *gpio_base[5]; |
---|
.. | .. |
---|
102 | 110 | /* core_cru */ |
---|
103 | 111 | { REG_REGION(0x300, 0x310, 4, &corecru_base, WMSK_VAL)}, |
---|
104 | 112 | { 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)}, |
---|
105 | 117 | |
---|
106 | 118 | /* core_sgrf */ |
---|
107 | 119 | { REG_REGION(0x004, 0x014, 4, &coresgrf_base, 0)}, |
---|
.. | .. |
---|
274 | 286 | { REG_REGION(0x30, 0x30, 4, &stimer_base, 0)}, |
---|
275 | 287 | }; |
---|
276 | 288 | |
---|
| 289 | +static int is_rv1103, is_rv1106; |
---|
| 290 | + |
---|
277 | 291 | #define PLL_LOCKED_TIMEOUT 600000U |
---|
278 | 292 | |
---|
279 | 293 | static void pm_pll_wait_lock(u32 pll_id) |
---|
.. | .. |
---|
309 | 323 | |
---|
310 | 324 | static void gic400_restore(void) |
---|
311 | 325 | { |
---|
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); |
---|
313 | 330 | rkpm_gicv2_cpu_restore(gicd_base, gicc_base, &gicc_ctx_save); |
---|
314 | 331 | } |
---|
315 | 332 | |
---|
.. | .. |
---|
377 | 394 | if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_USBDEV_EN)) |
---|
378 | 395 | rkpm_printstr("USBDEV detect wakeup\n"); |
---|
379 | 396 | |
---|
380 | | - if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_TIMEROUT_EN)) |
---|
| 397 | + if (pmu_int_st & BIT(RV1106_PMU_WAKEUP_TIMEOUT_EN)) |
---|
381 | 398 | rkpm_printstr("TIMEOUT interrupt wakeup\n"); |
---|
382 | 399 | |
---|
383 | 400 | rkpm_printch('\n'); |
---|
.. | .. |
---|
408 | 425 | |
---|
409 | 426 | rkpm_bootdata_l2ctlr_f = 1; |
---|
410 | 427 | 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; |
---|
411 | 509 | } |
---|
412 | 510 | |
---|
413 | 511 | static void clock_suspend(void) |
---|
.. | .. |
---|
560 | 658 | { |
---|
561 | 659 | writel_relaxed(WITH_16BITS_WMSK(ddr_data.pmucru_sel_con7), |
---|
562 | 660 | 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); |
---|
563 | 664 | } |
---|
564 | 665 | |
---|
565 | 666 | static void ddr_sleep_config(void) |
---|
.. | .. |
---|
616 | 717 | ddr_data.ioc1_1a_iomux_l = readl_relaxed(ioc_base[1] + 0); |
---|
617 | 718 | |
---|
618 | 719 | pmu_wkup_con = |
---|
619 | | - /* BIT(RV1106_PMU_WAKEUP_TIMEROUT_EN) | */ |
---|
620 | 720 | /* BIT(RV1106_PMU_WAKEUP_CPU_INT_EN) | */ |
---|
621 | 721 | BIT(RV1106_PMU_WAKEUP_GPIO_INT_EN) | |
---|
622 | 722 | 0; |
---|
| 723 | + if (IS_ENABLED(CONFIG_RV1106_PMU_WAKEUP_TIMEOUT)) |
---|
| 724 | + pmu_wkup_con |= BIT(RV1106_PMU_WAKEUP_TIMEOUT_EN); |
---|
623 | 725 | |
---|
624 | 726 | pmu_pwr_con = |
---|
625 | 727 | BIT(RV1106_PMU_PWRMODE_EN) | |
---|
.. | .. |
---|
685 | 787 | BIT(RV1106_PMU_GPLL_PD_ENA) | |
---|
686 | 788 | 0; |
---|
687 | 789 | |
---|
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 | | - |
---|
696 | 790 | /* pmu_debug */ |
---|
697 | 791 | writel_relaxed(0xffffff01, pmu_base + RV1106_PMU_INFO_TX_CON); |
---|
698 | 792 | writel_relaxed(BITS_WITH_WMASK(0x1, 0xf, 4), ioc_base[1] + 0); |
---|
699 | 793 | |
---|
700 | 794 | /* 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); |
---|
704 | 797 | |
---|
705 | 798 | /* Pmu's clk has switched to 24M back When pmu FSM counts |
---|
706 | 799 | * the follow counters, so we should use 24M to calculate |
---|
707 | 800 | * these counters. |
---|
708 | 801 | */ |
---|
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); |
---|
712 | 805 | |
---|
713 | 806 | /* pmu reset hold */ |
---|
714 | 807 | writel_relaxed(0xffffffff, pmugrf_base + RV1106_PMUGRF_SOC_CON(4)); |
---|
.. | .. |
---|
831 | 924 | gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H); |
---|
832 | 925 | } |
---|
833 | 926 | |
---|
| 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 | + |
---|
834 | 939 | static void gpio_config(void) |
---|
835 | 940 | { |
---|
| 941 | + u32 iomux, dir, lvl, pull, id; |
---|
| 942 | + u32 cfg, i; |
---|
| 943 | + |
---|
| 944 | + if (slp_cfg == NULL) |
---|
| 945 | + return; |
---|
| 946 | + |
---|
836 | 947 | ddr_data.gpio0a_iomux_l = readl_relaxed(ioc_base[0] + 0); |
---|
837 | 948 | ddr_data.gpio0a_iomux_h = readl_relaxed(ioc_base[0] + 0x4); |
---|
838 | 949 | ddr_data.gpio0a0_pull = readl_relaxed(ioc_base[0] + 0x38); |
---|
839 | 950 | ddr_data.gpio0_ddr_l = readl_relaxed(gpio_base[0] + RV1106_GPIO_SWPORT_DDR_L); |
---|
840 | 951 | ddr_data.gpio0_ddr_h = readl_relaxed(gpio_base[0] + RV1106_GPIO_SWPORT_DDR_H); |
---|
841 | 952 | |
---|
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); |
---|
846 | 960 | |
---|
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 | + } |
---|
857 | 967 | |
---|
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 | + } |
---|
860 | 974 | |
---|
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); |
---|
865 | 978 | |
---|
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 | + } |
---|
870 | 981 | |
---|
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 | + } |
---|
875 | 985 | } |
---|
876 | 986 | |
---|
877 | 987 | static void gpio_restore(void) |
---|
878 | 988 | { |
---|
| 989 | + if (slp_cfg == NULL) |
---|
| 990 | + return; |
---|
| 991 | + |
---|
879 | 992 | writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_l), ioc_base[0] + 0); |
---|
880 | 993 | writel_relaxed(WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_h), ioc_base[0] + 0x4); |
---|
881 | 994 | |
---|
.. | .. |
---|
949 | 1062 | |
---|
950 | 1063 | cpu_do_idle(); |
---|
951 | 1064 | |
---|
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"); |
---|
953 | 1077 | |
---|
954 | 1078 | return 1; |
---|
955 | 1079 | } |
---|
.. | .. |
---|
958 | 1082 | { |
---|
959 | 1083 | rkpm_printstr("rv1106 enter sleep\n"); |
---|
960 | 1084 | |
---|
| 1085 | + slp_cfg = rockchip_get_cur_sleep_config(); |
---|
| 1086 | + |
---|
961 | 1087 | local_fiq_disable(); |
---|
962 | 1088 | |
---|
963 | 1089 | rv1106_dbg_irq_prepare(); |
---|
964 | 1090 | |
---|
965 | 1091 | rkpm_printch('-'); |
---|
966 | 1092 | |
---|
| 1093 | +RE_ENTER_SLEEP: |
---|
967 | 1094 | clock_suspend(); |
---|
968 | 1095 | rkpm_printch('0'); |
---|
969 | 1096 | |
---|
.. | .. |
---|
1001 | 1128 | clock_resume(); |
---|
1002 | 1129 | rkpm_printch('-'); |
---|
1003 | 1130 | |
---|
| 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 | + |
---|
1004 | 1148 | fiq_glue_resume(); |
---|
1005 | 1149 | |
---|
1006 | 1150 | rv1106_dbg_irq_finish(); |
---|
.. | .. |
---|
1015 | 1159 | { |
---|
1016 | 1160 | void __iomem *dev_reg_base; |
---|
1017 | 1161 | |
---|
| 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 | + |
---|
1018 | 1167 | dev_reg_base = ioremap(RV1106_DEV_REG_BASE, RV1106_DEV_REG_SIZE); |
---|
1019 | 1168 | if (dev_reg_base) |
---|
1020 | 1169 | pr_info("%s map dev_reg 0x%x -> 0x%x\n", |
---|
.. | .. |
---|
1024 | 1173 | |
---|
1025 | 1174 | gicd_base = dev_reg_base + RV1106_GIC_OFFSET + 0x1000; |
---|
1026 | 1175 | gicc_base = dev_reg_base + RV1106_GIC_OFFSET + 0x2000; |
---|
| 1176 | + |
---|
| 1177 | + hptimer_base = dev_reg_base + RV1106_HPTIMER_OFFSET; |
---|
1027 | 1178 | |
---|
1028 | 1179 | firewall_ddr_base = dev_reg_base + RV1106_FW_DDR_OFFSET; |
---|
1029 | 1180 | firewall_syssram_base = dev_reg_base + RV1106_FW_SRAM_OFFSET; |
---|
.. | .. |
---|
1056 | 1207 | |
---|
1057 | 1208 | pmucru_base = dev_reg_base + RV1106_PMUCRU_OFFSET; |
---|
1058 | 1209 | cru_base = dev_reg_base + RV1106_CRU_OFFSET; |
---|
| 1210 | + pvtpllcru_base = dev_reg_base + RV1106_PVTPLLCRU_OFFSET; |
---|
1059 | 1211 | pericru_base = dev_reg_base + RV1106_PERICRU_OFFSET; |
---|
1060 | 1212 | vicru_base = dev_reg_base + RV1106_VICRU_OFFSET; |
---|
1061 | 1213 | npucru_base = dev_reg_base + RV1106_NPUCRU_OFFSET; |
---|
1062 | 1214 | corecru_base = dev_reg_base + RV1106_CORECRU_OFFSET; |
---|
1063 | 1215 | venccru_base = dev_reg_base + RV1106_VENCCRU_OFFSET; |
---|
1064 | 1216 | vocru_base = dev_reg_base + RV1106_VOCRU_OFFSET; |
---|
| 1217 | + mbox_base = dev_reg_base + RV1106_MBOX_OFFSET; |
---|
1065 | 1218 | |
---|
1066 | 1219 | ioc_base[0] = dev_reg_base + RV1106_GPIO0IOC_OFFSET; |
---|
1067 | 1220 | ioc_base[1] = dev_reg_base + RV1106_GPIO1IOC_OFFSET; |
---|
.. | .. |
---|
1092 | 1245 | /* biu auto con */ |
---|
1093 | 1246 | writel_relaxed(0x07ff07ff, pmu_base + RV1106_PMU_BIU_AUTO_CON); |
---|
1094 | 1247 | |
---|
| 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 | + |
---|
1095 | 1252 | rkpm_region_mem_init(RV1106_PM_REG_REGION_MEM_SIZE); |
---|
1096 | 1253 | rkpm_reg_rgns_init(); |
---|
1097 | 1254 | |
---|