Merge "msm_fb: mdss: Fix suspend/resume for panel driver"
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
index 82e76fc..26bddd9 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
@@ -14,7 +14,7 @@
- qcom,mdss-pan-bpp: Specifies the panel bits per pixel. Default value is 24(rgb888).
18 = for rgb666
16 = for rgb565
-- qcom,panel-phy-regulatorSettings: An array of length 8 that specifies the PHY
+- qcom,panel-phy-regulatorSettings: An array of length 7 that specifies the PHY
regulator settings for the panel.
- qcom,panel-phy-timingSettings: An array of length 12 that specifies the PHY
timing settings for the panel.
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index e685785..e409a0b 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -100,17 +100,21 @@
return ret;
}
- ret = regulator_enable(dsi_drv.vdd_vreg);
- if (ret) {
- pr_err("%s: Failed to enable regulator.\n", __func__);
- return ret;
- }
-
ret = regulator_enable(dsi_drv.vdd_io_vreg);
if (ret) {
pr_err("%s: Failed to enable regulator.\n", __func__);
return ret;
}
+ msleep(20);
+ wmb();
+
+ ret = regulator_enable(dsi_drv.vdd_vreg);
+ if (ret) {
+ pr_err("%s: Failed to enable regulator.\n", __func__);
+ return ret;
+ }
+ msleep(20);
+ wmb();
ret = regulator_enable(dsi_drv.dsi_vreg);
if (ret) {
@@ -130,13 +134,13 @@
return ret;
}
- ret = regulator_disable(dsi_drv.vdd_io_vreg);
+ ret = regulator_disable(dsi_drv.dsi_vreg);
if (ret) {
pr_err("%s: Failed to disable regulator.\n", __func__);
return ret;
}
- ret = regulator_disable(dsi_drv.dsi_vreg);
+ ret = regulator_disable(dsi_drv.vdd_io_vreg);
if (ret) {
pr_err("%s: Failed to disable regulator.\n", __func__);
return ret;
@@ -165,11 +169,11 @@
return 0;
}
-static int mdss_dsi_off(struct mdss_panel_data *pdata)
+static int mdss_dsi_ctrl_unprepare(struct mdss_panel_data *pdata)
{
- int ret = 0;
struct mdss_panel_info *pinfo;
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+ int ret = 0;
ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
panel_data);
@@ -180,9 +184,6 @@
pinfo = &pdata->panel_info;
- if (pdata->panel_info.type == MIPI_VIDEO_PANEL)
- mdss_dsi_controller_cfg(0, pdata);
-
mdss_dsi_op_mode_config(DSI_CMD_MODE, pdata);
ret = ctrl_pdata->off(pdata);
@@ -191,16 +192,23 @@
return ret;
}
+ return ret;
+}
+
+static int mdss_dsi_off(struct mdss_panel_data *pdata)
+{
+ int ret = 0;
+
spin_lock_bh(&dsi_clk_lock);
mdss_dsi_clk_disable(pdata);
- /* disable dsi engine */
- MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004, 0);
-
spin_unlock_bh(&dsi_clk_lock);
mdss_dsi_unprepare_clocks();
+ /* disable DSI controller */
+ mdss_dsi_controller_cfg(0, pdata);
+
ret = mdss_dsi_panel_power_on(0);
if (ret) {
pr_err("%s: Panel power off failed\n", __func__);
@@ -232,11 +240,13 @@
pinfo = &pdata->panel_info;
- MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x118, 1);
- MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x118, 0);
+ ret = mdss_dsi_panel_power_on(1);
+ if (ret) {
+ pr_err("%s: Panel power on failed\n", __func__);
+ return ret;
+ }
mdss_dsi_phy_sw_reset((ctrl_pdata->ctrl_base));
- mdss_dsi_phy_enable((ctrl_pdata->ctrl_base), 1);
mdss_dsi_phy_init(pdata);
mdss_dsi_prepare_clocks();
@@ -312,12 +322,6 @@
wmb();
}
- ret = mdss_dsi_panel_power_on(1);
- if (ret) {
- pr_err("%s: Panel power on failed\n", __func__);
- return ret;
- }
-
ret = ctrl_pdata->on(pdata);
if (ret) {
pr_err("%s: unable to initialize the panel\n", __func__);
@@ -481,6 +485,7 @@
(ctrl_pdata->panel_data).on = mdss_dsi_on;
(ctrl_pdata->panel_data).off = mdss_dsi_off;
+ (ctrl_pdata->panel_data).intf_unprepare = mdss_dsi_ctrl_unprepare;
memcpy(&((ctrl_pdata->panel_data).panel_info),
&(panel_data->panel_info),
sizeof(struct mdss_panel_info));
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index e47891e..5d0d578 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -861,6 +861,16 @@
sleep_us, timeout_us))
pr_info("%s: FIFO status=%x failed\n", __func__, status);
+ /* Check for VIDEO_MODE_ENGINE_BUSY */
+ if (readl_poll_timeout(((ctrl_pdata->ctrl_base) + 0x0008),
+ status,
+ ((status & 0x08) == 0),
+ sleep_us, timeout_us)) {
+ pr_debug("%s: DSI status=%x\n", __func__, status);
+ pr_debug("%s: Doing sw reset\n", __func__);
+ mdss_dsi_sw_reset(pdata);
+ }
+
dsi_ctrl = MIPI_INP((ctrl_pdata->ctrl_base) + 0x0004);
if (enable)
dsi_ctrl |= 0x01;
@@ -884,14 +894,21 @@
return;
}
-
dsi_ctrl = MIPI_INP((ctrl_pdata->ctrl_base) + 0x0004);
- dsi_ctrl &= ~0x07;
+ /*If Video enabled, Keep Video and Cmd mode ON */
+ if (dsi_ctrl & 0x02)
+ dsi_ctrl &= ~0x05;
+ else
+ dsi_ctrl &= ~0x07;
+
if (mode == DSI_VIDEO_MODE) {
dsi_ctrl |= 0x03;
intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK;
} else { /* command mode */
dsi_ctrl |= 0x05;
+ if (pdata->panel_info.type == MIPI_VIDEO_PANEL)
+ dsi_ctrl |= 0x02;
+
intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_ERROR_MASK |
DSI_INTR_CMD_MDP_DONE_MASK;
}
@@ -1102,6 +1119,7 @@
mdss_dsi_buf_init(tp);
mdss_dsi_cmd_dma_add(tp, pkt_size_cmd);
mdss_dsi_cmd_dma_tx(tp, pdata);
+ pr_debug("%s: Max packet size sent\n", __func__);
}
mdss_dsi_buf_init(tp);
@@ -1161,6 +1179,7 @@
rp->len -= diff; /* align bytes */
break;
default:
+ pr_debug("%s: Unknown cmd received\n", __func__);
break;
}
@@ -1261,6 +1280,8 @@
for (i = 0; i < cnt; i++) {
data = (u32)MIPI_INP((ctrl_pdata->ctrl_base) + off);
*lp++ = ntohl(data); /* to network byte order */
+ pr_debug("%s: data = 0x%x and ntohl(data) = 0x%x\n",
+ __func__, data, ntohl(data));
off -= 4;
rp->len += sizeof(*lp);
}
diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
index 63ad5cc..b247e4d 100644
--- a/drivers/video/msm/mdss/mdss_dsi_panel.c
+++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
@@ -40,20 +40,6 @@
static int rst_gpio;
static int disp_en;
-struct qpnp_pin_cfg param = {
- .mode = QPNP_PIN_MODE_DIG_OUT,
- .output_type = QPNP_PIN_OUT_BUF_OPEN_DRAIN_NMOS,
- .invert = QPNP_PIN_INVERT_ENABLE,
- .pull = QPNP_PIN_MPP_PULL_UP_30KOHM,
- .vin_sel = QPNP_PIN_VIN3,
- .out_strength = QPNP_PIN_OUT_STRENGTH_HIGH,
- .select = QPNP_PIN_SEL_DTEST3,
- .master_en = QPNP_PIN_MASTER_ENABLE,
- .aout_ref = QPNP_PIN_AOUT_0V625,
- .ain_route = QPNP_PIN_AIN_AMUX_CH7,
- .cs_out = QPNP_PIN_CS_OUT_20MA,
-};
-
void mdss_dsi_panel_reset(int enable)
{
if (!disp_en)
@@ -64,13 +50,20 @@
pr_debug("%s:%d, reset line not configured\n",
__func__, __LINE__);
+ pr_debug("%s: enable = %d\n", __func__, enable);
+
if (enable) {
- gpio_set_value(disp_en, 1);
gpio_set_value(rst_gpio, 1);
- usleep(10);
+ msleep(20);
+ wmb();
gpio_set_value(rst_gpio, 0);
- usleep(200);
+ udelay(200);
+ wmb();
gpio_set_value(rst_gpio, 1);
+ msleep(20);
+ wmb();
+ gpio_set_value(disp_en, 1);
+ wmb();
} else {
gpio_set_value(rst_gpio, 0);
gpio_set_value(disp_en, 0);
@@ -113,7 +106,7 @@
pr_debug("%s:%d, debug info (mode) : %d\n", __func__, __LINE__,
mipi->mode);
- mdss_dsi_panel_reset(1);
+ mdss_dsi_sw_reset(pdata);
if (mipi->mode == DSI_VIDEO_MODE) {
mdss_dsi_cmds_tx(pdata, &dsi_panel_tx_buf, dsi_panel_on_cmds,
@@ -142,8 +135,6 @@
return -EINVAL;
}
- mdss_dsi_panel_reset(0);
-
return 0;
}
@@ -202,14 +193,6 @@
pr_err("%s:%d, reset gpio not specified\n",
__func__, __LINE__);
} else {
- rc = qpnp_pin_config(rst_gpio, ¶m);
- if (rc) {
- pr_err("request reset gpio failed, rc=%d\n",
- rc);
- gpio_free(disp_en);
- return rc;
- }
-
rc = gpio_request(rst_gpio, "disp_rst_n");
if (rc) {
pr_err("request reset gpio failed, rc=%d\n",
@@ -328,7 +311,7 @@
panel_data->panel_info.mipi.frame_rate = (!rc ? tmp : 60);
data = of_get_property(np, "qcom,panel-phy-regulatorSettings", &len);
- if ((!data) || (len != 8)) {
+ if ((!data) || (len != 7)) {
pr_err("%s:%d, Unable to read Phy regulator settings",
__func__, __LINE__);
goto error;
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 26fbca1..872b6c4 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -577,6 +577,13 @@
ctl->power_on = false;
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+
+ if (pdata->intf_unprepare)
+ ret = pdata->intf_unprepare(pdata);
+
+ if (ret)
+ pr_err("%s: intf_unprepare failed\n", __func__);
+
if (ctl->stop_fnc)
ret = ctl->stop_fnc(ctl);
else
@@ -586,6 +593,7 @@
pr_warn("error powering off intf ctl=%d\n", ctl->num);
ret = pdata->off(pdata);
+
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
ctl->play_cnt = 0;
diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h
index f1a4e50..5cdfe34 100644
--- a/drivers/video/msm/mdss/mdss_panel.h
+++ b/drivers/video/msm/mdss/mdss_panel.h
@@ -86,7 +86,7 @@
/* DSI PHY configuration */
struct mdss_dsi_phy_ctrl {
- uint32_t regulator[8];
+ uint32_t regulator[7];
uint32_t timing[12];
uint32_t ctrl[4];
uint32_t strength[2];
@@ -180,6 +180,7 @@
struct mdss_panel_info panel_info;
void (*set_backlight) (struct mdss_panel_data *pdata,
u32 bl_level);
+ int (*intf_unprepare) (struct mdss_panel_data *pdata);
unsigned char *mmss_cc_base;
/* function entry chain */
diff --git a/drivers/video/msm/mdss/msm_mdss_io_8974.c b/drivers/video/msm/mdss/msm_mdss_io_8974.c
index 545d53c..1232ec6 100644
--- a/drivers/video/msm/mdss/msm_mdss_io_8974.c
+++ b/drivers/video/msm/mdss/msm_mdss_io_8974.c
@@ -212,25 +212,34 @@
{
/* start phy sw reset */
MIPI_OUTP(ctrl_base + 0x12c, 0x0001);
+ udelay(1000);
wmb();
- usleep(1);
/* end phy sw reset */
MIPI_OUTP(ctrl_base + 0x12c, 0x0000);
+ udelay(100);
wmb();
- usleep(1);
}
void mdss_dsi_phy_enable(unsigned char *ctrl_base, int on)
{
if (on) {
+ MIPI_OUTP(ctrl_base + 0x03cc, 0x03);
+ wmb();
+ usleep(100);
MIPI_OUTP(ctrl_base + 0x0220, 0x006);
- usleep(10);
+ wmb();
+ usleep(100);
MIPI_OUTP(ctrl_base + 0x0268, 0x001);
- usleep(10);
+ wmb();
+ usleep(100);
MIPI_OUTP(ctrl_base + 0x0268, 0x000);
- usleep(10);
+ wmb();
+ usleep(100);
MIPI_OUTP(ctrl_base + 0x0220, 0x007);
wmb();
+ MIPI_OUTP(ctrl_base + 0x03cc, 0x01);
+ wmb();
+ usleep(100);
/* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
MIPI_OUTP(ctrl_base + 0x0470, 0x07e);
@@ -266,12 +275,25 @@
pd = ((ctrl_pdata->panel_data).panel_info.mipi).dsi_phy_db;
+ /* Strength ctrl 0 */
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0484, 0x07);
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0484, pd->strength[0]);
+
off = 0x0580; /* phy regulator ctrl settings */
- for (i = 0; i < 8; i++) {
- MIPI_OUTP((ctrl_pdata->ctrl_base) + off, pd->regulator[i]);
- wmb();
- off += 4;
- }
+ /* Regulator ctrl - CAL_PWD_CFG */
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + off + (4 * 6), pd->regulator[6]);
+ /* Regulator ctrl - TEST */
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + off + (4 * 5), pd->regulator[5]);
+ /* Regulator ctrl 3 */
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + off + (4 * 3), pd->regulator[3]);
+ /* Regulator ctrl 2 */
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + off + (4 * 2), pd->regulator[2]);
+ /* Regulator ctrl 1 */
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + off + (4 * 1), pd->regulator[1]);
+ /* Regulator ctrl 0 */
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + off + (4 * 0), pd->regulator[0]);
+ /* Regulator ctrl 4 */
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + off + (4 * 4), pd->regulator[4]);
off = 0x0440; /* phy timing ctrl 0 - 11 */
for (i = 0; i < 12; i++) {
@@ -280,17 +302,15 @@
off += 4;
}
- /* Strength ctrl 0 - 1 */
- MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0484, pd->strength[0]);
- MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0488, pd->strength[1]);
+ /* MMSS_DSI_0_PHY_DSIPHY_CTRL_1 */
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0474, 0x00);
+ /* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0470, 0x5f);
wmb();
- off = 0x04b4; /* phy BIST ctrl 0 - 5 */
- for (i = 0; i < 6; i++) {
- MIPI_OUTP((ctrl_pdata->ctrl_base) + off, pd->bistCtrl[i]);
- wmb();
- off += 4;
- }
+ /* Strength ctrl 1 */
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0488, pd->strength[1]);
+ wmb();
/* 4 lanes + clk lane configuration */
/* lane config n * (0 - 4) & DataPath setup */
@@ -304,4 +324,20 @@
off += 4;
}
}
+
+ /* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0470, 0x7f);
+ wmb();
+
+ /* DSI_0_PHY_DSIPHY_GLBL_TEST_CTRL */
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x04d4, 0x01);
+ wmb();
+
+ off = 0x04b4; /* phy BIST ctrl 0 - 5 */
+ for (i = 0; i < 6; i++) {
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + off, pd->bistCtrl[i]);
+ wmb();
+ off += 4;
+ }
+
}