drm: msm: dsi-staging: alter clock enabling path in DSI driver
This change alters clock voting mechansim on DSI DRM driver.DSI driver
creates sde power client in order to vote for core clocks.
CRs-Fixed: 2023444
Change-Id: I7e2ec962d97cb2b8969a6d9c49c393f5f29784f2
Signed-off-by: Shashank Babu Chinta Venkata <sbchin@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_clk.h b/drivers/gpu/drm/msm/dsi-staging/dsi_clk.h
index 0e2e7ec..2a84a2d 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_clk.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_clk.h
@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/clk.h>
+#include "sde_power_handle.h"
#define MAX_STRING_LEN 32
#define MAX_DSI_CTRL 2
@@ -67,6 +68,8 @@
* @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
*/
struct dsi_core_clk_info {
struct clk *mdp_core_clk;
@@ -74,6 +77,8 @@
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;
};
/**
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c b/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c
index 9650a0b..2fcf10ba 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c
@@ -185,10 +185,12 @@
{
int rc = 0;
- rc = clk_prepare_enable(c_clks->clks.mdp_core_clk);
- if (rc) {
- pr_err("failed to enable mdp_core_clk, rc=%d\n", rc);
- goto error;
+ if (c_clks->clks.mdp_core_clk) {
+ rc = clk_prepare_enable(c_clks->clks.mdp_core_clk);
+ if (rc) {
+ pr_err("failed to enable mdp_core_clk, rc=%d\n", rc);
+ goto error;
+ }
}
if (c_clks->clks.mnoc_clk) {
@@ -199,28 +201,36 @@
}
}
- rc = clk_prepare_enable(c_clks->clks.iface_clk);
- if (rc) {
- pr_err("failed to enable iface_clk, rc=%d\n", rc);
- goto error_disable_mnoc_clk;
+ if (c_clks->clks.iface_clk) {
+ rc = clk_prepare_enable(c_clks->clks.iface_clk);
+ if (rc) {
+ pr_err("failed to enable iface_clk, rc=%d\n", rc);
+ goto error_disable_mnoc_clk;
+ }
}
- rc = clk_prepare_enable(c_clks->clks.bus_clk);
- if (rc) {
- pr_err("failed to enable bus_clk, rc=%d\n", rc);
- goto error_disable_iface_clk;
+ if (c_clks->clks.bus_clk) {
+ rc = clk_prepare_enable(c_clks->clks.bus_clk);
+ if (rc) {
+ pr_err("failed to enable bus_clk, rc=%d\n", rc);
+ goto error_disable_iface_clk;
+ }
}
- rc = clk_prepare_enable(c_clks->clks.core_mmss_clk);
- if (rc) {
- pr_err("failed to enable core_mmss_clk, rc=%d\n", rc);
- goto error_disable_bus_clk;
+ if (c_clks->clks.core_mmss_clk) {
+ rc = clk_prepare_enable(c_clks->clks.core_mmss_clk);
+ if (rc) {
+ pr_err("failed to enable core_mmss_clk, rc=%d\n", rc);
+ goto error_disable_bus_clk;
+ }
}
- rc = msm_bus_scale_client_update_request(c_clks->bus_handle, 1);
- if (rc) {
- pr_err("bus scale client enable failed, rc=%d\n", rc);
- goto error_disable_mmss_clk;
+ if (c_clks->bus_handle) {
+ rc = msm_bus_scale_client_update_request(c_clks->bus_handle, 1);
+ if (rc) {
+ pr_err("bus scale client enable failed, rc=%d\n", rc);
+ goto error_disable_mmss_clk;
+ }
}
return rc;
@@ -458,11 +468,18 @@
*/
m_clks = &clks[master_ndx];
+ rc = sde_power_resource_enable(m_clks->clks.phandle,
+ m_clks->clks.dsi_core_client, true);
+
+ if (rc) {
+ pr_err("Power resource enable failed, rc=%d\n", rc);
+ goto error;
+ }
rc = dsi_core_clk_start(m_clks);
if (rc) {
pr_err("failed to turn on master clocks, rc=%d\n", rc);
- goto error;
+ goto error_disable_master_resource;
}
/* Turn on rest of the core clocks */
@@ -471,15 +488,28 @@
if (!clk || (clk == m_clks))
continue;
+ rc = sde_power_resource_enable(clk->clks.phandle,
+ clk->clks.dsi_core_client, true);
+ if (rc) {
+ pr_err("Power resource enable failed, rc=%d\n", rc);
+ goto error_disable_master;
+ }
+
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);
goto error_disable_master;
}
}
- return rc;
+
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);
error:
return rc;
}
@@ -547,14 +577,30 @@
continue;
rc = dsi_core_clk_stop(clk);
- if (rc)
- pr_err("failed to turn off clocks, rc=%d\n", rc);
+ if (rc) {
+ pr_debug("failed to turn off clocks, rc=%d\n", rc);
+ 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;
+ }
}
rc = dsi_core_clk_stop(m_clks);
- if (rc)
+ if (rc) {
pr_err("failed to turn off master clocks, rc=%d\n", rc);
+ 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);
+error:
return rc;
}
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index cd851bc..5df48c3 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -490,30 +490,26 @@
core->mdp_core_clk = devm_clk_get(&pdev->dev, "mdp_core_clk");
if (IS_ERR(core->mdp_core_clk)) {
- rc = PTR_ERR(core->mdp_core_clk);
- pr_err("failed to get mdp_core_clk, rc=%d\n", rc);
- goto fail;
+ core->mdp_core_clk = NULL;
+ pr_debug("failed to get mdp_core_clk, rc=%d\n", rc);
}
core->iface_clk = devm_clk_get(&pdev->dev, "iface_clk");
if (IS_ERR(core->iface_clk)) {
- rc = PTR_ERR(core->iface_clk);
- pr_err("failed to get iface_clk, rc=%d\n", rc);
- goto fail;
+ core->iface_clk = NULL;
+ pr_debug("failed to get iface_clk, rc=%d\n", rc);
}
core->core_mmss_clk = devm_clk_get(&pdev->dev, "core_mmss_clk");
if (IS_ERR(core->core_mmss_clk)) {
- rc = PTR_ERR(core->core_mmss_clk);
- pr_err("failed to get core_mmss_clk, rc=%d\n", rc);
- goto fail;
+ core->core_mmss_clk = NULL;
+ pr_debug("failed to get core_mmss_clk, rc=%d\n", rc);
}
core->bus_clk = devm_clk_get(&pdev->dev, "bus_clk");
if (IS_ERR(core->bus_clk)) {
- rc = PTR_ERR(core->bus_clk);
- pr_err("failed to get bus_clk, rc=%d\n", rc);
- goto fail;
+ core->bus_clk = NULL;
+ pr_debug("failed to get bus_clk, rc=%d\n", rc);
}
core->mnoc_clk = devm_clk_get(&pdev->dev, "mnoc_clk");
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index ddf791c..bcaf428 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -2228,10 +2228,12 @@
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) {
@@ -2247,6 +2249,7 @@
drm, display);
return -EINVAL;
}
+ priv = drm->dev_private;
mutex_lock(&display->display_lock);
@@ -2260,7 +2263,6 @@
for (i = 0; i < display->ctrl_count; i++) {
display_ctrl = &display->ctrl[i];
-
rc = dsi_ctrl_drv_init(display_ctrl->ctrl, display->root);
if (rc) {
pr_err("[%s] failed to initialize ctrl[%d], rc=%d\n",
@@ -2280,9 +2282,19 @@
sizeof(struct dsi_core_clk_info));
memcpy(&info.l_clks[i], &display_ctrl->ctrl->clk_info.link_clks,
sizeof(struct dsi_link_clk_info));
+ info.c_clks[i].phandle = &priv->phandle;
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]",
+ dsi_client_name, i);
+ goto error_ctrl_deinit;
+ }
}
info.pre_clkoff_cb = dsi_pre_clkoff_cb;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
index 89bba96..cfbb14ec 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
@@ -29,7 +29,7 @@
#include "dsi_panel.h"
#define MAX_DSI_CTRLS_PER_DISPLAY 2
-
+#define DSI_CLIENT_NAME_SIZE 20
/*
* DSI Validate Mode modifiers
* @DSI_VALIDATE_FLAG_ALLOW_ADJUST: Allow mode validation to also do fixup
diff --git a/drivers/gpu/drm/msm/sde_power_handle.h b/drivers/gpu/drm/msm/sde_power_handle.h
index 4c172a4..4e262a3 100644
--- a/drivers/gpu/drm/msm/sde_power_handle.h
+++ b/drivers/gpu/drm/msm/sde_power_handle.h
@@ -21,6 +21,8 @@
#define SDE_POWER_HANDLE_ENABLE_BUS_IB_QUOTA 64000
#define SDE_POWER_HANDLE_DISABLE_BUS_IB_QUOTA 0
+#include <linux/sde_io_util.h>
+
/**
* mdss_bus_vote_type: register bus vote type
* VOTE_INDEX_DISABLE: removes the client vote