drm/msm/dpu: Use OPP API to set clk/perf state
On some qualcomm platforms DPU needs to express a performance state requirement on a power domain depending on the clock rates. Use OPP table from DT to register with OPP framework and use dev_pm_opp_set_rate() to set the clk/perf state. Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org> Reviewed-by: Rob Clark <robdclark@chromium.org> Reviewed-by: Matthias Kaehlcke <mka@chromium.org> Signed-off-by: Rob Clark <robdclark@chromium.org>
This commit is contained in:
parent
5e16372b59
commit
b0530eb119
|
@ -7,6 +7,7 @@
|
|||
#include <linux/debugfs.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/pm_opp.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/bitmap.h>
|
||||
|
@ -218,7 +219,7 @@ static int _dpu_core_perf_set_core_clk_rate(struct dpu_kms *kms, u64 rate)
|
|||
rate = core_clk->max_rate;
|
||||
|
||||
core_clk->rate = rate;
|
||||
return msm_dss_clk_set_rate(core_clk, 1);
|
||||
return dev_pm_opp_set_rate(&kms->pdev->dev, core_clk->rate);
|
||||
}
|
||||
|
||||
static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/debugfs.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/pm_opp.h>
|
||||
|
||||
#include <drm/drm_crtc.h>
|
||||
#include <drm/drm_file.h>
|
||||
|
@ -1025,11 +1026,24 @@ static int dpu_bind(struct device *dev, struct device *master, void *data)
|
|||
if (!dpu_kms)
|
||||
return -ENOMEM;
|
||||
|
||||
dpu_kms->opp_table = dev_pm_opp_set_clkname(dev, "core");
|
||||
if (IS_ERR(dpu_kms->opp_table))
|
||||
return PTR_ERR(dpu_kms->opp_table);
|
||||
/* OPP table is optional */
|
||||
ret = dev_pm_opp_of_add_table(dev);
|
||||
if (!ret) {
|
||||
dpu_kms->has_opp_table = true;
|
||||
} else if (ret != -ENODEV) {
|
||||
dev_err(dev, "invalid OPP table in device tree\n");
|
||||
dev_pm_opp_put_clkname(dpu_kms->opp_table);
|
||||
return ret;
|
||||
}
|
||||
|
||||
mp = &dpu_kms->mp;
|
||||
ret = msm_dss_parse_clock(pdev, mp);
|
||||
if (ret) {
|
||||
DPU_ERROR("failed to parse clocks, ret=%d\n", ret);
|
||||
return ret;
|
||||
goto err;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, dpu_kms);
|
||||
|
@ -1043,6 +1057,11 @@ static int dpu_bind(struct device *dev, struct device *master, void *data)
|
|||
|
||||
priv->kms = &dpu_kms->base;
|
||||
return ret;
|
||||
err:
|
||||
if (dpu_kms->has_opp_table)
|
||||
dev_pm_opp_of_remove_table(dev);
|
||||
dev_pm_opp_put_clkname(dpu_kms->opp_table);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dpu_unbind(struct device *dev, struct device *master, void *data)
|
||||
|
@ -1057,6 +1076,10 @@ static void dpu_unbind(struct device *dev, struct device *master, void *data)
|
|||
|
||||
if (dpu_kms->rpm_enabled)
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
if (dpu_kms->has_opp_table)
|
||||
dev_pm_opp_of_remove_table(dev);
|
||||
dev_pm_opp_put_clkname(dpu_kms->opp_table);
|
||||
}
|
||||
|
||||
static const struct component_ops dpu_ops = {
|
||||
|
@ -1082,6 +1105,8 @@ static int __maybe_unused dpu_runtime_suspend(struct device *dev)
|
|||
struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
|
||||
struct dss_module_power *mp = &dpu_kms->mp;
|
||||
|
||||
/* Drop the performance state vote */
|
||||
dev_pm_opp_set_rate(dev, 0);
|
||||
rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
|
||||
if (rc)
|
||||
DPU_ERROR("clock disable failed rc:%d\n", rc);
|
||||
|
|
|
@ -128,6 +128,10 @@ struct dpu_kms {
|
|||
|
||||
struct platform_device *pdev;
|
||||
bool rpm_enabled;
|
||||
|
||||
struct opp_table *opp_table;
|
||||
bool has_opp_table;
|
||||
|
||||
struct dss_module_power mp;
|
||||
|
||||
/* reference count bandwidth requests, so we know when we can
|
||||
|
|
Loading…
Reference in New Issue