summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAravind Venkateswaran <aravindh@codeaurora.org>2016-03-30 16:25:57 -0700
committerJeevan Shriram <jshriram@codeaurora.org>2016-04-22 15:00:27 -0700
commit37b3e8da8b31f33cf8984e9cfb561c9fed6ecf5b (patch)
tree313bcb98148b344c633911e8930577f32e07a7c9 /drivers
parentd5faefb4157bbbaeafabaaadd6a5904c23eb8f47 (diff)
msm: mdss: add support for dsi byte interface clock
DSI controller version 2.0 and above require configuring an additional link clock called the byte interface clock which is used to drive all high-speed PPI signals. Add support to configure this clock. CRs-Fixed: 1000724 Change-Id: I907823b21ad2c6152899233fc52f38d17bcc5ed1 Signed-off-by: Aravind Venkateswaran <aravindh@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c25
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_clk.c62
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi_clk.h4
-rw-r--r--drivers/video/fbdev/msm/msm_mdss_io_8974.c9
5 files changed, 100 insertions, 2 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index 903d8741ae13..0573dcb3c9d6 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -2788,6 +2788,7 @@ static int mdss_dsi_ctrl_clock_init(struct platform_device *ctrl_pdev,
info.link_clks.esc_clk = ctrl_pdata->esc_clk;
info.link_clks.byte_clk = ctrl_pdata->byte_clk;
info.link_clks.pixel_clk = ctrl_pdata->pixel_clk;
+ info.link_clks.byte_intf_clk = ctrl_pdata->byte_intf_clk;
info.pre_clkoff_cb = mdss_dsi_pre_clkoff_cb;
info.post_clkon_cb = mdss_dsi_post_clkon_cb;
@@ -2950,6 +2951,24 @@ end:
return rc;
}
+static int mdss_dsi_ctrl_validate_config(struct mdss_dsi_ctrl_pdata *ctrl)
+{
+ int rc = 0;
+
+ /*
+ * check to make sure that the byte interface clock is specified for
+ * DSI ctrl version 2 and above.
+ */
+ if ((ctrl->shared_data->hw_rev >= MDSS_DSI_HW_REV_200) &&
+ (!ctrl->byte_intf_clk)) {
+ pr_err("%s: byte intf clk must be defined for hw rev 0x%08x\n",
+ __func__, ctrl->shared_data->hw_rev);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
{
int rc = 0;
@@ -3099,6 +3118,12 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
INIT_DELAYED_WORK(&ctrl_pdata->dba_work, mdss_dsi_dba_work);
+ rc = mdss_dsi_ctrl_validate_config(ctrl_pdata);
+ if (rc) {
+ pr_err("%s: invalid controller configuration\n", __func__);
+ goto error_shadow_clk_deinit;
+ }
+
pr_info("%s: Dsi Ctrl->%d initialized, DSI rev:0x%x, PHY rev:0x%x\n",
__func__, index, ctrl_pdata->shared_data->hw_rev,
ctrl_pdata->shared_data->phy_rev);
diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h
index 56e12dc5ca48..c91bc29c9bcc 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.h
+++ b/drivers/video/fbdev/msm/mdss_dsi.h
@@ -57,6 +57,7 @@
#define MDSS_DSI_HW_REV_104 0x10040000 /* 8996 */
#define MDSS_DSI_HW_REV_104_1 0x10040001 /* 8996 */
#define MDSS_DSI_HW_REV_104_2 0x10040002 /* 8937 */
+#define MDSS_DSI_HW_REV_200 0x20000000 /* cobalt */
#define MDSS_DSI_HW_REV_STEP_0 0x0
#define MDSS_DSI_HW_REV_STEP_1 0x1
@@ -419,6 +420,7 @@ struct mdss_dsi_ctrl_pdata {
struct clk *byte_clk_rcg;
struct clk *pixel_clk_rcg;
struct clk *vco_dummy_clk;
+ struct clk *byte_intf_clk;
u8 ctrl_state;
int panel_mode;
int irq_cnt;
diff --git a/drivers/video/fbdev/msm/mdss_dsi_clk.c b/drivers/video/fbdev/msm/mdss_dsi_clk.c
index 727d6707444c..a43174d8ce84 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_clk.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_clk.c
@@ -178,6 +178,21 @@ static int dsi_link_clk_set_rate(struct dsi_link_clks *l_clks)
goto error;
}
+ /*
+ * If byte_intf_clk is present, set rate for that too.
+ * For DPHY:
+ * byte_intf_clk_rate = byte_clk_rate / 2
+ * todo: this needs to be revisited when support for CPHY is added
+ */
+ if (l_clks->clks.byte_intf_clk) {
+ rc = clk_set_rate(l_clks->clks.byte_intf_clk,
+ l_clks->byte_clk_rate / 2);
+ if (rc) {
+ pr_err("set rate failed for byte intf clk rc=%d\n", rc);
+ goto error;
+ }
+ }
+
error:
return rc;
}
@@ -204,8 +219,19 @@ static int dsi_link_clk_prepare(struct dsi_link_clks *l_clks)
goto pixel_clk_err;
}
+ if (l_clks->clks.byte_intf_clk) {
+ rc = clk_prepare(l_clks->clks.byte_intf_clk);
+ if (rc) {
+ pr_err("%s: Failed to prepare dsi byte_intf clk\n",
+ __func__);
+ goto byte_intf_clk_err;
+ }
+ }
+
return rc;
+byte_intf_clk_err:
+ clk_unprepare(l_clks->clks.pixel_clk);
pixel_clk_err:
clk_unprepare(l_clks->clks.byte_clk);
byte_clk_err:
@@ -218,6 +244,8 @@ static int dsi_link_clk_unprepare(struct dsi_link_clks *l_clks)
{
int rc = 0;
+ if (l_clks->clks.byte_intf_clk)
+ clk_unprepare(l_clks->clks.byte_intf_clk);
clk_unprepare(l_clks->clks.pixel_clk);
clk_unprepare(l_clks->clks.byte_clk);
clk_unprepare(l_clks->clks.esc_clk);
@@ -247,8 +275,19 @@ static int dsi_link_clk_enable(struct dsi_link_clks *l_clks)
goto pixel_clk_err;
}
+ if (l_clks->clks.byte_intf_clk) {
+ rc = clk_enable(l_clks->clks.byte_intf_clk);
+ if (rc) {
+ pr_err("%s: Failed to enable dsi byte_intf clk\n",
+ __func__);
+ goto byte_intf_clk_err;
+ }
+ }
+
return rc;
+byte_intf_clk_err:
+ clk_disable(l_clks->clks.pixel_clk);
pixel_clk_err:
clk_disable(l_clks->clks.byte_clk);
byte_clk_err:
@@ -261,6 +300,8 @@ static int dsi_link_clk_disable(struct dsi_link_clks *l_clks)
{
int rc = 0;
+ if (l_clks->clks.byte_intf_clk)
+ clk_disable(l_clks->clks.byte_intf_clk);
clk_disable(l_clks->clks.esc_clk);
clk_disable(l_clks->clks.pixel_clk);
clk_disable(l_clks->clks.byte_clk);
@@ -622,9 +663,27 @@ static int dsi_set_clk_rate(struct mdss_dsi_clk_mngr *mngr, int clk, u32 rate,
mngr->link_clks.byte_clk_rate = rate;
if (!flags) {
rc = clk_set_rate(mngr->link_clks.clks.byte_clk, rate);
- if (rc)
+ if (rc) {
pr_err("set rate failed for byte clk rc=%d\n",
rc);
+ goto error;
+ }
+
+ /*
+ * If byte_intf_clk is present, set rate for that too.
+ * For DPHY:
+ * byte_intf_clk_rate = byte_clk_rate / 2
+ * todo: this needs to be revisited when support for
+ * CPHY is added.
+ */
+ if (mngr->link_clks.clks.byte_intf_clk) {
+ rc = clk_set_rate(
+ mngr->link_clks.clks.byte_intf_clk,
+ rate / 2);
+ if (rc)
+ pr_err("set rate failed for byte intf clk rc=%d\n",
+ rc);
+ }
}
break;
case MDSS_DSI_LINK_PIX_CLK:
@@ -642,6 +701,7 @@ static int dsi_set_clk_rate(struct mdss_dsi_clk_mngr *mngr, int clk, u32 rate,
break;
}
+error:
return rc;
}
diff --git a/drivers/video/fbdev/msm/mdss_dsi_clk.h b/drivers/video/fbdev/msm/mdss_dsi_clk.h
index d42228b48171..f4d9c016e0c5 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_clk.h
+++ b/drivers/video/fbdev/msm/mdss_dsi_clk.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -36,6 +36,7 @@ enum mdss_dsi_link_clk_type {
MDSS_DSI_LINK_ESC_CLK,
MDSS_DSI_LINK_BYTE_CLK,
MDSS_DSI_LINK_PIX_CLK,
+ MDSS_DSI_LINK_BYTE_INTF_CLK,
MDSS_DSI_LINK_CLK_MAX,
};
@@ -105,6 +106,7 @@ struct mdss_dsi_link_clk_info {
struct clk *esc_clk;
struct clk *byte_clk;
struct clk *pixel_clk;
+ struct clk *byte_intf_clk;
};
struct dsi_panel_clk_ctrl {
diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
index 805f58d65e62..f14082968d84 100644
--- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c
+++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
@@ -1416,6 +1416,8 @@ error:
void mdss_dsi_link_clk_deinit(struct device *dev,
struct mdss_dsi_ctrl_pdata *ctrl)
{
+ if (ctrl->byte_intf_clk)
+ devm_clk_put(dev, ctrl->byte_intf_clk);
if (ctrl->vco_dummy_clk)
devm_clk_put(dev, ctrl->vco_dummy_clk);
if (ctrl->pixel_clk_rcg)
@@ -1490,6 +1492,13 @@ int mdss_dsi_link_clk_init(struct platform_device *pdev,
ctrl->vco_dummy_clk = NULL;
}
+ ctrl->byte_intf_clk = devm_clk_get(dev, "byte_intf_clk");
+ if (IS_ERR(ctrl->byte_intf_clk)) {
+ pr_debug("%s: can't find byte int clk. rc=%d\n", __func__, rc);
+ ctrl->byte_intf_clk = NULL;
+ }
+
+
error:
if (rc)
mdss_dsi_link_clk_deinit(dev, ctrl);