diff options
author | Dhaval Patel <pdhaval@codeaurora.org> | 2018-05-04 10:08:05 -0700 |
---|---|---|
committer | Dhaval Patel <pdhaval@codeaurora.org> | 2019-04-24 13:27:48 -0700 |
commit | a74d2cf7fa2f7ae79df54ee1a8f20de8e550d097 (patch) | |
tree | 4525cf583c9dbe120a91ba313773ea58282ff506 | |
parent | a702cd897f3c0e114138c11525529df3ef0dd05c (diff) | |
download | display-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.c | 3 | ||||
-rw-r--r-- | msm/dp/dp_power.c | 41 | ||||
-rw-r--r-- | msm/dp/dp_power.h | 5 | ||||
-rw-r--r-- | msm/dsi/dsi_clk.h | 8 | ||||
-rw-r--r-- | msm/dsi/dsi_clk_manager.c | 29 | ||||
-rw-r--r-- | msm/dsi/dsi_display.c | 39 | ||||
-rw-r--r-- | msm/dsi/dsi_display.h | 3 | ||||
-rw-r--r-- | msm/msm_drv.c | 43 | ||||
-rw-r--r-- | msm/msm_drv.h | 1 | ||||
-rw-r--r-- | msm/sde/sde_color_processing.c | 19 | ||||
-rw-r--r-- | msm/sde/sde_core_irq.c | 38 | ||||
-rw-r--r-- | msm/sde/sde_core_perf.c | 21 | ||||
-rw-r--r-- | msm/sde/sde_core_perf.h | 4 | ||||
-rw-r--r-- | msm/sde/sde_crtc.c | 66 | ||||
-rw-r--r-- | msm/sde/sde_crtc.h | 7 | ||||
-rw-r--r-- | msm/sde/sde_encoder.c | 66 | ||||
-rw-r--r-- | msm/sde/sde_kms.c | 108 | ||||
-rw-r--r-- | msm/sde/sde_kms.h | 10 | ||||
-rw-r--r-- | msm/sde/sde_plane.c | 48 | ||||
-rw-r--r-- | msm/sde/sde_trace.h | 9 | ||||
-rw-r--r-- | msm/sde_dbg.c | 54 | ||||
-rw-r--r-- | msm/sde_dbg.h | 4 | ||||
-rw-r--r-- | msm/sde_power_handle.c | 411 | ||||
-rw-r--r-- | msm/sde_power_handle.h | 75 | ||||
-rw-r--r-- | msm/sde_rsc.c | 162 | ||||
-rw-r--r-- | msm/sde_rsc_priv.h | 4 |
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; }; /** |