msm: mdss: hdmi: proper 8974 phy settings for electrical compliance

Fix the PHY programming sequence as per hardware recommendations
to make sure eye diagram compliance is successful specifically for
4k resolutions.

Change-Id: I95a7254fd15f0b1b202d0d7c4a578f2d63cbbead
Signed-off-by: Ajay Singh Parmar <aparmar@codeaurora.org>
This commit is contained in:
Ajay Singh Parmar 2014-10-07 00:53:50 -07:00 committed by Gerrit - the friendly Code Review server
parent 2b9842c479
commit ef78cc6f2b
3 changed files with 123 additions and 85 deletions

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, 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
@ -216,6 +216,8 @@ static void hdmi_vco_disable(struct clk *c)
REG_W(0x0, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(5);
REG_W(0x0, hdmi_phy_base + HDMI_PHY_GLB_CFG);
udelay(5);
REG_W(0x7F, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
clk_disable(mdss_ahb_clk);
@ -479,9 +481,20 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
REG_W(0xF4, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG10);
REG_W(0x02, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG11);
REG_W(0x1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(50);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(200);
REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x07, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1);
REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
REG_W(0xDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0);
@ -493,7 +506,7 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
REG_W(0x1A, hdmi_phy_base + HDMI_PHY_DCC_CFG1);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG0);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG1);
REG_W(0x02, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
REG_W(0x22, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3);
udelay(200);
break;
@ -523,9 +536,20 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
REG_W(0x2a, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG10);
REG_W(0x03, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG11);
REG_W(0X1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(50);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(200);
REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x07, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0X0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1);
REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
REG_W(0XDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0);
@ -537,7 +561,7 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
REG_W(0X1A, hdmi_phy_base + HDMI_PHY_DCC_CFG1);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG0);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG1);
REG_W(0x02, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
REG_W(0x22, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3);
udelay(200);
break;
@ -567,9 +591,20 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
REG_W(0x2A, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG10);
REG_W(0x03, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG11);
REG_W(0x1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(50);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(200);
REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x07, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1);
REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
REG_W(0xDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0);
@ -581,7 +616,7 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
REG_W(0x1A, hdmi_phy_base + HDMI_PHY_DCC_CFG1);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG0);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG1);
REG_W(0x02, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
REG_W(0x22, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3);
udelay(200);
break;
@ -609,9 +644,20 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
REG_W(0x8A, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG10);
REG_W(0x02, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG11);
REG_W(0x1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(50);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(200);
REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x07, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1);
REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
REG_W(0xDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0);
@ -655,9 +701,20 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
REG_W(0xE6, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG10);
REG_W(0x02, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG11);
REG_W(0x1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(50);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(200);
REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x07, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1);
REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
REG_W(0xDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0);
@ -698,9 +755,20 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
REG_W(0x38, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG10);
REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG11);
REG_W(0x1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(50);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(200);
REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x07, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1);
REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
REG_W(0xDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0);
@ -741,9 +809,19 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
REG_W(0x3E, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG10);
REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG11);
REG_W(0x1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(50);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x07, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1);
REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
REG_W(0xDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0);
@ -784,9 +862,20 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
REG_W(0xCD, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG10);
REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG11);
REG_W(0x1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(50);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(200);
REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x07, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1);
REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
REG_W(0xDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0);
@ -798,7 +887,7 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
REG_W(0x1A, hdmi_phy_base + HDMI_PHY_DCC_CFG1);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG0);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG1);
REG_W(0x02, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
REG_W(0x3F, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3);
udelay(200);
break;
@ -812,7 +901,15 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
REG_W(0x1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
udelay(50);
REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x07, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1);
REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
REG_W(0xDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0);
@ -838,18 +935,9 @@ static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
if (rate < 825000000)
REG_W(0x01, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
else
REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
REG_W(0x3F, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3);
REG_W(0x62, hdmi_phy_base + HDMI_PHY_BIST_PATN0);
REG_W(0x03, hdmi_phy_base + HDMI_PHY_BIST_PATN1);
REG_W(0x69, hdmi_phy_base + HDMI_PHY_BIST_PATN2);
REG_W(0x02, hdmi_phy_base + HDMI_PHY_BIST_PATN3);
udelay(200);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_BIST_CFG1);
REG_W(0x00, hdmi_phy_base + HDMI_PHY_BIST_CFG0);
}
/* Make sure writes complete before disabling iface clock */
@ -2664,6 +2752,7 @@ static struct clk_ops hdmi_mux_ops;
static int hdmi_mux_prepare(struct clk *c)
{
int ret = 0;
ret = clk_prepare(mdss_ahb_clk);
if (c && c->ops && c->ops->set_rate)
ret = c->ops->set_rate(c, c->rate);

View File

@ -421,7 +421,6 @@ static const char *hdmi_tx_io_name(u32 type)
{
switch (type) {
case HDMI_TX_CORE_IO: return "core_physical";
case HDMI_TX_PHY_IO: return "phy_physical";
case HDMI_TX_QFPROM_IO: return "qfprom_physical";
default: return NULL;
}
@ -2226,51 +2225,6 @@ static void hdmi_tx_phy_reset(struct hdmi_tx_ctrl *hdmi_ctrl)
DSS_REG_W_ND(io, HDMI_PHY_CTRL, val | SW_RESET_PLL);
} /* hdmi_tx_phy_reset */
static void hdmi_tx_init_phy(struct hdmi_tx_ctrl *hdmi_ctrl)
{
struct dss_io_data *io = NULL;
if (!hdmi_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
return;
}
io = &hdmi_ctrl->pdata.io[HDMI_TX_PHY_IO];
if (!io->base) {
DEV_DBG("%s: phy not initialized or init not available\n",
__func__);
return;
}
DSS_REG_W_ND(io, HDMI_PHY_ANA_CFG0, 0x1B);
DSS_REG_W_ND(io, HDMI_PHY_ANA_CFG1, 0xF2);
DSS_REG_W_ND(io, HDMI_PHY_BIST_CFG0, 0x0);
DSS_REG_W_ND(io, HDMI_PHY_BIST_PATN0, 0x0);
DSS_REG_W_ND(io, HDMI_PHY_BIST_PATN1, 0x0);
DSS_REG_W_ND(io, HDMI_PHY_BIST_PATN2, 0x0);
DSS_REG_W_ND(io, HDMI_PHY_BIST_PATN3, 0x0);
DSS_REG_W_ND(io, HDMI_PHY_PD_CTRL1, 0x20);
} /* hdmi_tx_init_phy */
static void hdmi_tx_powerdown_phy(struct hdmi_tx_ctrl *hdmi_ctrl)
{
struct dss_io_data *io = NULL;
if (!hdmi_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
return;
}
io = &hdmi_ctrl->pdata.io[HDMI_TX_PHY_IO];
if (!io->base) {
DEV_DBG("%s: phy not initialized or pd not available\n",
__func__);
return;
}
DSS_REG_W_ND(io, HDMI_PHY_PD_CTRL0, 0x7F);
} /* hdmi_tx_powerdown_phy */
static int hdmi_tx_audio_acr_setup(struct hdmi_tx_ctrl *hdmi_ctrl,
bool enabled)
{
@ -2790,16 +2744,13 @@ static int hdmi_tx_start(struct hdmi_tx_ctrl *hdmi_ctrl)
}
hdmi_tx_set_mode(hdmi_ctrl, false);
hdmi_tx_init_phy(hdmi_ctrl);
DSS_REG_W(io, HDMI_USEC_REFTIMER, 0x0001001B);
hdmi_tx_set_mode(hdmi_ctrl, true);
DSS_REG_W(io, HDMI_USEC_REFTIMER, 0x0001001B);
rc = hdmi_tx_video_setup(hdmi_ctrl, hdmi_ctrl->video_resolution);
if (rc) {
DEV_ERR("%s: hdmi_tx_video_setup failed. rc=%d\n",
__func__, rc);
hdmi_tx_set_mode(hdmi_ctrl, false);
DEV_ERR("%s: video setup failed. rc=%d\n", __func__, rc);
hdmi_tx_set_mode(hdmi_ctrl, true);
return rc;
}
@ -2816,7 +2767,7 @@ static int hdmi_tx_start(struct hdmi_tx_ctrl *hdmi_ctrl)
hdmi_tx_set_spd_infoframe(hdmi_ctrl);
}
/* todo: CEC */
hdmi_tx_set_mode(hdmi_ctrl, true);
DEV_INFO("%s: HDMI Core: Initialized\n", __func__);
@ -2884,8 +2835,6 @@ static int hdmi_tx_power_off(struct mdss_panel_data *panel_data)
if (!hdmi_tx_is_dvi_mode(hdmi_ctrl))
hdmi_tx_audio_off(hdmi_ctrl);
hdmi_tx_powerdown_phy(hdmi_ctrl);
hdmi_cec_deconfig(hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC]);
hdmi_tx_core_off(hdmi_ctrl);
@ -2928,8 +2877,7 @@ static int hdmi_tx_power_on(struct mdss_panel_data *panel_data)
}
if (!hdmi_ctrl->hpd_initialized) {
DEV_ERR("%s: HDMI on is not possible w/o cable detection.\n",
__func__);
DEV_ERR("%s: hpd not initialized\n", __func__);
return -EPERM;
}
@ -2954,6 +2902,9 @@ static int hdmi_tx_power_on(struct mdss_panel_data *panel_data)
hdmi_cec_config(
hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC]);
hdmi_tx_set_vendor_specific_infoframe(hdmi_ctrl);
hdmi_tx_set_spd_infoframe(hdmi_ctrl);
if (!hdmi_tx_is_hdcp_enabled(hdmi_ctrl))
hdmi_tx_set_audio_switch_node(hdmi_ctrl, 1);
@ -2974,7 +2925,6 @@ static int hdmi_tx_power_on(struct mdss_panel_data *panel_data)
hdmi_cec_config(hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC]);
if (hdmi_ctrl->hpd_state) {
DEV_DBG("%s: Turning HDMI on\n", __func__);
rc = hdmi_tx_start(hdmi_ctrl);
if (rc) {
DEV_ERR("%s: hdmi_tx_start failed. rc=%d\n",
@ -2986,9 +2936,9 @@ static int hdmi_tx_power_on(struct mdss_panel_data *panel_data)
end:
dss_reg_dump(io->base, io->len, "HDMI-ON: ", REG_DUMP);
DEV_INFO("%s: HDMI=%s DVI= %s\n", __func__,
DEV_DBG("%s: Tx: %s (%s mode)\n", __func__,
hdmi_tx_is_controller_on(hdmi_ctrl) ? "ON" : "OFF" ,
hdmi_tx_is_dvi_mode(hdmi_ctrl) ? "ON" : "OFF");
hdmi_tx_is_dvi_mode(hdmi_ctrl) ? "DVI" : "HDMI");
hdmi_tx_hpd_polarity_setup(hdmi_ctrl, HPD_DISCONNECT_POLARITY);

View File

@ -18,7 +18,6 @@
enum hdmi_tx_io_type {
HDMI_TX_CORE_IO,
HDMI_TX_PHY_IO,
HDMI_TX_QFPROM_IO,
HDMI_TX_MAX_IO
};