pm33xx.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * AM33XX Power Management Routines
  4. *
  5. * Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/
  6. * Vaibhav Bedia, Dave Gerlach
  7. */
  8. #include <linux/clk.h>
  9. #include <linux/cpu.h>
  10. #include <linux/err.h>
  11. #include <linux/genalloc.h>
  12. #include <linux/kernel.h>
  13. #include <linux/init.h>
  14. #include <linux/io.h>
  15. #include <linux/module.h>
  16. #include <linux/nvmem-consumer.h>
  17. #include <linux/of.h>
  18. #include <linux/platform_data/pm33xx.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/rtc.h>
  21. #include <linux/rtc/rtc-omap.h>
  22. #include <linux/sizes.h>
  23. #include <linux/sram.h>
  24. #include <linux/suspend.h>
  25. #include <linux/ti-emif-sram.h>
  26. #include <linux/wkup_m3_ipc.h>
  27. #include <asm/proc-fns.h>
  28. #include <asm/suspend.h>
  29. #include <asm/system_misc.h>
  30. #define AMX3_PM_SRAM_SYMBOL_OFFSET(sym) ((unsigned long)(sym) - \
  31. (unsigned long)pm_sram->do_wfi)
  32. #define RTC_SCRATCH_RESUME_REG 0
  33. #define RTC_SCRATCH_MAGIC_REG 1
  34. #define RTC_REG_BOOT_MAGIC 0x8cd0 /* RTC */
  35. #define GIC_INT_SET_PENDING_BASE 0x200
  36. #define AM43XX_GIC_DIST_BASE 0x48241000
  37. static u32 rtc_magic_val;
  38. static int (*am33xx_do_wfi_sram)(unsigned long unused);
  39. static phys_addr_t am33xx_do_wfi_sram_phys;
  40. static struct gen_pool *sram_pool, *sram_pool_data;
  41. static unsigned long ocmcram_location, ocmcram_location_data;
  42. static struct rtc_device *omap_rtc;
  43. static void __iomem *gic_dist_base;
  44. static struct am33xx_pm_platform_data *pm_ops;
  45. static struct am33xx_pm_sram_addr *pm_sram;
  46. static struct device *pm33xx_dev;
  47. static struct wkup_m3_ipc *m3_ipc;
  48. #ifdef CONFIG_SUSPEND
  49. static int rtc_only_idle;
  50. static int retrigger_irq;
  51. static unsigned long suspend_wfi_flags;
  52. static struct wkup_m3_wakeup_src wakeup_src = {.irq_nr = 0,
  53. .src = "Unknown",
  54. };
  55. static struct wkup_m3_wakeup_src rtc_alarm_wakeup = {
  56. .irq_nr = 108, .src = "RTC Alarm",
  57. };
  58. static struct wkup_m3_wakeup_src rtc_ext_wakeup = {
  59. .irq_nr = 0, .src = "Ext wakeup",
  60. };
  61. #endif
  62. static u32 sram_suspend_address(unsigned long addr)
  63. {
  64. return ((unsigned long)am33xx_do_wfi_sram +
  65. AMX3_PM_SRAM_SYMBOL_OFFSET(addr));
  66. }
  67. static int am33xx_push_sram_idle(void)
  68. {
  69. struct am33xx_pm_ro_sram_data ro_sram_data;
  70. int ret;
  71. u32 table_addr, ro_data_addr;
  72. void *copy_addr;
  73. ro_sram_data.amx3_pm_sram_data_virt = ocmcram_location_data;
  74. ro_sram_data.amx3_pm_sram_data_phys =
  75. gen_pool_virt_to_phys(sram_pool_data, ocmcram_location_data);
  76. ro_sram_data.rtc_base_virt = pm_ops->get_rtc_base_addr();
  77. /* Save physical address to calculate resume offset during pm init */
  78. am33xx_do_wfi_sram_phys = gen_pool_virt_to_phys(sram_pool,
  79. ocmcram_location);
  80. am33xx_do_wfi_sram = sram_exec_copy(sram_pool, (void *)ocmcram_location,
  81. pm_sram->do_wfi,
  82. *pm_sram->do_wfi_sz);
  83. if (!am33xx_do_wfi_sram) {
  84. dev_err(pm33xx_dev,
  85. "PM: %s: am33xx_do_wfi copy to sram failed\n",
  86. __func__);
  87. return -ENODEV;
  88. }
  89. table_addr =
  90. sram_suspend_address((unsigned long)pm_sram->emif_sram_table);
  91. ret = ti_emif_copy_pm_function_table(sram_pool, (void *)table_addr);
  92. if (ret) {
  93. dev_dbg(pm33xx_dev,
  94. "PM: %s: EMIF function copy failed\n", __func__);
  95. return -EPROBE_DEFER;
  96. }
  97. ro_data_addr =
  98. sram_suspend_address((unsigned long)pm_sram->ro_sram_data);
  99. copy_addr = sram_exec_copy(sram_pool, (void *)ro_data_addr,
  100. &ro_sram_data,
  101. sizeof(ro_sram_data));
  102. if (!copy_addr) {
  103. dev_err(pm33xx_dev,
  104. "PM: %s: ro_sram_data copy to sram failed\n",
  105. __func__);
  106. return -ENODEV;
  107. }
  108. return 0;
  109. }
  110. static int __init am43xx_map_gic(void)
  111. {
  112. gic_dist_base = ioremap(AM43XX_GIC_DIST_BASE, SZ_4K);
  113. if (!gic_dist_base)
  114. return -ENOMEM;
  115. return 0;
  116. }
  117. #ifdef CONFIG_SUSPEND
  118. static struct wkup_m3_wakeup_src rtc_wake_src(void)
  119. {
  120. u32 i;
  121. i = __raw_readl(pm_ops->get_rtc_base_addr() + 0x44) & 0x40;
  122. if (i) {
  123. retrigger_irq = rtc_alarm_wakeup.irq_nr;
  124. return rtc_alarm_wakeup;
  125. }
  126. retrigger_irq = rtc_ext_wakeup.irq_nr;
  127. return rtc_ext_wakeup;
  128. }
  129. static int am33xx_rtc_only_idle(unsigned long wfi_flags)
  130. {
  131. omap_rtc_power_off_program(&omap_rtc->dev);
  132. am33xx_do_wfi_sram(wfi_flags);
  133. return 0;
  134. }
  135. static int am33xx_pm_suspend(suspend_state_t suspend_state)
  136. {
  137. int i, ret = 0;
  138. if (suspend_state == PM_SUSPEND_MEM &&
  139. pm_ops->check_off_mode_enable()) {
  140. pm_ops->prepare_rtc_suspend();
  141. pm_ops->save_context();
  142. suspend_wfi_flags |= WFI_FLAG_RTC_ONLY;
  143. clk_save_context();
  144. ret = pm_ops->soc_suspend(suspend_state, am33xx_rtc_only_idle,
  145. suspend_wfi_flags);
  146. suspend_wfi_flags &= ~WFI_FLAG_RTC_ONLY;
  147. dev_info(pm33xx_dev, "Entering RTC Only mode with DDR in self-refresh\n");
  148. if (!ret) {
  149. clk_restore_context();
  150. pm_ops->restore_context();
  151. m3_ipc->ops->set_rtc_only(m3_ipc);
  152. am33xx_push_sram_idle();
  153. }
  154. } else {
  155. ret = pm_ops->soc_suspend(suspend_state, am33xx_do_wfi_sram,
  156. suspend_wfi_flags);
  157. }
  158. if (ret) {
  159. dev_err(pm33xx_dev, "PM: Kernel suspend failure\n");
  160. } else {
  161. i = m3_ipc->ops->request_pm_status(m3_ipc);
  162. switch (i) {
  163. case 0:
  164. dev_info(pm33xx_dev,
  165. "PM: Successfully put all powerdomains to target state\n");
  166. break;
  167. case 1:
  168. dev_err(pm33xx_dev,
  169. "PM: Could not transition all powerdomains to target state\n");
  170. ret = -1;
  171. break;
  172. default:
  173. dev_err(pm33xx_dev,
  174. "PM: CM3 returned unknown result = %d\n", i);
  175. ret = -1;
  176. }
  177. /* print the wakeup reason */
  178. if (rtc_only_idle) {
  179. wakeup_src = rtc_wake_src();
  180. pr_info("PM: Wakeup source %s\n", wakeup_src.src);
  181. } else {
  182. pr_info("PM: Wakeup source %s\n",
  183. m3_ipc->ops->request_wake_src(m3_ipc));
  184. }
  185. }
  186. if (suspend_state == PM_SUSPEND_MEM && pm_ops->check_off_mode_enable())
  187. pm_ops->prepare_rtc_resume();
  188. return ret;
  189. }
  190. static int am33xx_pm_enter(suspend_state_t suspend_state)
  191. {
  192. int ret = 0;
  193. switch (suspend_state) {
  194. case PM_SUSPEND_MEM:
  195. case PM_SUSPEND_STANDBY:
  196. ret = am33xx_pm_suspend(suspend_state);
  197. break;
  198. default:
  199. ret = -EINVAL;
  200. }
  201. return ret;
  202. }
  203. static int am33xx_pm_begin(suspend_state_t state)
  204. {
  205. int ret = -EINVAL;
  206. struct nvmem_device *nvmem;
  207. if (state == PM_SUSPEND_MEM && pm_ops->check_off_mode_enable()) {
  208. nvmem = devm_nvmem_device_get(&omap_rtc->dev,
  209. "omap_rtc_scratch0");
  210. if (!IS_ERR(nvmem))
  211. nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4, 4,
  212. (void *)&rtc_magic_val);
  213. rtc_only_idle = 1;
  214. } else {
  215. rtc_only_idle = 0;
  216. }
  217. switch (state) {
  218. case PM_SUSPEND_MEM:
  219. ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_DEEPSLEEP);
  220. break;
  221. case PM_SUSPEND_STANDBY:
  222. ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_STANDBY);
  223. break;
  224. }
  225. return ret;
  226. }
  227. static void am33xx_pm_end(void)
  228. {
  229. u32 val = 0;
  230. struct nvmem_device *nvmem;
  231. nvmem = devm_nvmem_device_get(&omap_rtc->dev, "omap_rtc_scratch0");
  232. if (IS_ERR(nvmem))
  233. return;
  234. m3_ipc->ops->finish_low_power(m3_ipc);
  235. if (rtc_only_idle) {
  236. if (retrigger_irq) {
  237. /*
  238. * 32 bits of Interrupt Set-Pending correspond to 32
  239. * 32 interrupts. Compute the bit offset of the
  240. * Interrupt and set that particular bit
  241. * Compute the register offset by dividing interrupt
  242. * number by 32 and mutiplying by 4
  243. */
  244. writel_relaxed(1 << (retrigger_irq & 31),
  245. gic_dist_base + GIC_INT_SET_PENDING_BASE
  246. + retrigger_irq / 32 * 4);
  247. }
  248. nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4, 4,
  249. (void *)&val);
  250. }
  251. rtc_only_idle = 0;
  252. }
  253. static int am33xx_pm_valid(suspend_state_t state)
  254. {
  255. switch (state) {
  256. case PM_SUSPEND_STANDBY:
  257. case PM_SUSPEND_MEM:
  258. return 1;
  259. default:
  260. return 0;
  261. }
  262. }
  263. static const struct platform_suspend_ops am33xx_pm_ops = {
  264. .begin = am33xx_pm_begin,
  265. .end = am33xx_pm_end,
  266. .enter = am33xx_pm_enter,
  267. .valid = am33xx_pm_valid,
  268. };
  269. #endif /* CONFIG_SUSPEND */
  270. static void am33xx_pm_set_ipc_ops(void)
  271. {
  272. u32 resume_address;
  273. int temp;
  274. temp = ti_emif_get_mem_type();
  275. if (temp < 0) {
  276. dev_err(pm33xx_dev, "PM: Cannot determine memory type, no PM available\n");
  277. return;
  278. }
  279. m3_ipc->ops->set_mem_type(m3_ipc, temp);
  280. /* Physical resume address to be used by ROM code */
  281. resume_address = am33xx_do_wfi_sram_phys +
  282. *pm_sram->resume_offset + 0x4;
  283. m3_ipc->ops->set_resume_address(m3_ipc, (void *)resume_address);
  284. }
  285. static void am33xx_pm_free_sram(void)
  286. {
  287. gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz);
  288. gen_pool_free(sram_pool_data, ocmcram_location_data,
  289. sizeof(struct am33xx_pm_ro_sram_data));
  290. }
  291. /*
  292. * Push the minimal suspend-resume code to SRAM
  293. */
  294. static int am33xx_pm_alloc_sram(void)
  295. {
  296. struct device_node *np;
  297. int ret = 0;
  298. np = of_find_compatible_node(NULL, NULL, "ti,omap3-mpu");
  299. if (!np) {
  300. np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu");
  301. if (!np) {
  302. dev_err(pm33xx_dev, "PM: %s: Unable to find device node for mpu\n",
  303. __func__);
  304. return -ENODEV;
  305. }
  306. }
  307. sram_pool = of_gen_pool_get(np, "pm-sram", 0);
  308. if (!sram_pool) {
  309. dev_err(pm33xx_dev, "PM: %s: Unable to get sram pool for ocmcram\n",
  310. __func__);
  311. ret = -ENODEV;
  312. goto mpu_put_node;
  313. }
  314. sram_pool_data = of_gen_pool_get(np, "pm-sram", 1);
  315. if (!sram_pool_data) {
  316. dev_err(pm33xx_dev, "PM: %s: Unable to get sram data pool for ocmcram\n",
  317. __func__);
  318. ret = -ENODEV;
  319. goto mpu_put_node;
  320. }
  321. ocmcram_location = gen_pool_alloc(sram_pool, *pm_sram->do_wfi_sz);
  322. if (!ocmcram_location) {
  323. dev_err(pm33xx_dev, "PM: %s: Unable to allocate memory from ocmcram\n",
  324. __func__);
  325. ret = -ENOMEM;
  326. goto mpu_put_node;
  327. }
  328. ocmcram_location_data = gen_pool_alloc(sram_pool_data,
  329. sizeof(struct emif_regs_amx3));
  330. if (!ocmcram_location_data) {
  331. dev_err(pm33xx_dev, "PM: Unable to allocate memory from ocmcram\n");
  332. gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz);
  333. ret = -ENOMEM;
  334. }
  335. mpu_put_node:
  336. of_node_put(np);
  337. return ret;
  338. }
  339. static int am33xx_pm_rtc_setup(void)
  340. {
  341. struct device_node *np;
  342. unsigned long val = 0;
  343. struct nvmem_device *nvmem;
  344. np = of_find_node_by_name(NULL, "rtc");
  345. if (of_device_is_available(np)) {
  346. omap_rtc = rtc_class_open("rtc0");
  347. if (!omap_rtc) {
  348. pr_warn("PM: rtc0 not available");
  349. return -EPROBE_DEFER;
  350. }
  351. nvmem = devm_nvmem_device_get(&omap_rtc->dev,
  352. "omap_rtc_scratch0");
  353. if (!IS_ERR(nvmem)) {
  354. nvmem_device_read(nvmem, RTC_SCRATCH_MAGIC_REG * 4,
  355. 4, (void *)&rtc_magic_val);
  356. if ((rtc_magic_val & 0xffff) != RTC_REG_BOOT_MAGIC)
  357. pr_warn("PM: bootloader does not support rtc-only!\n");
  358. nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4,
  359. 4, (void *)&val);
  360. val = pm_sram->resume_address;
  361. nvmem_device_write(nvmem, RTC_SCRATCH_RESUME_REG * 4,
  362. 4, (void *)&val);
  363. }
  364. } else {
  365. pr_warn("PM: no-rtc available, rtc-only mode disabled.\n");
  366. }
  367. return 0;
  368. }
  369. static int am33xx_pm_probe(struct platform_device *pdev)
  370. {
  371. struct device *dev = &pdev->dev;
  372. int ret;
  373. if (!of_machine_is_compatible("ti,am33xx") &&
  374. !of_machine_is_compatible("ti,am43"))
  375. return -ENODEV;
  376. pm_ops = dev->platform_data;
  377. if (!pm_ops) {
  378. dev_err(dev, "PM: Cannot get core PM ops!\n");
  379. return -ENODEV;
  380. }
  381. ret = am43xx_map_gic();
  382. if (ret) {
  383. pr_err("PM: Could not ioremap GIC base\n");
  384. return ret;
  385. }
  386. pm_sram = pm_ops->get_sram_addrs();
  387. if (!pm_sram) {
  388. dev_err(dev, "PM: Cannot get PM asm function addresses!!\n");
  389. return -ENODEV;
  390. }
  391. m3_ipc = wkup_m3_ipc_get();
  392. if (!m3_ipc) {
  393. pr_err("PM: Cannot get wkup_m3_ipc handle\n");
  394. return -EPROBE_DEFER;
  395. }
  396. pm33xx_dev = dev;
  397. ret = am33xx_pm_alloc_sram();
  398. if (ret)
  399. return ret;
  400. ret = am33xx_pm_rtc_setup();
  401. if (ret)
  402. goto err_free_sram;
  403. ret = am33xx_push_sram_idle();
  404. if (ret)
  405. goto err_free_sram;
  406. am33xx_pm_set_ipc_ops();
  407. #ifdef CONFIG_SUSPEND
  408. suspend_set_ops(&am33xx_pm_ops);
  409. /*
  410. * For a system suspend we must flush the caches, we want
  411. * the DDR in self-refresh, we want to save the context
  412. * of the EMIF, and we want the wkup_m3 to handle low-power
  413. * transition.
  414. */
  415. suspend_wfi_flags |= WFI_FLAG_FLUSH_CACHE;
  416. suspend_wfi_flags |= WFI_FLAG_SELF_REFRESH;
  417. suspend_wfi_flags |= WFI_FLAG_SAVE_EMIF;
  418. suspend_wfi_flags |= WFI_FLAG_WAKE_M3;
  419. #endif /* CONFIG_SUSPEND */
  420. ret = pm_ops->init();
  421. if (ret) {
  422. dev_err(dev, "Unable to call core pm init!\n");
  423. ret = -ENODEV;
  424. goto err_put_wkup_m3_ipc;
  425. }
  426. return 0;
  427. err_put_wkup_m3_ipc:
  428. wkup_m3_ipc_put(m3_ipc);
  429. err_free_sram:
  430. am33xx_pm_free_sram();
  431. pm33xx_dev = NULL;
  432. return ret;
  433. }
  434. static int am33xx_pm_remove(struct platform_device *pdev)
  435. {
  436. suspend_set_ops(NULL);
  437. wkup_m3_ipc_put(m3_ipc);
  438. am33xx_pm_free_sram();
  439. return 0;
  440. }
  441. static struct platform_driver am33xx_pm_driver = {
  442. .driver = {
  443. .name = "pm33xx",
  444. },
  445. .probe = am33xx_pm_probe,
  446. .remove = am33xx_pm_remove,
  447. };
  448. module_platform_driver(am33xx_pm_driver);
  449. MODULE_ALIAS("platform:pm33xx");
  450. MODULE_LICENSE("GPL v2");
  451. MODULE_DESCRIPTION("am33xx power management driver");