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>
This commit is contained in:
Aravind Venkateswaran 2016-03-30 16:25:57 -07:00 committed by Jeevan Shriram
parent d5faefb415
commit 37b3e8da8b
5 changed files with 100 additions and 2 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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 {

View file

@ -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);