On some qualcomm platforms DPU needs to express a perforamnce state requirement on a power domain depennding 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@xxxxxxxxxxxxxx> --- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 7 ++++++- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c index 9f20f397f77d..db21a86b242b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c @@ -15,6 +15,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> @@ -298,7 +299,11 @@ 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); + + if (dev_pm_opp_get_opp_table(&kms->pdev->dev)) + return dev_pm_opp_set_rate(&kms->pdev->dev, core_clk->rate); + else + return msm_dss_clk_set_rate(core_clk, 1); } static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 885bf88afa3e..684bd6982aaf 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -22,6 +22,7 @@ #include <linux/debugfs.h> #include <linux/of_irq.h> #include <linux/dma-buf.h> +#include <linux/pm_opp.h> #include "msm_drv.h" #include "msm_mmu.h" @@ -1014,6 +1015,12 @@ static int dpu_bind(struct device *dev, struct device *master, void *data) if (!dpu_kms) return -ENOMEM; + dev_pm_opp_set_clkname(dev, "core"); + + ret = dev_pm_opp_of_add_table(dev); + if (ret) + dev_err(dev, "failed to init OPP table: %d\n", ret); + mp = &dpu_kms->mp; ret = msm_dss_parse_clock(pdev, mp); if (ret) { @@ -1040,6 +1047,7 @@ static void dpu_unbind(struct device *dev, struct device *master, void *data) struct dpu_kms *dpu_kms = platform_get_drvdata(pdev); struct dss_module_power *mp = &dpu_kms->mp; + dev_pm_opp_of_remove_table(dev); msm_dss_put_clk(mp->clk_config, mp->num_clk); devm_kfree(&pdev->dev, mp->clk_config); mp->num_clk = 0; @@ -1078,6 +1086,7 @@ static int __maybe_unused dpu_runtime_suspend(struct device *dev) return rc; } + 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); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation