Guest User

Untitled

a guest
May 9th, 2022
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.04 KB | None | 0 0
  1. diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
  2. index acce9d02dba0..9641769c64d1 100644
  3. --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
  4. +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
  5. @@ -29,13 +29,34 @@ static int panfrost_devfreq_target(struct device *dev, unsigned long *freq,
  6. u32 flags)
  7. {
  8. struct dev_pm_opp *opp;
  9. + struct panfrost_device *pfdev = dev_get_drvdata(dev);
  10. + int ret, err;
  11. + char needs_reparenting = pfdev->mtk_clk_mux != NULL;
  12.  
  13. opp = devfreq_recommended_opp(dev, freq, flags);
  14. if (IS_ERR(opp))
  15. return PTR_ERR(opp);
  16. dev_pm_opp_put(opp);
  17.  
  18. - return dev_pm_opp_set_rate(dev, *freq);
  19. + if (needs_reparenting) {
  20. + err = clk_set_parent(pfdev->mtk_clk_mux, pfdev->mtk_clk_sub);
  21. + if (err) {
  22. + DRM_DEV_ERROR(dev, "Failed to select sub clock source\n");
  23. + return err;
  24. + }
  25. + }
  26. +
  27. + ret = dev_pm_opp_set_rate(dev, *freq);
  28. +
  29. + if (needs_reparenting) {
  30. + err = clk_set_parent(pfdev->mtk_clk_mux, pfdev->mtk_clk_parent);
  31. + if (err) {
  32. + DRM_DEV_ERROR(dev, "Failed to select main clock source\n");
  33. + return err;
  34. + }
  35. + }
  36. +
  37. + return ret;
  38. }
  39.  
  40. static void panfrost_devfreq_reset(struct panfrost_devfreq *pfdevfreq)
  41. @@ -91,16 +112,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
  42. struct devfreq *devfreq;
  43. struct opp_table *opp_table;
  44. struct thermal_cooling_device *cooling;
  45. - struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
  46. -
  47. - if (pfdev->comp->num_supplies > 1) {
  48. - /*
  49. - * GPUs with more than 1 supply require platform-specific handling:
  50. - * continue without devfreq
  51. - */
  52. - DRM_DEV_INFO(dev, "More than 1 supply is not supported yet\n");
  53. - return 0;
  54. - }
  55. + struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
  56.  
  57. opp_table = dev_pm_opp_set_regulators(dev, pfdev->comp->supply_names,
  58. pfdev->comp->num_supplies);
  59. diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c
  60. index a2a09c51eed7..b77d738c7fb8 100644
  61. --- a/drivers/gpu/drm/panfrost/panfrost_device.c
  62. +++ b/drivers/gpu/drm/panfrost/panfrost_device.c
  63. @@ -67,6 +67,32 @@ static int panfrost_clk_init(struct panfrost_device *pfdev)
  64. goto disable_clock;
  65. }
  66.  
  67. + pfdev->mtk_clk_mux = devm_clk_get_optional(pfdev->dev, "clk_mux");
  68. + if (pfdev->mtk_clk_mux) {
  69. + if (IS_ERR(pfdev->mtk_clk_mux)) {
  70. + dev_err(pfdev->dev, "get clk_mux failed %ld\n",
  71. + PTR_ERR(pfdev->mtk_clk_mux));
  72. + err = PTR_ERR(pfdev->mtk_clk_mux);
  73. + goto disable_clock;
  74. + }
  75. +
  76. + pfdev->mtk_clk_parent = devm_clk_get(pfdev->dev, "clk_main_parent");
  77. + if (IS_ERR(pfdev->mtk_clk_parent)) {
  78. + dev_err(pfdev->dev, "get clk_main_parent failed %ld\n",
  79. + PTR_ERR(pfdev->mtk_clk_parent));
  80. + err = PTR_ERR(pfdev->mtk_clk_parent);
  81. + goto disable_clock;
  82. + }
  83. +
  84. + pfdev->mtk_clk_sub = devm_clk_get(pfdev->dev, "clk_sub_parent");
  85. + if (IS_ERR(pfdev->mtk_clk_sub)) {
  86. + dev_err(pfdev->dev, "get clk_sub_parent failed %ld\n",
  87. + PTR_ERR(pfdev->mtk_clk_sub));
  88. + err = PTR_ERR(pfdev->mtk_clk_sub);
  89. + goto disable_clock;
  90. + }
  91. + }
  92. +
  93. return 0;
  94.  
  95. disable_clock:
  96. diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h
  97. index 8b2cdb8c701d..410b6099fea9 100644
  98. --- a/drivers/gpu/drm/panfrost/panfrost_device.h
  99. +++ b/drivers/gpu/drm/panfrost/panfrost_device.h
  100. @@ -84,6 +84,9 @@ struct panfrost_device {
  101. void __iomem *iomem;
  102. struct clk *clock;
  103. struct clk *bus_clock;
  104. + struct clk *mtk_clk_mux;
  105. + struct clk *mtk_clk_parent;
  106. + struct clk *mtk_clk_sub;
  107. struct regulator_bulk_data *regulators;
  108. struct reset_control *rstc;
  109. /* pm_domains for devices with more than one. */
  110. diff --git a/drivers/opp/core.c b/drivers/opp/core.c
  111. index 65df3a106cf5..a3534dd83a00 100644
  112. --- a/drivers/opp/core.c
  113. +++ b/drivers/opp/core.c
  114. @@ -784,18 +784,15 @@ static int _generic_set_opp_regulator(struct opp_table *opp_table,
  115. struct regulator *reg = opp_table->regulators[0];
  116. struct dev_pm_opp *old_opp = opp_table->current_opp;
  117. int ret;
  118. -
  119. - /* This function only supports single regulator per device */
  120. - if (WARN_ON(opp_table->regulator_count > 1)) {
  121. - dev_err(dev, "multiple regulators are not supported\n");
  122. - return -EINVAL;
  123. - }
  124. + unsigned i;
  125.  
  126. /* Scaling up? Scale voltage before frequency */
  127. if (!scaling_down) {
  128. - ret = _set_opp_voltage(dev, reg, opp->supplies);
  129. - if (ret)
  130. - goto restore_voltage;
  131. + for (i = 0; i < opp_table->regulator_count; i++) {
  132. + ret = _set_opp_voltage(dev, opp_table->regulators[i], &opp->supplies[i]);
  133. + if (ret)
  134. + goto restore_voltage;
  135. + }
  136. }
  137.  
  138. /* Change frequency */
  139. @@ -805,9 +802,11 @@ static int _generic_set_opp_regulator(struct opp_table *opp_table,
  140.  
  141. /* Scaling down? Scale voltage after frequency */
  142. if (scaling_down) {
  143. - ret = _set_opp_voltage(dev, reg, opp->supplies);
  144. - if (ret)
  145. - goto restore_freq;
  146. + for (i = 0; i < opp_table->regulator_count; i++) {
  147. + ret = _set_opp_voltage(dev, opp_table->regulators[i], &opp->supplies[i]);
  148. + if (ret)
  149. + goto restore_freq;
  150. + }
  151. }
  152.  
  153. /*
  154. --
  155.  
Advertisement
Add Comment
Please, Sign In to add comment