summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_devfreq.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index fe5f12f16a63..58dfb15a8757 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -4,6 +4,7 @@
#include <linux/clk.h>
#include <linux/devfreq.h>
#include <linux/devfreq_cooling.h>
+#include <linux/nvmem-consumer.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
@@ -82,6 +83,31 @@ static struct devfreq_dev_profile panfrost_devfreq_profile = {
.get_dev_status = panfrost_devfreq_get_dev_status,
};
+static int panfrost_read_speedbin(struct device *dev)
+{
+ u32 val;
+ int ret;
+
+ ret = nvmem_cell_read_variable_le_u32(dev, "speed-bin", &val);
+ if (ret) {
+ /*
+ * -ENOENT means that this platform doesn't support speedbins
+ * as it didn't declare any speed-bin nvmem: in this case, we
+ * keep going without it; any other error means that we are
+ * supposed to read the bin value, but we failed doing so.
+ */
+ if (ret != -ENOENT) {
+ DRM_DEV_ERROR(dev, "Cannot read speed-bin (%d).", ret);
+ return ret;
+ }
+
+ return 0;
+ }
+ DRM_DEV_DEBUG(dev, "Using speed-bin = 0x%x\n", val);
+
+ return devm_pm_opp_set_supported_hw(dev, &val, 1);
+}
+
int panfrost_devfreq_init(struct panfrost_device *pfdev)
{
int ret;
@@ -101,6 +127,10 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
return 0;
}
+ ret = panfrost_read_speedbin(dev);
+ if (ret)
+ return ret;
+
ret = devm_pm_opp_set_regulators(dev, pfdev->comp->supply_names);
if (ret) {
/* Continue if the optional regulator is missing */