summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
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);