* [PATCH 1/4] drm/msm/dpu: Use OPP API to set clk/perf state
2020-06-30 11:56 [PATCH 0/4] DVFS support for dpu and dsi Rajendra Nayak
@ 2020-06-30 11:56 ` Rajendra Nayak
2020-06-30 11:56 ` [PATCH 2/4] drm/msm: dsi: " Rajendra Nayak
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: Rajendra Nayak @ 2020-06-30 11:56 UTC (permalink / raw)
To: robdclark, sean, agross, bjorn.andersson
Cc: dri-devel, linux-arm-msm, devicetree, linux-kernel, mka, Rajendra Nayak
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>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 3 ++-
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 26 +++++++++++++++++++++++++-
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 4 ++++
3 files changed, 31 insertions(+), 2 deletions(-)
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 7c230f7..b36919d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -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)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index b8615d4..0bc8ec4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -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,23 @@ 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");
+ 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 +1056,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 +1075,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 +1104,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);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index a3b122b..7400cd7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -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
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/4] drm/msm: dsi: Use OPP API to set clk/perf state
2020-06-30 11:56 [PATCH 0/4] DVFS support for dpu and dsi Rajendra Nayak
2020-06-30 11:56 ` [PATCH 1/4] drm/msm/dpu: Use OPP API to set clk/perf state Rajendra Nayak
@ 2020-06-30 11:56 ` Rajendra Nayak
2020-07-01 16:27 ` Matthias Kaehlcke
2020-06-30 11:56 ` [PATCH 3/4] arm64: dts: sdm845: Add DSI and MDP OPP tables and power-domains Rajendra Nayak
2020-06-30 11:56 ` [PATCH 4/4] arm64: dts: sc7180: " Rajendra Nayak
3 siblings, 1 reply; 9+ messages in thread
From: Rajendra Nayak @ 2020-06-30 11:56 UTC (permalink / raw)
To: robdclark, sean, agross, bjorn.andersson
Cc: dri-devel, linux-arm-msm, devicetree, linux-kernel, mka, Rajendra Nayak
On SDM845 DSI needs to express a perforamnce 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>
---
drivers/gpu/drm/msm/dsi/dsi.h | 2 ++
drivers/gpu/drm/msm/dsi/dsi_cfg.c | 4 +--
drivers/gpu/drm/msm/dsi/dsi_host.c | 58 ++++++++++++++++++++++++++++++++++++++
3 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 4de771d..ba7583c 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -180,10 +180,12 @@ int msm_dsi_runtime_suspend(struct device *dev);
int msm_dsi_runtime_resume(struct device *dev);
int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host);
int dsi_link_clk_set_rate_v2(struct msm_dsi_host *msm_host);
+int dsi_link_clk_set_rate_6g_v2(struct msm_dsi_host *msm_host);
int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host);
int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host);
void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host);
void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host);
+void dsi_link_clk_disable_6g_v2(struct msm_dsi_host *msm_host);
int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size);
int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size);
void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index 813d69d..773c4fe 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -210,9 +210,9 @@ static const struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = {
};
static const struct msm_dsi_host_cfg_ops msm_dsi_6g_v2_host_ops = {
- .link_clk_set_rate = dsi_link_clk_set_rate_6g,
+ .link_clk_set_rate = dsi_link_clk_set_rate_6g_v2,
.link_clk_enable = dsi_link_clk_enable_6g,
- .link_clk_disable = dsi_link_clk_disable_6g,
+ .link_clk_disable = dsi_link_clk_disable_6g_v2,
.clk_init_ver = dsi_clk_init_6g_v2,
.tx_buf_alloc = dsi_tx_buf_alloc_6g,
.tx_buf_get = dsi_tx_buf_get_6g,
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 11ae5b8..890531c 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -14,6 +14,7 @@
#include <linux/of_graph.h>
#include <linux/of_irq.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/pm_opp.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/spinlock.h>
@@ -111,6 +112,9 @@ struct msm_dsi_host {
struct clk *pixel_clk_src;
struct clk *byte_intf_clk;
+ struct opp_table *opp_table;
+ bool has_opp_table;
+
u32 byte_clk_rate;
u32 pixel_clk_rate;
u32 esc_clk_rate;
@@ -537,6 +541,38 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
return 0;
}
+int dsi_link_clk_set_rate_6g_v2(struct msm_dsi_host *msm_host)
+{
+ int ret;
+ struct device *dev = &msm_host->pdev->dev;
+
+ DBG("Set clk rates: pclk=%d, byteclk=%d",
+ msm_host->mode->clock, msm_host->byte_clk_rate);
+
+ ret = dev_pm_opp_set_rate(dev, msm_host->byte_clk_rate);
+ if (ret) {
+ pr_err("%s: dev_pm_opp_set_rate failed %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = clk_set_rate(msm_host->pixel_clk, msm_host->pixel_clk_rate);
+ if (ret) {
+ pr_err("%s: Failed to set rate pixel clk, %d\n", __func__, ret);
+ return ret;
+ }
+
+ if (msm_host->byte_intf_clk) {
+ ret = clk_set_rate(msm_host->byte_intf_clk,
+ msm_host->byte_clk_rate / 2);
+ if (ret) {
+ pr_err("%s: Failed to set rate byte intf clk, %d\n",
+ __func__, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
{
@@ -665,6 +701,13 @@ void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host)
clk_disable_unprepare(msm_host->byte_clk);
}
+void dsi_link_clk_disable_6g_v2(struct msm_dsi_host *msm_host)
+{
+ /* Drop the performance state vote */
+ dev_pm_opp_set_rate(&msm_host->pdev->dev, 0);
+ dsi_link_clk_disable_6g(msm_host);
+}
+
void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host)
{
clk_disable_unprepare(msm_host->pixel_clk);
@@ -1879,6 +1922,18 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
goto fail;
}
+ msm_host->opp_table = dev_pm_opp_set_clkname(&pdev->dev, "byte");
+ if (IS_ERR(msm_host->opp_table))
+ return PTR_ERR(msm_host->opp_table);
+ /* OPP table is optional */
+ ret = dev_pm_opp_of_add_table(&pdev->dev);
+ if (!ret) {
+ msm_host->has_opp_table = true;
+ } else if (ret != -ENODEV) {
+ dev_err(&pdev->dev, "invalid OPP table in device tree\n");
+ return ret;
+ }
+
init_completion(&msm_host->dma_comp);
init_completion(&msm_host->video_comp);
mutex_init(&msm_host->dev_mutex);
@@ -1914,6 +1969,9 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host)
mutex_destroy(&msm_host->cmd_mutex);
mutex_destroy(&msm_host->dev_mutex);
+ if (msm_host->has_opp_table)
+ dev_pm_opp_of_remove_table(&msm_host->pdev->dev);
+ dev_pm_opp_put_clkname(msm_host->opp_table);
pm_runtime_disable(&msm_host->pdev->dev);
}
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/4] drm/msm: dsi: Use OPP API to set clk/perf state
2020-06-30 11:56 ` [PATCH 2/4] drm/msm: dsi: " Rajendra Nayak
@ 2020-07-01 16:27 ` Matthias Kaehlcke
2020-07-02 8:55 ` Rajendra Nayak
0 siblings, 1 reply; 9+ messages in thread
From: Matthias Kaehlcke @ 2020-07-01 16:27 UTC (permalink / raw)
To: Rajendra Nayak
Cc: robdclark, sean, agross, bjorn.andersson, dri-devel,
linux-arm-msm, devicetree, linux-kernel
On Tue, Jun 30, 2020 at 05:26:14PM +0530, Rajendra Nayak wrote:
> On SDM845 DSI needs to express a perforamnce state
nit: performance
> 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>
> ---
> drivers/gpu/drm/msm/dsi/dsi.h | 2 ++
> drivers/gpu/drm/msm/dsi/dsi_cfg.c | 4 +--
> drivers/gpu/drm/msm/dsi/dsi_host.c | 58 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 62 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
> index 4de771d..ba7583c 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi.h
> +++ b/drivers/gpu/drm/msm/dsi/dsi.h
> @@ -180,10 +180,12 @@ int msm_dsi_runtime_suspend(struct device *dev);
> int msm_dsi_runtime_resume(struct device *dev);
> int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host);
> int dsi_link_clk_set_rate_v2(struct msm_dsi_host *msm_host);
> +int dsi_link_clk_set_rate_6g_v2(struct msm_dsi_host *msm_host);
> int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host);
> int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host);
> void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host);
> void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host);
> +void dsi_link_clk_disable_6g_v2(struct msm_dsi_host *msm_host);
> int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size);
> int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size);
> void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host);
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
> index 813d69d..773c4fe 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
> @@ -210,9 +210,9 @@ static const struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = {
> };
>
> static const struct msm_dsi_host_cfg_ops msm_dsi_6g_v2_host_ops = {
> - .link_clk_set_rate = dsi_link_clk_set_rate_6g,
> + .link_clk_set_rate = dsi_link_clk_set_rate_6g_v2,
> .link_clk_enable = dsi_link_clk_enable_6g,
> - .link_clk_disable = dsi_link_clk_disable_6g,
> + .link_clk_disable = dsi_link_clk_disable_6g_v2,
> .clk_init_ver = dsi_clk_init_6g_v2,
> .tx_buf_alloc = dsi_tx_buf_alloc_6g,
> .tx_buf_get = dsi_tx_buf_get_6g,
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index 11ae5b8..890531c 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -14,6 +14,7 @@
> #include <linux/of_graph.h>
> #include <linux/of_irq.h>
> #include <linux/pinctrl/consumer.h>
> +#include <linux/pm_opp.h>
> #include <linux/regmap.h>
> #include <linux/regulator/consumer.h>
> #include <linux/spinlock.h>
> @@ -111,6 +112,9 @@ struct msm_dsi_host {
> struct clk *pixel_clk_src;
> struct clk *byte_intf_clk;
>
> + struct opp_table *opp_table;
> + bool has_opp_table;
> +
> u32 byte_clk_rate;
> u32 pixel_clk_rate;
> u32 esc_clk_rate;
> @@ -537,6 +541,38 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
> return 0;
> }
>
> +int dsi_link_clk_set_rate_6g_v2(struct msm_dsi_host *msm_host)
> +{
> + int ret;
> + struct device *dev = &msm_host->pdev->dev;
> +
> + DBG("Set clk rates: pclk=%d, byteclk=%d",
> + msm_host->mode->clock, msm_host->byte_clk_rate);
> +
> + ret = dev_pm_opp_set_rate(dev, msm_host->byte_clk_rate);
> + if (ret) {
> + pr_err("%s: dev_pm_opp_set_rate failed %d\n", __func__, ret);
> + return ret;
> + }
> +
> + ret = clk_set_rate(msm_host->pixel_clk, msm_host->pixel_clk_rate);
> + if (ret) {
> + pr_err("%s: Failed to set rate pixel clk, %d\n", __func__, ret);
> + return ret;
> + }
> +
> + if (msm_host->byte_intf_clk) {
> + ret = clk_set_rate(msm_host->byte_intf_clk,
> + msm_host->byte_clk_rate / 2);
> + if (ret) {
> + pr_err("%s: Failed to set rate byte intf clk, %d\n",
> + __func__, ret);
> + return ret;
> + }
> + }
> +
> + return 0;
> +}
xThis function is essentially the same as dsi_link_clk_set_rate_6g(),
except for the use of dev_pm_opp_set_rate() instead of clk_set_rate().
IIUC dev_pm_opp_set_rate() just calls clk_set_rate() if the device has
no OPP table. If that's correct you could just call dev_pm_opp_set_rate()
in dsi_link_clk_set_rate_6g().
/*
* For IO devices which require an OPP on some platforms/SoCs
* while just needing to scale the clock on some others
* we look for empty OPP tables with just a clock handle and
* scale only the clk. This makes dev_pm_opp_set_rate()
* equivalent to a clk_set_rate()
*/
if (!_get_opp_count(opp_table)) {
ret = _generic_set_opp_clk_only(dev, clk, freq);
goto put_opp_table;
}
https://elixir.bootlin.com/linux/v5.7.6/source/drivers/opp/core.c#L855
> int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
> {
> @@ -665,6 +701,13 @@ void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host)
> clk_disable_unprepare(msm_host->byte_clk);
> }
>
> +void dsi_link_clk_disable_6g_v2(struct msm_dsi_host *msm_host)
> +{
> + /* Drop the performance state vote */
> + dev_pm_opp_set_rate(&msm_host->pdev->dev, 0);
Couldn't you just do this in dsi_link_clk_disable_6g() ?
> + dsi_link_clk_disable_6g(msm_host);
> +}
> +
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/4] drm/msm: dsi: Use OPP API to set clk/perf state
2020-07-01 16:27 ` Matthias Kaehlcke
@ 2020-07-02 8:55 ` Rajendra Nayak
0 siblings, 0 replies; 9+ messages in thread
From: Rajendra Nayak @ 2020-07-02 8:55 UTC (permalink / raw)
To: Matthias Kaehlcke
Cc: robdclark, sean, agross, bjorn.andersson, dri-devel,
linux-arm-msm, devicetree, linux-kernel
On 7/1/2020 9:57 PM, Matthias Kaehlcke wrote:
> On Tue, Jun 30, 2020 at 05:26:14PM +0530, Rajendra Nayak wrote:
>> On SDM845 DSI needs to express a perforamnce state
>
> nit: performance
>
>> 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>
>> ---
>> drivers/gpu/drm/msm/dsi/dsi.h | 2 ++
>> drivers/gpu/drm/msm/dsi/dsi_cfg.c | 4 +--
>> drivers/gpu/drm/msm/dsi/dsi_host.c | 58 ++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 62 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
>> index 4de771d..ba7583c 100644
>> --- a/drivers/gpu/drm/msm/dsi/dsi.h
>> +++ b/drivers/gpu/drm/msm/dsi/dsi.h
>> @@ -180,10 +180,12 @@ int msm_dsi_runtime_suspend(struct device *dev);
>> int msm_dsi_runtime_resume(struct device *dev);
>> int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host);
>> int dsi_link_clk_set_rate_v2(struct msm_dsi_host *msm_host);
>> +int dsi_link_clk_set_rate_6g_v2(struct msm_dsi_host *msm_host);
>> int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host);
>> int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host);
>> void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host);
>> void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host);
>> +void dsi_link_clk_disable_6g_v2(struct msm_dsi_host *msm_host);
>> int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size);
>> int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size);
>> void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host);
>> diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
>> index 813d69d..773c4fe 100644
>> --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
>> +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
>> @@ -210,9 +210,9 @@ static const struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = {
>> };
>>
>> static const struct msm_dsi_host_cfg_ops msm_dsi_6g_v2_host_ops = {
>> - .link_clk_set_rate = dsi_link_clk_set_rate_6g,
>> + .link_clk_set_rate = dsi_link_clk_set_rate_6g_v2,
>> .link_clk_enable = dsi_link_clk_enable_6g,
>> - .link_clk_disable = dsi_link_clk_disable_6g,
>> + .link_clk_disable = dsi_link_clk_disable_6g_v2,
>> .clk_init_ver = dsi_clk_init_6g_v2,
>> .tx_buf_alloc = dsi_tx_buf_alloc_6g,
>> .tx_buf_get = dsi_tx_buf_get_6g,
>> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
>> index 11ae5b8..890531c 100644
>> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
>> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
>> @@ -14,6 +14,7 @@
>> #include <linux/of_graph.h>
>> #include <linux/of_irq.h>
>> #include <linux/pinctrl/consumer.h>
>> +#include <linux/pm_opp.h>
>> #include <linux/regmap.h>
>> #include <linux/regulator/consumer.h>
>> #include <linux/spinlock.h>
>> @@ -111,6 +112,9 @@ struct msm_dsi_host {
>> struct clk *pixel_clk_src;
>> struct clk *byte_intf_clk;
>>
>> + struct opp_table *opp_table;
>> + bool has_opp_table;
>> +
>> u32 byte_clk_rate;
>> u32 pixel_clk_rate;
>> u32 esc_clk_rate;
>> @@ -537,6 +541,38 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
>> return 0;
>> }
>>
>> +int dsi_link_clk_set_rate_6g_v2(struct msm_dsi_host *msm_host)
>> +{
>> + int ret;
>> + struct device *dev = &msm_host->pdev->dev;
>> +
>> + DBG("Set clk rates: pclk=%d, byteclk=%d",
>> + msm_host->mode->clock, msm_host->byte_clk_rate);
>> +
>> + ret = dev_pm_opp_set_rate(dev, msm_host->byte_clk_rate);
>> + if (ret) {
>> + pr_err("%s: dev_pm_opp_set_rate failed %d\n", __func__, ret);
>> + return ret;
>> + }
>> +
>> + ret = clk_set_rate(msm_host->pixel_clk, msm_host->pixel_clk_rate);
>> + if (ret) {
>> + pr_err("%s: Failed to set rate pixel clk, %d\n", __func__, ret);
>> + return ret;
>> + }
>> +
>> + if (msm_host->byte_intf_clk) {
>> + ret = clk_set_rate(msm_host->byte_intf_clk,
>> + msm_host->byte_clk_rate / 2);
>> + if (ret) {
>> + pr_err("%s: Failed to set rate byte intf clk, %d\n",
>> + __func__, ret);
>> + return ret;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>
> xThis function is essentially the same as dsi_link_clk_set_rate_6g(),
> except for the use of dev_pm_opp_set_rate() instead of clk_set_rate().
>
> IIUC dev_pm_opp_set_rate() just calls clk_set_rate() if the device has
> no OPP table. If that's correct you could just call dev_pm_opp_set_rate()
> in dsi_link_clk_set_rate_6g().
>
> /*
> * For IO devices which require an OPP on some platforms/SoCs
> * while just needing to scale the clock on some others
> * we look for empty OPP tables with just a clock handle and
> * scale only the clk. This makes dev_pm_opp_set_rate()
> * equivalent to a clk_set_rate()
> */
> if (!_get_opp_count(opp_table)) {
> ret = _generic_set_opp_clk_only(dev, clk, freq);
> goto put_opp_table;
> }
ah, thats right, I think I had this code from before that support got
added to dev_pm_opp_set_rate() and I just did not update this driver to
make use of it. Thanks for catching it, I will fix it up and repost soon.
>
> https://elixir.bootlin.com/linux/v5.7.6/source/drivers/opp/core.c#L855
>
>> int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
>> {
>> @@ -665,6 +701,13 @@ void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host)
>> clk_disable_unprepare(msm_host->byte_clk);
>> }
>>
>> +void dsi_link_clk_disable_6g_v2(struct msm_dsi_host *msm_host)
>> +{
>> + /* Drop the performance state vote */
>> + dev_pm_opp_set_rate(&msm_host->pdev->dev, 0);
>
> Couldn't you just do this in dsi_link_clk_disable_6g() ?
yes, looks like I can, I'll get rid of both of these additional functions.
thanks,
Rajendra
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/4] arm64: dts: sdm845: Add DSI and MDP OPP tables and power-domains
2020-06-30 11:56 [PATCH 0/4] DVFS support for dpu and dsi Rajendra Nayak
2020-06-30 11:56 ` [PATCH 1/4] drm/msm/dpu: Use OPP API to set clk/perf state Rajendra Nayak
2020-06-30 11:56 ` [PATCH 2/4] drm/msm: dsi: " Rajendra Nayak
@ 2020-06-30 11:56 ` Rajendra Nayak
2020-07-01 15:06 ` Matthias Kaehlcke
2020-06-30 11:56 ` [PATCH 4/4] arm64: dts: sc7180: " Rajendra Nayak
3 siblings, 1 reply; 9+ messages in thread
From: Rajendra Nayak @ 2020-06-30 11:56 UTC (permalink / raw)
To: robdclark, sean, agross, bjorn.andersson
Cc: dri-devel, linux-arm-msm, devicetree, linux-kernel, mka, Rajendra Nayak
Add the OPP tables for DSI and MDP based on the perf state/clk
requirements, and add the power-domains property to specify the
scalable power domain.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
arch/arm64/boot/dts/qcom/sdm845.dtsi | 59 ++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 8eb5a31..b6afeb2 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -3296,6 +3296,35 @@
#power-domain-cells = <1>;
};
+ dsi_opp_table: dsi-opp-table {
+ compatible = "operating-points-v2";
+
+ opp-19200000 {
+ opp-hz = /bits/ 64 <19200000>;
+ required-opps = <&rpmhpd_opp_min_svs>;
+ };
+
+ opp-180000000 {
+ opp-hz = /bits/ 64 <180000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-275000000 {
+ opp-hz = /bits/ 64 <275000000>;
+ required-opps = <&rpmhpd_opp_svs>;
+ };
+
+ opp-328580000 {
+ opp-hz = /bits/ 64 <328580000>;
+ required-opps = <&rpmhpd_opp_svs_l1>;
+ };
+
+ opp-358000000 {
+ opp-hz = /bits/ 64 <358000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+ };
+
mdss: mdss@ae00000 {
compatible = "qcom,sdm845-mdss";
reg = <0 0x0ae00000 0 0x1000>;
@@ -3340,6 +3369,8 @@
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
assigned-clock-rates = <300000000>,
<19200000>;
+ operating-points-v2 = <&mdp_opp_table>;
+ power-domains = <&rpmhpd SDM845_CX>;
interrupt-parent = <&mdss>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
@@ -3364,6 +3395,30 @@
};
};
};
+
+ mdp_opp_table: mdp-opp-table {
+ compatible = "operating-points-v2";
+
+ opp-19200000 {
+ opp-hz = /bits/ 64 <19200000>;
+ required-opps = <&rpmhpd_opp_min_svs>;
+ };
+
+ opp-171428571 {
+ opp-hz = /bits/ 64 <171428571>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-344000000 {
+ opp-hz = /bits/ 64 <344000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>;
+ };
+
+ opp-430000000 {
+ opp-hz = /bits/ 64 <430000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+ };
};
dsi0: dsi@ae94000 {
@@ -3386,6 +3441,8 @@
"core",
"iface",
"bus";
+ operating-points-v2 = <&dsi_opp_table>;
+ power-domains = <&rpmhpd SDM845_CX>;
phys = <&dsi0_phy>;
phy-names = "dsi";
@@ -3450,6 +3507,8 @@
"core",
"iface",
"bus";
+ operating-points-v2 = <&dsi_opp_table>;
+ power-domains = <&rpmhpd SDM845_CX>;
phys = <&dsi1_phy>;
phy-names = "dsi";
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 3/4] arm64: dts: sdm845: Add DSI and MDP OPP tables and power-domains
2020-06-30 11:56 ` [PATCH 3/4] arm64: dts: sdm845: Add DSI and MDP OPP tables and power-domains Rajendra Nayak
@ 2020-07-01 15:06 ` Matthias Kaehlcke
0 siblings, 0 replies; 9+ messages in thread
From: Matthias Kaehlcke @ 2020-07-01 15:06 UTC (permalink / raw)
To: Rajendra Nayak
Cc: robdclark, sean, agross, bjorn.andersson, dri-devel,
linux-arm-msm, devicetree, linux-kernel
On Tue, Jun 30, 2020 at 05:26:15PM +0530, Rajendra Nayak wrote:
> Add the OPP tables for DSI and MDP based on the perf state/clk
> requirements, and add the power-domains property to specify the
> scalable power domain.
>
> Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
> ---
> arch/arm64/boot/dts/qcom/sdm845.dtsi | 59 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 59 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> index 8eb5a31..b6afeb2 100644
> --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> @@ -3296,6 +3296,35 @@
> #power-domain-cells = <1>;
> };
>
> + dsi_opp_table: dsi-opp-table {
> + compatible = "operating-points-v2";
> +
> + opp-19200000 {
> + opp-hz = /bits/ 64 <19200000>;
> + required-opps = <&rpmhpd_opp_min_svs>;
> + };
> +
> + opp-180000000 {
> + opp-hz = /bits/ 64 <180000000>;
> + required-opps = <&rpmhpd_opp_low_svs>;
> + };
> +
> + opp-275000000 {
> + opp-hz = /bits/ 64 <275000000>;
> + required-opps = <&rpmhpd_opp_svs>;
> + };
> +
> + opp-328580000 {
> + opp-hz = /bits/ 64 <328580000>;
> + required-opps = <&rpmhpd_opp_svs_l1>;
> + };
> +
> + opp-358000000 {
> + opp-hz = /bits/ 64 <358000000>;
> + required-opps = <&rpmhpd_opp_nom>;
> + };
> + };
> +
I still don't like the shared OPP tables to be positioned inmidst of the
device nodes, but it seems we currently don't have a better convention.
> mdss: mdss@ae00000 {
> compatible = "qcom,sdm845-mdss";
> reg = <0 0x0ae00000 0 0x1000>;
> @@ -3340,6 +3369,8 @@
> <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
> assigned-clock-rates = <300000000>,
> <19200000>;
> + operating-points-v2 = <&mdp_opp_table>;
> + power-domains = <&rpmhpd SDM845_CX>;
>
> interrupt-parent = <&mdss>;
> interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
> @@ -3364,6 +3395,30 @@
> };
> };
> };
> +
> + mdp_opp_table: mdp-opp-table {
> + compatible = "operating-points-v2";
> +
> + opp-19200000 {
> + opp-hz = /bits/ 64 <19200000>;
> + required-opps = <&rpmhpd_opp_min_svs>;
> + };
> +
> + opp-171428571 {
> + opp-hz = /bits/ 64 <171428571>;
> + required-opps = <&rpmhpd_opp_low_svs>;
> + };
> +
> + opp-344000000 {
> + opp-hz = /bits/ 64 <344000000>;
> + required-opps = <&rpmhpd_opp_svs_l1>;
> + };
> +
> + opp-430000000 {
> + opp-hz = /bits/ 64 <430000000>;
> + required-opps = <&rpmhpd_opp_nom>;
> + };
> + };
> };
>
> dsi0: dsi@ae94000 {
> @@ -3386,6 +3441,8 @@
> "core",
> "iface",
> "bus";
> + operating-points-v2 = <&dsi_opp_table>;
> + power-domains = <&rpmhpd SDM845_CX>;
>
> phys = <&dsi0_phy>;
> phy-names = "dsi";
> @@ -3450,6 +3507,8 @@
> "core",
> "iface",
> "bus";
> + operating-points-v2 = <&dsi_opp_table>;
> + power-domains = <&rpmhpd SDM845_CX>;
>
> phys = <&dsi1_phy>;
> phy-names = "dsi";
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/4] arm64: dts: sc7180: Add DSI and MDP OPP tables and power-domains
2020-06-30 11:56 [PATCH 0/4] DVFS support for dpu and dsi Rajendra Nayak
` (2 preceding siblings ...)
2020-06-30 11:56 ` [PATCH 3/4] arm64: dts: sdm845: Add DSI and MDP OPP tables and power-domains Rajendra Nayak
@ 2020-06-30 11:56 ` Rajendra Nayak
2020-07-01 15:08 ` Matthias Kaehlcke
3 siblings, 1 reply; 9+ messages in thread
From: Rajendra Nayak @ 2020-06-30 11:56 UTC (permalink / raw)
To: robdclark, sean, agross, bjorn.andersson
Cc: dri-devel, linux-arm-msm, devicetree, linux-kernel, mka, Rajendra Nayak
Add the OPP tables for DSI and MDP based on the perf state/clk
requirements, and add the power-domains property to specify the
scalable power domain.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
arch/arm64/boot/dts/qcom/sc7180.dtsi | 49 ++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index ad57df2..3430c33f 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -2482,6 +2482,8 @@
<19200000>,
<19200000>,
<19200000>;
+ operating-points-v2 = <&mdp_opp_table>;
+ power-domains = <&rpmhpd SC7180_CX>;
interrupt-parent = <&mdss>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
@@ -2499,6 +2501,31 @@
};
};
};
+
+ mdp_opp_table: mdp-opp-table {
+ compatible = "operating-points-v2";
+
+ opp-200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ required-opps = <&rpmhpd_opp_svs>;
+ };
+
+ opp-345000000 {
+ opp-hz = /bits/ 64 <345000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>;
+ };
+
+ opp-460000000 {
+ opp-hz = /bits/ 64 <460000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+ };
+
};
dsi0: dsi@ae94000 {
@@ -2522,6 +2549,9 @@
"iface",
"bus";
+ operating-points-v2 = <&dsi_opp_table>;
+ power-domains = <&rpmhpd SC7180_CX>;
+
phys = <&dsi_phy>;
phy-names = "dsi";
@@ -2547,6 +2577,25 @@
};
};
};
+
+ dsi_opp_table: dsi-opp-table {
+ compatible = "operating-points-v2";
+
+ opp-187500000 {
+ opp-hz = /bits/ 64 <187500000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ required-opps = <&rpmhpd_opp_svs>;
+ };
+
+ opp-358000000 {
+ opp-hz = /bits/ 64 <358000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>;
+ };
+ };
};
dsi_phy: dsi-phy@ae94400 {
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 4/4] arm64: dts: sc7180: Add DSI and MDP OPP tables and power-domains
2020-06-30 11:56 ` [PATCH 4/4] arm64: dts: sc7180: " Rajendra Nayak
@ 2020-07-01 15:08 ` Matthias Kaehlcke
0 siblings, 0 replies; 9+ messages in thread
From: Matthias Kaehlcke @ 2020-07-01 15:08 UTC (permalink / raw)
To: Rajendra Nayak
Cc: robdclark, sean, agross, bjorn.andersson, dri-devel,
linux-arm-msm, devicetree, linux-kernel
On Tue, Jun 30, 2020 at 05:26:16PM +0530, Rajendra Nayak wrote:
> Add the OPP tables for DSI and MDP based on the perf state/clk
> requirements, and add the power-domains property to specify the
> scalable power domain.
>
> Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
^ permalink raw reply [flat|nested] 9+ messages in thread