hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/soc/rockchip/rockchip_opp_select.c
....@@ -1165,12 +1165,13 @@
11651165 }
11661166
11671167 void rockchip_of_get_pvtm_sel(struct device *dev, struct device_node *np,
1168
- char *reg_name, int process,
1168
+ char *reg_name, int bin, int process,
11691169 int *volt_sel, int *scale_sel)
11701170 {
11711171 struct property *prop = NULL;
11721172 char name[NAME_MAX];
11731173 int pvtm, ret;
1174
+ u32 hw = 0;
11741175
11751176 if (of_property_read_bool(np, "rockchip,pvtm-pvtpll"))
11761177 pvtm = rockchip_get_pvtm_pvtpll(dev, np, reg_name);
....@@ -1185,6 +1186,12 @@
11851186 snprintf(name, sizeof(name),
11861187 "rockchip,p%d-pvtm-voltage-sel", process);
11871188 prop = of_find_property(np, name, NULL);
1189
+ } else if (bin >= 0) {
1190
+ of_property_read_u32(np, "rockchip,pvtm-hw", &hw);
1191
+ if (hw && (hw & BIT(bin))) {
1192
+ sprintf(name, "rockchip,pvtm-voltage-sel-hw");
1193
+ prop = of_find_property(np, name, NULL);
1194
+ }
11881195 }
11891196 if (!prop)
11901197 sprintf(name, "rockchip,pvtm-voltage-sel");
....@@ -1195,6 +1202,7 @@
11951202 next:
11961203 if (!scale_sel)
11971204 return;
1205
+ prop = NULL;
11981206 if (process >= 0) {
11991207 snprintf(name, sizeof(name),
12001208 "rockchip,p%d-pvtm-scaling-sel", process);
....@@ -1294,6 +1302,46 @@
12941302 }
12951303 EXPORT_SYMBOL(rockchip_get_volt_rm_table);
12961304
1305
+int rockchip_get_soc_info(struct device *dev, struct device_node *np, int *bin,
1306
+ int *process)
1307
+{
1308
+ u8 value = 0;
1309
+ int ret = 0;
1310
+
1311
+ if (*bin >= 0 || *process >= 0)
1312
+ return 0;
1313
+
1314
+ if (of_property_match_string(np, "nvmem-cell-names",
1315
+ "remark_spec_serial_number") >= 0)
1316
+ rockchip_nvmem_cell_read_u8(np, "remark_spec_serial_number", &value);
1317
+
1318
+ if (!value && of_property_match_string(np, "nvmem-cell-names",
1319
+ "specification_serial_number") >= 0) {
1320
+ ret = rockchip_nvmem_cell_read_u8(np,
1321
+ "specification_serial_number",
1322
+ &value);
1323
+ if (ret) {
1324
+ dev_err(dev,
1325
+ "Failed to get specification_serial_number\n");
1326
+ return ret;
1327
+ }
1328
+ }
1329
+
1330
+ /* M */
1331
+ if (value == 0xd)
1332
+ *bin = 1;
1333
+ /* J */
1334
+ else if (value == 0xa)
1335
+ *bin = 2;
1336
+
1337
+ if (*bin < 0)
1338
+ *bin = 0;
1339
+ dev_info(dev, "bin=%d\n", *bin);
1340
+
1341
+ return 0;
1342
+}
1343
+EXPORT_SYMBOL(rockchip_get_soc_info);
1344
+
12971345 void rockchip_get_scale_volt_sel(struct device *dev, char *lkg_name,
12981346 char *reg_name, int bin, int process,
12991347 int *scale, int *volt_sel)
....@@ -1311,7 +1359,7 @@
13111359
13121360 rockchip_of_get_lkg_sel(dev, np, lkg_name, process,
13131361 &lkg_volt_sel, &lkg_scale);
1314
- rockchip_of_get_pvtm_sel(dev, np, reg_name, process,
1362
+ rockchip_of_get_pvtm_sel(dev, np, reg_name, bin, process,
13151363 &pvtm_volt_sel, &pvtm_scale);
13161364 rockchip_of_get_bin_sel(dev, np, bin, &bin_scale);
13171365 rockchip_of_get_bin_volt_sel(dev, np, bin, &bin_volt_sel);
....@@ -1348,6 +1396,42 @@
13481396 return dev_pm_opp_set_prop_name(dev, name);
13491397 }
13501398 EXPORT_SYMBOL(rockchip_set_opp_prop_name);
1399
+
1400
+struct opp_table *rockchip_set_opp_supported_hw(struct device *dev,
1401
+ struct device_node *np,
1402
+ int bin, int volt_sel)
1403
+{
1404
+ struct opp_table *opp_table;
1405
+ u32 supported_hw[2];
1406
+ u32 version = 0, speed = 0;
1407
+
1408
+ if (!of_property_read_bool(np, "rockchip,supported-hw"))
1409
+ return NULL;
1410
+
1411
+ opp_table = dev_pm_opp_get_opp_table(dev);
1412
+ if (!opp_table)
1413
+ return NULL;
1414
+ if (opp_table->supported_hw) {
1415
+ dev_pm_opp_put_opp_table(opp_table);
1416
+ return NULL;
1417
+ }
1418
+ dev_pm_opp_put_opp_table(opp_table);
1419
+
1420
+ if (bin >= 0)
1421
+ version = bin;
1422
+ if (volt_sel >= 0)
1423
+ speed = volt_sel;
1424
+
1425
+ /* SoC Version */
1426
+ supported_hw[0] = BIT(version);
1427
+ /* Speed Grade */
1428
+ supported_hw[1] = BIT(speed);
1429
+
1430
+ dev_info(dev, "soc version=%d, speed=%d\n", version, speed);
1431
+
1432
+ return dev_pm_opp_set_supported_hw(dev, supported_hw, 2);
1433
+}
1434
+EXPORT_SYMBOL(rockchip_set_opp_supported_hw);
13511435
13521436 static int rockchip_adjust_opp_by_irdrop(struct device *dev,
13531437 struct device_node *np,
....@@ -1484,9 +1568,14 @@
14841568 if (opp->rate > opp_info.max_freq * 1000000)
14851569 continue;
14861570
1487
- opp->supplies->u_volt += opp_info.volt * 1000;
1488
- if (opp->supplies->u_volt > opp->supplies->u_volt_max)
1489
- opp->supplies->u_volt = opp->supplies->u_volt_max;
1571
+ opp->supplies[0].u_volt += opp_info.volt * 1000;
1572
+ if (opp->supplies[0].u_volt > opp->supplies[0].u_volt_max)
1573
+ opp->supplies[0].u_volt = opp->supplies[0].u_volt_max;
1574
+ if (opp_table->regulator_count > 1) {
1575
+ opp->supplies[1].u_volt += opp_info.volt * 1000;
1576
+ if (opp->supplies[1].u_volt > opp->supplies[1].u_volt_max)
1577
+ opp->supplies[1].u_volt = opp->supplies[1].u_volt_max;
1578
+ }
14901579 }
14911580 mutex_unlock(&opp_table->lock);
14921581
....@@ -1810,11 +1899,13 @@
18101899 info->data->get_soc_info(dev, np, &bin, &process);
18111900
18121901 next:
1902
+ rockchip_get_soc_info(dev, np, &bin, &process);
18131903 rockchip_get_scale_volt_sel(dev, lkg_name, reg_name, bin, process,
18141904 &scale, &volt_sel);
18151905 if (info && info->data && info->data->set_soc_info)
18161906 info->data->set_soc_info(dev, np, bin, process, volt_sel);
18171907 rockchip_set_opp_prop_name(dev, process, volt_sel);
1908
+ rockchip_set_opp_supported_hw(dev, np, bin, volt_sel);
18181909 ret = dev_pm_opp_of_add_table(dev);
18191910 if (ret) {
18201911 dev_err(dev, "Invalid operating-points in device tree.\n");