forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/soc/ti/pm33xx.c
....@@ -6,6 +6,7 @@
66 * Vaibhav Bedia, Dave Gerlach
77 */
88
9
+#include <linux/clk.h>
910 #include <linux/cpu.h>
1011 #include <linux/err.h>
1112 #include <linux/genalloc.h>
....@@ -13,9 +14,14 @@
1314 #include <linux/init.h>
1415 #include <linux/io.h>
1516 #include <linux/module.h>
17
+#include <linux/nvmem-consumer.h>
1618 #include <linux/of.h>
19
+#include <linux/of_address.h>
1720 #include <linux/platform_data/pm33xx.h>
1821 #include <linux/platform_device.h>
22
+#include <linux/pm_runtime.h>
23
+#include <linux/rtc.h>
24
+#include <linux/rtc/rtc-omap.h>
1925 #include <linux/sizes.h>
2026 #include <linux/sram.h>
2127 #include <linux/suspend.h>
....@@ -29,11 +35,24 @@
2935 #define AMX3_PM_SRAM_SYMBOL_OFFSET(sym) ((unsigned long)(sym) - \
3036 (unsigned long)pm_sram->do_wfi)
3137
38
+#define RTC_SCRATCH_RESUME_REG 0
39
+#define RTC_SCRATCH_MAGIC_REG 1
40
+#define RTC_REG_BOOT_MAGIC 0x8cd0 /* RTC */
41
+#define GIC_INT_SET_PENDING_BASE 0x200
42
+#define AM43XX_GIC_DIST_BASE 0x48241000
43
+
44
+static void __iomem *rtc_base_virt;
45
+static struct clk *rtc_fck;
46
+static u32 rtc_magic_val;
47
+
3248 static int (*am33xx_do_wfi_sram)(unsigned long unused);
3349 static phys_addr_t am33xx_do_wfi_sram_phys;
3450
3551 static struct gen_pool *sram_pool, *sram_pool_data;
3652 static unsigned long ocmcram_location, ocmcram_location_data;
53
+
54
+static struct rtc_device *omap_rtc;
55
+static void __iomem *gic_dist_base;
3756
3857 static struct am33xx_pm_platform_data *pm_ops;
3958 static struct am33xx_pm_sram_addr *pm_sram;
....@@ -41,7 +60,23 @@
4160 static struct device *pm33xx_dev;
4261 static struct wkup_m3_ipc *m3_ipc;
4362
63
+#ifdef CONFIG_SUSPEND
64
+static int rtc_only_idle;
65
+static int retrigger_irq;
4466 static unsigned long suspend_wfi_flags;
67
+
68
+static struct wkup_m3_wakeup_src wakeup_src = {.irq_nr = 0,
69
+ .src = "Unknown",
70
+};
71
+
72
+static struct wkup_m3_wakeup_src rtc_alarm_wakeup = {
73
+ .irq_nr = 108, .src = "RTC Alarm",
74
+};
75
+
76
+static struct wkup_m3_wakeup_src rtc_ext_wakeup = {
77
+ .irq_nr = 0, .src = "Ext wakeup",
78
+};
79
+#endif
4580
4681 static u32 sram_suspend_address(unsigned long addr)
4782 {
....@@ -49,13 +84,140 @@
4984 AMX3_PM_SRAM_SYMBOL_OFFSET(addr));
5085 }
5186
87
+static int am33xx_push_sram_idle(void)
88
+{
89
+ struct am33xx_pm_ro_sram_data ro_sram_data;
90
+ int ret;
91
+ u32 table_addr, ro_data_addr;
92
+ void *copy_addr;
93
+
94
+ ro_sram_data.amx3_pm_sram_data_virt = ocmcram_location_data;
95
+ ro_sram_data.amx3_pm_sram_data_phys =
96
+ gen_pool_virt_to_phys(sram_pool_data, ocmcram_location_data);
97
+ ro_sram_data.rtc_base_virt = rtc_base_virt;
98
+
99
+ /* Save physical address to calculate resume offset during pm init */
100
+ am33xx_do_wfi_sram_phys = gen_pool_virt_to_phys(sram_pool,
101
+ ocmcram_location);
102
+
103
+ am33xx_do_wfi_sram = sram_exec_copy(sram_pool, (void *)ocmcram_location,
104
+ pm_sram->do_wfi,
105
+ *pm_sram->do_wfi_sz);
106
+ if (!am33xx_do_wfi_sram) {
107
+ dev_err(pm33xx_dev,
108
+ "PM: %s: am33xx_do_wfi copy to sram failed\n",
109
+ __func__);
110
+ return -ENODEV;
111
+ }
112
+
113
+ table_addr =
114
+ sram_suspend_address((unsigned long)pm_sram->emif_sram_table);
115
+ ret = ti_emif_copy_pm_function_table(sram_pool, (void *)table_addr);
116
+ if (ret) {
117
+ dev_dbg(pm33xx_dev,
118
+ "PM: %s: EMIF function copy failed\n", __func__);
119
+ return -EPROBE_DEFER;
120
+ }
121
+
122
+ ro_data_addr =
123
+ sram_suspend_address((unsigned long)pm_sram->ro_sram_data);
124
+ copy_addr = sram_exec_copy(sram_pool, (void *)ro_data_addr,
125
+ &ro_sram_data,
126
+ sizeof(ro_sram_data));
127
+ if (!copy_addr) {
128
+ dev_err(pm33xx_dev,
129
+ "PM: %s: ro_sram_data copy to sram failed\n",
130
+ __func__);
131
+ return -ENODEV;
132
+ }
133
+
134
+ return 0;
135
+}
136
+
137
+static int am33xx_do_sram_idle(u32 wfi_flags)
138
+{
139
+ int ret = 0;
140
+
141
+ if (!m3_ipc || !pm_ops)
142
+ return 0;
143
+
144
+ if (wfi_flags & WFI_FLAG_WAKE_M3)
145
+ ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_IDLE);
146
+
147
+ return pm_ops->cpu_suspend(am33xx_do_wfi_sram, wfi_flags);
148
+}
149
+
150
+static int __init am43xx_map_gic(void)
151
+{
152
+ gic_dist_base = ioremap(AM43XX_GIC_DIST_BASE, SZ_4K);
153
+
154
+ if (!gic_dist_base)
155
+ return -ENOMEM;
156
+
157
+ return 0;
158
+}
159
+
52160 #ifdef CONFIG_SUSPEND
161
+static struct wkup_m3_wakeup_src rtc_wake_src(void)
162
+{
163
+ u32 i;
164
+
165
+ i = __raw_readl(rtc_base_virt + 0x44) & 0x40;
166
+
167
+ if (i) {
168
+ retrigger_irq = rtc_alarm_wakeup.irq_nr;
169
+ return rtc_alarm_wakeup;
170
+ }
171
+
172
+ retrigger_irq = rtc_ext_wakeup.irq_nr;
173
+
174
+ return rtc_ext_wakeup;
175
+}
176
+
177
+static int am33xx_rtc_only_idle(unsigned long wfi_flags)
178
+{
179
+ omap_rtc_power_off_program(&omap_rtc->dev);
180
+ am33xx_do_wfi_sram(wfi_flags);
181
+ return 0;
182
+}
183
+
184
+/*
185
+ * Note that the RTC module clock must be re-enabled only for rtc+ddr suspend.
186
+ * And looks like the module can stay in SYSC_IDLE_SMART_WKUP mode configured
187
+ * by the interconnect code just fine for both rtc+ddr suspend and retention
188
+ * suspend.
189
+ */
53190 static int am33xx_pm_suspend(suspend_state_t suspend_state)
54191 {
55192 int i, ret = 0;
56193
57
- ret = pm_ops->soc_suspend((unsigned long)suspend_state,
58
- am33xx_do_wfi_sram, suspend_wfi_flags);
194
+ if (suspend_state == PM_SUSPEND_MEM &&
195
+ pm_ops->check_off_mode_enable()) {
196
+ ret = clk_prepare_enable(rtc_fck);
197
+ if (ret) {
198
+ dev_err(pm33xx_dev, "Failed to enable clock: %i\n", ret);
199
+ return ret;
200
+ }
201
+
202
+ pm_ops->save_context();
203
+ suspend_wfi_flags |= WFI_FLAG_RTC_ONLY;
204
+ clk_save_context();
205
+ ret = pm_ops->soc_suspend(suspend_state, am33xx_rtc_only_idle,
206
+ suspend_wfi_flags);
207
+
208
+ suspend_wfi_flags &= ~WFI_FLAG_RTC_ONLY;
209
+ dev_info(pm33xx_dev, "Entering RTC Only mode with DDR in self-refresh\n");
210
+
211
+ if (!ret) {
212
+ clk_restore_context();
213
+ pm_ops->restore_context();
214
+ m3_ipc->ops->set_rtc_only(m3_ipc);
215
+ am33xx_push_sram_idle();
216
+ }
217
+ } else {
218
+ ret = pm_ops->soc_suspend(suspend_state, am33xx_do_wfi_sram,
219
+ suspend_wfi_flags);
220
+ }
59221
60222 if (ret) {
61223 dev_err(pm33xx_dev, "PM: Kernel suspend failure\n");
....@@ -77,7 +239,19 @@
77239 "PM: CM3 returned unknown result = %d\n", i);
78240 ret = -1;
79241 }
242
+
243
+ /* print the wakeup reason */
244
+ if (rtc_only_idle) {
245
+ wakeup_src = rtc_wake_src();
246
+ pr_info("PM: Wakeup source %s\n", wakeup_src.src);
247
+ } else {
248
+ pr_info("PM: Wakeup source %s\n",
249
+ m3_ipc->ops->request_wake_src(m3_ipc));
250
+ }
80251 }
252
+
253
+ if (suspend_state == PM_SUSPEND_MEM && pm_ops->check_off_mode_enable())
254
+ clk_disable_unprepare(rtc_fck);
81255
82256 return ret;
83257 }
....@@ -101,6 +275,20 @@
101275 static int am33xx_pm_begin(suspend_state_t state)
102276 {
103277 int ret = -EINVAL;
278
+ struct nvmem_device *nvmem;
279
+
280
+ if (state == PM_SUSPEND_MEM && pm_ops->check_off_mode_enable()) {
281
+ nvmem = devm_nvmem_device_get(&omap_rtc->dev,
282
+ "omap_rtc_scratch0");
283
+ if (!IS_ERR(nvmem))
284
+ nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4, 4,
285
+ (void *)&rtc_magic_val);
286
+ rtc_only_idle = 1;
287
+ } else {
288
+ rtc_only_idle = 0;
289
+ }
290
+
291
+ pm_ops->begin_suspend();
104292
105293 switch (state) {
106294 case PM_SUSPEND_MEM:
....@@ -116,7 +304,35 @@
116304
117305 static void am33xx_pm_end(void)
118306 {
307
+ u32 val = 0;
308
+ struct nvmem_device *nvmem;
309
+
310
+ nvmem = devm_nvmem_device_get(&omap_rtc->dev, "omap_rtc_scratch0");
311
+ if (IS_ERR(nvmem))
312
+ return;
313
+
119314 m3_ipc->ops->finish_low_power(m3_ipc);
315
+ if (rtc_only_idle) {
316
+ if (retrigger_irq) {
317
+ /*
318
+ * 32 bits of Interrupt Set-Pending correspond to 32
319
+ * 32 interrupts. Compute the bit offset of the
320
+ * Interrupt and set that particular bit
321
+ * Compute the register offset by dividing interrupt
322
+ * number by 32 and mutiplying by 4
323
+ */
324
+ writel_relaxed(1 << (retrigger_irq & 31),
325
+ gic_dist_base + GIC_INT_SET_PENDING_BASE
326
+ + retrigger_irq / 32 * 4);
327
+ }
328
+
329
+ nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4, 4,
330
+ (void *)&val);
331
+ }
332
+
333
+ rtc_only_idle = 0;
334
+
335
+ pm_ops->finish_suspend();
120336 }
121337
122338 static int am33xx_pm_valid(suspend_state_t state)
....@@ -219,54 +435,61 @@
219435 return ret;
220436 }
221437
222
-static int am33xx_push_sram_idle(void)
438
+static int am33xx_pm_rtc_setup(void)
223439 {
224
- struct am33xx_pm_ro_sram_data ro_sram_data;
225
- int ret;
226
- u32 table_addr, ro_data_addr;
227
- void *copy_addr;
440
+ struct device_node *np;
441
+ unsigned long val = 0;
442
+ struct nvmem_device *nvmem;
443
+ int error;
228444
229
- ro_sram_data.amx3_pm_sram_data_virt = ocmcram_location_data;
230
- ro_sram_data.amx3_pm_sram_data_phys =
231
- gen_pool_virt_to_phys(sram_pool_data, ocmcram_location_data);
232
- ro_sram_data.rtc_base_virt = pm_ops->get_rtc_base_addr();
445
+ np = of_find_node_by_name(NULL, "rtc");
233446
234
- /* Save physical address to calculate resume offset during pm init */
235
- am33xx_do_wfi_sram_phys = gen_pool_virt_to_phys(sram_pool,
236
- ocmcram_location);
447
+ if (of_device_is_available(np)) {
448
+ /* RTC interconnect target module clock */
449
+ rtc_fck = of_clk_get_by_name(np->parent, "fck");
450
+ if (IS_ERR(rtc_fck))
451
+ return PTR_ERR(rtc_fck);
237452
238
- am33xx_do_wfi_sram = sram_exec_copy(sram_pool, (void *)ocmcram_location,
239
- pm_sram->do_wfi,
240
- *pm_sram->do_wfi_sz);
241
- if (!am33xx_do_wfi_sram) {
242
- dev_err(pm33xx_dev,
243
- "PM: %s: am33xx_do_wfi copy to sram failed\n",
244
- __func__);
245
- return -ENODEV;
246
- }
453
+ rtc_base_virt = of_iomap(np, 0);
454
+ if (!rtc_base_virt) {
455
+ pr_warn("PM: could not iomap rtc");
456
+ error = -ENODEV;
457
+ goto err_clk_put;
458
+ }
247459
248
- table_addr =
249
- sram_suspend_address((unsigned long)pm_sram->emif_sram_table);
250
- ret = ti_emif_copy_pm_function_table(sram_pool, (void *)table_addr);
251
- if (ret) {
252
- dev_dbg(pm33xx_dev,
253
- "PM: %s: EMIF function copy failed\n", __func__);
254
- return -EPROBE_DEFER;
255
- }
460
+ omap_rtc = rtc_class_open("rtc0");
461
+ if (!omap_rtc) {
462
+ pr_warn("PM: rtc0 not available");
463
+ error = -EPROBE_DEFER;
464
+ goto err_iounmap;
465
+ }
256466
257
- ro_data_addr =
258
- sram_suspend_address((unsigned long)pm_sram->ro_sram_data);
259
- copy_addr = sram_exec_copy(sram_pool, (void *)ro_data_addr,
260
- &ro_sram_data,
261
- sizeof(ro_sram_data));
262
- if (!copy_addr) {
263
- dev_err(pm33xx_dev,
264
- "PM: %s: ro_sram_data copy to sram failed\n",
265
- __func__);
266
- return -ENODEV;
467
+ nvmem = devm_nvmem_device_get(&omap_rtc->dev,
468
+ "omap_rtc_scratch0");
469
+ if (!IS_ERR(nvmem)) {
470
+ nvmem_device_read(nvmem, RTC_SCRATCH_MAGIC_REG * 4,
471
+ 4, (void *)&rtc_magic_val);
472
+ if ((rtc_magic_val & 0xffff) != RTC_REG_BOOT_MAGIC)
473
+ pr_warn("PM: bootloader does not support rtc-only!\n");
474
+
475
+ nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4,
476
+ 4, (void *)&val);
477
+ val = pm_sram->resume_address;
478
+ nvmem_device_write(nvmem, RTC_SCRATCH_RESUME_REG * 4,
479
+ 4, (void *)&val);
480
+ }
481
+ } else {
482
+ pr_warn("PM: no-rtc available, rtc-only mode disabled.\n");
267483 }
268484
269485 return 0;
486
+
487
+err_iounmap:
488
+ iounmap(rtc_base_virt);
489
+err_clk_put:
490
+ clk_put(rtc_fck);
491
+
492
+ return error;
270493 }
271494
272495 static int am33xx_pm_probe(struct platform_device *pdev)
....@@ -284,34 +507,42 @@
284507 return -ENODEV;
285508 }
286509
510
+ ret = am43xx_map_gic();
511
+ if (ret) {
512
+ pr_err("PM: Could not ioremap GIC base\n");
513
+ return ret;
514
+ }
515
+
287516 pm_sram = pm_ops->get_sram_addrs();
288517 if (!pm_sram) {
289518 dev_err(dev, "PM: Cannot get PM asm function addresses!!\n");
290519 return -ENODEV;
291520 }
292521
522
+ m3_ipc = wkup_m3_ipc_get();
523
+ if (!m3_ipc) {
524
+ pr_err("PM: Cannot get wkup_m3_ipc handle\n");
525
+ return -EPROBE_DEFER;
526
+ }
527
+
293528 pm33xx_dev = dev;
294529
295530 ret = am33xx_pm_alloc_sram();
296531 if (ret)
297
- return ret;
532
+ goto err_wkup_m3_ipc_put;
298533
299
- ret = am33xx_push_sram_idle();
534
+ ret = am33xx_pm_rtc_setup();
300535 if (ret)
301536 goto err_free_sram;
302537
303
- m3_ipc = wkup_m3_ipc_get();
304
- if (!m3_ipc) {
305
- dev_dbg(dev, "PM: Cannot get wkup_m3_ipc handle\n");
306
- ret = -EPROBE_DEFER;
307
- goto err_free_sram;
308
- }
538
+ ret = am33xx_push_sram_idle();
539
+ if (ret)
540
+ goto err_unsetup_rtc;
309541
310542 am33xx_pm_set_ipc_ops();
311543
312544 #ifdef CONFIG_SUSPEND
313545 suspend_set_ops(&am33xx_pm_ops);
314
-#endif /* CONFIG_SUSPEND */
315546
316547 /*
317548 * For a system suspend we must flush the caches, we want
....@@ -323,29 +554,50 @@
323554 suspend_wfi_flags |= WFI_FLAG_SELF_REFRESH;
324555 suspend_wfi_flags |= WFI_FLAG_SAVE_EMIF;
325556 suspend_wfi_flags |= WFI_FLAG_WAKE_M3;
557
+#endif /* CONFIG_SUSPEND */
326558
327
- ret = pm_ops->init();
559
+ pm_runtime_enable(dev);
560
+ ret = pm_runtime_get_sync(dev);
561
+ if (ret < 0) {
562
+ pm_runtime_put_noidle(dev);
563
+ goto err_pm_runtime_disable;
564
+ }
565
+
566
+ ret = pm_ops->init(am33xx_do_sram_idle);
328567 if (ret) {
329568 dev_err(dev, "Unable to call core pm init!\n");
330569 ret = -ENODEV;
331
- goto err_put_wkup_m3_ipc;
570
+ goto err_pm_runtime_put;
332571 }
333572
334573 return 0;
335574
336
-err_put_wkup_m3_ipc:
337
- wkup_m3_ipc_put(m3_ipc);
575
+err_pm_runtime_put:
576
+ pm_runtime_put_sync(dev);
577
+err_pm_runtime_disable:
578
+ pm_runtime_disable(dev);
579
+err_unsetup_rtc:
580
+ iounmap(rtc_base_virt);
581
+ clk_put(rtc_fck);
338582 err_free_sram:
339583 am33xx_pm_free_sram();
340584 pm33xx_dev = NULL;
585
+err_wkup_m3_ipc_put:
586
+ wkup_m3_ipc_put(m3_ipc);
341587 return ret;
342588 }
343589
344590 static int am33xx_pm_remove(struct platform_device *pdev)
345591 {
592
+ pm_runtime_put_sync(&pdev->dev);
593
+ pm_runtime_disable(&pdev->dev);
594
+ if (pm_ops->deinit)
595
+ pm_ops->deinit();
346596 suspend_set_ops(NULL);
347597 wkup_m3_ipc_put(m3_ipc);
348598 am33xx_pm_free_sram();
599
+ iounmap(rtc_base_virt);
600
+ clk_put(rtc_fck);
349601 return 0;
350602 }
351603