pmu.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. /*
  2. * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <errno.h>
  8. #include <platform_def.h>
  9. #include <arch_helpers.h>
  10. #include <bl31/bl31.h>
  11. #include <common/debug.h>
  12. #include <drivers/console.h>
  13. #include <drivers/delay_timer.h>
  14. #include <lib/bakery_lock.h>
  15. #include <lib/mmio.h>
  16. #include <plat/common/platform.h>
  17. #include <plat_private.h>
  18. #include <pmu.h>
  19. #include <pmu_com.h>
  20. #include <rk3328_def.h>
  21. DEFINE_BAKERY_LOCK(rockchip_pd_lock);
  22. static struct rk3328_sleep_ddr_data ddr_data;
  23. static __sramdata struct rk3328_sleep_sram_data sram_data;
  24. static uint32_t cpu_warm_boot_addr;
  25. #pragma weak rk3328_pmic_suspend
  26. #pragma weak rk3328_pmic_resume
  27. static inline uint32_t get_cpus_pwr_domain_cfg_info(uint32_t cpu_id)
  28. {
  29. uint32_t pd_reg, apm_reg;
  30. pd_reg = mmio_read_32(PMU_BASE + PMU_PWRDN_CON) & BIT(cpu_id);
  31. apm_reg = mmio_read_32(PMU_BASE + PMU_CPUAPM_CON(cpu_id)) &
  32. BIT(core_pm_en);
  33. if (pd_reg && !apm_reg)
  34. return core_pwr_pd;
  35. else if (!pd_reg && apm_reg)
  36. return core_pwr_wfi;
  37. ERROR("%s: 0x%x, 0x%x\n", __func__, pd_reg, apm_reg);
  38. while (1)
  39. ;
  40. }
  41. static int cpus_power_domain_on(uint32_t cpu_id)
  42. {
  43. uint32_t cpu_pd, cfg_info;
  44. cpu_pd = PD_CPU0 + cpu_id;
  45. cfg_info = get_cpus_pwr_domain_cfg_info(cpu_id);
  46. if (cfg_info == core_pwr_pd) {
  47. /* disable apm cfg */
  48. mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(cpu_id),
  49. CORES_PM_DISABLE);
  50. /* if the cores have be on, power off it firstly */
  51. if (pmu_power_domain_st(cpu_pd) == pmu_pd_on) {
  52. mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(cpu_id),
  53. CORES_PM_DISABLE);
  54. pmu_power_domain_ctr(cpu_pd, pmu_pd_off);
  55. }
  56. pmu_power_domain_ctr(cpu_pd, pmu_pd_on);
  57. } else {
  58. if (pmu_power_domain_st(cpu_pd) == pmu_pd_on) {
  59. WARN("%s: cpu%d is not in off,!\n", __func__, cpu_id);
  60. return -EINVAL;
  61. }
  62. mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(cpu_id),
  63. BIT(core_pm_sft_wakeup_en));
  64. }
  65. return 0;
  66. }
  67. static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg)
  68. {
  69. uint32_t cpu_pd, core_pm_value;
  70. cpu_pd = PD_CPU0 + cpu_id;
  71. if (pmu_power_domain_st(cpu_pd) == pmu_pd_off)
  72. return 0;
  73. if (pd_cfg == core_pwr_pd) {
  74. if (check_cpu_wfie(cpu_id, CKECK_WFEI_MSK))
  75. return -EINVAL;
  76. /* disable apm cfg */
  77. mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(cpu_id),
  78. CORES_PM_DISABLE);
  79. pmu_power_domain_ctr(cpu_pd, pmu_pd_off);
  80. } else {
  81. core_pm_value = BIT(core_pm_en) | BIT(core_pm_dis_int);
  82. if (pd_cfg == core_pwr_wfi_int)
  83. core_pm_value |= BIT(core_pm_int_wakeup_en);
  84. mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(cpu_id),
  85. core_pm_value);
  86. }
  87. return 0;
  88. }
  89. static void nonboot_cpus_off(void)
  90. {
  91. uint32_t boot_cpu, cpu;
  92. /* turn off noboot cpus */
  93. boot_cpu = plat_my_core_pos();
  94. for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
  95. if (cpu == boot_cpu)
  96. continue;
  97. cpus_power_domain_off(cpu, core_pwr_pd);
  98. }
  99. }
  100. void sram_save(void)
  101. {
  102. /* TODO: support the sdram save for rk3328 SoCs*/
  103. }
  104. void sram_restore(void)
  105. {
  106. /* TODO: support the sdram restore for rk3328 SoCs */
  107. }
  108. int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint)
  109. {
  110. uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
  111. assert(cpu_id < PLATFORM_CORE_COUNT);
  112. assert(cpuson_flags[cpu_id] == 0);
  113. cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG;
  114. cpuson_entry_point[cpu_id] = entrypoint;
  115. dsb();
  116. cpus_power_domain_on(cpu_id);
  117. return 0;
  118. }
  119. int rockchip_soc_cores_pwr_dm_off(void)
  120. {
  121. uint32_t cpu_id = plat_my_core_pos();
  122. cpus_power_domain_off(cpu_id, core_pwr_wfi);
  123. return 0;
  124. }
  125. int rockchip_soc_cores_pwr_dm_suspend(void)
  126. {
  127. uint32_t cpu_id = plat_my_core_pos();
  128. assert(cpu_id < PLATFORM_CORE_COUNT);
  129. assert(cpuson_flags[cpu_id] == 0);
  130. cpuson_flags[cpu_id] = PMU_CPU_AUTO_PWRDN;
  131. cpuson_entry_point[cpu_id] = (uintptr_t)plat_get_sec_entrypoint();
  132. dsb();
  133. cpus_power_domain_off(cpu_id, core_pwr_wfi_int);
  134. return 0;
  135. }
  136. int rockchip_soc_cores_pwr_dm_on_finish(void)
  137. {
  138. uint32_t cpu_id = plat_my_core_pos();
  139. mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(cpu_id), CORES_PM_DISABLE);
  140. return 0;
  141. }
  142. int rockchip_soc_cores_pwr_dm_resume(void)
  143. {
  144. uint32_t cpu_id = plat_my_core_pos();
  145. mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(cpu_id), CORES_PM_DISABLE);
  146. return 0;
  147. }
  148. void __dead2 rockchip_soc_soft_reset(void)
  149. {
  150. mmio_write_32(CRU_BASE + CRU_CRU_MODE, PLL_SLOW_MODE(CPLL_ID));
  151. mmio_write_32(CRU_BASE + CRU_CRU_MODE, PLL_SLOW_MODE(GPLL_ID));
  152. mmio_write_32(CRU_BASE + CRU_CRU_MODE, PLL_SLOW_MODE(NPLL_ID));
  153. mmio_write_32(CRU_BASE + CRU_CRU_MODE, PLL_SLOW_MODE(APLL_ID));
  154. dsb();
  155. mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, CRU_GLB_SRST_FST_VALUE);
  156. dsb();
  157. /*
  158. * Maybe the HW needs some times to reset the system,
  159. * so we do not hope the core to execute valid codes.
  160. */
  161. while (1)
  162. ;
  163. }
  164. /*
  165. * For PMIC RK805, its sleep pin is connect with gpio2_d2 from rk3328.
  166. * If the PMIC is configured for responding the sleep pin to power off it,
  167. * once the pin is output high, it will get the pmic power off.
  168. */
  169. void __dead2 rockchip_soc_system_off(void)
  170. {
  171. uint32_t val;
  172. /* gpio config */
  173. val = mmio_read_32(GRF_BASE + GRF_GPIO2D_IOMUX);
  174. val &= ~GPIO2_D2_GPIO_MODE;
  175. mmio_write_32(GRF_BASE + GRF_GPIO2D_IOMUX, val);
  176. /* config output */
  177. val = mmio_read_32(GPIO2_BASE + SWPORTA_DDR);
  178. val |= GPIO2_D2;
  179. mmio_write_32(GPIO2_BASE + SWPORTA_DDR, val);
  180. /* config output high level */
  181. val = mmio_read_32(GPIO2_BASE);
  182. val |= GPIO2_D2;
  183. mmio_write_32(GPIO2_BASE, val);
  184. dsb();
  185. while (1)
  186. ;
  187. }
  188. static uint32_t clk_ungt_msk[CRU_CLKGATE_NUMS] = {
  189. 0x187f, 0x0000, 0x010c, 0x0000, 0x0200,
  190. 0x0010, 0x0000, 0x0017, 0x001f, 0x0000,
  191. 0x0000, 0x0000, 0x0000, 0x0003, 0x0000,
  192. 0xf001, 0x27c0, 0x04D9, 0x03ff, 0x0000,
  193. 0x0000, 0x0000, 0x0010, 0x0000, 0x0000,
  194. 0x0000, 0x0000, 0x0003, 0x0008
  195. };
  196. static void clks_gating_suspend(uint32_t *ungt_msk)
  197. {
  198. int i;
  199. for (i = 0; i < CRU_CLKGATE_NUMS; i++) {
  200. ddr_data.clk_ungt_save[i] =
  201. mmio_read_32(CRU_BASE + CRU_CLKGATE_CON(i));
  202. mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(i),
  203. ((~ungt_msk[i]) << 16) | 0xffff);
  204. }
  205. }
  206. static void clks_gating_resume(void)
  207. {
  208. int i;
  209. for (i = 0; i < CRU_CLKGATE_NUMS; i++)
  210. mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(i),
  211. ddr_data.clk_ungt_save[i] | 0xffff0000);
  212. }
  213. static inline void pm_pll_wait_lock(uint32_t pll_id)
  214. {
  215. uint32_t delay = PLL_LOCKED_TIMEOUT;
  216. while (delay > 0) {
  217. if (mmio_read_32(CRU_BASE + PLL_CONS(pll_id, 1)) &
  218. PLL_IS_LOCKED)
  219. break;
  220. delay--;
  221. }
  222. if (delay == 0)
  223. ERROR("lock-pll: %d\n", pll_id);
  224. }
  225. static inline void pll_pwr_dwn(uint32_t pll_id, uint32_t pd)
  226. {
  227. mmio_write_32(CRU_BASE + PLL_CONS(pll_id, 1),
  228. BITS_WITH_WMASK(1U, 1U, 15));
  229. if (pd)
  230. mmio_write_32(CRU_BASE + PLL_CONS(pll_id, 1),
  231. BITS_WITH_WMASK(1, 1, 14));
  232. else
  233. mmio_write_32(CRU_BASE + PLL_CONS(pll_id, 1),
  234. BITS_WITH_WMASK(0, 1, 14));
  235. }
  236. static __sramfunc void dpll_suspend(void)
  237. {
  238. int i;
  239. /* slow mode */
  240. mmio_write_32(CRU_BASE + CRU_CRU_MODE, PLL_SLOW_MODE(DPLL_ID));
  241. /* save pll con */
  242. for (i = 0; i < CRU_PLL_CON_NUMS; i++)
  243. sram_data.dpll_con_save[i] =
  244. mmio_read_32(CRU_BASE + PLL_CONS(DPLL_ID, i));
  245. mmio_write_32(CRU_BASE + PLL_CONS(DPLL_ID, 1),
  246. BITS_WITH_WMASK(1U, 1U, 15));
  247. mmio_write_32(CRU_BASE + PLL_CONS(DPLL_ID, 1),
  248. BITS_WITH_WMASK(1, 1, 14));
  249. }
  250. static __sramfunc void dpll_resume(void)
  251. {
  252. uint32_t delay = PLL_LOCKED_TIMEOUT;
  253. mmio_write_32(CRU_BASE + PLL_CONS(DPLL_ID, 1),
  254. BITS_WITH_WMASK(1U, 1U, 15));
  255. mmio_write_32(CRU_BASE + PLL_CONS(DPLL_ID, 1),
  256. BITS_WITH_WMASK(0, 1, 14));
  257. mmio_write_32(CRU_BASE + PLL_CONS(DPLL_ID, 1),
  258. sram_data.dpll_con_save[1] | 0xc0000000);
  259. dsb();
  260. while (delay > 0) {
  261. if (mmio_read_32(CRU_BASE + PLL_CONS(DPLL_ID, 1)) &
  262. PLL_IS_LOCKED)
  263. break;
  264. delay--;
  265. }
  266. if (delay == 0)
  267. while (1)
  268. ;
  269. mmio_write_32(CRU_BASE + CRU_CRU_MODE,
  270. PLL_NORM_MODE(DPLL_ID));
  271. }
  272. static inline void pll_suspend(uint32_t pll_id)
  273. {
  274. int i;
  275. /* slow mode */
  276. mmio_write_32(CRU_BASE + CRU_CRU_MODE, PLL_SLOW_MODE(pll_id));
  277. /* save pll con */
  278. for (i = 0; i < CRU_PLL_CON_NUMS; i++)
  279. ddr_data.cru_plls_con_save[pll_id][i] =
  280. mmio_read_32(CRU_BASE + PLL_CONS(pll_id, i));
  281. /* powerdown pll */
  282. pll_pwr_dwn(pll_id, pmu_pd_off);
  283. }
  284. static inline void pll_resume(uint32_t pll_id)
  285. {
  286. mmio_write_32(CRU_BASE + PLL_CONS(pll_id, 1),
  287. ddr_data.cru_plls_con_save[pll_id][1] | 0xc0000000);
  288. pm_pll_wait_lock(pll_id);
  289. if (PLL_IS_NORM_MODE(ddr_data.cru_mode_save, pll_id))
  290. mmio_write_32(CRU_BASE + CRU_CRU_MODE,
  291. PLL_NORM_MODE(pll_id));
  292. }
  293. static void pm_plls_suspend(void)
  294. {
  295. ddr_data.cru_mode_save = mmio_read_32(CRU_BASE + CRU_CRU_MODE);
  296. ddr_data.clk_sel0 = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(0));
  297. ddr_data.clk_sel1 = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(1));
  298. ddr_data.clk_sel18 = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(18));
  299. ddr_data.clk_sel20 = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(20));
  300. ddr_data.clk_sel24 = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(24));
  301. ddr_data.clk_sel38 = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(38));
  302. pll_suspend(NPLL_ID);
  303. pll_suspend(CPLL_ID);
  304. pll_suspend(GPLL_ID);
  305. pll_suspend(APLL_ID);
  306. /* core */
  307. mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(0),
  308. BITS_WITH_WMASK(0, 0x1f, 0));
  309. /* pclk_dbg */
  310. mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(1),
  311. BITS_WITH_WMASK(0, 0xf, 0));
  312. /* crypto */
  313. mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(20),
  314. BITS_WITH_WMASK(0, 0x1f, 0));
  315. /* pwm0 */
  316. mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(24),
  317. BITS_WITH_WMASK(0, 0x7f, 8));
  318. /* uart2 from 24M */
  319. mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(18),
  320. BITS_WITH_WMASK(2, 0x3, 8));
  321. /* clk_rtc32k */
  322. mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(38),
  323. BITS_WITH_WMASK(767, 0x3fff, 0) |
  324. BITS_WITH_WMASK(2U, 0x3u, 14));
  325. }
  326. static void pm_plls_resume(void)
  327. {
  328. /* clk_rtc32k */
  329. mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(38),
  330. ddr_data.clk_sel38 |
  331. BITS_WMSK(0x3fff, 0) |
  332. BITS_WMSK(0x3u, 14));
  333. /* uart2 */
  334. mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(18),
  335. ddr_data.clk_sel18 | BITS_WMSK(0x3, 8));
  336. /* pwm0 */
  337. mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(24),
  338. ddr_data.clk_sel24 | BITS_WMSK(0x7f, 8));
  339. /* crypto */
  340. mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(20),
  341. ddr_data.clk_sel20 | BITS_WMSK(0x1f, 0));
  342. /* pclk_dbg */
  343. mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(1),
  344. ddr_data.clk_sel1 | BITS_WMSK(0xf, 0));
  345. /* core */
  346. mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(0),
  347. ddr_data.clk_sel0 | BITS_WMSK(0x1f, 0));
  348. pll_pwr_dwn(APLL_ID, pmu_pd_on);
  349. pll_pwr_dwn(GPLL_ID, pmu_pd_on);
  350. pll_pwr_dwn(CPLL_ID, pmu_pd_on);
  351. pll_pwr_dwn(NPLL_ID, pmu_pd_on);
  352. pll_resume(APLL_ID);
  353. pll_resume(GPLL_ID);
  354. pll_resume(CPLL_ID);
  355. pll_resume(NPLL_ID);
  356. }
  357. #define ARCH_TIMER_TICKS_PER_US (SYS_COUNTER_FREQ_IN_TICKS / 1000000)
  358. static __sramfunc void sram_udelay(uint32_t us)
  359. {
  360. uint64_t pct_orig, pct_now;
  361. uint64_t to_wait = ARCH_TIMER_TICKS_PER_US * us;
  362. isb();
  363. pct_orig = read_cntpct_el0();
  364. do {
  365. isb();
  366. pct_now = read_cntpct_el0();
  367. } while ((pct_now - pct_orig) <= to_wait);
  368. }
  369. /*
  370. * For PMIC RK805, its sleep pin is connect with gpio2_d2 from rk3328.
  371. * If the PMIC is configured for responding the sleep pin
  372. * to get it into sleep mode,
  373. * once the pin is output high, it will get the pmic into sleep mode.
  374. */
  375. __sramfunc void rk3328_pmic_suspend(void)
  376. {
  377. sram_data.pmic_sleep_save = mmio_read_32(GRF_BASE + PMIC_SLEEP_REG);
  378. sram_data.pmic_sleep_gpio_save[1] = mmio_read_32(GPIO2_BASE + 4);
  379. sram_data.pmic_sleep_gpio_save[0] = mmio_read_32(GPIO2_BASE);
  380. mmio_write_32(GRF_BASE + PMIC_SLEEP_REG, BITS_WITH_WMASK(0, 0x3, 4));
  381. mmio_write_32(GPIO2_BASE + 4,
  382. sram_data.pmic_sleep_gpio_save[1] | BIT(26));
  383. mmio_write_32(GPIO2_BASE,
  384. sram_data.pmic_sleep_gpio_save[0] | BIT(26));
  385. }
  386. __sramfunc void rk3328_pmic_resume(void)
  387. {
  388. mmio_write_32(GPIO2_BASE, sram_data.pmic_sleep_gpio_save[0]);
  389. mmio_write_32(GPIO2_BASE + 4, sram_data.pmic_sleep_gpio_save[1]);
  390. mmio_write_32(GRF_BASE + PMIC_SLEEP_REG,
  391. sram_data.pmic_sleep_save | BITS_WMSK(0xffffu, 0));
  392. /* Resuming volt need a lot of time */
  393. sram_udelay(100);
  394. }
  395. static __sramfunc void ddr_suspend(void)
  396. {
  397. sram_data.pd_sr_idle_save = mmio_read_32(DDR_UPCTL_BASE +
  398. DDR_PCTL2_PWRCTL);
  399. sram_data.pd_sr_idle_save &= SELFREF_EN;
  400. mmio_clrbits_32(DDR_UPCTL_BASE + DDR_PCTL2_PWRCTL, SELFREF_EN);
  401. sram_data.ddr_grf_con0 = mmio_read_32(DDR_GRF_BASE +
  402. DDRGRF_SOC_CON(0));
  403. mmio_write_32(DDR_GRF_BASE, BIT_WITH_WMSK(14) | WMSK_BIT(15));
  404. /*
  405. * Override csysreq from ddrc and
  406. * send valid csysreq signal to PMU,
  407. * csysreq is controlled by ddrc only
  408. */
  409. /* in self-refresh */
  410. mmio_setbits_32(PMU_BASE + PMU_SFT_CON, BIT(0));
  411. while ((mmio_read_32(DDR_GRF_BASE + DDRGRF_SOC_STATUS(1)) &
  412. (0x03 << 12)) != (0x02 << 12))
  413. ;
  414. /* ddr retention */
  415. mmio_setbits_32(PMU_BASE + PMU_SFT_CON, BIT(2));
  416. /* ddr gating */
  417. mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(0),
  418. BITS_WITH_WMASK(0x7, 0x7, 4));
  419. mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(7),
  420. BITS_WITH_WMASK(1, 1, 4));
  421. mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(18),
  422. BITS_WITH_WMASK(0x1ff, 0x1ff, 1));
  423. mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(27),
  424. BITS_WITH_WMASK(0x3, 0x3, 0));
  425. dpll_suspend();
  426. }
  427. __sramfunc void dmc_restore(void)
  428. {
  429. dpll_resume();
  430. /* ddr gating */
  431. mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(0),
  432. BITS_WITH_WMASK(0, 0x7, 4));
  433. mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(7),
  434. BITS_WITH_WMASK(0, 1, 4));
  435. mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(18),
  436. BITS_WITH_WMASK(0, 0x1ff, 1));
  437. mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(27),
  438. BITS_WITH_WMASK(0, 0x3, 0));
  439. /* ddr de_retention */
  440. mmio_clrbits_32(PMU_BASE + PMU_SFT_CON, BIT(2));
  441. /* exit self-refresh */
  442. mmio_clrbits_32(PMU_BASE + PMU_SFT_CON, BIT(0));
  443. while ((mmio_read_32(DDR_GRF_BASE + DDRGRF_SOC_STATUS(1)) &
  444. (0x03 << 12)) != (0x00 << 12))
  445. ;
  446. mmio_write_32(DDR_GRF_BASE, sram_data.ddr_grf_con0 | 0xc0000000);
  447. if (sram_data.pd_sr_idle_save)
  448. mmio_setbits_32(DDR_UPCTL_BASE + DDR_PCTL2_PWRCTL,
  449. SELFREF_EN);
  450. }
  451. static __sramfunc void sram_dbg_uart_suspend(void)
  452. {
  453. sram_data.uart2_ier = mmio_read_32(UART2_BASE + UART_IER);
  454. mmio_write_32(UART2_BASE + UART_IER, UART_INT_DISABLE);
  455. mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(16), 0x20002000);
  456. mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(2), 0x00040004);
  457. }
  458. __sramfunc void sram_dbg_uart_resume(void)
  459. {
  460. /* restore uart clk and reset fifo */
  461. mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(16), 0x20000000);
  462. mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(2), 0x00040000);
  463. mmio_write_32(UART2_BASE + UART_FCR, UART_FIFO_RESET);
  464. mmio_write_32(UART2_BASE + UART_IER, sram_data.uart2_ier);
  465. }
  466. static __sramfunc void sram_soc_enter_lp(void)
  467. {
  468. uint32_t apm_value;
  469. apm_value = BIT(core_pm_en) |
  470. BIT(core_pm_dis_int) |
  471. BIT(core_pm_int_wakeup_en);
  472. mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(PD_CPU0), apm_value);
  473. dsb();
  474. isb();
  475. err_loop:
  476. wfi();
  477. /*
  478. *Soc will enter low power mode and
  479. *do not return to here.
  480. */
  481. goto err_loop;
  482. }
  483. __sramfunc void sram_suspend(void)
  484. {
  485. /* disable mmu and icache */
  486. disable_mmu_icache_el3();
  487. tlbialle3();
  488. dsbsy();
  489. isb();
  490. mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1),
  491. ((uintptr_t)&pmu_cpuson_entrypoint >> CPU_BOOT_ADDR_ALIGN) |
  492. CPU_BOOT_ADDR_WMASK);
  493. /* ddr self-refresh and gating phy */
  494. ddr_suspend();
  495. rk3328_pmic_suspend();
  496. sram_dbg_uart_suspend();
  497. sram_soc_enter_lp();
  498. }
  499. void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void)
  500. {
  501. sram_suspend();
  502. /* should never reach here */
  503. psci_power_down_wfi();
  504. }
  505. int rockchip_soc_sys_pwr_dm_suspend(void)
  506. {
  507. clks_gating_suspend(clk_ungt_msk);
  508. pm_plls_suspend();
  509. return 0;
  510. }
  511. int rockchip_soc_sys_pwr_dm_resume(void)
  512. {
  513. pm_plls_resume();
  514. clks_gating_resume();
  515. plat_rockchip_gic_cpuif_enable();
  516. return 0;
  517. }
  518. void rockchip_plat_mmu_el3(void)
  519. {
  520. /* TODO: support the el3 for rk3328 SoCs */
  521. }
  522. void plat_rockchip_pmu_init(void)
  523. {
  524. uint32_t cpu;
  525. for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
  526. cpuson_flags[cpu] = 0;
  527. cpu_warm_boot_addr = (uint64_t)platform_cpu_warmboot;
  528. /* the warm booting address of cpus */
  529. mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1),
  530. (cpu_warm_boot_addr >> CPU_BOOT_ADDR_ALIGN) |
  531. CPU_BOOT_ADDR_WMASK);
  532. nonboot_cpus_off();
  533. INFO("%s: pd status 0x%x\n",
  534. __func__, mmio_read_32(PMU_BASE + PMU_PWRDN_ST));
  535. }