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>
This commit is contained in:
parent
a702cd897f
commit
a74d2cf7fa
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
rc = pm_runtime_get_sync(sde_kms->dev->dev);
|
||||
if (rc > 0)
|
||||
rc = 0;
|
||||
|
||||
priv = dev->dev_private;
|
||||
if (!priv)
|
||||
return -EINVAL;
|
||||
|
||||
SDE_EVT32(genpd->device_count);
|
||||
|
||||
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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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];
|
||||
|
||||
@ -2825,21 +2825,6 @@ static struct vbif_debug_bus_entry vbif_dbg_bus_msm8998[] = {
|
||||
{0x21c, 0x214, 0, 14, 0, 0xc}, /* xin blocks - clock side */
|
||||
};
|
||||
|
||||
/**
|
||||
* _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
|
||||
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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[0] = div_u64(in_ab_quota, total_data_paths_cnt);
|
||||
ib_quota[0] = div_u64(in_ib_quota, total_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];
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
if (rc) {
|
||||
pr_debug("number of axi port property not specified\n");
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
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;
|
||||
if (!node)
|
||||
goto end;
|
||||
|
||||
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");
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
pr_debug("register %s data_bus_hdl=%x\n", name,
|
||||
pdbus->data_bus_hdl);
|
||||
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");
|
||||
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)
|
||||
{
|
||||
|
@ -73,38 +73,11 @@ enum SDE_POWER_HANDLE_DBUS_ID {
|
||||
SDE_POWER_HANDLE_DBUS_ID_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
@ -195,41 +164,18 @@ int sde_power_resource_init(struct platform_device *pdev,
|
||||
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.
|
||||
|
162
msm/sde_rsc.c
162
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,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user