hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/soc/rockchip/pm_domains.c
....@@ -93,19 +93,26 @@
9393 #define QOS_SATURATION 0x14
9494 #define QOS_EXTCONTROL 0x18
9595
96
+#define SHAPING_NBPKTMAX0 0x0
97
+
9698 struct rockchip_pm_domain {
9799 struct generic_pm_domain genpd;
98100 const struct rockchip_domain_info *info;
99101 struct rockchip_pmu *pmu;
100102 int num_qos;
103
+ int num_shaping;
101104 struct regmap **qos_regmap;
105
+ struct regmap **shaping_regmap;
102106 u32 *qos_save_regs[MAX_QOS_REGS_NUM];
107
+ u32 *shaping_save_regs;
103108 bool *qos_is_need_init[MAX_QOS_REGS_NUM];
109
+ bool *shaping_is_need_init;
104110 int num_clks;
105111 struct clk_bulk_data *clks;
106112 bool is_ignore_pwr;
107113 bool is_qos_saved;
108114 bool is_qos_need_init;
115
+ bool is_shaping_need_init;
109116 struct regulator *supply;
110117 };
111118
....@@ -124,35 +131,6 @@
124131 module_param_named(always_on, pm_domain_always_on, bool, 0644);
125132 MODULE_PARM_DESC(always_on,
126133 "Always keep pm domains power on except for system suspend.");
127
-
128
-#ifdef MODULE
129
-static bool keepon_startup = true;
130
-static void rockchip_pd_keepon_do_release(void);
131
-
132
-static int pd_param_set_keepon_startup(const char *val,
133
- const struct kernel_param *kp)
134
-{
135
- int ret;
136
-
137
- ret = param_set_bool(val, kp);
138
- if (ret)
139
- return ret;
140
-
141
- if (!keepon_startup)
142
- rockchip_pd_keepon_do_release();
143
-
144
- return 0;
145
-}
146
-
147
-static const struct kernel_param_ops pd_keepon_startup_ops = {
148
- .set = pd_param_set_keepon_startup,
149
- .get = param_get_bool,
150
-};
151
-
152
-module_param_cb(keepon_startup, &pd_keepon_startup_ops, &keepon_startup, 0644);
153
-MODULE_PARM_DESC(keepon_startup,
154
- "Keep pm domains power on during system startup.");
155
-#endif
156134
157135 static void rockchip_pmu_lock(struct rockchip_pm_domain *pd)
158136 {
....@@ -459,6 +437,45 @@
459437 }
460438 EXPORT_SYMBOL(rockchip_pmu_idle_request);
461439
440
+static int rockchip_pmu_save_shaping(struct rockchip_pm_domain *pd)
441
+{
442
+ int i;
443
+
444
+ for (i = 0; i < pd->num_shaping; i++)
445
+ regmap_read(pd->shaping_regmap[i], SHAPING_NBPKTMAX0,
446
+ &pd->shaping_save_regs[i]);
447
+
448
+ return 0;
449
+}
450
+
451
+static int rockchip_pmu_restore_shaping(struct rockchip_pm_domain *pd)
452
+{
453
+ int i;
454
+
455
+ for (i = 0; i < pd->num_shaping; i++)
456
+ regmap_write(pd->shaping_regmap[i], SHAPING_NBPKTMAX0,
457
+ pd->shaping_save_regs[i]);
458
+
459
+ return 0;
460
+}
461
+
462
+static void rockchip_pmu_init_shaping(struct rockchip_pm_domain *pd)
463
+{
464
+ int i;
465
+
466
+ if (!pd->is_shaping_need_init)
467
+ return;
468
+
469
+ for (i = 0; i < pd->num_shaping; i++)
470
+ if (pd->shaping_is_need_init[i])
471
+ regmap_write(pd->shaping_regmap[i], SHAPING_NBPKTMAX0,
472
+ pd->shaping_save_regs[i]);
473
+
474
+ kfree(pd->shaping_is_need_init);
475
+ pd->shaping_is_need_init = NULL;
476
+ pd->is_shaping_need_init = false;
477
+}
478
+
462479 static int rockchip_pmu_save_qos(struct rockchip_pm_domain *pd)
463480 {
464481 int i;
....@@ -480,7 +497,8 @@
480497 QOS_EXTCONTROL,
481498 &pd->qos_save_regs[4][i]);
482499 }
483
- return 0;
500
+
501
+ return rockchip_pmu_save_shaping(pd);
484502 }
485503
486504 static int rockchip_pmu_restore_qos(struct rockchip_pm_domain *pd)
....@@ -505,12 +523,14 @@
505523 pd->qos_save_regs[4][i]);
506524 }
507525
508
- return 0;
526
+ return rockchip_pmu_restore_shaping(pd);
509527 }
510528
511529 static void rockchip_pmu_init_qos(struct rockchip_pm_domain *pd)
512530 {
513531 int i;
532
+
533
+ rockchip_pmu_init_shaping(pd);
514534
515535 if (!pd->is_qos_need_init)
516536 return;
....@@ -809,7 +829,7 @@
809829
810830 if (pd->is_qos_saved)
811831 rockchip_pmu_restore_qos(pd);
812
- if (pd->is_qos_need_init)
832
+ if (pd->is_qos_need_init || pd->is_shaping_need_init)
813833 rockchip_pmu_init_qos(pd);
814834 }
815835
....@@ -949,8 +969,13 @@
949969 if (!pd->is_qos_need_init) {
950970 kfree(pd->qos_is_need_init[0]);
951971 pd->qos_is_need_init[0] = NULL;
952
- return;
953972 }
973
+ if (!pd->is_shaping_need_init) {
974
+ kfree(pd->shaping_is_need_init);
975
+ pd->shaping_is_need_init = NULL;
976
+ }
977
+ if (!pd->is_qos_need_init && !pd->is_shaping_need_init)
978
+ return;
954979
955980 is_pd_on = rockchip_pmu_domain_is_on(pd);
956981 if (is_pd_on) {
....@@ -982,6 +1007,79 @@
9821007 }
9831008
9841009 return 0;
1010
+}
1011
+
1012
+static int rockchip_pd_of_get_shaping(struct rockchip_pm_domain *pd,
1013
+ struct device_node *node)
1014
+{
1015
+ struct rockchip_pmu *pmu = pd->pmu;
1016
+ struct device_node *shaping_node;
1017
+ int num_shaping = 0, num_shaping_reg = 0;
1018
+ int error, i;
1019
+ u32 val;
1020
+
1021
+ num_shaping = of_count_phandle_with_args(node, "pm_shaping", NULL);
1022
+
1023
+ for (i = 0; i < num_shaping; i++) {
1024
+ shaping_node = of_parse_phandle(node, "pm_shaping", i);
1025
+ if (shaping_node && of_device_is_available(shaping_node))
1026
+ pd->num_shaping++;
1027
+ of_node_put(shaping_node);
1028
+ }
1029
+
1030
+ if (pd->num_shaping > 0) {
1031
+ pd->shaping_regmap = devm_kcalloc(pmu->dev, pd->num_shaping,
1032
+ sizeof(*pd->shaping_regmap),
1033
+ GFP_KERNEL);
1034
+ if (!pd->shaping_regmap)
1035
+ return -ENOMEM;
1036
+ pd->shaping_save_regs = devm_kmalloc(pmu->dev, sizeof(u32) *
1037
+ pd->num_shaping,
1038
+ GFP_KERNEL);
1039
+ if (!pd->shaping_save_regs)
1040
+ return -ENOMEM;
1041
+ pd->shaping_is_need_init = kcalloc(pd->num_shaping, sizeof(bool),
1042
+ GFP_KERNEL);
1043
+ if (!pd->shaping_is_need_init)
1044
+ return -ENOMEM;
1045
+ for (i = 0; i < num_shaping; i++) {
1046
+ shaping_node = of_parse_phandle(node, "pm_shaping", i);
1047
+ if (!shaping_node) {
1048
+ error = -ENODEV;
1049
+ goto err_free_init;
1050
+ }
1051
+ if (of_device_is_available(shaping_node)) {
1052
+ pd->shaping_regmap[num_shaping_reg] =
1053
+ syscon_node_to_regmap(shaping_node);
1054
+ if (IS_ERR(pd->shaping_regmap[num_shaping_reg])) {
1055
+ of_node_put(shaping_node);
1056
+ error = -ENODEV;
1057
+ goto err_free_init;
1058
+ }
1059
+ if (!of_property_read_u32(shaping_node,
1060
+ "shaping-init",
1061
+ &val)) {
1062
+ pd->shaping_save_regs[i] = val;
1063
+ pd->shaping_is_need_init[i] = true;
1064
+ pd->is_shaping_need_init = true;
1065
+ }
1066
+ num_shaping_reg++;
1067
+ }
1068
+ of_node_put(shaping_node);
1069
+ if (num_shaping_reg > pd->num_shaping) {
1070
+ error = -EINVAL;
1071
+ goto err_free_init;
1072
+ }
1073
+ }
1074
+ }
1075
+
1076
+ return 0;
1077
+
1078
+err_free_init:
1079
+ kfree(pd->shaping_is_need_init);
1080
+ pd->shaping_is_need_init = NULL;
1081
+
1082
+ return error;
9851083 }
9861084
9871085 static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
....@@ -1160,6 +1258,10 @@
11601258 }
11611259 }
11621260
1261
+ error = rockchip_pd_of_get_shaping(pd, node);
1262
+ if (error)
1263
+ goto err_unprepare_clocks;
1264
+
11631265 if (pd->info->name)
11641266 pd->genpd.name = pd->info->name;
11651267 else
....@@ -1309,6 +1411,31 @@
13091411 return error;
13101412 }
13111413
1414
+#ifdef MODULE
1415
+void rockchip_pd_disable_unused(void)
1416
+{
1417
+ struct generic_pm_domain *genpd;
1418
+ struct rockchip_pm_domain *pd;
1419
+ int i;
1420
+
1421
+ if (!g_pmu)
1422
+ return;
1423
+
1424
+ for (i = 0; i < g_pmu->genpd_data.num_domains; i++) {
1425
+ genpd = g_pmu->genpd_data.domains[i];
1426
+ if (genpd) {
1427
+ pd = to_rockchip_pd(genpd);
1428
+ if (pd->info->always_on)
1429
+ continue;
1430
+ if (pd->info->keepon_startup &&
1431
+ (genpd->flags & GENPD_FLAG_ALWAYS_ON))
1432
+ genpd->flags &= (~GENPD_FLAG_ALWAYS_ON);
1433
+ queue_work(pm_wq, &genpd->power_off_work);
1434
+ }
1435
+ }
1436
+}
1437
+EXPORT_SYMBOL_GPL(rockchip_pd_disable_unused);
1438
+#else
13121439 static void rockchip_pd_keepon_do_release(void)
13131440 {
13141441 struct generic_pm_domain *genpd;
....@@ -1334,7 +1461,6 @@
13341461 }
13351462 }
13361463
1337
-#ifndef MODULE
13381464 static int __init rockchip_pd_keepon_release(void)
13391465 {
13401466 rockchip_pd_keepon_do_release();