hc
2023-11-06 e3e12f52b214121840b44c91de5b3e5af5d3eb84
kernel/drivers/gpu/arm/mali400/mali/platform/rk/rk.c
....@@ -34,7 +34,10 @@
3434 #include <linux/dma-mapping.h>
3535 #include <linux/pm_runtime.h>
3636 #include <linux/delay.h>
37
+#include <linux/regmap.h>
38
+#include <linux/mfd/syscon.h>
3739 #include <linux/rockchip/cpu.h>
40
+#include <soc/rockchip/rockchip_ipa.h>
3841 #include <soc/rockchip/rockchip_opp_select.h>
3942
4043 #include <linux/mali/mali_utgard.h>
....@@ -47,6 +50,7 @@
4750
4851 /*---------------------------------------------------------------------------*/
4952
53
+#define RK3528_GPU_SD_SLP_HAST 0x10024
5054 #define DEFAULT_UTILISATION_PERIOD_IN_MS (100)
5155
5256 /*
....@@ -55,6 +59,7 @@
5559 struct rk_context {
5660 /* mali device. */
5761 struct device *dev;
62
+ struct regmap *grf;
5863 /* is the GPU powered on? */
5964 bool is_powered;
6065 /* debug only, the period in ms to count gpu_utilisation. */
....@@ -183,6 +188,10 @@
183188 }
184189
185190 platform->dev = dev;
191
+ platform->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
192
+ "rockchip,grf");
193
+ if (IS_ERR(platform->grf))
194
+ platform->grf = NULL;
186195 platform->is_powered = false;
187196
188197 platform->utilisation_period = DEFAULT_UTILISATION_PERIOD_IN_MS;
....@@ -232,73 +241,7 @@
232241 static u32 static_coefficient;
233242 static s32 ts[4];
234243 static struct thermal_zone_device *gpu_tz;
235
-
236
-static int power_model_simple_init(struct platform_device *pdev)
237
-{
238
- struct device_node *power_model_node;
239
- const char *tz_name;
240
- u32 static_power, dynamic_power;
241
- u32 voltage, voltage_squared, voltage_cubed, frequency;
242
-
243
- power_model_node = of_get_child_by_name(pdev->dev.of_node,
244
- "power_model");
245
- if (!power_model_node) {
246
- dev_err(&pdev->dev, "could not find power_model node\n");
247
- return -ENODEV;
248
- }
249
- if (!of_device_is_compatible(power_model_node,
250
- "arm,mali-simple-power-model")) {
251
- dev_err(&pdev->dev, "power_model incompatible with simple power model\n");
252
- return -ENODEV;
253
- }
254
-
255
- if (of_property_read_string(power_model_node, "thermal-zone",
256
- &tz_name)) {
257
- dev_err(&pdev->dev, "ts in power_model not available\n");
258
- return -EINVAL;
259
- }
260
-
261
- gpu_tz = thermal_zone_get_zone_by_name(tz_name);
262
- if (IS_ERR(gpu_tz)) {
263
- pr_warn_ratelimited("Error getting gpu thermal zone '%s'(%ld), not yet ready?\n",
264
- tz_name,
265
- PTR_ERR(gpu_tz));
266
- gpu_tz = NULL;
267
- }
268
-
269
- if (of_property_read_u32(power_model_node, "static-power",
270
- &static_power)) {
271
- dev_err(&pdev->dev, "static-power in power_model not available\n");
272
- return -EINVAL;
273
- }
274
- if (of_property_read_u32(power_model_node, "dynamic-power",
275
- &dynamic_power)) {
276
- dev_err(&pdev->dev, "dynamic-power in power_model not available\n");
277
- return -EINVAL;
278
- }
279
- if (of_property_read_u32(power_model_node, "voltage",
280
- &voltage)) {
281
- dev_err(&pdev->dev, "voltage in power_model not available\n");
282
- return -EINVAL;
283
- }
284
- if (of_property_read_u32(power_model_node, "frequency",
285
- &frequency)) {
286
- dev_err(&pdev->dev, "frequency in power_model not available\n");
287
- return -EINVAL;
288
- }
289
- voltage_squared = (voltage * voltage) / 1000;
290
- voltage_cubed = voltage * voltage * voltage;
291
- static_coefficient = (static_power << 20) / (voltage_cubed >> 10);
292
- dynamic_coefficient = (((dynamic_power * 1000) / voltage_squared)
293
- * 1000) / frequency;
294
-
295
- if (of_property_read_u32_array(power_model_node, "ts", (u32 *)ts, 4)) {
296
- dev_err(&pdev->dev, "ts in power_model not available\n");
297
- return -EINVAL;
298
- }
299
-
300
- return 0;
301
-}
244
+static struct ipa_power_model_data *model_data;
302245
303246 /* Calculate gpu static power example for reference */
304247 static unsigned long rk_model_static_power(struct devfreq *devfreq,
....@@ -360,10 +303,107 @@
360303 return dynamic_power;
361304 }
362305
363
-struct devfreq_cooling_power rk_cooling_ops = {
306
+static struct devfreq_cooling_power rk_cooling_ops = {
364307 .get_static_power = rk_model_static_power,
365308 .get_dynamic_power = rk_model_dynamic_power,
366309 };
310
+
311
+static unsigned long mali_devfreq_get_static_power(struct devfreq *devfreq,
312
+ unsigned long voltage)
313
+{
314
+ return rockchip_ipa_get_static_power(model_data, voltage);
315
+}
316
+
317
+static int power_model_simple_init(struct platform_device *pdev)
318
+{
319
+ struct device_node *power_model_node;
320
+ const char *tz_name;
321
+ u32 static_power, dynamic_power;
322
+ u32 voltage, voltage_squared, voltage_cubed, frequency;
323
+
324
+ if (of_find_compatible_node(pdev->dev.of_node, NULL, "simple-power-model")) {
325
+ of_property_read_u32(pdev->dev.of_node,
326
+ "dynamic-power-coefficient",
327
+ (u32 *)&rk_cooling_ops.dyn_power_coeff);
328
+ model_data = rockchip_ipa_power_model_init(&pdev->dev,
329
+ "gpu_leakage");
330
+ if (IS_ERR_OR_NULL(model_data)) {
331
+ model_data = NULL;
332
+ dev_err(&pdev->dev, "failed to initialize power model\n");
333
+ } else if (model_data->dynamic_coefficient) {
334
+ rk_cooling_ops.dyn_power_coeff =
335
+ model_data->dynamic_coefficient;
336
+ rk_cooling_ops.get_dynamic_power = NULL;
337
+ rk_cooling_ops.get_static_power = mali_devfreq_get_static_power;
338
+ }
339
+ if (!rk_cooling_ops.dyn_power_coeff) {
340
+ dev_err(&pdev->dev, "failed to get dynamic-coefficient\n");
341
+ return -EINVAL;
342
+ }
343
+
344
+ return 0;
345
+ }
346
+
347
+ power_model_node = of_get_child_by_name(pdev->dev.of_node,
348
+ "power_model");
349
+ if (!power_model_node) {
350
+ dev_err(&pdev->dev, "could not find power_model node\n");
351
+ return -ENODEV;
352
+ }
353
+ if (!of_device_is_compatible(power_model_node,
354
+ "arm,mali-simple-power-model")) {
355
+ dev_err(&pdev->dev, "power_model incompatible with simple power model\n");
356
+ return -ENODEV;
357
+ }
358
+
359
+ if (of_property_read_string(power_model_node, "thermal-zone",
360
+ &tz_name)) {
361
+ dev_err(&pdev->dev, "ts in power_model not available\n");
362
+ return -EINVAL;
363
+ }
364
+
365
+ gpu_tz = thermal_zone_get_zone_by_name(tz_name);
366
+ if (IS_ERR(gpu_tz)) {
367
+ pr_warn_ratelimited("Error getting gpu thermal zone '%s'(%ld), not yet ready?\n",
368
+ tz_name,
369
+ PTR_ERR(gpu_tz));
370
+ gpu_tz = NULL;
371
+ }
372
+
373
+ if (of_property_read_u32(power_model_node, "static-power",
374
+ &static_power)) {
375
+ dev_err(&pdev->dev, "static-power in power_model not available\n");
376
+ return -EINVAL;
377
+ }
378
+ if (of_property_read_u32(power_model_node, "dynamic-power",
379
+ &dynamic_power)) {
380
+ dev_err(&pdev->dev, "dynamic-power in power_model not available\n");
381
+ return -EINVAL;
382
+ }
383
+ if (of_property_read_u32(power_model_node, "voltage",
384
+ &voltage)) {
385
+ dev_err(&pdev->dev, "voltage in power_model not available\n");
386
+ return -EINVAL;
387
+ }
388
+ if (of_property_read_u32(power_model_node, "frequency",
389
+ &frequency)) {
390
+ dev_err(&pdev->dev, "frequency in power_model not available\n");
391
+ return -EINVAL;
392
+ }
393
+ voltage_squared = (voltage * voltage) / 1000;
394
+ voltage_cubed = voltage * voltage * voltage;
395
+ static_coefficient = (static_power << 20) / (voltage_cubed >> 10);
396
+ dynamic_coefficient = (((dynamic_power * 1000) / voltage_squared)
397
+ * 1000) / frequency;
398
+
399
+ if (of_property_read_u32_array(power_model_node, "ts", (u32 *)ts, 4)) {
400
+ dev_err(&pdev->dev, "ts in power_model not available\n");
401
+ return -EINVAL;
402
+ }
403
+
404
+ return 0;
405
+}
406
+
367407 #endif
368408
369409 /*---------------------------------------------------------------------------*/
....@@ -376,8 +416,7 @@
376416 #if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_HAVE_CLK)
377417 struct mali_device *mdev = dev_get_drvdata(dev);
378418
379
- if (mdev->clock)
380
- ret = clk_enable(mdev->clock);
419
+ ret = clk_bulk_enable(mdev->num_clks, mdev->clks);
381420 #endif
382421 return ret;
383422 }
....@@ -387,8 +426,7 @@
387426 #if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_HAVE_CLK)
388427 struct mali_device *mdev = dev_get_drvdata(dev);
389428
390
- if (mdev->clock)
391
- clk_disable(mdev->clock);
429
+ clk_bulk_disable(mdev->num_clks, mdev->clks);
392430 #endif
393431 }
394432
....@@ -432,6 +470,18 @@
432470 goto fail_to_enable_regulator;
433471 }
434472
473
+ if (cpu_is_rk3528()) {
474
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_HAVE_CLK)
475
+ struct mali_device *mdev = dev_get_drvdata(dev);
476
+
477
+ clk_set_rate(mdev->clock, mdev->current_freq);
478
+#endif
479
+ if (platform->grf)
480
+ regmap_write(platform->grf,
481
+ RK3528_GPU_SD_SLP_HAST,
482
+ 0xffff0000);
483
+ }
484
+
435485 platform->is_powered = true;
436486 }
437487
....@@ -449,6 +499,18 @@
449499 struct rk_context *platform = s_rk_context;
450500
451501 if (platform->is_powered) {
502
+ if (cpu_is_rk3528()) {
503
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_HAVE_CLK)
504
+ struct mali_device *mdev = dev_get_drvdata(dev);
505
+
506
+ //use normal pll 200M for gpu when suspend
507
+ clk_set_rate(mdev->clock, 200000000);
508
+#endif
509
+ if (platform->grf)
510
+ regmap_write(platform->grf,
511
+ RK3528_GPU_SD_SLP_HAST,
512
+ 0xfffffffd);
513
+ }
452514 rk_platform_disable_clk_gpu(dev);
453515 rk_platform_disable_gpu_regulator(dev);
454516