summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDhaval Patel <pdhaval@codeaurora.org>2018-05-04 10:08:05 -0700
committerDhaval Patel <pdhaval@codeaurora.org>2019-04-24 13:27:48 -0700
commita74d2cf7fa2f7ae79df54ee1a8f20de8e550d097 (patch)
tree4525cf583c9dbe120a91ba313773ea58282ff506
parenta702cd897f3c0e114138c11525529df3ef0dd05c (diff)
downloaddisplay-drivers-a74d2cf7fa2f7ae79df54ee1a8f20de8e550d097.tar.gz
disp: msm: add runtime_pm ops support in drm driver
Add runtime_pm ops support in drm driver instead of direct sde_power_resource_enable/disable call. It allows drm driver to use runtime pm refcount logic to track the resources instead of custom implementation. The change also removes the NRT_CLIENT support from sde_power_handle code to simplify it further. Change-Id: Ib14692dca5876703d0a230da2512d731b69b8ebb Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
-rw-r--r--msm/dp/dp_display.c3
-rw-r--r--msm/dp/dp_power.c41
-rw-r--r--msm/dp/dp_power.h5
-rw-r--r--msm/dsi/dsi_clk.h8
-rw-r--r--msm/dsi/dsi_clk_manager.c29
-rw-r--r--msm/dsi/dsi_display.c39
-rw-r--r--msm/dsi/dsi_display.h3
-rw-r--r--msm/msm_drv.c43
-rw-r--r--msm/msm_drv.h1
-rw-r--r--msm/sde/sde_color_processing.c19
-rw-r--r--msm/sde/sde_core_irq.c38
-rw-r--r--msm/sde/sde_core_perf.c21
-rw-r--r--msm/sde/sde_core_perf.h4
-rw-r--r--msm/sde/sde_crtc.c66
-rw-r--r--msm/sde/sde_crtc.h7
-rw-r--r--msm/sde/sde_encoder.c66
-rw-r--r--msm/sde/sde_kms.c108
-rw-r--r--msm/sde/sde_kms.h10
-rw-r--r--msm/sde/sde_plane.c48
-rw-r--r--msm/sde/sde_trace.h9
-rw-r--r--msm/sde_dbg.c54
-rw-r--r--msm/sde_dbg.h4
-rw-r--r--msm/sde_power_handle.c411
-rw-r--r--msm/sde_power_handle.h75
-rw-r--r--msm/sde_rsc.c162
-rw-r--r--msm/sde_rsc_priv.h4
26 files changed, 322 insertions, 956 deletions
diff --git a/msm/dp/dp_display.c b/msm/dp/dp_display.c
index 8ac7f46c..5387a1dc 100644
--- a/msm/dp/dp_display.c
+++ b/msm/dp/dp_display.c
@@ -1213,7 +1213,8 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
goto error_power;
}
- rc = dp->power->power_client_init(dp->power, &dp->priv->phandle);
+ rc = dp->power->power_client_init(dp->power, &dp->priv->phandle,
+ dp->dp_display.drm_dev);
if (rc) {
pr_err("Power client create failed\n");
goto error_aux;
diff --git a/msm/dp/dp_power.c b/msm/dp/dp_power.c
index deb9a1af..a7bc5837 100644
--- a/msm/dp/dp_power.c
+++ b/msm/dp/dp_power.c
@@ -6,6 +6,8 @@
#define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__
#include <linux/clk.h>
+#include <linux/pm_runtime.h>
+#include <drm/drmP.h>
#include "dp_power.h"
#include "dp_catalog.h"
@@ -20,8 +22,6 @@ struct dp_power_private {
struct clk *pixel1_parent;
struct dp_power dp_power;
- struct sde_power_client *dp_core_client;
- struct sde_power_handle *phandle;
bool core_clks_on;
bool link_clks_on;
@@ -458,14 +458,13 @@ static int dp_power_config_gpios(struct dp_power_private *power, bool flip,
}
static int dp_power_client_init(struct dp_power *dp_power,
- struct sde_power_handle *phandle)
+ struct sde_power_handle *phandle, struct drm_device *drm_dev)
{
int rc = 0;
struct dp_power_private *power;
- char dp_client_name[DP_CLIENT_NAME_SIZE];
- if (!dp_power) {
- pr_err("invalid power data\n");
+ if (!drm_dev) {
+ pr_err("invalid drm_dev\n");
return -EINVAL;
}
@@ -482,20 +481,11 @@ static int dp_power_client_init(struct dp_power *dp_power,
pr_err("failed to init clocks\n");
goto error_clk;
}
+ dp_power->phandle = phandle;
+ dp_power->drm_dev = drm_dev;
- power->phandle = phandle;
- snprintf(dp_client_name, DP_CLIENT_NAME_SIZE, "dp_core_client");
- power->dp_core_client = sde_power_client_create(phandle,
- dp_client_name);
- if (IS_ERR_OR_NULL(power->dp_core_client)) {
- pr_err("[%s] client creation failed for DP\n", dp_client_name);
- rc = -EINVAL;
- goto error_client;
- }
return 0;
-error_client:
- dp_power_clk_init(power, false);
error_clk:
dp_power_regulator_deinit(power);
error_power:
@@ -513,7 +503,6 @@ static void dp_power_client_deinit(struct dp_power *dp_power)
power = container_of(dp_power, struct dp_power_private, dp_power);
- sde_power_client_destroy(power->phandle, power->dp_core_client);
dp_power_clk_init(power, false);
dp_power_regulator_deinit(power);
}
@@ -559,7 +548,7 @@ static u64 dp_power_clk_get_rate(struct dp_power *dp_power, char *clk_name)
}
power = container_of(dp_power, struct dp_power_private, dp_power);
- mp = &power->phandle->mp;
+ mp = &dp_power->phandle->mp;
for (i = 0; i < mp->num_clk; i++) {
if (!strcmp(mp->clk_config[i].clk_name, clk_name)) {
rate = clk_get_rate(mp->clk_config[i].clk);
@@ -613,9 +602,8 @@ static int dp_power_init(struct dp_power *dp_power, bool flip)
goto err_gpio;
}
- rc = sde_power_resource_enable(power->phandle,
- power->dp_core_client, true);
- if (rc) {
+ rc = pm_runtime_get_sync(dp_power->drm_dev->dev);
+ if (rc < 0) {
pr_err("Power resource enable failed\n");
goto err_sde_power;
}
@@ -629,7 +617,7 @@ static int dp_power_init(struct dp_power *dp_power, bool flip)
return 0;
err_clk:
- sde_power_resource_enable(power->phandle, power->dp_core_client, false);
+ pm_runtime_put_sync(dp_power->drm_dev->dev);
err_sde_power:
dp_power_config_gpios(power, flip, false);
err_gpio:
@@ -657,13 +645,8 @@ static int dp_power_deinit(struct dp_power *dp_power)
dp_power_clk_enable(dp_power, DP_LINK_PM, false);
dp_power_clk_enable(dp_power, DP_CORE_PM, false);
+ pm_runtime_put_sync(dp_power->drm_dev->dev);
- rc = sde_power_resource_enable(power->phandle,
- power->dp_core_client, false);
- if (rc) {
- pr_err("Power resource disable failed, rc=%d\n", rc);
- goto exit;
- }
dp_power_config_gpios(power, false, false);
dp_power_pinctrl_set(power, false);
dp_power_regulator_ctrl(power, false);
diff --git a/msm/dp/dp_power.h b/msm/dp/dp_power.h
index bd581664..a5e5f5d9 100644
--- a/msm/dp/dp_power.h
+++ b/msm/dp/dp_power.h
@@ -19,6 +19,8 @@
* @clk_get_rate: get the current rate for provided clk_name
*/
struct dp_power {
+ struct drm_device *drm_dev;
+ struct sde_power_handle *phandle;
int (*init)(struct dp_power *power, bool flip);
int (*deinit)(struct dp_power *power);
int (*clk_enable)(struct dp_power *power, enum dp_pm_type pm_type,
@@ -26,7 +28,8 @@ struct dp_power {
int (*set_pixel_clk_parent)(struct dp_power *power, u32 stream_id);
u64 (*clk_get_rate)(struct dp_power *power, char *clk_name);
int (*power_client_init)(struct dp_power *power,
- struct sde_power_handle *phandle);
+ struct sde_power_handle *phandle,
+ struct drm_device *drm_dev);
void (*power_client_deinit)(struct dp_power *power);
};
diff --git a/msm/dsi/dsi_clk.h b/msm/dsi/dsi_clk.h
index db2e838a..a5b485b4 100644
--- a/msm/dsi/dsi_clk.h
+++ b/msm/dsi/dsi_clk.h
@@ -10,7 +10,7 @@
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/clk.h>
-#include "sde_power_handle.h"
+#include <drm/drmP.h>
#define MAX_STRING_LEN 32
#define MAX_DSI_CTRL 2
@@ -72,8 +72,7 @@ struct clk_ctrl_cb {
* @core_mmss_clk: Handle to MMSS core clock.
* @bus_clk: Handle to bus clock.
* @mnoc_clk: Handle to MMSS NOC clock.
- * @dsi_core_client: Pointer to SDE power client
- * @phandle: Pointer to SDE power handle
+ * @drm: Pointer to drm device node
*/
struct dsi_core_clk_info {
struct clk *mdp_core_clk;
@@ -81,8 +80,7 @@ struct dsi_core_clk_info {
struct clk *core_mmss_clk;
struct clk *bus_clk;
struct clk *mnoc_clk;
- struct sde_power_client *dsi_core_client;
- struct sde_power_handle *phandle;
+ struct drm_device *drm;
};
/**
diff --git a/msm/dsi/dsi_clk_manager.c b/msm/dsi/dsi_clk_manager.c
index 9a35c7ac..47881f10 100644
--- a/msm/dsi/dsi_clk_manager.c
+++ b/msm/dsi/dsi_clk_manager.c
@@ -7,6 +7,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/msm-bus.h>
+#include <linux/pm_runtime.h>
#include "dsi_clk.h"
struct dsi_core_clks {
@@ -554,10 +555,9 @@ static int dsi_display_core_clk_enable(struct dsi_core_clks *clks,
*/
m_clks = &clks[master_ndx];
- rc = sde_power_resource_enable(m_clks->clks.phandle,
- m_clks->clks.dsi_core_client, true);
- if (rc) {
+ rc = pm_runtime_get_sync(m_clks->clks.drm->dev);
+ if (rc < 0) {
pr_err("Power resource enable failed, rc=%d\n", rc);
goto error;
}
@@ -574,9 +574,8 @@ static int dsi_display_core_clk_enable(struct dsi_core_clks *clks,
if (!clk || (clk == m_clks))
continue;
- rc = sde_power_resource_enable(clk->clks.phandle,
- clk->clks.dsi_core_client, true);
- if (rc) {
+ rc = pm_runtime_get_sync(m_clks->clks.drm->dev);
+ if (rc < 0) {
pr_err("Power resource enable failed, rc=%d\n", rc);
goto error_disable_master;
}
@@ -584,8 +583,7 @@ static int dsi_display_core_clk_enable(struct dsi_core_clks *clks,
rc = dsi_core_clk_start(clk);
if (rc) {
pr_err("failed to turn on clocks, rc=%d\n", rc);
- (void)sde_power_resource_enable(clk->clks.phandle,
- clk->clks.dsi_core_client, false);
+ pm_runtime_put_sync(m_clks->clks.drm->dev);
goto error_disable_master;
}
}
@@ -594,8 +592,7 @@ error_disable_master:
(void)dsi_core_clk_stop(m_clks);
error_disable_master_resource:
- (void)sde_power_resource_enable(m_clks->clks.phandle,
- m_clks->clks.dsi_core_client, false);
+ pm_runtime_put_sync(m_clks->clks.drm->dev);
error:
return rc;
}
@@ -697,12 +694,7 @@ static int dsi_display_core_clk_disable(struct dsi_core_clks *clks,
goto error;
}
- rc = sde_power_resource_enable(clk->clks.phandle,
- clk->clks.dsi_core_client, false);
- if (rc) {
- pr_err("Power resource disable failed: %d\n", rc);
- goto error;
- }
+ pm_runtime_put_sync(m_clks->clks.drm->dev);
}
rc = dsi_core_clk_stop(m_clks);
@@ -711,10 +703,7 @@ static int dsi_display_core_clk_disable(struct dsi_core_clks *clks,
goto error;
}
- rc = sde_power_resource_enable(m_clks->clks.phandle,
- m_clks->clks.dsi_core_client, false);
- if (rc)
- pr_err("Power resource disable failed: %d\n", rc);
+ pm_runtime_put_sync(m_clks->clks.drm->dev);
error:
return rc;
}
diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c
index 0c1bfaae..e97442f7 100644
--- a/msm/dsi/dsi_display.c
+++ b/msm/dsi/dsi_display.c
@@ -4105,20 +4105,15 @@ int dsi_display_cont_splash_config(void *dsi_display)
return -EINVAL;
}
- mutex_lock(&display->display_lock);
-
- /* Vote for gdsc required to read register address space */
- display->cont_splash_client = sde_power_client_create(display->phandle,
- "cont_splash_client");
- rc = sde_power_resource_enable(display->phandle,
- display->cont_splash_client, true);
- if (rc) {
+ rc = pm_runtime_get_sync(display->drm_dev->dev);
+ if (rc < 0) {
pr_err("failed to vote gdsc for continuous splash, rc=%d\n",
rc);
- mutex_unlock(&display->display_lock);
- return -EINVAL;
+ return rc;
}
+ mutex_lock(&display->display_lock);
+
/* Verify whether continuous splash is enabled or not */
display->is_cont_splash_enabled =
dsi_display_get_cont_splash_status(display);
@@ -4172,8 +4167,7 @@ clk_manager_update:
false);
splash_disabled:
- (void)sde_power_resource_enable(display->phandle,
- display->cont_splash_client, false);
+ pm_runtime_put_sync(display->drm_dev->dev);
display->is_cont_splash_enabled = false;
mutex_unlock(&display->display_lock);
return rc;
@@ -4197,11 +4191,7 @@ int dsi_display_splash_res_cleanup(struct dsi_display *display)
pr_err("[%s] failed to disable DSI link clocks, rc=%d\n",
display->name, rc);
- rc = sde_power_resource_enable(display->phandle,
- display->cont_splash_client, false);
- if (rc)
- pr_err("failed to remove vote on gdsc for continuous splash, rc=%d\n",
- rc);
+ pm_runtime_put_sync(display->drm_dev->dev);
display->is_cont_splash_enabled = false;
/* Update splash status for clock manager */
@@ -4448,12 +4438,10 @@ static int dsi_display_bind(struct device *dev,
struct dsi_display *display;
struct dsi_clk_info info;
struct clk_ctrl_cb clk_cb;
- struct msm_drm_private *priv;
void *handle = NULL;
struct platform_device *pdev = to_platform_device(dev);
char *client1 = "dsi_clk_client";
char *client2 = "mdp_event_client";
- char dsi_client_name[DSI_CLIENT_NAME_SIZE];
int i, rc = 0;
if (!dev || !pdev || !master) {
@@ -4469,7 +4457,6 @@ static int dsi_display_bind(struct device *dev,
drm, display);
return -EINVAL;
}
- priv = drm->dev_private;
if (!display->panel_node)
return 0;
@@ -4522,22 +4509,12 @@ static int dsi_display_bind(struct device *dev,
(&display_ctrl->ctrl->clk_info.lp_link_clks),
sizeof(struct dsi_link_lp_clk_info));
- info.c_clks[i].phandle = &priv->phandle;
+ info.c_clks[i].drm = drm;
info.bus_handle[i] =
display_ctrl->ctrl->axi_bus_info.bus_handle;
info.ctrl_index[i] = display_ctrl->ctrl->cell_index;
- snprintf(dsi_client_name, DSI_CLIENT_NAME_SIZE,
- "dsi_core_client%u", i);
- info.c_clks[i].dsi_core_client = sde_power_client_create(
- info.c_clks[i].phandle, dsi_client_name);
- if (IS_ERR_OR_NULL(info.c_clks[i].dsi_core_client)) {
- pr_err("[%s] client creation failed for ctrl[%d]\n",
- dsi_client_name, i);
- goto error_ctrl_deinit;
- }
}
- display->phandle = &priv->phandle;
info.pre_clkoff_cb = dsi_pre_clkoff_cb;
info.pre_clkon_cb = dsi_pre_clkon_cb;
info.post_clkoff_cb = dsi_post_clkoff_cb;
diff --git a/msm/dsi/dsi_display.h b/msm/dsi/dsi_display.h
index 8162fc88..1c9fd5bf 100644
--- a/msm/dsi/dsi_display.h
+++ b/msm/dsi/dsi_display.h
@@ -239,9 +239,6 @@ struct dsi_display {
struct dsi_bridge *bridge;
u32 cmd_engine_refcount;
- struct sde_power_handle *phandle;
- struct sde_power_client *cont_splash_client;
-
void *clk_mngr;
void *dsi_clk_handle;
void *mdp_clk_handle;
diff --git a/msm/msm_drv.c b/msm/msm_drv.c
index 3b014aa9..671559ca 100644
--- a/msm/msm_drv.c
+++ b/msm/msm_drv.c
@@ -401,7 +401,6 @@ static int msm_drm_uninit(struct device *dev)
sde_dbg_destroy();
debugfs_remove_recursive(priv->debug_root);
- sde_power_client_destroy(&priv->phandle, priv->pclient);
sde_power_resource_deinit(pdev, &priv->phandle);
msm_mdss_destroy(ddev);
@@ -535,11 +534,6 @@ static int msm_component_bind_all(struct device *dev,
}
#endif
-static int msm_power_enable_wrapper(void *handle, void *client, bool enable)
-{
- return sde_power_resource_enable(handle, client, enable);
-}
-
static int msm_drm_display_thread_create(struct sched_param param,
struct msm_drm_private *priv, struct drm_device *ddev,
struct device *dev)
@@ -703,7 +697,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
struct drm_device *ddev;
struct msm_drm_private *priv;
struct msm_kms *kms = NULL;
- struct sde_dbg_power_ctrl dbg_power_ctrl = { 0 };
int ret;
struct sched_param param = { 0 };
@@ -741,17 +734,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
goto power_init_fail;
}
- priv->pclient = sde_power_client_create(&priv->phandle, "sde");
- if (IS_ERR_OR_NULL(priv->pclient)) {
- pr_err("sde power client create failed\n");
- ret = -EINVAL;
- goto power_client_fail;
- }
-
- dbg_power_ctrl.handle = &priv->phandle;
- dbg_power_ctrl.client = priv->pclient;
- dbg_power_ctrl.enable_fn = msm_power_enable_wrapper;
- ret = sde_dbg_init(&pdev->dev, &dbg_power_ctrl);
+ ret = sde_dbg_init(&pdev->dev);
if (ret) {
dev_err(dev, "failed to init sde dbg: %d\n", ret);
goto dbg_init_fail;
@@ -851,8 +834,6 @@ fail:
bind_fail:
sde_dbg_destroy();
dbg_init_fail:
- sde_power_client_destroy(&priv->phandle, priv->pclient);
-power_client_fail:
sde_power_resource_deinit(pdev, &priv->phandle);
power_init_fail:
msm_mdss_destroy(ddev);
@@ -927,8 +908,7 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file)
mutex_lock(&ctx->power_lock);
if (ctx->enable_refcnt) {
SDE_EVT32(ctx->enable_refcnt);
- sde_power_resource_enable(&priv->phandle,
- priv->pclient, false);
+ pm_runtime_put_sync(dev->dev);
}
mutex_unlock(&ctx->power_lock);
@@ -1602,10 +1582,12 @@ int msm_ioctl_power_ctrl(struct drm_device *dev, void *data,
}
if (vote_req) {
- rc = sde_power_resource_enable(&priv->phandle,
- priv->pclient, power_ctrl->enable);
+ if (power_ctrl->enable)
+ rc = pm_runtime_get_sync(dev->dev);
+ else
+ pm_runtime_put_sync(dev->dev);
- if (rc)
+ if (rc < 0)
ctx->enable_refcnt = old_cnt;
}
@@ -1756,7 +1738,9 @@ static int msm_runtime_suspend(struct device *dev)
DBG("");
if (priv->mdss)
- return msm_mdss_disable(priv->mdss);
+ msm_mdss_disable(priv->mdss);
+ else
+ sde_power_resource_enable(&priv->phandle, false);
return 0;
}
@@ -1765,13 +1749,16 @@ static int msm_runtime_resume(struct device *dev)
{
struct drm_device *ddev = dev_get_drvdata(dev);
struct msm_drm_private *priv = ddev->dev_private;
+ int ret;
DBG("");
if (priv->mdss)
- return msm_mdss_enable(priv->mdss);
+ ret = msm_mdss_enable(priv->mdss);
+ else
+ ret = sde_power_resource_enable(&priv->phandle, true);
- return 0;
+ return ret;
}
#endif
diff --git a/msm/msm_drv.h b/msm/msm_drv.h
index 7ae0ea38..a0937dd6 100644
--- a/msm/msm_drv.h
+++ b/msm/msm_drv.h
@@ -560,7 +560,6 @@ struct msm_drm_private {
struct msm_kms *kms;
struct sde_power_handle phandle;
- struct sde_power_client *pclient;
/* subordinate devices, if present: */
struct platform_device *gpu_pdev;
diff --git a/msm/sde/sde_color_processing.c b/msm/sde/sde_color_processing.c
index b3804816..b80b5aa9 100644
--- a/msm/sde/sde_color_processing.c
+++ b/msm/sde/sde_color_processing.c
@@ -2193,8 +2193,8 @@ static void sde_cp_notify_ad_event(struct drm_crtc *crtc_drm, void *arg)
}
priv = kms->dev->dev_private;
- ret = sde_power_resource_enable(&priv->phandle, kms->core_client, true);
- if (ret) {
+ ret = pm_runtime_get_sync(kms->dev->dev);
+ if (ret < 0) {
SDE_ERROR("failed to enable power resource %d\n", ret);
SDE_EVT32(ret, SDE_EVTLOG_ERROR);
return;
@@ -2203,8 +2203,7 @@ static void sde_cp_notify_ad_event(struct drm_crtc *crtc_drm, void *arg)
hw_dspp->ops.ad_read_intr_resp(hw_dspp, AD4_IN_OUT_BACKLIGHT,
&input_bl, &output_bl);
- sde_power_resource_enable(&priv->phandle, kms->core_client,
- false);
+ pm_runtime_put_sync(kms->dev->dev);
if (!input_bl || input_bl < output_bl)
return;
@@ -2426,7 +2425,6 @@ static void sde_cp_notify_hist_event(struct drm_crtc *crtc_drm, void *arg)
struct sde_crtc *crtc;
struct drm_event event;
struct drm_msm_hist *hist_data;
- struct msm_drm_private *priv;
struct sde_kms *kms;
int ret;
u32 i;
@@ -2451,9 +2449,8 @@ static void sde_cp_notify_hist_event(struct drm_crtc *crtc_drm, void *arg)
return;
}
- priv = kms->dev->dev_private;
- ret = sde_power_resource_enable(&priv->phandle, kms->core_client, true);
- if (ret) {
+ ret = pm_runtime_get_sync(kms->dev->dev);
+ if (ret < 0) {
SDE_ERROR("failed to enable power resource %d\n", ret);
SDE_EVT32(ret, SDE_EVTLOG_ERROR);
return;
@@ -2467,15 +2464,13 @@ static void sde_cp_notify_hist_event(struct drm_crtc *crtc_drm, void *arg)
if (!hw_dspp || !hw_dspp->ops.read_histogram) {
DRM_ERROR("invalid dspp %pK or read_histogram func\n",
hw_dspp);
- sde_power_resource_enable(&priv->phandle,
- kms->core_client, false);
+ pm_runtime_put_sync(kms->dev->dev);
return;
}
hw_dspp->ops.read_histogram(hw_dspp, hist_data);
}
- sde_power_resource_enable(&priv->phandle, kms->core_client,
- false);
+ pm_runtime_put_sync(kms->dev->dev);
/* send histogram event with blob id */
event.length = sizeof(u32);
event.type = DRM_EVENT_HISTOGRAM;
diff --git a/msm/sde/sde_core_irq.c b/msm/sde/sde_core_irq.c
index 9329f797..7c315a76 100644
--- a/msm/sde/sde_core_irq.c
+++ b/msm/sde/sde_core_irq.c
@@ -441,25 +441,16 @@ void sde_debugfs_core_irq_destroy(struct sde_kms *sde_kms)
void sde_core_irq_preinstall(struct sde_kms *sde_kms)
{
- struct msm_drm_private *priv;
int i;
int rc;
- if (!sde_kms) {
- SDE_ERROR("invalid sde_kms\n");
- return;
- } else if (!sde_kms->dev) {
- SDE_ERROR("invalid drm device\n");
- return;
- } else if (!sde_kms->dev->dev_private) {
- SDE_ERROR("invalid device private\n");
+ if (!sde_kms || !sde_kms->dev) {
+ SDE_ERROR("invalid sde_kms or dev\n");
return;
}
- priv = sde_kms->dev->dev_private;
- rc = sde_power_resource_enable(&priv->phandle, sde_kms->core_client,
- true);
- if (rc) {
+ rc = pm_runtime_get_sync(sde_kms->dev->dev);
+ if (rc < 0) {
SDE_ERROR("failed to enable power resource %d\n", rc);
SDE_EVT32(rc, SDE_EVTLOG_ERROR);
return;
@@ -467,7 +458,7 @@ void sde_core_irq_preinstall(struct sde_kms *sde_kms)
sde_clear_all_irqs(sde_kms);
sde_disable_all_irqs(sde_kms);
- sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
+ pm_runtime_put_sync(sde_kms->dev->dev);
spin_lock_init(&sde_kms->irq_obj.cb_lock);
@@ -493,26 +484,17 @@ int sde_core_irq_postinstall(struct sde_kms *sde_kms)
void sde_core_irq_uninstall(struct sde_kms *sde_kms)
{
- struct msm_drm_private *priv;
int i;
int rc;
unsigned long irq_flags;
- if (!sde_kms) {
- SDE_ERROR("invalid sde_kms\n");
- return;
- } else if (!sde_kms->dev) {
- SDE_ERROR("invalid drm device\n");
- return;
- } else if (!sde_kms->dev->dev_private) {
- SDE_ERROR("invalid device private\n");
+ if (!sde_kms || !sde_kms->dev) {
+ SDE_ERROR("invalid sde_kms or dev\n");
return;
}
- priv = sde_kms->dev->dev_private;
- rc = sde_power_resource_enable(&priv->phandle, sde_kms->core_client,
- true);
- if (rc) {
+ rc = pm_runtime_get_sync(sde_kms->dev->dev);
+ if (rc < 0) {
SDE_ERROR("failed to enable power resource %d\n", rc);
SDE_EVT32(rc, SDE_EVTLOG_ERROR);
return;
@@ -525,7 +507,7 @@ void sde_core_irq_uninstall(struct sde_kms *sde_kms)
sde_clear_all_irqs(sde_kms);
sde_disable_all_irqs(sde_kms);
- sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
+ pm_runtime_put_sync(sde_kms->dev->dev);
spin_lock_irqsave(&sde_kms->irq_obj.cb_lock, irq_flags);
kfree(sde_kms->irq_obj.irq_cb_tbl);
diff --git a/msm/sde/sde_core_perf.c b/msm/sde/sde_core_perf.c
index a044b8e7..ef1cd1f0 100644
--- a/msm/sde/sde_core_perf.c
+++ b/msm/sde/sde_core_perf.c
@@ -638,17 +638,8 @@ static void _sde_core_perf_crtc_update_bus(struct sde_kms *kms,
client_vote = _get_sde_client_type(curr_client_type, &kms->perf);
switch (client_vote) {
- case NRT_CLIENT:
- sde_power_data_bus_set_quota(&priv->phandle, kms->core_client,
- SDE_POWER_HANDLE_DATA_BUS_CLIENT_NRT,
- bus_id, bus_ab_quota, bus_ib_quota);
- SDE_DEBUG("client:%s bus_id=%d ab=%llu ib=%llu\n", "nrt",
- bus_id, bus_ab_quota, bus_ib_quota);
- break;
-
case RT_CLIENT:
- sde_power_data_bus_set_quota(&priv->phandle, kms->core_client,
- SDE_POWER_HANDLE_DATA_BUS_CLIENT_RT,
+ sde_power_data_bus_set_quota(&priv->phandle,
bus_id, bus_ab_quota, bus_ib_quota);
SDE_DEBUG("client:%s bus_id=%d ab=%llu ib=%llu\n", "rt",
bus_id, bus_ab_quota, bus_ib_quota);
@@ -671,12 +662,6 @@ static void _sde_core_perf_crtc_update_bus(struct sde_kms *kms,
switch (kms->perf.bw_vote_mode) {
case DISP_RSC_MODE:
sde_power_data_bus_set_quota(&priv->phandle,
- kms->core_client,
- SDE_POWER_HANDLE_DATA_BUS_CLIENT_NRT,
- bus_id, 0, 0);
- sde_power_data_bus_set_quota(&priv->phandle,
- kms->core_client,
- SDE_POWER_HANDLE_DATA_BUS_CLIENT_RT,
bus_id, 0, 0);
kms->perf.bw_vote_mode_updated = false;
break;
@@ -1212,10 +1197,9 @@ int sde_core_perf_init(struct sde_core_perf *perf,
struct drm_device *dev,
struct sde_mdss_cfg *catalog,
struct sde_power_handle *phandle,
- struct sde_power_client *pclient,
char *clk_name)
{
- if (!perf || !dev || !catalog || !phandle || !pclient || !clk_name) {
+ if (!perf || !dev || !catalog || !phandle || !clk_name) {
SDE_ERROR("invalid parameters\n");
return -EINVAL;
}
@@ -1223,7 +1207,6 @@ int sde_core_perf_init(struct sde_core_perf *perf,
perf->dev = dev;
perf->catalog = catalog;
perf->phandle = phandle;
- perf->pclient = pclient;
perf->clk_name = clk_name;
perf->sde_rsc_available = is_sde_rsc_available(SDE_RSC_INDEX);
/* set default mode */
diff --git a/msm/sde/sde_core_perf.h b/msm/sde/sde_core_perf.h
index 8d621e08..a0706aae 100644
--- a/msm/sde/sde_core_perf.h
+++ b/msm/sde/sde_core_perf.h
@@ -60,7 +60,6 @@ struct sde_core_perf_tune {
* @debugfs_root: top level debug folder
* @catalog: Pointer to catalog configuration
* @phandle: Pointer to power handler
- * @pclient: Pointer to power client
* @clk_name: core clock name
* @core_clk: Pointer to core clock structure
* @core_clk_rate: current core clock rate
@@ -81,7 +80,6 @@ struct sde_core_perf {
struct dentry *debugfs_root;
struct sde_mdss_cfg *catalog;
struct sde_power_handle *phandle;
- struct sde_power_client *pclient;
char *clk_name;
struct clk *core_clk;
u64 core_clk_rate;
@@ -141,14 +139,12 @@ void sde_core_perf_destroy(struct sde_core_perf *perf);
* @dev: Pointer to drm device
* @catalog: Pointer to catalog
* @phandle: Pointer to power handle
- * @pclient: Pointer to power client
* @clk_name: core clock name
*/
int sde_core_perf_init(struct sde_core_perf *perf,
struct drm_device *dev,
struct sde_mdss_cfg *catalog,
struct sde_power_handle *phandle,
- struct sde_power_client *pclient,
char *clk_name);
/**
diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c
index 21e6698b..1cecd9c2 100644
--- a/msm/sde/sde_crtc.c
+++ b/msm/sde/sde_crtc.c
@@ -120,35 +120,6 @@ static inline struct drm_encoder *_sde_crtc_get_encoder(struct drm_crtc *crtc)
return NULL;
}
-static inline int _sde_crtc_power_enable(struct sde_crtc *sde_crtc, bool enable)
-{
- struct drm_crtc *crtc;
- struct msm_drm_private *priv;
- struct sde_kms *sde_kms;
-
- if (!sde_crtc) {
- SDE_ERROR("invalid sde crtc\n");
- return -EINVAL;
- }
-
- crtc = &sde_crtc->base;
- if (!crtc->dev || !crtc->dev->dev_private) {
- SDE_ERROR("invalid drm device\n");
- return -EINVAL;
- }
-
- priv = crtc->dev->dev_private;
- if (!priv->kms) {
- SDE_ERROR("invalid kms\n");
- return -EINVAL;
- }
-
- sde_kms = to_sde_kms(priv->kms);
-
- return sde_power_resource_enable(&priv->phandle, sde_kms->core_client,
- enable);
-}
-
/**
* sde_crtc_calc_fps() - Calculates fps value.
* @sde_crtc : CRTC structure
@@ -3666,9 +3637,9 @@ static int _sde_crtc_vblank_enable_no_lock(
/* drop lock since power crtc cb may try to re-acquire lock */
mutex_unlock(&sde_crtc->crtc_lock);
- ret = _sde_crtc_power_enable(sde_crtc, true);
+ ret = pm_runtime_get_sync(crtc->dev->dev);
mutex_lock(&sde_crtc->crtc_lock);
- if (ret)
+ if (ret < 0)
return ret;
list_for_each_entry(enc, &dev->mode_config.encoder_list, head) {
@@ -3698,7 +3669,7 @@ static int _sde_crtc_vblank_enable_no_lock(
/* drop lock since power crtc cb may try to re-acquire lock */
mutex_unlock(&sde_crtc->crtc_lock);
- _sde_crtc_power_enable(sde_crtc, false);
+ pm_runtime_put_sync(crtc->dev->dev);
mutex_lock(&sde_crtc->crtc_lock);
}
@@ -5539,13 +5510,13 @@ static ssize_t _sde_crtc_misr_setup(struct file *file,
return -EINVAL;
}
- rc = _sde_crtc_power_enable(sde_crtc, true);
- if (rc)
+ rc = pm_runtime_get_sync(crtc->dev->dev);
+ if (rc < 0)
return rc;
sde_crtc->misr_enable_debugfs = enable;
sde_crtc_misr_setup(crtc, enable, frame_count);
- _sde_crtc_power_enable(sde_crtc, false);
+ pm_runtime_put_sync(crtc->dev->dev);
return count;
}
@@ -5573,8 +5544,8 @@ static ssize_t _sde_crtc_misr_read(struct file *file,
if (!sde_kms)
return -EINVAL;
- rc = _sde_crtc_power_enable(sde_crtc, true);
- if (rc)
+ rc = pm_runtime_get_sync(crtc->dev->dev);
+ if (rc < 0)
return rc;
if (sde_kms_is_secure_session_inprogress(sde_kms)) {
@@ -5628,7 +5599,7 @@ buff_check:
*ppos += len; /* increase offset */
end:
- _sde_crtc_power_enable(sde_crtc, false);
+ pm_runtime_put_sync(crtc->dev->dev);
return len;
}
@@ -6110,7 +6081,6 @@ static int _sde_crtc_event_enable(struct sde_kms *kms,
{
struct sde_crtc *crtc = NULL;
struct sde_crtc_irq_info *node;
- struct msm_drm_private *priv;
unsigned long flags;
bool found = false;
int ret, i = 0;
@@ -6151,13 +6121,10 @@ static int _sde_crtc_event_enable(struct sde_kms *kms,
return -EINVAL;
}
- priv = kms->dev->dev_private;
ret = 0;
if (crtc_drm->enabled) {
- ret = sde_power_resource_enable(&priv->phandle,
- kms->core_client, true);
- if (ret) {
- SDE_ERROR("failed to enable power resource %d\n", ret);
+ ret = pm_runtime_get_sync(crtc_drm->dev->dev);
+ if (ret < 0) {
SDE_EVT32(ret, SDE_EVTLOG_ERROR);
kfree(node);
return ret;
@@ -6175,8 +6142,7 @@ static int _sde_crtc_event_enable(struct sde_kms *kms,
}
mutex_unlock(&crtc->crtc_lock);
- sde_power_resource_enable(&priv->phandle, kms->core_client,
- false);
+ pm_runtime_put_sync(crtc_drm->dev->dev);
}
if (add_event)
@@ -6198,7 +6164,6 @@ static int _sde_crtc_event_disable(struct sde_kms *kms,
{
struct sde_crtc *crtc = NULL;
struct sde_crtc_irq_info *node = NULL;
- struct msm_drm_private *priv;
unsigned long flags;
bool found = false;
int ret;
@@ -6226,9 +6191,8 @@ static int _sde_crtc_event_disable(struct sde_kms *kms,
kfree(node);
return 0;
}
- priv = kms->dev->dev_private;
- ret = sde_power_resource_enable(&priv->phandle, kms->core_client, true);
- if (ret) {
+ ret = pm_runtime_get_sync(crtc_drm->dev->dev);
+ if (ret < 0) {
SDE_ERROR("failed to enable power resource %d\n", ret);
SDE_EVT32(ret, SDE_EVTLOG_ERROR);
kfree(node);
@@ -6237,7 +6201,7 @@ static int _sde_crtc_event_disable(struct sde_kms *kms,
ret = node->func(crtc_drm, false, &node->irq);
kfree(node);
- sde_power_resource_enable(&priv->phandle, kms->core_client, false);
+ pm_runtime_put_sync(crtc_drm->dev->dev);
return ret;
}
diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h
index 0171f4c3..091f3da1 100644
--- a/msm/sde/sde_crtc.h
+++ b/msm/sde/sde_crtc.h
@@ -595,7 +595,7 @@ enum sde_intf_mode sde_crtc_get_intf_mode(struct drm_crtc *crtc);
u32 sde_crtc_get_fps_mode(struct drm_crtc *crtc);
/**
- * sde_crtc_get_client_type - check the crtc type- rt, nrt, rsc, etc.
+ * sde_crtc_get_client_type - check the crtc type- rt, rsc_rt, etc.
* @crtc: Pointer to crtc
*/
static inline enum sde_crtc_client_type sde_crtc_get_client_type(
@@ -605,10 +605,9 @@ static inline enum sde_crtc_client_type sde_crtc_get_client_type(
crtc ? to_sde_crtc_state(crtc->state) : NULL;
if (!cstate)
- return NRT_CLIENT;
+ return RT_CLIENT;
- return sde_crtc_get_intf_mode(crtc) == INTF_MODE_WB_LINE ? NRT_CLIENT :
- (cstate->rsc_client ? RT_RSC_CLIENT : RT_CLIENT);
+ return cstate->rsc_client ? RT_RSC_CLIENT : RT_CLIENT;
}
/**
diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c
index b012d109..96a06055 100644
--- a/msm/sde/sde_encoder.c
+++ b/msm/sde/sde_encoder.c
@@ -417,36 +417,6 @@ int sde_encoder_in_cont_splash(struct drm_encoder *drm_enc)
sde_enc->cur_master->cont_splash_enabled;
}
-static inline int _sde_encoder_power_enable(struct sde_encoder_virt *sde_enc,
- bool enable)
-{
- struct drm_encoder *drm_enc;
- struct msm_drm_private *priv;
- struct sde_kms *sde_kms;
-
- if (!sde_enc) {
- SDE_ERROR("invalid sde enc\n");
- return -EINVAL;
- }
-
- drm_enc = &sde_enc->base;
- if (!drm_enc->dev || !drm_enc->dev->dev_private) {
- SDE_ERROR("drm device invalid\n");
- return -EINVAL;
- }
-
- priv = drm_enc->dev->dev_private;
- if (!priv->kms) {
- SDE_ERROR("invalid kms\n");
- return -EINVAL;
- }
-
- sde_kms = to_sde_kms(priv->kms);
-
- return sde_power_resource_enable(&priv->phandle, sde_kms->core_client,
- enable);
-}
-
void sde_encoder_helper_report_irq_timeout(struct sde_encoder_phys *phys_enc,
enum sde_intr_idx intr_idx)
{
@@ -2082,9 +2052,8 @@ static int _sde_encoder_resource_control_helper(struct drm_encoder *drm_enc,
if (enable) {
/* enable SDE core clks */
- rc = sde_power_resource_enable(&priv->phandle,
- sde_kms->core_client, true);
- if (rc) {
+ rc = pm_runtime_get_sync(drm_enc->dev->dev);
+ if (rc < 0) {
SDE_ERROR("failed to enable power resource %d\n", rc);
SDE_EVT32(rc, SDE_EVTLOG_ERROR);
return rc;
@@ -2096,8 +2065,7 @@ static int _sde_encoder_resource_control_helper(struct drm_encoder *drm_enc,
true);
if (rc) {
SDE_ERROR("failed to enable clk control %d\n", rc);
- sde_power_resource_enable(&priv->phandle,
- sde_kms->core_client, false);
+ pm_runtime_put_sync(drm_enc->dev->dev);
return rc;
}
@@ -2118,8 +2086,7 @@ static int _sde_encoder_resource_control_helper(struct drm_encoder *drm_enc,
sde_connector_clk_ctrl(sde_enc->cur_master->connector, false);
/* disable SDE core clks */
- sde_power_resource_enable(&priv->phandle,
- sde_kms->core_client, false);
+ pm_runtime_put_sync(drm_enc->dev->dev);
}
return 0;
@@ -3949,7 +3916,6 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)
sde_kms = to_sde_kms(priv->kms);
if (sde_kms != NULL) {
sde_power_scale_reg_bus(&priv->phandle,
- sde_kms->core_client,
VOTE_INDEX_LOW,
false);
}
@@ -4350,14 +4316,16 @@ static void sde_encoder_vsync_event_work_handler(struct kthread_work *work)
bool autorefresh_enabled = false;
int rc = 0;
ktime_t wakeup_time;
+ struct drm_encoder *drm_enc;
if (!sde_enc) {
SDE_ERROR("invalid sde encoder\n");
return;
}
- rc = _sde_encoder_power_enable(sde_enc, true);
- if (rc) {
+ drm_enc = &sde_enc->base;
+ rc = pm_runtime_get_sync(drm_enc->dev->dev);
+ if (rc < 0) {
SDE_ERROR_ENC(sde_enc, "sde enc power enabled failed:%d\n", rc);
return;
}
@@ -4381,7 +4349,7 @@ static void sde_encoder_vsync_event_work_handler(struct kthread_work *work)
nsecs_to_jiffies(ktime_to_ns(wakeup_time)));
exit:
- _sde_encoder_power_enable(sde_enc, false);
+ pm_runtime_put_sync(drm_enc->dev->dev);
}
int sde_encoder_poll_line_counts(struct drm_encoder *drm_enc)
@@ -4932,6 +4900,7 @@ static ssize_t _sde_encoder_misr_setup(struct file *file,
u32 frame_count, enable;
struct msm_drm_private *priv = NULL;
struct sde_kms *sde_kms = NULL;
+ struct drm_encoder *drm_enc;
if (!file || !file->private_data)
return -EINVAL;
@@ -4942,6 +4911,7 @@ static ssize_t _sde_encoder_misr_setup(struct file *file,
return -EINVAL;
sde_kms = to_sde_kms(priv->kms);
+ drm_enc = &sde_enc->base;
if (sde_kms_is_secure_session_inprogress(sde_kms)) {
SDE_DEBUG_ENC(sde_enc, "misr enable/disable not allowed\n");
@@ -4957,14 +4927,14 @@ static ssize_t _sde_encoder_misr_setup(struct file *file,
if (sscanf(buf, "%u %u", &enable, &frame_count) != 2)
return -EINVAL;
- rc = _sde_encoder_power_enable(sde_enc, true);
- if (rc)
+ rc = pm_runtime_get_sync(drm_enc->dev->dev);
+ if (rc < 0)
return rc;
sde_enc->misr_enable = enable;
sde_enc->misr_frame_count = frame_count;
sde_encoder_misr_configure(&sde_enc->base, enable, frame_count);
- _sde_encoder_power_enable(sde_enc, false);
+ pm_runtime_put_sync(drm_enc->dev->dev);
return count;
}
@@ -4974,6 +4944,7 @@ static ssize_t _sde_encoder_misr_read(struct file *file,
struct sde_encoder_virt *sde_enc;
struct msm_drm_private *priv = NULL;
struct sde_kms *sde_kms = NULL;
+ struct drm_encoder *drm_enc;
int i = 0, len = 0;
char buf[MISR_BUFF_SIZE + 1] = {'\0'};
int rc;
@@ -4993,9 +4964,10 @@ static ssize_t _sde_encoder_misr_read(struct file *file,
SDE_DEBUG_ENC(sde_enc, "misr read not allowed\n");
return -ENOTSUPP;
}
+ drm_enc = &sde_enc->base;
- rc = _sde_encoder_power_enable(sde_enc, true);
- if (rc)
+ rc = pm_runtime_get_sync(drm_enc->dev->dev);
+ if (rc < 0)
return rc;
if (!sde_enc->misr_enable) {
@@ -5045,7 +5017,7 @@ buff_check:
*ppos += len; /* increase offset */
end:
- _sde_encoder_power_enable(sde_enc, false);
+ pm_runtime_put_sync(drm_enc->dev->dev);
return len;
}
diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c
index 065f090b..27f33613 100644
--- a/msm/sde/sde_kms.c
+++ b/msm/sde/sde_kms.c
@@ -398,14 +398,11 @@ end:
static int _sde_kms_sui_misr_ctrl(struct sde_kms *sde_kms,
struct drm_crtc *crtc, bool enable)
{
- struct drm_device *dev = sde_kms->dev;
- struct msm_drm_private *priv = dev->dev_private;
int ret;
if (enable) {
- ret = sde_power_resource_enable(&priv->phandle,
- sde_kms->core_client, true);
- if (ret) {
+ ret = pm_runtime_get_sync(sde_kms->dev->dev);
+ if (ret < 0) {
SDE_ERROR("failed to enable resource, ret:%d\n", ret);
return ret;
}
@@ -414,16 +411,14 @@ static int _sde_kms_sui_misr_ctrl(struct sde_kms *sde_kms,
ret = _sde_kms_secure_ctrl_xin_clients(sde_kms, crtc, true);
if (ret) {
- sde_power_resource_enable(&priv->phandle,
- sde_kms->core_client, false);
+ pm_runtime_put_sync(sde_kms->dev->dev);
return ret;
}
} else {
_sde_kms_secure_ctrl_xin_clients(sde_kms, crtc, false);
sde_crtc_misr_setup(crtc, false, 0);
- sde_power_resource_enable(&priv->phandle,
- sde_kms->core_client, false);
+ pm_runtime_put_sync(sde_kms->dev->dev);
}
return 0;
@@ -783,7 +778,7 @@ static void sde_kms_prepare_commit(struct msm_kms *kms,
struct drm_encoder *encoder;
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
- int i, rc = 0;
+ int i, rc;
if (!kms)
return;
@@ -795,17 +790,15 @@ static void sde_kms_prepare_commit(struct msm_kms *kms,
priv = dev->dev_private;
SDE_ATRACE_BEGIN("prepare_commit");
- rc = sde_power_resource_enable(&priv->phandle, sde_kms->core_client,
- true);
- if (rc) {
- SDE_ERROR("failed to enable power resource %d\n", rc);
+ rc = pm_runtime_get_sync(sde_kms->dev->dev);
+ if (rc < 0) {
+ SDE_ERROR("failed to enable power resources %d\n", rc);
SDE_EVT32(rc, SDE_EVTLOG_ERROR);
goto end;
}
if (sde_kms->first_kickoff) {
- sde_power_scale_reg_bus(&priv->phandle, sde_kms->core_client,
- VOTE_INDEX_HIGH, false);
+ sde_power_scale_reg_bus(&priv->phandle, VOTE_INDEX_HIGH, false);
sde_kms->first_kickoff = false;
}
@@ -894,20 +887,16 @@ static void _sde_kms_release_splash_resource(struct sde_kms *sde_kms,
SDE_DEBUG("cont_splash handoff done for dpy:%d remaining:%d\n",
i, sde_kms->splash_data.num_splash_displays);
memset(splash_display, 0x0, sizeof(struct sde_splash_display));
-
}
/* remove the votes if all displays are done with splash */
if (!sde_kms->splash_data.num_splash_displays) {
for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++)
- sde_power_data_bus_set_quota(&priv->phandle,
- sde_kms->core_client,
- SDE_POWER_HANDLE_DATA_BUS_CLIENT_RT, i,
- SDE_POWER_HANDLE_ENABLE_BUS_AB_QUOTA,
- SDE_POWER_HANDLE_ENABLE_BUS_IB_QUOTA);
+ sde_power_data_bus_set_quota(&priv->phandle, i,
+ SDE_POWER_HANDLE_ENABLE_BUS_AB_QUOTA,
+ SDE_POWER_HANDLE_ENABLE_BUS_IB_QUOTA);
- sde_power_resource_enable(&priv->phandle,
- sde_kms->core_client, false);
+ pm_runtime_put_sync(sde_kms->dev->dev);
}
}
@@ -930,7 +919,7 @@ static void sde_kms_complete_commit(struct msm_kms *kms,
return;
priv = sde_kms->dev->dev_private;
- if (!sde_kms_power_resource_is_enabled(sde_kms->dev)) {
+ if (sde_kms_power_resource_is_enabled(sde_kms->dev) < 0) {
SDE_ERROR("power resource is not enabled\n");
return;
}
@@ -959,7 +948,7 @@ static void sde_kms_complete_commit(struct msm_kms *kms,
}
}
- sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
+ pm_runtime_put_sync(sde_kms->dev->dev);
for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i)
_sde_kms_release_splash_resource(sde_kms, crtc);
@@ -1662,10 +1651,6 @@ static void _sde_kms_hw_destroy(struct sde_kms *sde_kms,
sde_hw_catalog_deinit(sde_kms->catalog);
sde_kms->catalog = NULL;
- if (sde_kms->core_client)
- sde_power_client_destroy(&priv->phandle, sde_kms->core_client);
- sde_kms->core_client = NULL;
-
if (sde_kms->sid)
msm_iounmap(pdev, sde_kms->sid);
sde_kms->sid = NULL;
@@ -2898,23 +2883,15 @@ static void sde_kms_handle_power_event(u32 event_type, void *usr)
static int sde_kms_pd_enable(struct generic_pm_domain *genpd)
{
struct sde_kms *sde_kms = genpd_to_sde_kms(genpd);
- struct drm_device *dev;
- struct msm_drm_private *priv;
- int rc;
+ int rc = -EINVAL;
SDE_DEBUG("\n");
- dev = sde_kms->dev;
- if (!dev)
- return -EINVAL;
-
- priv = dev->dev_private;
- if (!priv)
- return -EINVAL;
-
- SDE_EVT32(genpd->device_count);
+ rc = pm_runtime_get_sync(sde_kms->dev->dev);
+ if (rc > 0)
+ rc = 0;
- rc = sde_power_resource_enable(&priv->phandle, priv->pclient, true);
+ SDE_EVT32(rc, genpd->device_count);
return rc;
}
@@ -2922,25 +2899,14 @@ static int sde_kms_pd_enable(struct generic_pm_domain *genpd)
static int sde_kms_pd_disable(struct generic_pm_domain *genpd)
{
struct sde_kms *sde_kms = genpd_to_sde_kms(genpd);
- struct drm_device *dev;
- struct msm_drm_private *priv;
- int rc;
SDE_DEBUG("\n");
- dev = sde_kms->dev;
- if (!dev)
- return -EINVAL;
-
- priv = dev->dev_private;
- if (!priv)
- return -EINVAL;
+ pm_runtime_put_sync(sde_kms->dev->dev);
SDE_EVT32(genpd->device_count);
- rc = sde_power_resource_enable(&priv->phandle, priv->pclient, false);
-
- return rc;
+ return 0;
}
static int _sde_kms_get_splash_data(struct sde_splash_data *data)
@@ -3155,9 +3121,7 @@ static int _sde_kms_hw_init_blocks(struct sde_kms *sde_kms,
int i, rc = -EINVAL;
for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++)
- sde_power_data_bus_set_quota(&priv->phandle,
- sde_kms->core_client,
- SDE_POWER_HANDLE_DATA_BUS_CLIENT_RT, i,
+ sde_power_data_bus_set_quota(&priv->phandle, i,
SDE_POWER_HANDLE_CONT_SPLASH_BUS_AB_QUOTA,
SDE_POWER_HANDLE_CONT_SPLASH_BUS_IB_QUOTA);
@@ -3281,7 +3245,7 @@ static int _sde_kms_hw_init_blocks(struct sde_kms *sde_kms,
}
rc = sde_core_perf_init(&sde_kms->perf, dev, sde_kms->catalog,
- &priv->phandle, priv->pclient, "core_clk");
+ &priv->phandle, "core_clk");
if (rc) {
SDE_ERROR("failed to init perf %d\n", rc);
goto perf_err;
@@ -3339,23 +3303,12 @@ static int sde_kms_hw_init(struct msm_kms *kms)
if (rc)
goto error;
- sde_kms->core_client = sde_power_client_create(&priv->phandle, "core");
- if (IS_ERR_OR_NULL(sde_kms->core_client)) {
- rc = PTR_ERR(sde_kms->core_client);
- if (!sde_kms->core_client)
- rc = -EINVAL;
- SDE_ERROR("sde power client create failed: %d\n", rc);
- sde_kms->core_client = NULL;
- goto error;
- }
-
rc = _sde_kms_get_splash_data(&sde_kms->splash_data);
if (rc)
SDE_DEBUG("sde splash data fetch failed: %d\n", rc);
- rc = sde_power_resource_enable(&priv->phandle, sde_kms->core_client,
- true);
- if (rc) {
+ rc = pm_runtime_get_sync(sde_kms->dev->dev);
+ if (rc < 0) {
SDE_ERROR("resource enable failed: %d\n", rc);
goto error;
}
@@ -3391,19 +3344,16 @@ static int sde_kms_hw_init(struct msm_kms *kms)
SDE_DEBUG("Skipping MDP Resources disable\n");
} else {
for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++)
- sde_power_data_bus_set_quota(&priv->phandle,
- sde_kms->core_client,
- SDE_POWER_HANDLE_DATA_BUS_CLIENT_RT, i,
+ sde_power_data_bus_set_quota(&priv->phandle, i,
SDE_POWER_HANDLE_ENABLE_BUS_AB_QUOTA,
SDE_POWER_HANDLE_ENABLE_BUS_IB_QUOTA);
- sde_power_resource_enable(&priv->phandle,
- sde_kms->core_client, false);
+ pm_runtime_put_sync(sde_kms->dev->dev);
}
return 0;
hw_init_err:
- sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
+ pm_runtime_put_sync(sde_kms->dev->dev);
error:
_sde_kms_hw_destroy(sde_kms, platformdev);
end:
diff --git a/msm/sde/sde_kms.h b/msm/sde/sde_kms.h
index 62da4de4..e65aa862 100644
--- a/msm/sde/sde_kms.h
+++ b/msm/sde/sde_kms.h
@@ -238,8 +238,6 @@ struct sde_kms {
bool genpd_init;
struct msm_gem_address_space *aspace[MSM_SMMU_DOMAIN_MAX];
- struct sde_power_client *core_client;
-
struct sde_power_event *power_event;
/* directory entry for debugfs */
@@ -312,14 +310,10 @@ bool sde_is_custom_client(void);
*/
static inline bool sde_kms_power_resource_is_enabled(struct drm_device *dev)
{
- struct msm_drm_private *priv;
-
- if (!dev || !dev->dev_private)
+ if (!dev)
return false;
- priv = dev->dev_private;
-
- return sde_power_resource_is_enabled(&priv->phandle);
+ return pm_runtime_enabled(dev->dev);
}
/**
diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c
index eff1a2d5..5eced69d 100644
--- a/msm/sde/sde_plane.c
+++ b/msm/sde/sde_plane.c
@@ -550,30 +550,20 @@ void sde_plane_set_revalidate(struct drm_plane *plane, bool enable)
int sde_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
{
struct sde_plane *psde;
- struct msm_drm_private *priv;
- struct sde_kms *sde_kms;
int rc;
- if (!plane || !plane->dev) {
+ if (!plane) {
SDE_ERROR("invalid arguments\n");
return -EINVAL;
}
- priv = plane->dev->dev_private;
- if (!priv || !priv->kms) {
- SDE_ERROR("invalid KMS reference\n");
- return -EINVAL;
- }
-
- sde_kms = to_sde_kms(priv->kms);
psde = to_sde_plane(plane);
if (!psde->is_rt_pipe)
goto end;
- rc = sde_power_resource_enable(&priv->phandle, sde_kms->core_client,
- true);
- if (rc) {
+ rc = pm_runtime_get_sync(plane->dev->dev);
+ if (rc < 0) {
SDE_ERROR("failed to enable power resource %d\n", rc);
SDE_EVT32(rc, SDE_EVTLOG_ERROR);
return rc;
@@ -581,7 +571,7 @@ int sde_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
_sde_plane_set_qos_ctrl(plane, enable, SDE_PLANE_QOS_PANIC_CTRL);
- sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
+ pm_runtime_put_sync(plane->dev->dev);
end:
return 0;
@@ -2103,28 +2093,6 @@ static int _sde_plane_fetch_halt(struct drm_plane *plane)
}
-static inline int _sde_plane_power_enable(struct drm_plane *plane, bool enable)
-{
- struct msm_drm_private *priv;
- struct sde_kms *sde_kms;
-
- if (!plane->dev || !plane->dev->dev_private) {
- SDE_ERROR("invalid drm device\n");
- return -EINVAL;
- }
-
- priv = plane->dev->dev_private;
- if (!priv->kms) {
- SDE_ERROR("invalid kms\n");
- return -EINVAL;
- }
-
- sde_kms = to_sde_kms(priv->kms);
-
- return sde_power_resource_enable(&priv->phandle, sde_kms->core_client,
- enable);
-}
-
static void sde_plane_cleanup_fb(struct drm_plane *plane,
struct drm_plane_state *old_state)
{
@@ -2149,10 +2117,10 @@ static void sde_plane_cleanup_fb(struct drm_plane *plane,
psde->pipe - SSPP_VIG0);
/* halt this plane now */
- ret = _sde_plane_power_enable(plane, true);
- if (ret) {
+ ret = pm_runtime_get_sync(plane->dev->dev);
+ if (ret < 0) {
SDE_ERROR("power resource enable failed with %d", ret);
- SDE_EVT32(ret);
+ SDE_EVT32(ret, SDE_EVTLOG_ERROR);
return;
}
@@ -2164,7 +2132,7 @@ static void sde_plane_cleanup_fb(struct drm_plane *plane,
SDE_EVT32(DRMID(plane), psde->pipe - SSPP_VIG0,
ret, SDE_EVTLOG_ERROR);
}
- _sde_plane_power_enable(plane, false);
+ pm_runtime_put_sync(plane->dev->dev);
}
msm_framebuffer_cleanup(old_state->fb, old_pstate->aspace);
diff --git a/msm/sde/sde_trace.h b/msm/sde/sde_trace.h
index 39ad0f12..e6ab33cc 100644
--- a/msm/sde/sde_trace.h
+++ b/msm/sde/sde_trace.h
@@ -86,23 +86,20 @@ TRACE_EVENT(sde_perf_set_ot,
)
TRACE_EVENT(sde_perf_update_bus,
- TP_PROTO(int client, u32 bus_id, unsigned long long ab_quota,
+ TP_PROTO(u32 bus_id, unsigned long long ab_quota,
unsigned long long ib_quota),
- TP_ARGS(client, bus_id, ab_quota, ib_quota),
+ TP_ARGS(bus_id, ab_quota, ib_quota),
TP_STRUCT__entry(
- __field(int, client)
__field(u32, bus_id);
__field(u64, ab_quota)
__field(u64, ib_quota)
),
TP_fast_assign(
- __entry->client = client;
__entry->bus_id = bus_id;
__entry->ab_quota = ab_quota;
__entry->ib_quota = ib_quota;
),
- TP_printk("Request client:%d bus_id:%d ab=%llu ib=%llu",
- __entry->client,
+ TP_printk("Request bus_id:%d ab=%llu ib=%llu",
__entry->bus_id,
__entry->ab_quota,
__entry->ib_quota)
diff --git a/msm/sde_dbg.c b/msm/sde_dbg.c
index ec019fb0..ad510c99 100644
--- a/msm/sde_dbg.c
+++ b/msm/sde_dbg.c
@@ -13,6 +13,8 @@
#include <linux/dma-buf.h>
#include <linux/slab.h>
#include <linux/list_sort.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
#include "sde_dbg.h"
#include "sde/sde_hw_catalog.h"
@@ -196,7 +198,6 @@ struct sde_dbg_regbuf {
* @reg_base_list: list of register dumping regions
* @dev: device pointer
* @mutex: mutex to serialize access to serialze dumps, debugfs access
- * @power_ctrl: callback structure for enabling power for reading hw registers
* @req_dump_blks: list of blocks requested for dumping
* @panic_on_err: whether to kernel panic after triggering dump via debugfs
* @dump_work: work struct for deferring register dump work to separate thread
@@ -216,7 +217,6 @@ static struct sde_dbg_base {
struct list_head reg_base_list;
struct device *dev;
struct mutex mutex;
- struct sde_dbg_power_ctrl power_ctrl;
struct sde_dbg_reg_base *req_dump_blks[SDE_DBG_BASE_MAX];
@@ -2826,21 +2826,6 @@ static struct vbif_debug_bus_entry vbif_dbg_bus_msm8998[] = {
};
/**
- * _sde_dbg_enable_power - use callback to turn power on for hw register access
- * @enable: whether to turn power on or off
- * Return: zero if success; error code otherwise
- */
-static inline int _sde_dbg_enable_power(int enable)
-{
- if (!sde_dbg_base.power_ctrl.enable_fn)
- return -EINVAL;
- return sde_dbg_base.power_ctrl.enable_fn(
- sde_dbg_base.power_ctrl.handle,
- sde_dbg_base.power_ctrl.client,
- enable);
-}
-
-/**
* _sde_dump_reg - helper function for dumping rotator register set content
* @dump_name: register set name
* @reg_dump_flag: dumping flag controlling in-log/memory dump location
@@ -2901,8 +2886,8 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
}
if (!from_isr) {
- rc = _sde_dbg_enable_power(true);
- if (rc) {
+ rc = pm_runtime_get_sync(sde_dbg_base.dev);
+ if (rc < 0) {
pr_err("failed to enable power %d\n", rc);
return;
}
@@ -2933,7 +2918,7 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
}
if (!from_isr)
- _sde_dbg_enable_power(false);
+ pm_runtime_put_sync(sde_dbg_base.dev);
}
/**
@@ -3138,8 +3123,8 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
}
}
- rc = _sde_dbg_enable_power(true);
- if (rc) {
+ rc = pm_runtime_get_sync(sde_dbg_base.dev);
+ if (rc < 0) {
pr_err("failed to enable power %d\n", rc);
return;
}
@@ -3183,7 +3168,7 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
head->wr_addr != DBGBUS_DSPP)
writel_relaxed(0x0, mem_base + DBGBUS_DSPP);
}
- _sde_dbg_enable_power(false);
+ pm_runtime_put_sync(sde_dbg_base.dev);
dev_info(sde_dbg_base.dev, "======== end %s dump =========\n",
bus->cmn.name);
@@ -3295,8 +3280,8 @@ static void _sde_dbg_dump_vbif_dbg_bus(struct sde_dbg_vbif_debug_bus *bus)
}
}
- rc = _sde_dbg_enable_power(true);
- if (rc) {
+ rc = pm_runtime_get_sync(sde_dbg_base.dev);
+ if (rc < 0) {
pr_err("failed to enable power %d\n", rc);
return;
}
@@ -3350,7 +3335,7 @@ static void _sde_dbg_dump_vbif_dbg_bus(struct sde_dbg_vbif_debug_bus *bus)
dump_addr += (head->block_cnt * head->test_pnt_cnt * 4);
}
- _sde_dbg_enable_power(false);
+ pm_runtime_put_sync(sde_dbg_base.dev);
dev_info(sde_dbg_base.dev, "======== end %s dump =========\n",
bus->cmn.name);
@@ -4234,8 +4219,8 @@ static ssize_t sde_dbg_reg_base_reg_write(struct file *file,
return -EFAULT;
}
- rc = _sde_dbg_enable_power(true);
- if (rc) {
+ rc = pm_runtime_get_sync(sde_dbg_base.dev);
+ if (rc < 0) {
mutex_unlock(&sde_dbg_base.mutex);
pr_err("failed to enable power %d\n", rc);
return rc;
@@ -4243,7 +4228,7 @@ static ssize_t sde_dbg_reg_base_reg_write(struct file *file,
writel_relaxed(data, dbg->base + off);
- _sde_dbg_enable_power(false);
+ pm_runtime_put_sync(sde_dbg_base.dev);
mutex_unlock(&sde_dbg_base.mutex);
@@ -4301,8 +4286,8 @@ static ssize_t sde_dbg_reg_base_reg_read(struct file *file,
ptr = dbg->base + dbg->off;
tot = 0;
- rc = _sde_dbg_enable_power(true);
- if (rc) {
+ rc = pm_runtime_get_sync(sde_dbg_base.dev);
+ if (rc < 0) {
mutex_unlock(&sde_dbg_base.mutex);
pr_err("failed to enable power %d\n", rc);
return rc;
@@ -4324,7 +4309,7 @@ static ssize_t sde_dbg_reg_base_reg_read(struct file *file,
break;
}
- _sde_dbg_enable_power(false);
+ pm_runtime_put_sync(sde_dbg_base.dev);
dbg->buf_len = tot;
}
@@ -4457,9 +4442,9 @@ void sde_dbg_init_dbg_buses(u32 hwversion)
}
}
-int sde_dbg_init(struct device *dev, struct sde_dbg_power_ctrl *power_ctrl)
+int sde_dbg_init(struct device *dev)
{
- if (!dev || !power_ctrl) {
+ if (!dev) {
pr_err("invalid params\n");
return -EINVAL;
}
@@ -4467,7 +4452,6 @@ int sde_dbg_init(struct device *dev, struct sde_dbg_power_ctrl *power_ctrl)
mutex_init(&sde_dbg_base.mutex);
INIT_LIST_HEAD(&sde_dbg_base.reg_base_list);
sde_dbg_base.dev = dev;
- sde_dbg_base.power_ctrl = *power_ctrl;
sde_dbg_base.evtlog = sde_evtlog_init();
if (IS_ERR_OR_NULL(sde_dbg_base.evtlog))
diff --git a/msm/sde_dbg.h b/msm/sde_dbg.h
index 0d67e4c2..5ef7fa68 100644
--- a/msm/sde_dbg.h
+++ b/msm/sde_dbg.h
@@ -213,11 +213,9 @@ void sde_dbg_init_dbg_buses(u32 hwversion);
/**
* sde_dbg_init - initialize global sde debug facilities: evtlog, regdump
* @dev: device handle
- * @power_ctrl: power control callback structure for enabling clocks
- * during register dumping
* Returns: 0 or -ERROR
*/
-int sde_dbg_init(struct device *dev, struct sde_dbg_power_ctrl *power_ctrl);
+int sde_dbg_init(struct device *dev);
/**
* sde_dbg_debugfs_register - register entries at the given debugfs dir
diff --git a/msm/sde_power_handle.c b/msm/sde_power_handle.c
index 1fb48ded..9a797714 100644
--- a/msm/sde_power_handle.c
+++ b/msm/sde_power_handle.c
@@ -77,53 +77,6 @@ static int sde_power_rsc_update(struct sde_power_handle *phandle, bool enable)
return ret;
}
-struct sde_power_client *sde_power_client_create(
- struct sde_power_handle *phandle, char *client_name)
-{
- struct sde_power_client *client;
- static u32 id;
-
- if (!client_name || !phandle) {
- pr_err("client name is null or invalid power data\n");
- return ERR_PTR(-EINVAL);
- }
-
- client = kzalloc(sizeof(struct sde_power_client), GFP_KERNEL);
- if (!client)
- return ERR_PTR(-ENOMEM);
-
- mutex_lock(&phandle->phandle_lock);
- strlcpy(client->name, client_name, MAX_CLIENT_NAME_LEN);
- client->usecase_ndx = VOTE_INDEX_DISABLE;
- client->id = id;
- client->active = true;
- pr_debug("client %s created:%pK id :%d\n", client_name,
- client, id);
- id++;
- list_add(&client->list, &phandle->power_client_clist);
- mutex_unlock(&phandle->phandle_lock);
-
- return client;
-}
-
-void sde_power_client_destroy(struct sde_power_handle *phandle,
- struct sde_power_client *client)
-{
- if (!client || !phandle) {
- pr_err("reg bus vote: invalid client handle\n");
- } else if (!client->active) {
- pr_err("sde power deinit already done\n");
- kfree(client);
- } else {
- pr_debug("bus vote client %s destroyed:%pK id:%u\n",
- client->name, client, client->id);
- mutex_lock(&phandle->phandle_lock);
- list_del_init(&client->list);
- mutex_unlock(&phandle->phandle_lock);
- kfree(client);
- }
-}
-
static int sde_power_parse_dt_supply(struct platform_device *pdev,
struct dss_module_power *mp)
{
@@ -329,9 +282,8 @@ clk_err:
#define MAX_AXI_PORT_COUNT 3
static int _sde_power_data_bus_set_quota(
- struct sde_power_data_bus_handle *pdbus,
- u64 ab_quota_rt, u64 ab_quota_nrt,
- u64 ib_quota_rt, u64 ib_quota_nrt)
+ struct sde_power_data_bus_handle *pdbus,
+ u64 in_ab_quota, u64 in_ib_quota)
{
int new_uc_idx;
u64 ab_quota[MAX_AXI_PORT_COUNT] = {0, 0};
@@ -343,42 +295,14 @@ static int _sde_power_data_bus_set_quota(
return -EINVAL;
}
- pdbus->ab_rt = ab_quota_rt;
- pdbus->ib_rt = ib_quota_rt;
- pdbus->ab_nrt = ab_quota_nrt;
- pdbus->ib_nrt = ib_quota_nrt;
-
- if (pdbus->enable) {
- ab_quota_rt = max_t(u64, ab_quota_rt,
- SDE_POWER_HANDLE_ENABLE_BUS_AB_QUOTA);
- ib_quota_rt = max_t(u64, ib_quota_rt,
- SDE_POWER_HANDLE_ENABLE_BUS_IB_QUOTA);
- ab_quota_nrt = max_t(u64, ab_quota_nrt,
- SDE_POWER_HANDLE_ENABLE_BUS_AB_QUOTA);
- ib_quota_nrt = max_t(u64, ib_quota_nrt,
- SDE_POWER_HANDLE_ENABLE_NRT_BUS_IB_QUOTA);
- } else {
- ab_quota_rt = min_t(u64, ab_quota_rt,
- SDE_POWER_HANDLE_DISABLE_BUS_AB_QUOTA);
- ib_quota_rt = min_t(u64, ib_quota_rt,
- SDE_POWER_HANDLE_DISABLE_BUS_IB_QUOTA);
- ab_quota_nrt = min_t(u64, ab_quota_nrt,
- SDE_POWER_HANDLE_DISABLE_BUS_AB_QUOTA);
- ib_quota_nrt = min_t(u64, ib_quota_nrt,
- SDE_POWER_HANDLE_DISABLE_BUS_IB_QUOTA);
- }
-
- if (!ab_quota_rt && !ab_quota_nrt && !ib_quota_rt && !ib_quota_nrt) {
+ if (!in_ab_quota && !in_ib_quota) {
new_uc_idx = 0;
} else {
int i;
struct msm_bus_vectors *vect = NULL;
struct msm_bus_scale_pdata *bw_table =
pdbus->data_bus_scale_table;
- u32 nrt_data_paths_cnt = pdbus->nrt_data_paths_cnt;
u32 total_data_paths_cnt = pdbus->data_paths_cnt;
- u32 rt_data_paths_cnt = total_data_paths_cnt -
- nrt_data_paths_cnt;
if (!bw_table || !total_data_paths_cnt ||
total_data_paths_cnt > MAX_AXI_PORT_COUNT) {
@@ -386,36 +310,12 @@ static int _sde_power_data_bus_set_quota(
return -EINVAL;
}
- if (nrt_data_paths_cnt) {
-
- ab_quota_rt = div_u64(ab_quota_rt, rt_data_paths_cnt);
- ab_quota_nrt = div_u64(ab_quota_nrt,
- nrt_data_paths_cnt);
-
- ib_quota_rt = div_u64(ib_quota_rt,
- rt_data_paths_cnt);
- ib_quota_nrt = div_u64(ib_quota_nrt,
- nrt_data_paths_cnt);
-
- for (i = 0; i < total_data_paths_cnt; i++) {
- if (i < rt_data_paths_cnt) {
- ab_quota[i] = ab_quota_rt;
- ib_quota[i] = ib_quota_rt;
- } else {
- ab_quota[i] = ab_quota_nrt;
- ib_quota[i] = ib_quota_nrt;
- }
- }
- } else {
- ab_quota[0] = div_u64(ab_quota_rt + ab_quota_nrt,
- total_data_paths_cnt);
- ib_quota[0] = div_u64(ib_quota_rt + ib_quota_nrt,
- total_data_paths_cnt);
-
- for (i = 1; i < total_data_paths_cnt; i++) {
- ab_quota[i] = ab_quota[0];
- ib_quota[i] = ib_quota[0];
- }
+ ab_quota[0] = div_u64(in_ab_quota, total_data_paths_cnt);
+ ib_quota[0] = div_u64(in_ib_quota, total_data_paths_cnt);
+
+ for (i = 1; i < total_data_paths_cnt; i++) {
+ ab_quota[i] = ab_quota[0];
+ ib_quota[i] = ib_quota[0];
}
new_uc_idx = (pdbus->curr_bw_uc_idx %
@@ -427,14 +327,12 @@ static int _sde_power_data_bus_set_quota(
vect->ib = ib_quota[i];
pr_debug(
- "%s uc_idx=%d %s path idx=%d ab=%llu ib=%llu\n",
- bw_table->name,
- new_uc_idx, (i < rt_data_paths_cnt) ?
- "rt" : "nrt", i, vect->ab, vect->ib);
+ "%s uc_idx=%d idx=%d ab=%llu ib=%llu\n",
+ bw_table->name, new_uc_idx, i, vect->ab,
+ vect->ib);
}
}
pdbus->curr_bw_uc_idx = new_uc_idx;
- pdbus->ao_bw_uc_idx = new_uc_idx;
SDE_ATRACE_BEGIN("msm_bus_scale_req");
rc = msm_bus_scale_client_update_request(pdbus->data_bus_hdl,
@@ -445,46 +343,22 @@ static int _sde_power_data_bus_set_quota(
}
int sde_power_data_bus_set_quota(struct sde_power_handle *phandle,
- struct sde_power_client *pclient,
- int bus_client, u32 bus_id,
- u64 ab_quota, u64 ib_quota)
+ u32 bus_id, u64 ab_quota, u64 ib_quota)
{
int rc = 0;
- int i;
- u64 total_ab_rt = 0, total_ib_rt = 0;
- u64 total_ab_nrt = 0, total_ib_nrt = 0;
- struct sde_power_client *client;
- if (!phandle || !pclient ||
- bus_client >= SDE_POWER_HANDLE_DATA_BUS_CLIENT_MAX ||
- bus_id >= SDE_POWER_HANDLE_DBUS_ID_MAX) {
+ if (!phandle || bus_id >= SDE_POWER_HANDLE_DBUS_ID_MAX) {
pr_err("invalid parameters\n");
return -EINVAL;
}
mutex_lock(&phandle->phandle_lock);
- pclient->ab[bus_client] = ab_quota;
- pclient->ib[bus_client] = ib_quota;
- trace_sde_perf_update_bus(bus_client, bus_id, ab_quota, ib_quota);
-
- list_for_each_entry(client, &phandle->power_client_clist, list) {
- for (i = 0; i < SDE_POWER_HANDLE_DATA_BUS_CLIENT_MAX; i++) {
- if (i == SDE_POWER_HANDLE_DATA_BUS_CLIENT_NRT) {
- total_ab_nrt += client->ab[i];
- total_ib_nrt += client->ib[i];
- } else {
- total_ab_rt += client->ab[i];
- total_ib_rt = max(total_ib_rt, client->ib[i]);
- }
- }
- }
+ trace_sde_perf_update_bus(bus_id, ab_quota, ib_quota);
if (phandle->data_bus_handle[bus_id].data_bus_hdl)
rc = _sde_power_data_bus_set_quota(
- &phandle->data_bus_handle[bus_id],
- total_ab_rt, total_ab_nrt,
- total_ib_rt, total_ib_nrt);
+ &phandle->data_bus_handle[bus_id], ab_quota, ib_quota);
mutex_unlock(&phandle->phandle_lock);
@@ -507,52 +381,33 @@ static int sde_power_data_bus_parse(struct platform_device *pdev,
int rc = 0;
int paths;
- pdbus->bus_channels = 1;
- rc = of_property_read_u32(pdev->dev.of_node,
- "qcom,sde-dram-channels", &pdbus->bus_channels);
- if (rc) {
- pr_debug("number of channels property not specified\n");
- rc = 0;
- }
+ node = of_get_child_by_name(pdev->dev.of_node, name);
+ if (!node)
+ goto end;
- pdbus->nrt_data_paths_cnt = 0;
- rc = of_property_read_u32(pdev->dev.of_node,
- "qcom,sde-num-nrt-paths",
- &pdbus->nrt_data_paths_cnt);
+ rc = of_property_read_u32(node, "qcom,msm-bus,num-paths", &paths);
if (rc) {
- pr_debug("number of axi port property not specified\n");
- rc = 0;
+ pr_err("Error. qcom,msm-bus,num-paths not found\n");
+ return rc;
}
+ pdbus->data_paths_cnt = paths;
- node = of_get_child_by_name(pdev->dev.of_node, name);
- if (node) {
- rc = of_property_read_u32(node,
- "qcom,msm-bus,num-paths", &paths);
- if (rc) {
- pr_err("Error. qcom,msm-bus,num-paths not found\n");
- return rc;
- }
- pdbus->data_paths_cnt = paths;
-
- pdbus->data_bus_scale_table =
- msm_bus_pdata_from_node(pdev, node);
- if (IS_ERR_OR_NULL(pdbus->data_bus_scale_table)) {
- pr_err("reg bus handle parsing failed\n");
- rc = PTR_ERR(pdbus->data_bus_scale_table);
- if (!pdbus->data_bus_scale_table)
- rc = -EINVAL;
- goto end;
- }
- pdbus->data_bus_hdl = msm_bus_scale_register_client(
- pdbus->data_bus_scale_table);
- if (!pdbus->data_bus_hdl) {
- pr_err("data_bus_client register failed\n");
+ pdbus->data_bus_scale_table = msm_bus_pdata_from_node(pdev, node);
+ if (IS_ERR_OR_NULL(pdbus->data_bus_scale_table)) {
+ pr_err("reg bus handle parsing failed\n");
+ rc = PTR_ERR(pdbus->data_bus_scale_table);
+ if (!pdbus->data_bus_scale_table)
rc = -EINVAL;
- goto end;
- }
- pr_debug("register %s data_bus_hdl=%x\n", name,
- pdbus->data_bus_hdl);
+ goto end;
+ }
+ pdbus->data_bus_hdl = msm_bus_scale_register_client(
+ pdbus->data_bus_scale_table);
+ if (!pdbus->data_bus_hdl) {
+ pr_err("data_bus_client register failed\n");
+ rc = -EINVAL;
+ goto end;
}
+ pr_debug("register %s data_bus_hdl=%x\n", name, pdbus->data_bus_hdl);
end:
return rc;
@@ -595,41 +450,6 @@ static void sde_power_reg_bus_unregister(u32 reg_bus_hdl)
msm_bus_scale_unregister_client(reg_bus_hdl);
}
-int sde_power_data_bus_state_update(struct sde_power_handle *phandle,
- bool enable)
-{
- int i;
-
- if (!phandle) {
- pr_err("invalid param\n");
- return -EINVAL;
- }
-
- for (i = SDE_POWER_HANDLE_DBUS_ID_MNOC;
- i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++)
- phandle->data_bus_handle[i].enable = enable;
-
- return 0;
-}
-
-static int sde_power_data_bus_update(struct sde_power_data_bus_handle *pdbus,
- bool enable)
-{
- int rc = 0;
-
- pdbus->enable = enable;
-
- if (pdbus->data_bus_hdl)
- rc = _sde_power_data_bus_set_quota(pdbus, pdbus->ab_rt,
- pdbus->ab_nrt, pdbus->ib_rt, pdbus->ib_nrt);
-
- if (rc)
- pr_err("failed to set data bus vote rc=%d enable:%d\n",
- rc, enable);
-
- return rc;
-}
-
static int sde_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
{
int rc = 0;
@@ -647,6 +467,13 @@ static int sde_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
return rc;
}
#else
+static int _sde_power_data_bus_set_quota(
+ struct sde_power_data_bus_handle *pdbus,
+ u64 in_ab_quota, u64 in_ib_quota)
+{
+ return 0;
+}
+
static int sde_power_data_bus_parse(struct platform_device *pdev,
struct sde_power_data_bus_handle *pdbus, const char *name)
{
@@ -659,9 +486,7 @@ static void sde_power_data_bus_unregister(
}
int sde_power_data_bus_set_quota(struct sde_power_handle *phandle,
- struct sde_power_client *pclient,
- int bus_client, u32 bus_id,
- u64 ab_quota, u64 ib_quota)
+ u32 bus_id, u64 ab_quota, u64 ib_quota)
{
return 0;
}
@@ -681,12 +506,6 @@ static int sde_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
return 0;
}
-static int sde_power_data_bus_update(struct sde_power_data_bus_handle *pdbus,
- bool enable)
-{
- return 0;
-}
-
int sde_power_data_bus_state_update(struct sde_power_handle *phandle,
bool enable)
{
@@ -763,7 +582,6 @@ int sde_power_resource_init(struct platform_device *pdev,
else
pr_debug("cx ipeak client parse failed\n");
- INIT_LIST_HEAD(&phandle->power_client_clist);
INIT_LIST_HEAD(&phandle->event_list);
phandle->rsc_client = NULL;
@@ -797,7 +615,6 @@ void sde_power_resource_deinit(struct platform_device *pdev,
struct sde_power_handle *phandle)
{
struct dss_module_power *mp;
- struct sde_power_client *curr_client, *next_client;
struct sde_power_event *curr_event, *next_event;
int i;
@@ -808,15 +625,6 @@ void sde_power_resource_deinit(struct platform_device *pdev,
mp = &phandle->mp;
mutex_lock(&phandle->phandle_lock);
- list_for_each_entry_safe(curr_client, next_client,
- &phandle->power_client_clist, list) {
- pr_err("cliend:%s-%d still registered with refcount:%d\n",
- curr_client->name, curr_client->id,
- curr_client->refcount);
- curr_client->active = false;
- list_del(&curr_client->list);
- }
-
list_for_each_entry_safe(curr_event, next_event,
&phandle->event_list, list) {
pr_err("event:%d, client:%s still registered\n",
@@ -852,47 +660,22 @@ void sde_power_resource_deinit(struct platform_device *pdev,
sde_rsc_client_destroy(phandle->rsc_client);
}
-
int sde_power_scale_reg_bus(struct sde_power_handle *phandle,
- struct sde_power_client *pclient, u32 usecase_ndx, bool skip_lock)
+ u32 usecase_ndx, bool skip_lock)
{
- struct sde_power_client *client;
int rc = 0;
- u32 max_usecase_ndx = VOTE_INDEX_DISABLE;
- if (!skip_lock) {
+ if (!skip_lock)
mutex_lock(&phandle->phandle_lock);
- if (WARN_ON(pclient->refcount == 0)) {
- /*
- * This is not expected, clients calling without skip
- * lock are outside the power resource enable, which
- * means that they should have enabled the power
- * resource before trying to scale.
- */
- rc = -EINVAL;
- goto exit;
- }
- }
-
- pr_debug("%pS: current idx:%d requested:%d client:%d\n",
- __builtin_return_address(0), pclient->usecase_ndx,
- usecase_ndx, pclient->id);
-
- pclient->usecase_ndx = usecase_ndx;
-
- list_for_each_entry(client, &phandle->power_client_clist, list) {
- if (client->usecase_ndx < VOTE_INDEX_MAX &&
- client->usecase_ndx > max_usecase_ndx)
- max_usecase_ndx = client->usecase_ndx;
- }
+ pr_debug("%pS: requested:%d\n",
+ __builtin_return_address(0), usecase_ndx);
rc = sde_power_reg_bus_update(phandle->reg_bus_hdl,
- max_usecase_ndx);
+ usecase_ndx);
if (rc)
pr_err("failed to set reg bus vote rc=%d\n", rc);
-exit:
if (!skip_lock)
mutex_unlock(&phandle->phandle_lock);
@@ -914,16 +697,12 @@ static inline bool _resource_changed(u32 current_usecase_ndx,
return false;
}
-int sde_power_resource_enable(struct sde_power_handle *phandle,
- struct sde_power_client *pclient, bool enable)
+int sde_power_resource_enable(struct sde_power_handle *phandle, bool enable)
{
- int rc = 0, i;
- bool changed = false;
- u32 max_usecase_ndx = VOTE_INDEX_DISABLE, prev_usecase_ndx;
- struct sde_power_client *client;
+ int rc = 0, i = 0;
struct dss_module_power *mp;
- if (!phandle || !pclient) {
+ if (!phandle) {
pr_err("invalid input argument\n");
return -EINVAL;
}
@@ -931,42 +710,8 @@ int sde_power_resource_enable(struct sde_power_handle *phandle,
mp = &phandle->mp;
mutex_lock(&phandle->phandle_lock);
- if (enable)
- pclient->refcount++;
- else if (pclient->refcount)
- pclient->refcount--;
- if (pclient->refcount)
- pclient->usecase_ndx = VOTE_INDEX_LOW;
- else
- pclient->usecase_ndx = VOTE_INDEX_DISABLE;
-
- list_for_each_entry(client, &phandle->power_client_clist, list) {
- if (client->usecase_ndx < VOTE_INDEX_MAX &&
- client->usecase_ndx > max_usecase_ndx)
- max_usecase_ndx = client->usecase_ndx;
- }
-
- /*
- * Check if we need to enable/disable the power resource, we won't
- * only-scale up/down the AHB vote in this API; if a client wants to
- * bump up the AHB clock above the LOW (default) level, it needs to
- * call 'sde_power_scale_reg_bus' with the desired vote after the power
- * resource was enabled.
- */
- if (_resource_changed(phandle->current_usecase_ndx,
- max_usecase_ndx)) {
- changed = true;
- prev_usecase_ndx = phandle->current_usecase_ndx;
- phandle->current_usecase_ndx = max_usecase_ndx;
- }
-
- pr_debug("%pS: changed=%d current idx=%d request client %s id:%u enable:%d refcount:%d\n",
- __builtin_return_address(0), changed, max_usecase_ndx,
- pclient->name, pclient->id, enable, pclient->refcount);
-
- if (!changed)
- goto end;
+ pr_debug("enable:%d\n", enable);
SDE_ATRACE_BEGIN("sde_power_resource_enable");
@@ -977,13 +722,16 @@ int sde_power_resource_enable(struct sde_power_handle *phandle,
sde_power_event_trigger_locked(phandle,
SDE_POWER_EVENT_PRE_ENABLE);
- for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) {
- rc = sde_power_data_bus_update(
- &phandle->data_bus_handle[i], enable);
+ for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX &&
+ phandle->data_bus_handle[i].data_bus_hdl; i++) {
+ rc = _sde_power_data_bus_set_quota(
+ &phandle->data_bus_handle[i],
+ SDE_POWER_HANDLE_ENABLE_BUS_AB_QUOTA,
+ SDE_POWER_HANDLE_ENABLE_BUS_IB_QUOTA);
if (rc) {
pr_err("failed to set data bus vote id=%d rc=%d\n",
i, rc);
- goto data_bus_hdl_err;
+ goto vreg_err;
}
}
rc = msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg,
@@ -993,8 +741,7 @@ int sde_power_resource_enable(struct sde_power_handle *phandle,
goto vreg_err;
}
- rc = sde_power_scale_reg_bus(phandle, pclient,
- max_usecase_ndx, true);
+ rc = sde_power_scale_reg_bus(phandle, VOTE_INDEX_LOW, true);
if (rc) {
pr_err("failed to set reg bus vote rc=%d\n", rc);
goto reg_bus_hdl_err;
@@ -1025,20 +772,21 @@ int sde_power_resource_enable(struct sde_power_handle *phandle,
msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
- sde_power_scale_reg_bus(phandle, pclient,
- max_usecase_ndx, true);
+ sde_power_scale_reg_bus(phandle, VOTE_INDEX_DISABLE, true);
msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, enable);
- for (i = 0 ; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++)
- sde_power_data_bus_update(&phandle->data_bus_handle[i],
- enable);
+ for (i = SDE_POWER_HANDLE_DBUS_ID_MAX - 1; i >= 0; i--)
+ if (phandle->data_bus_handle[i].data_bus_hdl)
+ _sde_power_data_bus_set_quota(
+ &phandle->data_bus_handle[i],
+ SDE_POWER_HANDLE_DISABLE_BUS_AB_QUOTA,
+ SDE_POWER_HANDLE_DISABLE_BUS_IB_QUOTA);
sde_power_event_trigger_locked(phandle,
SDE_POWER_EVENT_POST_DISABLE);
}
-end:
SDE_EVT32_VERBOSE(enable, SDE_EVTLOG_FUNC_EXIT);
mutex_unlock(&phandle->phandle_lock);
SDE_ATRACE_END("sde_power_resource_enable");
@@ -1047,29 +795,20 @@ end:
clk_err:
sde_power_rsc_update(phandle, false);
rsc_err:
- sde_power_scale_reg_bus(phandle, pclient, max_usecase_ndx, true);
+ sde_power_scale_reg_bus(phandle, VOTE_INDEX_DISABLE, true);
reg_bus_hdl_err:
msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, 0);
vreg_err:
- for (i = 0 ; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++)
- sde_power_data_bus_update(&phandle->data_bus_handle[i], 0);
-data_bus_hdl_err:
- phandle->current_usecase_ndx = prev_usecase_ndx;
+ for (i-- ; i >= 0 && phandle->data_bus_handle[i].data_bus_hdl; i--)
+ _sde_power_data_bus_set_quota(
+ &phandle->data_bus_handle[i],
+ SDE_POWER_HANDLE_DISABLE_BUS_AB_QUOTA,
+ SDE_POWER_HANDLE_DISABLE_BUS_IB_QUOTA);
mutex_unlock(&phandle->phandle_lock);
SDE_ATRACE_END("sde_power_resource_enable");
return rc;
}
-int sde_power_resource_is_enabled(struct sde_power_handle *phandle)
-{
- if (!phandle) {
- pr_err("invalid input argument\n");
- return false;
- }
-
- return phandle->current_usecase_ndx != VOTE_INDEX_DISABLE;
-}
-
int sde_cx_ipeak_vote(struct sde_power_handle *phandle, struct dss_clk *clock,
u64 requested_clk_rate, u64 prev_clk_rate, bool enable_vote)
{
diff --git a/msm/sde_power_handle.h b/msm/sde_power_handle.h
index d14441cb..3505c2b0 100644
--- a/msm/sde_power_handle.h
+++ b/msm/sde_power_handle.h
@@ -74,37 +74,10 @@ enum SDE_POWER_HANDLE_DBUS_ID {
};
/**
- * struct sde_power_client: stores the power client for sde driver
- * @name: name of the client
- * @usecase_ndx: current regs bus vote type
- * @refcount: current refcount if multiple modules are using same
- * same client for enable/disable. Power module will
- * aggregate the refcount and vote accordingly for this
- * client.
- * @id: assigned during create. helps for debugging.
- * @list: list to attach power handle master list
- * @ab: arbitrated bandwidth for each bus client
- * @ib: instantaneous bandwidth for each bus client
- * @active: inidcates the state of sde power handle
- */
-struct sde_power_client {
- char name[MAX_CLIENT_NAME_LEN];
- short usecase_ndx;
- short refcount;
- u32 id;
- struct list_head list;
- u64 ab[SDE_POWER_HANDLE_DATA_BUS_CLIENT_MAX];
- u64 ib[SDE_POWER_HANDLE_DATA_BUS_CLIENT_MAX];
- bool active;
-};
-
-/**
* struct sde_power_data_handle: power handle struct for data bus
* @data_bus_scale_table: pointer to bus scaling table
* @data_bus_hdl: current data bus handle
* @data_paths_cnt: number of rt data path ports
- * @nrt_data_paths_cnt: number of nrt data path ports
- * @bus_channels: number of memory bus channels
* @curr_bw_uc_idx: current use case index of data bus
* @ao_bw_uc_idx: active only use case index of data bus
* @ab_rt: realtime ab quota
@@ -117,8 +90,6 @@ struct sde_power_data_bus_handle {
struct msm_bus_scale_pdata *data_bus_scale_table;
u32 data_bus_hdl;
u32 data_paths_cnt;
- u32 nrt_data_paths_cnt;
- u32 bus_channels;
u32 curr_bw_uc_idx;
u32 ao_bw_uc_idx;
u64 ab_rt;
@@ -149,7 +120,6 @@ struct sde_power_event {
/**
* struct sde_power_handle: power handle main struct
* @mp: module power for clock and regulator
- * @client_clist: master list to store all clients
* @phandle_lock: lock to synchronize the enable/disable
* @dev: pointer to device structure
* @usecase_ndx: current usecase index
@@ -162,7 +132,6 @@ struct sde_power_event {
*/
struct sde_power_handle {
struct dss_module_power mp;
- struct list_head power_client_clist;
struct mutex phandle_lock;
struct device *dev;
u32 current_usecase_ndx;
@@ -196,40 +165,17 @@ void sde_power_resource_deinit(struct platform_device *pdev,
struct sde_power_handle *pdata);
/**
- * sde_power_client_create() - create the client on power handle
- * @pdata: power handle containing the resources
- * @client_name: new client name for registration
- *
- * Return: error code.
- */
-struct sde_power_client *sde_power_client_create(struct sde_power_handle *pdata,
- char *client_name);
-
-/**
- * sde_power_client_destroy() - destroy the client on power handle
- * @pdata: power handle containing the resources
- * @client_name: new client name for registration
- *
- * Return: none
- */
-void sde_power_client_destroy(struct sde_power_handle *phandle,
- struct sde_power_client *client);
-
-/**
* sde_power_resource_enable() - enable/disable the power resources
* @pdata: power handle containing the resources
- * @client: client information to enable/disable its vote
* @enable: boolean request for enable/disable
*
* Return: error code.
*/
-int sde_power_resource_enable(struct sde_power_handle *pdata,
- struct sde_power_client *pclient, bool enable);
+int sde_power_resource_enable(struct sde_power_handle *pdata, bool enable);
/**
* sde_power_scale_reg_bus() - Scale the registers bus for the specified client
* @phandle: power handle containing the resources
- * @pclient: client information to scale its vote
* @usecase_ndx: new use case to scale the reg bus
* @skip_lock: will skip holding the power rsrc mutex during the call, this is
* for internal callers that already hold this required lock.
@@ -237,15 +183,7 @@ int sde_power_resource_enable(struct sde_power_handle *pdata,
* Return: error code.
*/
int sde_power_scale_reg_bus(struct sde_power_handle *phandle,
- struct sde_power_client *pclient, u32 usecase_ndx, bool skip_lock);
-
-/**
- * sde_power_resource_is_enabled() - return true if power resource is enabled
- * @pdata: power handle containing the resources
- *
- * Return: true if enabled; false otherwise
- */
-int sde_power_resource_is_enabled(struct sde_power_handle *pdata);
+ u32 usecase_ndx, bool skip_lock);
/**
* sde_power_data_bus_state_update() - update data bus state
@@ -311,8 +249,6 @@ int sde_power_clk_set_flags(struct sde_power_handle *pdata,
/**
* sde_power_data_bus_set_quota() - set data bus quota for power client
* @phandle: power handle containing the resources
- * @client: client information to set quota
- * @bus_client: real-time or non-real-time bus client
* @bus_id: identifier of data bus, see SDE_POWER_HANDLE_DBUS_ID
* @ab_quota: arbitrated bus bandwidth
* @ib_quota: instantaneous bus bandwidth
@@ -320,20 +256,17 @@ int sde_power_clk_set_flags(struct sde_power_handle *pdata,
* Return: zero if success, or error code otherwise
*/
int sde_power_data_bus_set_quota(struct sde_power_handle *phandle,
- struct sde_power_client *pclient,
- int bus_client, u32 bus_id,
- u64 ab_quota, u64 ib_quota);
+ u32 bus_id, u64 ab_quota, u64 ib_quota);
/**
* sde_power_data_bus_bandwidth_ctrl() - control data bus bandwidth enable
* @phandle: power handle containing the resources
- * @client: client information to bandwidth control
* @enable: true to enable bandwidth for data base
*
* Return: none
*/
void sde_power_data_bus_bandwidth_ctrl(struct sde_power_handle *phandle,
- struct sde_power_client *pclient, int enable);
+ int enable);
/**
* sde_power_handle_register_event - register a callback function for an event.
diff --git a/msm/sde_rsc.c b/msm/sde_rsc.c
index f12f6bf5..8bf5385d 100644
--- a/msm/sde_rsc.c
+++ b/msm/sde_rsc.c
@@ -15,6 +15,7 @@
#include <linux/mutex.h>
#include <linux/of_platform.h>
#include <linux/module.h>
+#include <linux/pm_runtime.h>
#include <soc/qcom/rpmh.h>
#include <drm/drmP.h>
@@ -277,64 +278,6 @@ enum sde_rsc_state get_sde_rsc_current_state(int rsc_index)
}
EXPORT_SYMBOL(get_sde_rsc_current_state);
-static int sde_rsc_clk_enable(struct sde_power_handle *phandle,
- struct sde_power_client *pclient, bool enable)
-{
- int rc = 0;
- struct dss_module_power *mp;
-
- if (!phandle || !pclient) {
- pr_err("invalid input argument\n");
- return -EINVAL;
- }
-
- mp = &phandle->mp;
-
- if (enable)
- pclient->refcount++;
- else if (pclient->refcount)
- pclient->refcount--;
-
- if (pclient->refcount)
- pclient->usecase_ndx = VOTE_INDEX_LOW;
- else
- pclient->usecase_ndx = VOTE_INDEX_DISABLE;
-
- if (phandle->current_usecase_ndx == pclient->usecase_ndx)
- goto end;
-
- if (enable) {
- rc = msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg,
- enable);
- if (rc) {
- pr_err("failed to enable vregs rc=%d\n", rc);
- goto end;
- }
-
- rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
- if (rc) {
- pr_err("clock enable failed rc:%d\n", rc);
- msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg,
- !enable);
- goto end;
- }
- } else {
- msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
-
- rc = msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg,
- enable);
- if (rc) {
- pr_err("failed to disable vregs rc=%d\n", rc);
- goto end;
- }
- }
-
- phandle->current_usecase_ndx = pclient->usecase_ndx;
-
-end:
- return rc;
-}
-
static u32 sde_rsc_timer_calculate(struct sde_rsc_priv *rsc,
struct sde_rsc_cmd_config *cmd_config, enum sde_rsc_state state)
{
@@ -484,7 +427,7 @@ static int sde_rsc_switch_to_cmd(struct sde_rsc_priv *rsc,
*/
if (rsc->current_state == SDE_RSC_CMD_STATE) {
rc = 0;
- if (config && rsc->version < SDE_RSC_REV_3)
+ if (config)
goto vsync_wait;
else
goto end;
@@ -504,8 +447,7 @@ static int sde_rsc_switch_to_cmd(struct sde_rsc_priv *rsc,
vsync_wait:
/* indicate wait for vsync for vid to cmd state switch & cfg update */
- if (!rc && (rsc->version < SDE_RSC_REV_3) &&
- (rsc->current_state == SDE_RSC_VID_STATE ||
+ if (!rc && (rsc->current_state == SDE_RSC_VID_STATE ||
rsc->current_state == SDE_RSC_CMD_STATE)) {
/* clear VSYNC timestamp for indication when update completes */
if (rsc->hw_ops.hw_vsync)
@@ -623,7 +565,7 @@ static int sde_rsc_switch_to_vid(struct sde_rsc_priv *rsc,
*/
if (rsc->current_state == SDE_RSC_VID_STATE) {
rc = 0;
- if (config && rsc->version < SDE_RSC_REV_3)
+ if (config)
goto vsync_wait;
else
goto end;
@@ -644,8 +586,7 @@ static int sde_rsc_switch_to_vid(struct sde_rsc_priv *rsc,
vsync_wait:
/* indicate wait for vsync for vid to cmd state switch & cfg update */
- if (!rc && (rsc->version < SDE_RSC_REV_3) &&
- (rsc->current_state == SDE_RSC_VID_STATE ||
+ if (!rc && (rsc->current_state == SDE_RSC_VID_STATE ||
rsc->current_state == SDE_RSC_CMD_STATE)) {
/* clear VSYNC timestamp for indication when update completes */
if (rsc->hw_ops.hw_vsync)
@@ -879,7 +820,7 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client,
caller_client->name, state);
if (rsc->current_state == SDE_RSC_IDLE_STATE)
- sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
+ pm_runtime_get_sync(rsc->dev);
switch (state) {
case SDE_RSC_IDLE_STATE:
@@ -936,7 +877,7 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client,
clk_disable:
if (rsc->current_state == SDE_RSC_IDLE_STATE)
- sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false);
+ pm_runtime_put_sync(rsc->dev);
end:
mutex_unlock(&rsc->client_lock);
return rc;
@@ -1013,8 +954,8 @@ int sde_rsc_client_trigger_vote(struct sde_rsc_client *caller_client,
rsc->bw_config.ib_vote[i] = rsc->bw_config.new_ib_vote[i];
}
- rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
- if (rc)
+ rc = pm_runtime_get_sync(rsc->dev);
+ if (rc < 0)
goto clk_enable_fail;
if (delta_vote) {
@@ -1031,8 +972,6 @@ int sde_rsc_client_trigger_vote(struct sde_rsc_client *caller_client,
rpmh_invalidate(rsc->rpmh_dev);
for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++)
sde_power_data_bus_set_quota(&rsc->phandle,
- rsc->pclient,
- SDE_POWER_HANDLE_DATA_BUS_CLIENT_RT,
i, rsc->bw_config.ab_vote[i],
rsc->bw_config.ib_vote[i]);
rpmh_flush(rsc->rpmh_dev);
@@ -1046,7 +985,7 @@ int sde_rsc_client_trigger_vote(struct sde_rsc_client *caller_client,
rsc->hw_ops.tcs_use_ok(rsc);
end:
- sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false);
+ pm_runtime_put_sync(rsc->dev);
clk_enable_fail:
mutex_unlock(&rsc->client_lock);
@@ -1353,8 +1292,7 @@ static void sde_rsc_deinit(struct platform_device *pdev,
if (!rsc)
return;
- if (rsc->pclient)
- sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false);
+ pm_runtime_put_sync(rsc->dev);
if (rsc->sw_fs_enabled)
regulator_disable(rsc->fs);
if (rsc->fs)
@@ -1363,14 +1301,64 @@ static void sde_rsc_deinit(struct platform_device *pdev,
msm_dss_iounmap(&rsc->wrapper_io);
if (rsc->drv_io.base)
msm_dss_iounmap(&rsc->drv_io);
- if (rsc->pclient)
- sde_power_client_destroy(&rsc->phandle, rsc->pclient);
sde_power_resource_deinit(pdev, &rsc->phandle);
debugfs_remove_recursive(rsc->debugfs_root);
kfree(rsc);
}
+#ifdef CONFIG_PM
+static int sde_rsc_runtime_suspend(struct device *dev)
+{
+ struct sde_rsc_priv *rsc = dev_get_drvdata(dev);
+ struct dss_module_power *mp;
+
+ if (!rsc) {
+ pr_err("invalid drv data\n");
+ return -EINVAL;
+ }
+
+ mp = &rsc->phandle.mp;
+ msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
+ msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, false);
+
+ return 0;
+}
+
+static int sde_rsc_runtime_resume(struct device *dev)
+{
+ struct sde_rsc_priv *rsc = dev_get_drvdata(dev);
+ struct dss_module_power *mp;
+ int rc = 0;
+
+ if (!rsc) {
+ pr_err("invalid drv data\n");
+ return -EINVAL;
+ }
+
+ mp = &rsc->phandle.mp;
+ rc = msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, true);
+ if (rc) {
+ pr_err("failed to enable vregs rc=%d\n", rc);
+ goto end;
+ }
+
+ rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true);
+ if (rc) {
+ pr_err("clock enable failed rc:%d\n", rc);
+ msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, false);
+ }
+
+end:
+ return rc;
+}
+#endif
+
+static const struct dev_pm_ops sde_rsc_pm_ops = {
+ SET_RUNTIME_PM_OPS(sde_rsc_runtime_suspend,
+ sde_rsc_runtime_resume, NULL)
+};
+
/**
* sde_rsc_bind - bind rsc device with controlling device
* @dev: Pointer to base of platform device
@@ -1464,6 +1452,7 @@ static int sde_rsc_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, rsc);
+ rsc->dev = &pdev->dev;
of_property_read_u32(pdev->dev.of_node, "qcom,sde-rsc-version",
&rsc->version);
@@ -1492,20 +1481,6 @@ static int sde_rsc_probe(struct platform_device *pdev)
goto sde_rsc_fail;
}
- rsc->pclient = sde_power_client_create(&rsc->phandle, "rsc");
- if (IS_ERR_OR_NULL(rsc->pclient)) {
- ret = PTR_ERR(rsc->pclient);
- rsc->pclient = NULL;
- pr_err("sde rsc:power client create failed ret:%d\n", ret);
- goto sde_rsc_fail;
- }
-
- /**
- * sde rsc should always vote through enable path, sleep vote is
- * set to "0" by default.
- */
- sde_power_data_bus_state_update(&rsc->phandle, true);
-
rsc->rpmh_dev = rpmh_dev[SDE_RSC_INDEX + counter];
if (IS_ERR_OR_NULL(rsc->rpmh_dev)) {
ret = !rsc->rpmh_dev ? -EINVAL : PTR_ERR(rsc->rpmh_dev);
@@ -1550,15 +1525,17 @@ static int sde_rsc_probe(struct platform_device *pdev)
rsc->sw_fs_enabled = true;
- if (sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true)) {
- pr_err("failed to enable sde rsc power resources\n");
+ pm_runtime_enable(rsc->dev);
+ ret = pm_runtime_get_sync(rsc->dev);
+ if (ret < 0) {
+ pr_err("failed to enable sde rsc power resources rc:%d\n", ret);
goto sde_rsc_fail;
}
if (sde_rsc_timer_calculate(rsc, NULL, SDE_RSC_IDLE_STATE))
goto sde_rsc_fail;
- sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false);
+ pm_runtime_put_sync(rsc->dev);
INIT_LIST_HEAD(&rsc->client_list);
INIT_LIST_HEAD(&rsc->event_list);
@@ -1636,6 +1613,7 @@ static struct platform_driver sde_rsc_platform_driver = {
.name = "sde_rsc",
.of_match_table = dt_match,
.suppress_bind_attrs = true,
+ .pm = &sde_rsc_pm_ops,
},
};
diff --git a/msm/sde_rsc_priv.h b/msm/sde_rsc_priv.h
index 5aab0df8..ac4b295a 100644
--- a/msm/sde_rsc_priv.h
+++ b/msm/sde_rsc_priv.h
@@ -141,7 +141,6 @@ struct sde_rsc_bw_config {
* struct sde_rsc_priv: sde resource state coordinator(rsc) private handle
* @version: rsc sequence version
* @phandle: module power handle for clocks
- * @pclient: module power client of phandle
* @fs: "MDSS GDSC" handle
* @sw_fs_enabled: track "MDSS GDSC" sw vote during probe
*
@@ -179,11 +178,11 @@ struct sde_rsc_bw_config {
* rsc_vsync_wait: Refcount to indicate if we have to wait for the vsync.
* rsc_vsync_waitq: Queue to wait for the vsync.
* bw_config: check sde_rsc_bw_config structure description.
+ * dev: rsc device node
*/
struct sde_rsc_priv {
u32 version;
struct sde_power_handle phandle;
- struct sde_power_client *pclient;
struct regulator *fs;
bool sw_fs_enabled;
@@ -218,6 +217,7 @@ struct sde_rsc_priv {
wait_queue_head_t rsc_vsync_waitq;
struct sde_rsc_bw_config bw_config;
+ struct device *dev;
};
/**