plat_pm.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. /*
  2. * Copyright (c) 2013-2020, 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 <arch_helpers.h>
  9. #include <common/debug.h>
  10. #include <drivers/arm/cci.h>
  11. #include <drivers/arm/gicv2.h>
  12. #include <drivers/ti/uart/uart_16550.h>
  13. #include <lib/bakery_lock.h>
  14. #include <lib/mmio.h>
  15. #include <lib/psci/psci.h>
  16. #include <plat/arm/common/plat_arm.h>
  17. #include <mcucfg.h>
  18. #include <mt8173_def.h>
  19. #include <mt_cpuxgpt.h> /* generic_timer_backup() */
  20. #include <plat_private.h>
  21. #include <power_tracer.h>
  22. #include <rtc.h>
  23. #include <scu.h>
  24. #include <spm_hotplug.h>
  25. #include <spm_mcdi.h>
  26. #include <spm_suspend.h>
  27. #include <wdt.h>
  28. #define MTK_PWR_LVL0 0
  29. #define MTK_PWR_LVL1 1
  30. #define MTK_PWR_LVL2 2
  31. /* Macros to read the MTK power domain state */
  32. #define MTK_CORE_PWR_STATE(state) (state)->pwr_domain_state[MTK_PWR_LVL0]
  33. #define MTK_CLUSTER_PWR_STATE(state) (state)->pwr_domain_state[MTK_PWR_LVL1]
  34. #define MTK_SYSTEM_PWR_STATE(state) ((PLAT_MAX_PWR_LVL > MTK_PWR_LVL1) ?\
  35. (state)->pwr_domain_state[MTK_PWR_LVL2] : 0)
  36. #if PSCI_EXTENDED_STATE_ID
  37. /*
  38. * The table storing the valid idle power states. Ensure that the
  39. * array entries are populated in ascending order of state-id to
  40. * enable us to use binary search during power state validation.
  41. * The table must be terminated by a NULL entry.
  42. */
  43. const unsigned int mtk_pm_idle_states[] = {
  44. /* State-id - 0x001 */
  45. mtk_make_pwrstate_lvl2(MTK_LOCAL_STATE_RUN, MTK_LOCAL_STATE_RUN,
  46. MTK_LOCAL_STATE_RET, MTK_PWR_LVL0, PSTATE_TYPE_STANDBY),
  47. /* State-id - 0x002 */
  48. mtk_make_pwrstate_lvl2(MTK_LOCAL_STATE_RUN, MTK_LOCAL_STATE_RUN,
  49. MTK_LOCAL_STATE_OFF, MTK_PWR_LVL0, PSTATE_TYPE_POWERDOWN),
  50. /* State-id - 0x022 */
  51. mtk_make_pwrstate_lvl2(MTK_LOCAL_STATE_RUN, MTK_LOCAL_STATE_OFF,
  52. MTK_LOCAL_STATE_OFF, MTK_PWR_LVL1, PSTATE_TYPE_POWERDOWN),
  53. #if PLAT_MAX_PWR_LVL > MTK_PWR_LVL1
  54. /* State-id - 0x222 */
  55. mtk_make_pwrstate_lvl2(MTK_LOCAL_STATE_OFF, MTK_LOCAL_STATE_OFF,
  56. MTK_LOCAL_STATE_OFF, MTK_PWR_LVL2, PSTATE_TYPE_POWERDOWN),
  57. #endif
  58. 0,
  59. };
  60. #endif
  61. struct core_context {
  62. unsigned long timer_data[8];
  63. unsigned int count;
  64. unsigned int rst;
  65. unsigned int abt;
  66. unsigned int brk;
  67. };
  68. struct cluster_context {
  69. struct core_context core[PLATFORM_MAX_CPUS_PER_CLUSTER];
  70. };
  71. /*
  72. * Top level structure to hold the complete context of a multi cluster system
  73. */
  74. struct system_context {
  75. struct cluster_context cluster[PLATFORM_CLUSTER_COUNT];
  76. };
  77. /*
  78. * Top level structure which encapsulates the context of the entire system
  79. */
  80. static struct system_context dormant_data[1];
  81. static inline struct cluster_context *system_cluster(
  82. struct system_context *system,
  83. uint32_t clusterid)
  84. {
  85. return &system->cluster[clusterid];
  86. }
  87. static inline struct core_context *cluster_core(struct cluster_context *cluster,
  88. uint32_t cpuid)
  89. {
  90. return &cluster->core[cpuid];
  91. }
  92. static struct cluster_context *get_cluster_data(unsigned long mpidr)
  93. {
  94. uint32_t clusterid;
  95. clusterid = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
  96. return system_cluster(dormant_data, clusterid);
  97. }
  98. static struct core_context *get_core_data(unsigned long mpidr)
  99. {
  100. struct cluster_context *cluster;
  101. uint32_t cpuid;
  102. cluster = get_cluster_data(mpidr);
  103. cpuid = mpidr & MPIDR_CPU_MASK;
  104. return cluster_core(cluster, cpuid);
  105. }
  106. static void mt_save_generic_timer(unsigned long *container)
  107. {
  108. uint64_t ctl;
  109. uint64_t val;
  110. __asm__ volatile("mrs %x0, cntkctl_el1\n\t"
  111. "mrs %x1, cntp_cval_el0\n\t"
  112. "stp %x0, %x1, [%2, #0]"
  113. : "=&r" (ctl), "=&r" (val)
  114. : "r" (container)
  115. : "memory");
  116. __asm__ volatile("mrs %x0, cntp_tval_el0\n\t"
  117. "mrs %x1, cntp_ctl_el0\n\t"
  118. "stp %x0, %x1, [%2, #16]"
  119. : "=&r" (val), "=&r" (ctl)
  120. : "r" (container)
  121. : "memory");
  122. __asm__ volatile("mrs %x0, cntv_tval_el0\n\t"
  123. "mrs %x1, cntv_ctl_el0\n\t"
  124. "stp %x0, %x1, [%2, #32]"
  125. : "=&r" (val), "=&r" (ctl)
  126. : "r" (container)
  127. : "memory");
  128. }
  129. static void mt_restore_generic_timer(unsigned long *container)
  130. {
  131. uint64_t ctl;
  132. uint64_t val;
  133. __asm__ volatile("ldp %x0, %x1, [%2, #0]\n\t"
  134. "msr cntkctl_el1, %x0\n\t"
  135. "msr cntp_cval_el0, %x1"
  136. : "=&r" (ctl), "=&r" (val)
  137. : "r" (container)
  138. : "memory");
  139. __asm__ volatile("ldp %x0, %x1, [%2, #16]\n\t"
  140. "msr cntp_tval_el0, %x0\n\t"
  141. "msr cntp_ctl_el0, %x1"
  142. : "=&r" (val), "=&r" (ctl)
  143. : "r" (container)
  144. : "memory");
  145. __asm__ volatile("ldp %x0, %x1, [%2, #32]\n\t"
  146. "msr cntv_tval_el0, %x0\n\t"
  147. "msr cntv_ctl_el0, %x1"
  148. : "=&r" (val), "=&r" (ctl)
  149. : "r" (container)
  150. : "memory");
  151. }
  152. static inline uint64_t read_cntpctl(void)
  153. {
  154. uint64_t cntpctl;
  155. __asm__ volatile("mrs %x0, cntp_ctl_el0"
  156. : "=r" (cntpctl) : : "memory");
  157. return cntpctl;
  158. }
  159. static inline void write_cntpctl(uint64_t cntpctl)
  160. {
  161. __asm__ volatile("msr cntp_ctl_el0, %x0" : : "r"(cntpctl));
  162. }
  163. static void stop_generic_timer(void)
  164. {
  165. /*
  166. * Disable the timer and mask the irq to prevent
  167. * suprious interrupts on this cpu interface. It
  168. * will bite us when we come back if we don't. It
  169. * will be replayed on the inbound cluster.
  170. */
  171. uint64_t cntpctl = read_cntpctl();
  172. write_cntpctl(clr_cntp_ctl_enable(cntpctl));
  173. }
  174. static void mt_cpu_save(unsigned long mpidr)
  175. {
  176. struct core_context *core;
  177. core = get_core_data(mpidr);
  178. mt_save_generic_timer(core->timer_data);
  179. /* disable timer irq, and upper layer should enable it again. */
  180. stop_generic_timer();
  181. }
  182. static void mt_cpu_restore(unsigned long mpidr)
  183. {
  184. struct core_context *core;
  185. core = get_core_data(mpidr);
  186. mt_restore_generic_timer(core->timer_data);
  187. }
  188. static void mt_platform_save_context(unsigned long mpidr)
  189. {
  190. /* mcusys_save_context: */
  191. mt_cpu_save(mpidr);
  192. }
  193. static void mt_platform_restore_context(unsigned long mpidr)
  194. {
  195. /* mcusys_restore_context: */
  196. mt_cpu_restore(mpidr);
  197. }
  198. static void plat_cpu_standby(plat_local_state_t cpu_state)
  199. {
  200. u_register_t scr;
  201. scr = read_scr_el3();
  202. write_scr_el3(scr | SCR_IRQ_BIT);
  203. isb();
  204. dsb();
  205. wfi();
  206. write_scr_el3(scr);
  207. }
  208. /*******************************************************************************
  209. * MTK_platform handler called when an affinity instance is about to be turned
  210. * on. The level and mpidr determine the affinity instance.
  211. ******************************************************************************/
  212. static uintptr_t secure_entrypoint;
  213. static int plat_power_domain_on(unsigned long mpidr)
  214. {
  215. int rc = PSCI_E_SUCCESS;
  216. unsigned long cpu_id;
  217. unsigned long cluster_id;
  218. uintptr_t rv;
  219. cpu_id = mpidr & MPIDR_CPU_MASK;
  220. cluster_id = mpidr & MPIDR_CLUSTER_MASK;
  221. if (cluster_id)
  222. rv = (uintptr_t)&mt8173_mcucfg->mp1_rv_addr[cpu_id].rv_addr_lw;
  223. else
  224. rv = (uintptr_t)&mt8173_mcucfg->mp0_rv_addr[cpu_id].rv_addr_lw;
  225. mmio_write_32(rv, secure_entrypoint);
  226. INFO("mt_on[%ld:%ld], entry %x\n",
  227. cluster_id, cpu_id, mmio_read_32(rv));
  228. spm_hotplug_on(mpidr);
  229. return rc;
  230. }
  231. /*******************************************************************************
  232. * MTK_platform handler called when an affinity instance is about to be turned
  233. * off. The level and mpidr determine the affinity instance. The 'state' arg.
  234. * allows the platform to decide whether the cluster is being turned off and
  235. * take apt actions.
  236. *
  237. * CAUTION: This function is called with coherent stacks so that caches can be
  238. * turned off, flushed and coherency disabled. There is no guarantee that caches
  239. * will remain turned on across calls to this function as each affinity level is
  240. * dealt with. So do not write & read global variables across calls. It will be
  241. * wise to do flush a write to the global to prevent unpredictable results.
  242. ******************************************************************************/
  243. static void plat_power_domain_off(const psci_power_state_t *state)
  244. {
  245. unsigned long mpidr = read_mpidr_el1();
  246. /* Prevent interrupts from spuriously waking up this cpu */
  247. gicv2_cpuif_disable();
  248. spm_hotplug_off(mpidr);
  249. trace_power_flow(mpidr, CPU_DOWN);
  250. if (MTK_CLUSTER_PWR_STATE(state) == MTK_LOCAL_STATE_OFF) {
  251. /* Disable coherency if this cluster is to be turned off */
  252. plat_cci_disable();
  253. trace_power_flow(mpidr, CLUSTER_DOWN);
  254. }
  255. }
  256. /*******************************************************************************
  257. * MTK_platform handler called when an affinity instance is about to be
  258. * suspended. The level and mpidr determine the affinity instance. The 'state'
  259. * arg. allows the platform to decide whether the cluster is being turned off
  260. * and take apt actions.
  261. *
  262. * CAUTION: This function is called with coherent stacks so that caches can be
  263. * turned off, flushed and coherency disabled. There is no guarantee that caches
  264. * will remain turned on across calls to this function as each affinity level is
  265. * dealt with. So do not write & read global variables across calls. It will be
  266. * wise to do flush a write to the global to prevent unpredictable results.
  267. ******************************************************************************/
  268. static void plat_power_domain_suspend(const psci_power_state_t *state)
  269. {
  270. unsigned long mpidr = read_mpidr_el1();
  271. unsigned long cluster_id;
  272. unsigned long cpu_id;
  273. uintptr_t rv;
  274. cpu_id = mpidr & MPIDR_CPU_MASK;
  275. cluster_id = mpidr & MPIDR_CLUSTER_MASK;
  276. if (cluster_id)
  277. rv = (uintptr_t)&mt8173_mcucfg->mp1_rv_addr[cpu_id].rv_addr_lw;
  278. else
  279. rv = (uintptr_t)&mt8173_mcucfg->mp0_rv_addr[cpu_id].rv_addr_lw;
  280. mmio_write_32(rv, secure_entrypoint);
  281. if (MTK_SYSTEM_PWR_STATE(state) != MTK_LOCAL_STATE_OFF) {
  282. spm_mcdi_prepare_for_off_state(mpidr, MTK_PWR_LVL0);
  283. if (MTK_CLUSTER_PWR_STATE(state) == MTK_LOCAL_STATE_OFF)
  284. spm_mcdi_prepare_for_off_state(mpidr, MTK_PWR_LVL1);
  285. }
  286. mt_platform_save_context(mpidr);
  287. /* Perform the common cluster specific operations */
  288. if (MTK_CLUSTER_PWR_STATE(state) == MTK_LOCAL_STATE_OFF) {
  289. /* Disable coherency if this cluster is to be turned off */
  290. plat_cci_disable();
  291. }
  292. if (MTK_SYSTEM_PWR_STATE(state) == MTK_LOCAL_STATE_OFF) {
  293. wdt_suspend();
  294. disable_scu(mpidr);
  295. generic_timer_backup();
  296. spm_system_suspend();
  297. /* Prevent interrupts from spuriously waking up this cpu */
  298. gicv2_cpuif_disable();
  299. }
  300. }
  301. /*******************************************************************************
  302. * MTK_platform handler called when an affinity instance has just been powered
  303. * on after being turned off earlier. The level and mpidr determine the affinity
  304. * instance. The 'state' arg. allows the platform to decide whether the cluster
  305. * was turned off prior to wakeup and do what's necessary to setup it up
  306. * correctly.
  307. ******************************************************************************/
  308. void mtk_system_pwr_domain_resume(void);
  309. static void plat_power_domain_on_finish(const psci_power_state_t *state)
  310. {
  311. unsigned long mpidr = read_mpidr_el1();
  312. assert(state->pwr_domain_state[MPIDR_AFFLVL0] == MTK_LOCAL_STATE_OFF);
  313. if ((PLAT_MAX_PWR_LVL > MTK_PWR_LVL1) &&
  314. (state->pwr_domain_state[MTK_PWR_LVL2] == MTK_LOCAL_STATE_OFF))
  315. mtk_system_pwr_domain_resume();
  316. if (state->pwr_domain_state[MPIDR_AFFLVL1] == MTK_LOCAL_STATE_OFF) {
  317. plat_cci_enable();
  318. trace_power_flow(mpidr, CLUSTER_UP);
  319. }
  320. if ((PLAT_MAX_PWR_LVL > MTK_PWR_LVL1) &&
  321. (state->pwr_domain_state[MTK_PWR_LVL2] == MTK_LOCAL_STATE_OFF))
  322. return;
  323. /* Enable the gic cpu interface */
  324. gicv2_cpuif_enable();
  325. gicv2_pcpu_distif_init();
  326. trace_power_flow(mpidr, CPU_UP);
  327. }
  328. /*******************************************************************************
  329. * MTK_platform handler called when an affinity instance has just been powered
  330. * on after having been suspended earlier. The level and mpidr determine the
  331. * affinity instance.
  332. ******************************************************************************/
  333. static void plat_power_domain_suspend_finish(const psci_power_state_t *state)
  334. {
  335. unsigned long mpidr = read_mpidr_el1();
  336. if (state->pwr_domain_state[MTK_PWR_LVL0] == MTK_LOCAL_STATE_RET)
  337. return;
  338. if (MTK_SYSTEM_PWR_STATE(state) == MTK_LOCAL_STATE_OFF) {
  339. /* Enable the gic cpu interface */
  340. plat_arm_gic_init();
  341. spm_system_suspend_finish();
  342. enable_scu(mpidr);
  343. wdt_resume();
  344. }
  345. /* Perform the common cluster specific operations */
  346. if (MTK_CLUSTER_PWR_STATE(state) == MTK_LOCAL_STATE_OFF) {
  347. /* Enable coherency if this cluster was off */
  348. plat_cci_enable();
  349. }
  350. mt_platform_restore_context(mpidr);
  351. if (MTK_SYSTEM_PWR_STATE(state) != MTK_LOCAL_STATE_OFF) {
  352. spm_mcdi_finish_for_on_state(mpidr, MTK_PWR_LVL0);
  353. if (MTK_CLUSTER_PWR_STATE(state) == MTK_LOCAL_STATE_OFF)
  354. spm_mcdi_finish_for_on_state(mpidr, MTK_PWR_LVL1);
  355. }
  356. gicv2_pcpu_distif_init();
  357. }
  358. static void plat_get_sys_suspend_power_state(psci_power_state_t *req_state)
  359. {
  360. assert(PLAT_MAX_PWR_LVL >= 2);
  361. for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
  362. req_state->pwr_domain_state[i] = MTK_LOCAL_STATE_OFF;
  363. }
  364. /*******************************************************************************
  365. * MTK handlers to shutdown/reboot the system
  366. ******************************************************************************/
  367. static void __dead2 plat_system_off(void)
  368. {
  369. INFO("MTK System Off\n");
  370. rtc_bbpu_power_down();
  371. wfi();
  372. ERROR("MTK System Off: operation not handled.\n");
  373. panic();
  374. }
  375. static void __dead2 plat_system_reset(void)
  376. {
  377. /* Write the System Configuration Control Register */
  378. INFO("MTK System Reset\n");
  379. wdt_trigger_reset();
  380. wfi();
  381. ERROR("MTK System Reset: operation not handled.\n");
  382. panic();
  383. }
  384. #if !PSCI_EXTENDED_STATE_ID
  385. static int plat_validate_power_state(unsigned int power_state,
  386. psci_power_state_t *req_state)
  387. {
  388. int pstate = psci_get_pstate_type(power_state);
  389. int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
  390. int i;
  391. assert(req_state);
  392. if (pwr_lvl > PLAT_MAX_PWR_LVL)
  393. return PSCI_E_INVALID_PARAMS;
  394. /* Sanity check the requested state */
  395. if (pstate == PSTATE_TYPE_STANDBY) {
  396. /*
  397. * It's possible to enter standby only on power level 0
  398. * Ignore any other power level.
  399. */
  400. if (pwr_lvl != 0)
  401. return PSCI_E_INVALID_PARAMS;
  402. req_state->pwr_domain_state[MTK_PWR_LVL0] =
  403. MTK_LOCAL_STATE_RET;
  404. } else {
  405. for (i = 0; i <= pwr_lvl; i++)
  406. req_state->pwr_domain_state[i] =
  407. MTK_LOCAL_STATE_OFF;
  408. }
  409. /*
  410. * We expect the 'state id' to be zero.
  411. */
  412. if (psci_get_pstate_id(power_state))
  413. return PSCI_E_INVALID_PARAMS;
  414. return PSCI_E_SUCCESS;
  415. }
  416. #else
  417. int plat_validate_power_state(unsigned int power_state,
  418. psci_power_state_t *req_state)
  419. {
  420. unsigned int state_id;
  421. int i;
  422. assert(req_state);
  423. /*
  424. * Currently we are using a linear search for finding the matching
  425. * entry in the idle power state array. This can be made a binary
  426. * search if the number of entries justify the additional complexity.
  427. */
  428. for (i = 0; !!mtk_pm_idle_states[i]; i++) {
  429. if (power_state == mtk_pm_idle_states[i])
  430. break;
  431. }
  432. /* Return error if entry not found in the idle state array */
  433. if (!mtk_pm_idle_states[i])
  434. return PSCI_E_INVALID_PARAMS;
  435. i = 0;
  436. state_id = psci_get_pstate_id(power_state);
  437. /* Parse the State ID and populate the state info parameter */
  438. while (state_id) {
  439. req_state->pwr_domain_state[i++] = state_id &
  440. MTK_LOCAL_PSTATE_MASK;
  441. state_id >>= MTK_LOCAL_PSTATE_WIDTH;
  442. }
  443. return PSCI_E_SUCCESS;
  444. }
  445. #endif
  446. void mtk_system_pwr_domain_resume(void)
  447. {
  448. console_switch_state(CONSOLE_FLAG_BOOT);
  449. /* Assert system power domain is available on the platform */
  450. assert(PLAT_MAX_PWR_LVL >= MTK_PWR_LVL2);
  451. plat_arm_gic_init();
  452. console_switch_state(CONSOLE_FLAG_RUNTIME);
  453. }
  454. static const plat_psci_ops_t plat_plat_pm_ops = {
  455. .cpu_standby = plat_cpu_standby,
  456. .pwr_domain_on = plat_power_domain_on,
  457. .pwr_domain_on_finish = plat_power_domain_on_finish,
  458. .pwr_domain_off = plat_power_domain_off,
  459. .pwr_domain_suspend = plat_power_domain_suspend,
  460. .pwr_domain_suspend_finish = plat_power_domain_suspend_finish,
  461. .system_off = plat_system_off,
  462. .system_reset = plat_system_reset,
  463. .validate_power_state = plat_validate_power_state,
  464. .get_sys_suspend_power_state = plat_get_sys_suspend_power_state,
  465. };
  466. int plat_setup_psci_ops(uintptr_t sec_entrypoint,
  467. const plat_psci_ops_t **psci_ops)
  468. {
  469. *psci_ops = &plat_plat_pm_ops;
  470. secure_entrypoint = sec_entrypoint;
  471. return 0;
  472. }
  473. /*
  474. * The PSCI generic code uses this API to let the platform participate in state
  475. * coordination during a power management operation. It compares the platform
  476. * specific local power states requested by each cpu for a given power domain
  477. * and returns the coordinated target power state that the domain should
  478. * enter. A platform assigns a number to a local power state. This default
  479. * implementation assumes that the platform assigns these numbers in order of
  480. * increasing depth of the power state i.e. for two power states X & Y, if X < Y
  481. * then X represents a shallower power state than Y. As a result, the
  482. * coordinated target local power state for a power domain will be the minimum
  483. * of the requested local power states.
  484. */
  485. plat_local_state_t plat_get_target_pwr_state(unsigned int lvl,
  486. const plat_local_state_t *states,
  487. unsigned int ncpu)
  488. {
  489. plat_local_state_t target = PLAT_MAX_OFF_STATE, temp;
  490. assert(ncpu);
  491. do {
  492. temp = *states++;
  493. if (temp < target)
  494. target = temp;
  495. } while (--ncpu);
  496. return target;
  497. }