forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/soc/rockchip/rockchip_pm_config.c
....@@ -17,6 +17,7 @@
1717 #include <linux/pm.h>
1818 #include <linux/regulator/driver.h>
1919 #include <linux/regulator/machine.h>
20
+#include <linux/rockchip/rockchip_pm_config.h>
2021 #include <linux/rockchip/rockchip_sip.h>
2122 #include <linux/suspend.h>
2223 #include <dt-bindings/input/input.h>
....@@ -27,6 +28,10 @@
2728 #define MAX_ON_OFF_REG_PROP_NAME_LEN 60
2829 #define MAX_CONFIG_PROP_NAME_LEN 60
2930
31
+#define RK_ATAG_MCU_SLP_CORE 0x526b0001
32
+#define RK_ATAG_MCU_SLP_MAX 0x526b00ff
33
+#define RK_ATAG_NONE 0x00000000
34
+
3035 enum rk_pm_state {
3136 RK_PM_MEM = 0,
3237 RK_PM_MEM_LITE,
....@@ -34,6 +39,7 @@
3439 RK_PM_STATE_MAX
3540 };
3641
42
+#ifndef MODULE
3743 static const char * const pm_state_str[RK_PM_STATE_MAX] = {
3844 [RK_PM_MEM] = "mem",
3945 [RK_PM_MEM_LITE] = "mem-lite",
....@@ -44,13 +50,37 @@
4450 struct regulator_dev *on_reg_list[MAX_ON_OFF_REG_NUM];
4551 struct regulator_dev *off_reg_list[MAX_ON_OFF_REG_NUM];
4652 } on_off_regs_list[RK_PM_STATE_MAX];
53
+#endif
4754
48
-static struct rk_sleep_config {
49
- u32 mode_config;
50
- u32 wakeup_config;
51
-} sleep_config[RK_PM_STATE_MAX];
55
+/* rk_tag related defines */
56
+#define sleep_tag_next(t) \
57
+ ((struct rk_sleep_tag *)((__u32 *)(t) + (t)->hdr.size))
58
+
59
+struct rk_tag_header {
60
+ u32 size;
61
+ u32 tag;
62
+};
63
+
64
+struct rk_sleep_tag {
65
+ struct rk_tag_header hdr;
66
+ u32 params[];
67
+};
68
+
69
+struct rk_mcu_sleep_core_tag {
70
+ struct rk_tag_header hdr;
71
+ u32 total_size;
72
+ u32 reserve[13];
73
+};
74
+
75
+struct rk_mcu_sleep_tags {
76
+ struct rk_mcu_sleep_core_tag core;
77
+ struct rk_sleep_tag slp_tags;
78
+};
79
+
80
+struct rk_sleep_config *sleep_config;
5281
5382 static const struct of_device_id pm_match_table[] = {
83
+ { .compatible = "rockchip,pm-config",},
5484 { .compatible = "rockchip,pm-px30",},
5585 { .compatible = "rockchip,pm-rk1808",},
5686 { .compatible = "rockchip,pm-rk322x",},
....@@ -59,25 +89,89 @@
5989 { .compatible = "rockchip,pm-rk3328",},
6090 { .compatible = "rockchip,pm-rk3368",},
6191 { .compatible = "rockchip,pm-rk3399",},
92
+ { .compatible = "rockchip,pm-rk3528",},
93
+ { .compatible = "rockchip,pm-rk3562",},
6294 { .compatible = "rockchip,pm-rk3568",},
95
+ { .compatible = "rockchip,pm-rk3588",},
6396 { .compatible = "rockchip,pm-rv1126",},
6497 { },
6598 };
6699
100
+#ifndef MODULE
101
+enum {
102
+ RK_PM_VIRT_PWROFF_EN = 0,
103
+ RK_PM_VIRT_PWROFF_IRQ_CFG = 1,
104
+ RK_PM_VIRT_PWROFF_MAX,
105
+};
106
+
107
+static u32 *virtual_pwroff_irqs;
108
+
67109 static void rockchip_pm_virt_pwroff_prepare(void)
68110 {
69
- int error;
111
+ int error, i;
112
+
113
+ pm_wakeup_clear(0);
70114
71115 regulator_suspend_prepare(PM_SUSPEND_MEM);
72116
73
- error = disable_nonboot_cpus();
117
+ error = suspend_disable_secondary_cpus();
74118 if (error) {
75119 pr_err("Disable nonboot cpus failed!\n");
76120 return;
77121 }
78122
79
- sip_smc_set_suspend_mode(VIRTUAL_POWEROFF, 0, 1);
123
+ sip_smc_set_suspend_mode(VIRTUAL_POWEROFF, RK_PM_VIRT_PWROFF_EN, 1);
124
+
125
+ if (virtual_pwroff_irqs) {
126
+ for (i = 0; virtual_pwroff_irqs[i]; i++) {
127
+ error = sip_smc_set_suspend_mode(VIRTUAL_POWEROFF,
128
+ RK_PM_VIRT_PWROFF_IRQ_CFG,
129
+ virtual_pwroff_irqs[i]);
130
+ if (error) {
131
+ pr_err("%s: config virtual_pwroff_irqs[%d] error, overflow or update trust!\n",
132
+ __func__, i);
133
+ break;
134
+ }
135
+ }
136
+ }
137
+
80138 sip_smc_virtual_poweroff();
139
+}
140
+
141
+static int parse_virtual_pwroff_config(struct device_node *node)
142
+{
143
+ int ret = 0, cnt;
144
+ u32 virtual_poweroff_en = 0;
145
+
146
+ if (!of_property_read_u32_array(node,
147
+ "rockchip,virtual-poweroff",
148
+ &virtual_poweroff_en, 1) &&
149
+ virtual_poweroff_en)
150
+ pm_power_off_prepare = rockchip_pm_virt_pwroff_prepare;
151
+
152
+ if (!virtual_poweroff_en)
153
+ return 0;
154
+
155
+ cnt = of_property_count_u32_elems(node, "rockchip,virtual-poweroff-irqs");
156
+ if (cnt > 0) {
157
+ /* 0 as the last element of virtual_pwroff_irqs */
158
+ virtual_pwroff_irqs = kzalloc((cnt + 1) * sizeof(u32), GFP_KERNEL);
159
+ if (!virtual_pwroff_irqs) {
160
+ ret = -ENOMEM;
161
+ goto out;
162
+ }
163
+
164
+ ret = of_property_read_u32_array(node, "rockchip,virtual-poweroff-irqs",
165
+ virtual_pwroff_irqs, cnt);
166
+ if (ret) {
167
+ pr_err("%s: get rockchip,virtual-poweroff-irqs error\n",
168
+ __func__);
169
+ goto out;
170
+ }
171
+ }
172
+
173
+out:
174
+ return ret;
81175 }
82176
83177 static int parse_sleep_config(struct device_node *node, enum rk_pm_state state)
....@@ -159,19 +253,170 @@
159253 return 0;
160254 }
161255
256
+const struct rk_sleep_config *rockchip_get_cur_sleep_config(void)
257
+{
258
+ suspend_state_t suspend_state = mem_sleep_current;
259
+ enum rk_pm_state state = suspend_state - PM_SUSPEND_MEM;
260
+
261
+ if (state >= RK_PM_STATE_MAX)
262
+ return NULL;
263
+
264
+ return &sleep_config[state];
265
+}
266
+EXPORT_SYMBOL_GPL(rockchip_get_cur_sleep_config);
267
+#endif
268
+
269
+static int parse_mcu_sleep_config(struct device_node *node)
270
+{
271
+ int ret, cnt;
272
+ struct arm_smccc_res res;
273
+ struct device_node *mcu_sleep_node;
274
+ struct device_node *child;
275
+ struct rk_mcu_sleep_tags *config;
276
+ struct rk_sleep_tag *slp_tag;
277
+ char *end;
278
+
279
+ mcu_sleep_node = of_find_node_by_name(node, "rockchip-mcu-sleep-cfg");
280
+ if (IS_ERR_OR_NULL(mcu_sleep_node)) {
281
+ ret = -ENODEV;
282
+ goto out;
283
+ }
284
+
285
+ cnt = of_get_child_count(mcu_sleep_node);
286
+ if (!cnt) {
287
+ ret = -EINVAL;
288
+ goto free_mcu_mode;
289
+ }
290
+
291
+ /*
292
+ * 4kb for sleep parameters
293
+ */
294
+ res = sip_smc_request_share_mem(1, SHARE_PAGE_TYPE_SLEEP);
295
+ if (res.a0 != 0) {
296
+ pr_err("%s: no trust memory for mcu_sleep\n", __func__);
297
+ ret = -ENOMEM;
298
+ goto free_mcu_mode;
299
+ }
300
+
301
+ /* Initialize core tag */
302
+ memset((void *)res.a1, 0, sizeof(struct rk_mcu_sleep_tags));
303
+ config = (struct rk_mcu_sleep_tags *)res.a1;
304
+ config->core.hdr.tag = RK_ATAG_MCU_SLP_CORE;
305
+ config->core.hdr.size = sizeof(struct rk_mcu_sleep_core_tag) / sizeof(u32);
306
+ config->core.total_size = sizeof(struct rk_mcu_sleep_tags) -
307
+ sizeof(struct rk_sleep_tag);
308
+
309
+ slp_tag = &config->slp_tags;
310
+
311
+ /* End point of sleep data */
312
+ end = (char *)config + PAGE_SIZE - sizeof(struct rk_sleep_tag);
313
+
314
+ for_each_available_child_of_node(mcu_sleep_node, child) {
315
+ /* Is overflow? */
316
+ if ((char *)slp_tag->params >= end)
317
+ break;
318
+
319
+ ret = of_property_read_u32_array(child, "rockchip,tag",
320
+ &slp_tag->hdr.tag, 1);
321
+ if (ret ||
322
+ slp_tag->hdr.tag <= RK_ATAG_MCU_SLP_CORE ||
323
+ slp_tag->hdr.tag >= RK_ATAG_MCU_SLP_MAX) {
324
+ pr_info("%s: no or invalid rockchip,tag in %s\n",
325
+ __func__, child->name);
326
+
327
+ continue;
328
+ }
329
+
330
+ cnt = of_property_count_u32_elems(child, "rockchip,params");
331
+ if (cnt > 0) {
332
+ /* Is overflow? */
333
+ if ((char *)(slp_tag->params + cnt) >= end) {
334
+ pr_warn("%s: no more space for rockchip,tag in %s\n",
335
+ __func__, child->name);
336
+ break;
337
+ }
338
+
339
+ ret = of_property_read_u32_array(child, "rockchip,params",
340
+ slp_tag->params, cnt);
341
+ if (ret) {
342
+ pr_err("%s: rockchip,params error in %s\n",
343
+ __func__, child->name);
344
+ break;
345
+ }
346
+
347
+ slp_tag->hdr.size =
348
+ cnt + sizeof(struct rk_tag_header) / sizeof(u32);
349
+ } else if (cnt == 0) {
350
+ slp_tag->hdr.size = 0;
351
+ } else {
352
+ continue;
353
+ }
354
+
355
+ config->core.total_size += slp_tag->hdr.size * sizeof(u32);
356
+
357
+ slp_tag = sleep_tag_next(slp_tag);
358
+ }
359
+
360
+ /* Add none tag.
361
+ * Compiler will combine the follow code as "str xzr, [x28]", but
362
+ * "slp->hdr" may not be 8-byte alignment. So we use memset_io instead:
363
+ * slp_tag->hdr.size = 0;
364
+ * slp_tag->hdr.tag = RK_ATAG_NONE;
365
+ */
366
+ memset_io(&slp_tag->hdr, 0, sizeof(slp_tag->hdr));
367
+
368
+ config->core.total_size += sizeof(struct rk_sleep_tag);
369
+
370
+ ret = 0;
371
+
372
+free_mcu_mode:
373
+ of_node_put(mcu_sleep_node);
374
+out:
375
+ return ret;
376
+}
377
+
378
+static int parse_io_config(struct device *dev)
379
+{
380
+ int ret = 0, cnt;
381
+ struct device_node *node = dev->of_node;
382
+ struct rk_sleep_config *config = &sleep_config[RK_PM_MEM];
383
+
384
+ cnt = of_property_count_u32_elems(node, "rockchip,sleep-io-config");
385
+ if (cnt > 0) {
386
+ /* 0 as the last element of virtual_pwroff_irqs */
387
+ config->sleep_io_config =
388
+ devm_kmalloc_array(dev, cnt, sizeof(u32), GFP_KERNEL);
389
+ if (!config->sleep_io_config) {
390
+ ret = -ENOMEM;
391
+ goto out;
392
+ }
393
+
394
+ ret = of_property_read_u32_array(node, "rockchip,sleep-io-config",
395
+ config->sleep_io_config, cnt);
396
+ if (ret) {
397
+ dev_err(dev, "get rockchip,sleep-io-config error\n");
398
+ goto out;
399
+ }
400
+
401
+ config->sleep_io_config_cnt = cnt;
402
+ } else {
403
+ dev_dbg(dev, "not set sleep-pin-config\n");
404
+ }
405
+
406
+out:
407
+ return ret;
408
+}
409
+
162410 static int pm_config_probe(struct platform_device *pdev)
163411 {
164412 const struct of_device_id *match_id;
165413 struct device_node *node;
166
- struct rk_sleep_config *config = &sleep_config[RK_PM_MEM];
167
- u32 pwm_regulator_config = 0;
168
- int gpio_temp[10];
169
- u32 sleep_debug_en = 0;
170
- u32 apios_suspend = 0;
171
- u32 virtual_poweroff_en = 0;
414
+ struct rk_sleep_config *config;
415
+
172416 enum of_gpio_flags flags;
173417 int i = 0;
174418 int length;
419
+ int ret;
175420
176421 match_id = of_match_node(pm_match_table, pdev->dev.of_node);
177422 if (!match_id)
....@@ -183,6 +428,14 @@
183428 dev_err(&pdev->dev, "%s dev node err\n", __func__);
184429 return -ENODEV;
185430 }
431
+
432
+ sleep_config =
433
+ devm_kmalloc_array(&pdev->dev, RK_PM_STATE_MAX,
434
+ sizeof(*sleep_config), GFP_KERNEL);
435
+ if (!sleep_config)
436
+ return -ENOMEM;
437
+
438
+ config = &sleep_config[RK_PM_MEM];
186439
187440 if (of_property_read_u32_array(node,
188441 "rockchip,sleep-mode-config",
....@@ -200,58 +453,90 @@
200453
201454 if (of_property_read_u32_array(node,
202455 "rockchip,pwm-regulator-config",
203
- &pwm_regulator_config, 1))
456
+ &config->pwm_regulator_config, 1))
204457 dev_warn(&pdev->dev, "not set pwm-regulator-config\n");
205458 else
206459 sip_smc_set_suspend_mode(PWM_REGULATOR_CONFIG,
207
- pwm_regulator_config,
460
+ config->pwm_regulator_config,
208461 0);
209462
210463 length = of_gpio_named_count(node, "rockchip,power-ctrl");
211464
212465 if (length > 0 && length < 10) {
466
+ config->power_ctrl_config_cnt = length;
467
+ config->power_ctrl_config =
468
+ devm_kmalloc_array(&pdev->dev, length,
469
+ sizeof(u32), GFP_KERNEL);
470
+ if (!config->power_ctrl_config)
471
+ return -ENOMEM;
472
+
213473 for (i = 0; i < length; i++) {
214
- gpio_temp[i] = of_get_named_gpio_flags(node,
215
- "rockchip,power-ctrl",
216
- i,
217
- &flags);
218
- if (!gpio_is_valid(gpio_temp[i]))
474
+ config->power_ctrl_config[i] =
475
+ of_get_named_gpio_flags(node,
476
+ "rockchip,power-ctrl",
477
+ i,
478
+ &flags);
479
+ if (!gpio_is_valid(config->power_ctrl_config[i]))
219480 break;
220481 sip_smc_set_suspend_mode(GPIO_POWER_CONFIG,
221482 i,
222
- gpio_temp[i]);
483
+ config->power_ctrl_config[i]);
223484 }
224485 }
225486 sip_smc_set_suspend_mode(GPIO_POWER_CONFIG, i, PM_INVALID_GPIO);
226487
227488 if (!of_property_read_u32_array(node,
228489 "rockchip,sleep-debug-en",
229
- &sleep_debug_en, 1))
490
+ &config->sleep_debug_en, 1))
230491 sip_smc_set_suspend_mode(SUSPEND_DEBUG_ENABLE,
231
- sleep_debug_en,
492
+ config->sleep_debug_en,
232493 0);
233494
234495 if (!of_property_read_u32_array(node,
235496 "rockchip,apios-suspend",
236
- &apios_suspend, 1))
497
+ &config->apios_suspend, 1))
237498 sip_smc_set_suspend_mode(APIOS_SUSPEND_CONFIG,
238
- apios_suspend,
499
+ config->apios_suspend,
239500 0);
240501
241502 if (!of_property_read_u32_array(node,
242
- "rockchip,virtual-poweroff",
243
- &virtual_poweroff_en, 1) &&
244
- virtual_poweroff_en)
245
- pm_power_off_prepare = rockchip_pm_virt_pwroff_prepare;
503
+ "rockchip,sleep-io-ret-config",
504
+ &config->io_ret_config, 1)) {
505
+ ret = sip_smc_set_suspend_mode(SUSPEND_IO_RET_CONFIG, config->io_ret_config, 0);
506
+ if (ret)
507
+ dev_warn(&pdev->dev,
508
+ "sleep-io-ret-config failed (%d), check parameters or update trust\n",
509
+ ret);
510
+ }
511
+
512
+ if (!of_property_read_u32_array(node,
513
+ "rockchip,sleep-pin-config",
514
+ config->sleep_pin_config, 2)) {
515
+ ret = sip_smc_set_suspend_mode(SLEEP_PIN_CONFIG,
516
+ config->sleep_pin_config[0],
517
+ config->sleep_pin_config[1]);
518
+ if (ret)
519
+ dev_warn(&pdev->dev,
520
+ "sleep-pin-config failed (%d), check parameters or update trust\n",
521
+ ret);
522
+ }
523
+
524
+ parse_io_config(&pdev->dev);
525
+ parse_mcu_sleep_config(node);
526
+
527
+#ifndef MODULE
528
+ parse_virtual_pwroff_config(node);
246529
247530 for (i = RK_PM_MEM; i < RK_PM_STATE_MAX; i++) {
248531 parse_sleep_config(node, i);
249532 parse_on_off_regulator(node, i);
250533 }
534
+#endif
251535
252536 return 0;
253537 }
254538
539
+#ifndef MODULE
255540 static int pm_config_prepare(struct device *dev)
256541 {
257542 int i;
....@@ -299,13 +584,16 @@
299584 static const struct dev_pm_ops rockchip_pm_ops = {
300585 .prepare = pm_config_prepare,
301586 };
587
+#endif
302588
303589 static struct platform_driver pm_driver = {
304590 .probe = pm_config_probe,
305591 .driver = {
306592 .name = "rockchip-pm",
307593 .of_match_table = pm_match_table,
594
+#ifndef MODULE
308595 .pm = &rockchip_pm_ops,
596
+#endif
309597 },
310598 };
311599