-
-
Save invisiblek/b3debf9d92b08990b0a7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c | |
index e54adc4..ee8994a 100644 | |
--- a/drivers/video/msm/mdss/mdss_dsi.c | |
+++ b/drivers/video/msm/mdss/mdss_dsi.c | |
@@ -1,4 +1,4 @@ | |
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. | |
+/* Copyright (c) 2012-2014, 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 | |
@@ -21,17 +21,12 @@ | |
#include <linux/gpio.h> | |
#include <linux/err.h> | |
#include <linux/regulator/consumer.h> | |
-#ifdef CONFIG_LGE_MIPI_DSI_LGD_NT35521_WXGA | |
-#include <mach/board_lge.h> | |
-#endif | |
#include "mdss.h" | |
#include "mdss_panel.h" | |
#include "mdss_dsi.h" | |
#include "mdss_debug.h" | |
-static unsigned char *mdss_dsi_base; | |
- | |
static int mdss_dsi_regulator_init(struct platform_device *pdev) | |
{ | |
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; | |
@@ -67,6 +62,9 @@ static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata, int enable) | |
panel_data); | |
pr_debug("%s: enable=%d\n", __func__, enable); | |
+ if (pdata->panel_info.dynamic_switch_pending) | |
+ return 0; | |
+ | |
if (enable) { | |
ret = msm_dss_enable_vreg( | |
ctrl_pdata->power_data.vreg_config, | |
@@ -77,29 +75,25 @@ static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata, int enable) | |
goto error; | |
} | |
-#ifdef CONFIG_LGE_MIPI_DSI_LGD_NT35521_WXGA | |
- if (pdata->panel_info.panel_power_on == 0) | |
- nt35521_panel_power(pdata,1); | |
-#endif | |
- ret = mdss_dsi_panel_reset(pdata, 1); | |
+ if (!pdata->panel_info.mipi.lp11_init) { | |
+ ret = mdss_dsi_panel_reset(pdata, 1); | |
+ if (ret) { | |
+ pr_err("%s: Panel reset failed. rc=%d\n", | |
+ __func__, ret); | |
+ if (msm_dss_enable_vreg( | |
+ ctrl_pdata->power_data.vreg_config, | |
+ ctrl_pdata->power_data.num_vreg, 0)) | |
+ pr_err("Disable vregs failed\n"); | |
+ goto error; | |
+ } | |
+ } | |
+ } else { | |
+ ret = mdss_dsi_panel_reset(pdata, 0); | |
if (ret) { | |
pr_err("%s: Panel reset failed. rc=%d\n", | |
__func__, ret); | |
- if (msm_dss_enable_vreg( | |
- ctrl_pdata->power_data.vreg_config, | |
- ctrl_pdata->power_data.num_vreg, 0)) | |
- pr_err("Disable vregs failed\n"); | |
goto error; | |
} | |
- | |
- } else { | |
-#ifdef CONFIG_LGE_MIPI_DSI_LGD_NT35521_WXGA | |
- mdelay(120); | |
-#endif | |
- mdss_dsi_panel_reset(pdata, 0); | |
-#ifdef CONFIG_LGE_MIPI_DSI_LGD_NT35521_WXGA | |
- nt35521_panel_power(pdata,0); | |
-#endif | |
ret = msm_dss_enable_vreg( | |
ctrl_pdata->power_data.vreg_config, | |
ctrl_pdata->power_data.num_vreg, 0); | |
@@ -107,9 +101,6 @@ static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata, int enable) | |
pr_err("%s: Failed to disable vregs.rc=%d\n", | |
__func__, ret); | |
} | |
-#ifdef CONFIG_LGE_MIPI_DSI_LGD_NT35521_WXGA | |
- mdelay(1); | |
-#endif | |
} | |
error: | |
return ret; | |
@@ -140,7 +131,7 @@ static int mdss_dsi_get_dt_vreg_data(struct device *dev, | |
if (!dev || !mp) { | |
pr_err("%s: invalid input\n", __func__); | |
rc = -EINVAL; | |
- goto error; | |
+ return rc; | |
} | |
of_node = dev->of_node; | |
@@ -320,7 +311,7 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata) | |
if (!pdata->panel_info.panel_power_on) { | |
pr_warn("%s:%d Panel already off.\n", __func__, __LINE__); | |
- return -EPERM; | |
+ return 0; | |
} | |
pdata->panel_info.panel_power_on = 0; | |
@@ -328,33 +319,25 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata) | |
ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, | |
panel_data); | |
+ mutex_lock(&ctrl_pdata->mutex); | |
panel_info = &ctrl_pdata->panel_data.panel_info; | |
pr_debug("%s+: ctrl=%p ndx=%d\n", __func__, | |
ctrl_pdata, ctrl_pdata->ndx); | |
if (pdata->panel_info.type == MIPI_CMD_PANEL) | |
- mdss_dsi_clk_ctrl(ctrl_pdata, 1); | |
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); | |
/* disable DSI controller */ | |
mdss_dsi_controller_cfg(0, pdata); | |
- mdss_dsi_clk_ctrl(ctrl_pdata, 0); | |
- | |
- ret = mdss_dsi_enable_bus_clocks(ctrl_pdata); | |
- if (ret) { | |
- pr_err("%s: failed to enable bus clocks. rc=%d\n", __func__, | |
- ret); | |
- mdss_dsi_panel_power_on(pdata, 0); | |
- return ret; | |
- } | |
- | |
/* disable DSI phy */ | |
- mdss_dsi_phy_enable(ctrl_pdata, 0); | |
+ mdss_dsi_phy_disable(ctrl_pdata); | |
- mdss_dsi_disable_bus_clocks(ctrl_pdata); | |
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); | |
ret = mdss_dsi_panel_power_on(pdata, 0); | |
if (ret) { | |
+ mutex_unlock(&ctrl_pdata->mutex); | |
pr_err("%s: Panel power off failed\n", __func__); | |
return ret; | |
} | |
@@ -364,71 +347,28 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata) | |
&& (panel_info->new_fps != panel_info->mipi.frame_rate)) | |
panel_info->mipi.frame_rate = panel_info->new_fps; | |
+ mutex_unlock(&ctrl_pdata->mutex); | |
pr_debug("%s-:\n", __func__); | |
return ret; | |
} | |
-int mdss_dsi_on(struct mdss_panel_data *pdata) | |
+static void __mdss_dsi_ctrl_setup(struct mdss_panel_data *pdata) | |
{ | |
- int ret = 0; | |
- u32 clk_rate; | |
+ struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; | |
struct mdss_panel_info *pinfo; | |
struct mipi_panel_info *mipi; | |
+ u32 clk_rate; | |
u32 hbp, hfp, vbp, vfp, hspw, vspw, width, height; | |
u32 ystride, bpp, data, dst_bpp; | |
u32 dummy_xres, dummy_yres; | |
- struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; | |
u32 hsync_period, vsync_period; | |
-#ifdef CONFIG_LGE_MIPI_DSI_LGD_NT35521_WXGA | |
- u32 tmp; | |
-#endif | |
- | |
- if (pdata == NULL) { | |
- pr_err("%s: Invalid input data\n", __func__); | |
- return -EINVAL; | |
- } | |
- | |
- if (pdata->panel_info.panel_power_on) { | |
- pr_warn("%s:%d Panel already on.\n", __func__, __LINE__); | |
- return 0; | |
- } | |
ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, | |
panel_data); | |
- pr_debug("%s+: ctrl=%p ndx=%d\n", | |
- __func__, ctrl_pdata, ctrl_pdata->ndx); | |
- | |
pinfo = &pdata->panel_info; | |
- ret = msm_dss_enable_vreg(ctrl_pdata->power_data.vreg_config, | |
- ctrl_pdata->power_data.num_vreg, 1); | |
- if (ret) { | |
- pr_err("%s:Failed to enable vregs. rc=%d\n", __func__, ret); | |
- return ret; | |
- } | |
- | |
- pdata->panel_info.panel_power_on = 1; | |
- | |
- if (!pdata->panel_info.mipi.lp11_init) | |
- mdss_dsi_panel_reset(pdata, 1); | |
- | |
- ret = mdss_dsi_enable_bus_clocks(ctrl_pdata); | |
- if (ret) { | |
- pr_err("%s: failed to enable bus clocks. rc=%d\n", __func__, | |
- ret); | |
- mdss_dsi_panel_power_on(pdata, 0); | |
- pdata->panel_info.panel_power_on = 0; | |
- return ret; | |
- } | |
- | |
- mdss_dsi_phy_sw_reset((ctrl_pdata->ctrl_base)); | |
- mdss_dsi_phy_init(pdata); | |
- mdss_dsi_disable_bus_clocks(ctrl_pdata); | |
- | |
- mdss_dsi_clk_ctrl(ctrl_pdata, 1); | |
- | |
clk_rate = pdata->panel_info.clk_rate; | |
clk_rate = min(clk_rate, pdata->panel_info.clk_max); | |
@@ -458,7 +398,7 @@ int mdss_dsi_on(struct mdss_panel_data *pdata) | |
vsync_period = vspw + vbp + height + dummy_yres + vfp; | |
hsync_period = hspw + hbp + width + dummy_xres + hfp; | |
- mipi = &pdata->panel_info.mipi; | |
+ mipi = &pdata->panel_info.mipi; | |
if (pdata->panel_info.type == MIPI_VIDEO_PANEL) { | |
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x24, | |
((hspw + hbp + width + dummy_xres) << 16 | | |
@@ -496,34 +436,290 @@ int mdss_dsi_on(struct mdss_panel_data *pdata) | |
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x64, data); | |
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x5C, data); | |
} | |
+} | |
- mdss_dsi_sw_reset(pdata); | |
- mdss_dsi_host_init(mipi, pdata); | |
+static inline bool __mdss_dsi_ulps_feature_enabled( | |
+ struct mdss_panel_data *pdata) | |
+{ | |
+ return pdata->panel_info.ulps_feature_enabled; | |
+} | |
+ | |
+static int mdss_dsi_ulps_config_sub(struct mdss_dsi_ctrl_pdata *ctrl_pdata, | |
+ int enable) | |
+{ | |
+ int ret = 0; | |
+ struct mdss_panel_data *pdata = NULL; | |
+ struct mipi_panel_info *pinfo = NULL; | |
+ u32 lane_status = 0; | |
+ u32 active_lanes = 0; | |
+ | |
+ if (!ctrl_pdata) { | |
+ pr_err("%s: invalid input\n", __func__); | |
+ return -EINVAL; | |
+ } | |
-#ifdef CONFIG_LGE_MIPI_DSI_LGD_NT35521_WXGA | |
- if(nt35521_panel_power(pdata, 1)){ | |
- pr_err("%s:Failed to disable lge_asus_panel_power.rc\n",__func__); | |
+ pdata = &ctrl_pdata->panel_data; | |
+ if (!pdata) { | |
+ pr_err("%s: Invalid panel data\n", __func__); | |
+ return -EINVAL; | |
+ } | |
+ pinfo = &pdata->panel_info.mipi; | |
+ | |
+ if (!__mdss_dsi_ulps_feature_enabled(pdata)) { | |
+ pr_debug("%s: ULPS feature not supported. enable=%d\n", | |
+ __func__, enable); | |
+ return -ENOTSUPP; | |
+ } | |
+ | |
+ if (enable && !ctrl_pdata->ulps) { | |
+ /* No need to configure ULPS mode when entering suspend state */ | |
+ if (!pdata->panel_info.panel_power_on) { | |
+ pr_err("%s: panel off. returning\n", __func__); | |
+ goto error; | |
+ } | |
+ | |
+ if (__mdss_dsi_clk_enabled(ctrl_pdata, DSI_LINK_CLKS)) { | |
+ pr_err("%s: cannot enter ulps mode if dsi clocks are on\n", | |
+ __func__); | |
+ ret = -EPERM; | |
+ goto error; | |
+ } | |
+ | |
+ ret = mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); | |
+ if (ret) { | |
+ pr_err("%s: Failed to enable clocks. rc=%d\n", | |
+ __func__, ret); | |
+ goto error; | |
+ } | |
+ | |
+ /* | |
+ * ULPS Entry Request. | |
+ * Wait for a short duration to ensure that the lanes | |
+ * enter ULP state. | |
+ */ | |
+ MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0AC, 0x01F); | |
+ usleep(100); | |
+ | |
+ /* Check to make sure that all active data lanes are in ULPS */ | |
+ if (pinfo->data_lane3) | |
+ active_lanes |= BIT(11); | |
+ if (pinfo->data_lane2) | |
+ active_lanes |= BIT(10); | |
+ if (pinfo->data_lane1) | |
+ active_lanes |= BIT(9); | |
+ if (pinfo->data_lane0) | |
+ active_lanes |= BIT(8); | |
+ active_lanes |= BIT(12); /* clock lane */ | |
+ lane_status = MIPI_INP(ctrl_pdata->ctrl_base + 0xA8); | |
+ if (lane_status & active_lanes) { | |
+ pr_err("%s: ULPS entry req failed. Lane status=0x%08x\n", | |
+ __func__, lane_status); | |
+ ret = -EINVAL; | |
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); | |
+ goto error; | |
+ } | |
+ | |
+ /* Enable MMSS DSI Clamps */ | |
+ MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, 0x3FF); | |
+ MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, 0x83FF); | |
+ | |
+ wmb(); | |
+ | |
+ MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x108, 0x1); | |
+ /* disable DSI controller */ | |
+ mdss_dsi_controller_cfg(0, pdata); | |
+ | |
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); | |
+ ctrl_pdata->ulps = true; | |
+ } else if (ctrl_pdata->ulps) { | |
+ ret = mdss_dsi_clk_ctrl(ctrl_pdata, DSI_BUS_CLKS, 1); | |
+ if (ret) { | |
+ pr_err("%s: Failed to enable bus clocks. rc=%d\n", | |
+ __func__, ret); | |
+ goto error; | |
+ } | |
+ | |
+ MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x108, 0x0); | |
+ mdss_dsi_phy_init(pdata); | |
+ | |
+ __mdss_dsi_ctrl_setup(pdata); | |
+ mdss_dsi_sw_reset(pdata); | |
+ mdss_dsi_host_init(pdata); | |
+ mdss_dsi_op_mode_config(pdata->panel_info.mipi.mode, | |
+ pdata); | |
+ | |
+ /* | |
+ * ULPS Entry Request. This is needed because, after power | |
+ * collapse and reset, the DSI controller resets back to | |
+ * idle state and not ULPS. | |
+ * Wait for a short duration to ensure that the lanes | |
+ * enter ULP state. | |
+ */ | |
+ MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0AC, 0x01F); | |
+ usleep(100); | |
+ | |
+ /* Disable MMSS DSI Clamps */ | |
+ MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, 0x3FF); | |
+ MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, 0x0); | |
+ | |
+ ret = mdss_dsi_clk_ctrl(ctrl_pdata, DSI_LINK_CLKS, 1); | |
+ if (ret) { | |
+ pr_err("%s: Failed to enable link clocks. rc=%d\n", | |
+ __func__, ret); | |
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_BUS_CLKS, 0); | |
+ goto error; | |
+ } | |
+ | |
+ /* | |
+ * ULPS Exit Request | |
+ * Hardware requirement is to wait for at least 1ms | |
+ */ | |
+ MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0AC, 0x1F00); | |
+ usleep(1000); | |
+ MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0AC, 0x0); | |
+ | |
+ /* | |
+ * Wait for a short duration before enabling | |
+ * data transmission | |
+ */ | |
+ usleep(100); | |
+ | |
+ lane_status = MIPI_INP(ctrl_pdata->ctrl_base + 0xA8); | |
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_LINK_CLKS, 0); | |
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_BUS_CLKS, 0); | |
+ ctrl_pdata->ulps = false; | |
+ } | |
+ | |
+ pr_debug("%s: DSI lane status = 0x%08x. Ulps %s\n", __func__, | |
+ lane_status, enable ? "enabled" : "disabled"); | |
+ | |
+error: | |
+ return ret; | |
+} | |
+ | |
+static int mdss_dsi_update_panel_config(struct mdss_dsi_ctrl_pdata *ctrl_pdata, | |
+ int mode) | |
+{ | |
+ int ret = 0; | |
+ struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info); | |
+ | |
+ if (mode == DSI_CMD_MODE) { | |
+ pinfo->mipi.mode = DSI_CMD_MODE; | |
+ pinfo->type = MIPI_CMD_PANEL; | |
+ pinfo->mipi.vsync_enable = 1; | |
+ pinfo->mipi.hw_vsync_mode = 1; | |
+ } else { /*video mode*/ | |
+ pinfo->mipi.mode = DSI_VIDEO_MODE; | |
+ pinfo->type = MIPI_VIDEO_PANEL; | |
+ pinfo->mipi.vsync_enable = 0; | |
+ pinfo->mipi.hw_vsync_mode = 0; | |
+ } | |
+ | |
+ ctrl_pdata->panel_mode = pinfo->mipi.mode; | |
+ mdss_panel_get_dst_fmt(pinfo->bpp, pinfo->mipi.mode, | |
+ pinfo->mipi.pixel_packing, &(pinfo->mipi.dst_format)); | |
+ pinfo->cont_splash_enabled = 0; | |
+ | |
+ return ret; | |
+} | |
+static int mdss_dsi_ulps_config(struct mdss_dsi_ctrl_pdata *ctrl, | |
+ int enable) | |
+{ | |
+ int rc; | |
+ struct mdss_dsi_ctrl_pdata *mctrl = NULL; | |
+ | |
+ if (&ctrl->mmss_misc_io == NULL) { | |
+ pr_err("%s: mmss_misc_io is NULL. ULPS not valid\n", __func__); | |
+ return -EINVAL; | |
+ } | |
+ | |
+ if (mdss_dsi_is_slave_ctrl(ctrl)) { | |
+ mctrl = mdss_dsi_get_master_ctrl(); | |
+ if (!mctrl) { | |
+ pr_err("%s: Unable to get master control\n", __func__); | |
+ return -EINVAL; | |
+ } | |
+ } | |
+ | |
+ if (mctrl) { | |
+ pr_debug("%s: configuring ulps (%s) for master ctrl%d\n", | |
+ __func__, (enable ? "on" : "off"), ctrl->ndx); | |
+ rc = mdss_dsi_ulps_config_sub(mctrl, enable); | |
+ if (rc) | |
+ return rc; | |
+ } | |
+ | |
+ pr_debug("%s: configuring ulps (%s) for ctrl%d\n", | |
+ __func__, (enable ? "on" : "off"), ctrl->ndx); | |
+ return mdss_dsi_ulps_config_sub(ctrl, enable); | |
+} | |
+ | |
+int mdss_dsi_on(struct mdss_panel_data *pdata) | |
+{ | |
+ int ret = 0; | |
+ struct mdss_panel_info *pinfo; | |
+ struct mipi_panel_info *mipi; | |
+ struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; | |
+ | |
+ if (pdata == NULL) { | |
+ pr_err("%s: Invalid input data\n", __func__); | |
+ return -EINVAL; | |
+ } | |
+ | |
+ if (pdata->panel_info.panel_power_on) { | |
+ pr_warn("%s:%d Panel already on.\n", __func__, __LINE__); | |
return 0; | |
} | |
- mipi->force_clk_lane_hs = 1; | |
- mdelay(5); | |
+ ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, | |
+ panel_data); | |
+ | |
+ pr_debug("%s+: ctrl=%p ndx=%d\n", | |
+ __func__, ctrl_pdata, ctrl_pdata->ndx); | |
+ | |
+ pinfo = &pdata->panel_info; | |
+ mipi = &pdata->panel_info.mipi; | |
- tmp = MIPI_INP((ctrl_pdata->ctrl_base) + 0xac); | |
- tmp &= ~(1<<28); | |
- MIPI_OUTP((ctrl_pdata->ctrl_base) + 0xac, tmp); | |
- wmb(); | |
-#endif | |
+ ret = mdss_dsi_panel_power_on(pdata, 1); | |
+ if (ret) { | |
+ pr_err("%s:Panel power on failed. rc=%d\n", __func__, ret); | |
+ return ret; | |
+ } | |
+ | |
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_BUS_CLKS, 1); | |
+ if (ret) { | |
+ pr_err("%s: failed to enable bus clocks. rc=%d\n", __func__, | |
+ ret); | |
+ ret = mdss_dsi_panel_power_on(pdata, 0); | |
+ if (ret) { | |
+ pr_err("%s: Panel reset failed. rc=%d\n", | |
+ __func__, ret); | |
+ return ret; | |
+ } | |
+ pdata->panel_info.panel_power_on = 0; | |
+ return ret; | |
+ } | |
+ pdata->panel_info.panel_power_on = 1; | |
+ | |
+ mdss_dsi_phy_sw_reset((ctrl_pdata->ctrl_base)); | |
+ mdss_dsi_phy_init(pdata); | |
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_BUS_CLKS, 0); | |
+ | |
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); | |
+ | |
+ __mdss_dsi_ctrl_setup(pdata); | |
+ mdss_dsi_sw_reset(pdata); | |
+ mdss_dsi_host_init(pdata); | |
/* | |
* Issue hardware reset line after enabling the DSI clocks and data | |
* data lanes for LP11 init | |
*/ | |
- if (pdata->panel_info.mipi.lp11_init) | |
+ if (mipi->lp11_init) | |
mdss_dsi_panel_reset(pdata, 1); | |
- if (pdata->panel_info.mipi.init_delay) | |
- usleep(pdata->panel_info.mipi.init_delay); | |
+ if (mipi->init_delay) | |
+ usleep(mipi->init_delay); | |
if (mipi->force_clk_lane_hs) { | |
u32 tmp; | |
@@ -535,7 +731,7 @@ int mdss_dsi_on(struct mdss_panel_data *pdata) | |
} | |
if (pdata->panel_info.type == MIPI_CMD_PANEL) | |
- mdss_dsi_clk_ctrl(ctrl_pdata, 0); | |
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); | |
pr_debug("%s-:\n", __func__); | |
return 0; | |
@@ -559,11 +755,13 @@ static int mdss_dsi_unblank(struct mdss_panel_data *pdata) | |
mipi = &pdata->panel_info.mipi; | |
if (!(ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT)) { | |
- ret = ctrl_pdata->on(pdata); | |
- if (ret) { | |
- pr_err("%s: unable to initialize the panel\n", | |
+ if (!pdata->panel_info.dynamic_switch_pending) { | |
+ ret = ctrl_pdata->on(pdata); | |
+ if (ret) { | |
+ pr_err("%s: unable to initialize the panel\n", | |
__func__); | |
- return ret; | |
+ return ret; | |
+ } | |
} | |
ctrl_pdata->ctrl_state |= CTRL_STATE_PANEL_INIT; | |
} | |
@@ -597,8 +795,36 @@ static int mdss_dsi_blank(struct mdss_panel_data *pdata) | |
panel_data); | |
mipi = &pdata->panel_info.mipi; | |
+ if (__mdss_dsi_ulps_feature_enabled(pdata) && | |
+ (ctrl_pdata->ulps)) { | |
+ /* Disable ULPS mode before blanking the panel */ | |
+ ret = mdss_dsi_ulps_config(ctrl_pdata, 0); | |
+ if (ret) { | |
+ pr_err("%s: failed to exit ULPS mode. rc=%d\n", | |
+ __func__, ret); | |
+ return ret; | |
+ } | |
+ } | |
+ | |
+ if (pdata->panel_info.type == MIPI_VIDEO_PANEL && | |
+ ctrl_pdata->off_cmds.link_state == DSI_LP_MODE) { | |
+ mdss_dsi_sw_reset(pdata); | |
+ mdss_dsi_host_init(pdata); | |
+ } | |
+ | |
mdss_dsi_op_mode_config(DSI_CMD_MODE, pdata); | |
+ if (pdata->panel_info.dynamic_switch_pending) { | |
+ pr_info("%s: switching to %s mode\n", __func__, | |
+ (pdata->panel_info.mipi.mode ? "video" : "command")); | |
+ if (pdata->panel_info.type == MIPI_CMD_PANEL) { | |
+ ctrl_pdata->switch_mode(pdata, DSI_VIDEO_MODE); | |
+ } else if (pdata->panel_info.type == MIPI_VIDEO_PANEL) { | |
+ ctrl_pdata->switch_mode(pdata, DSI_CMD_MODE); | |
+ mdss_dsi_set_tear_off(ctrl_pdata); | |
+ } | |
+ } | |
+ | |
if (pdata->panel_info.type == MIPI_CMD_PANEL) { | |
if (mipi->vsync_enable && mipi->hw_vsync_mode | |
&& gpio_is_valid(ctrl_pdata->disp_te_gpio)) { | |
@@ -607,10 +833,12 @@ static int mdss_dsi_blank(struct mdss_panel_data *pdata) | |
} | |
if (ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT) { | |
- ret = ctrl_pdata->off(pdata); | |
- if (ret) { | |
- pr_err("%s: Panel OFF failed\n", __func__); | |
- return ret; | |
+ if (!pdata->panel_info.dynamic_switch_pending) { | |
+ ret = ctrl_pdata->off(pdata); | |
+ if (ret) { | |
+ pr_err("%s: Panel OFF failed\n", __func__); | |
+ return ret; | |
+ } | |
} | |
ctrl_pdata->ctrl_state &= ~CTRL_STATE_PANEL_INIT; | |
} | |
@@ -643,17 +871,8 @@ int mdss_dsi_cont_splash_on(struct mdss_panel_data *pdata) | |
"Incorrect Ctrl state=0x%x\n", ctrl_pdata->ctrl_state); | |
mdss_dsi_sw_reset(pdata); | |
- mdss_dsi_host_init(mipi, pdata); | |
+ mdss_dsi_host_init(pdata); | |
mdss_dsi_op_mode_config(mipi->mode, pdata); | |
- | |
- if (ctrl_pdata->on_cmds.link_state == DSI_LP_MODE) { | |
- ret = mdss_dsi_unblank(pdata); | |
- if (ret) { | |
- pr_err("%s: unblank failed\n", __func__); | |
- return ret; | |
- } | |
- } | |
- | |
pr_debug("%s-:End\n", __func__); | |
return ret; | |
} | |
@@ -682,33 +901,58 @@ static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps) | |
if (new_fps != | |
ctrl_pdata->panel_data.panel_info.mipi.frame_rate) { | |
- rc = mdss_dsi_clk_div_config | |
- (&ctrl_pdata->panel_data.panel_info, new_fps); | |
- if (rc) { | |
- pr_err("%s: unable to initialize the clk dividers\n", | |
- __func__); | |
- return rc; | |
- } | |
- ctrl_pdata->pclk_rate = | |
- ctrl_pdata->panel_data.panel_info.mipi.dsi_pclk_rate; | |
- ctrl_pdata->byte_clk_rate = | |
- ctrl_pdata->panel_data.panel_info.clk_rate / 8; | |
- | |
if (pdata->panel_info.dfps_update | |
- == DFPS_IMMEDIATE_CLK_UPDATE_MODE) { | |
- dsi_ctrl = MIPI_INP((ctrl_pdata->ctrl_base) + | |
- 0x0004); | |
- ctrl_pdata->panel_data.panel_info.mipi.frame_rate = | |
- new_fps; | |
- dsi_ctrl &= ~0x2; | |
- MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004, | |
- dsi_ctrl); | |
- mdss_dsi_controller_cfg(true, pdata); | |
- mdss_dsi_clk_ctrl(ctrl_pdata, 0); | |
- mdss_dsi_clk_ctrl(ctrl_pdata, 1); | |
- dsi_ctrl |= 0x2; | |
- MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004, | |
- dsi_ctrl); | |
+ == DFPS_IMMEDIATE_PORCH_UPDATE_MODE) { | |
+ u32 hsync_period, vsync_period; | |
+ u32 new_dsi_v_total, current_dsi_v_total; | |
+ vsync_period = | |
+ mdss_panel_get_vtotal(&pdata->panel_info); | |
+ hsync_period = | |
+ mdss_panel_get_htotal(&pdata->panel_info); | |
+ current_dsi_v_total = | |
+ MIPI_INP((ctrl_pdata->ctrl_base) + 0x2C); | |
+ new_dsi_v_total = | |
+ ((vsync_period - 1) << 16) | (hsync_period - 1); | |
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C, | |
+ (current_dsi_v_total | 0x8000000)); | |
+ if (new_dsi_v_total & 0x8000000) { | |
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C, | |
+ new_dsi_v_total); | |
+ } else { | |
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C, | |
+ (new_dsi_v_total | 0x8000000)); | |
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C, | |
+ (new_dsi_v_total & 0x7ffffff)); | |
+ } | |
+ pdata->panel_info.mipi.frame_rate = new_fps; | |
+ } else { | |
+ rc = mdss_dsi_clk_div_config | |
+ (&ctrl_pdata->panel_data.panel_info, new_fps); | |
+ if (rc) { | |
+ pr_err("%s: unable to initialize the clk dividers\n", | |
+ __func__); | |
+ return rc; | |
+ } | |
+ ctrl_pdata->pclk_rate = | |
+ pdata->panel_info.mipi.dsi_pclk_rate; | |
+ ctrl_pdata->byte_clk_rate = | |
+ pdata->panel_info.clk_rate / 8; | |
+ | |
+ if (pdata->panel_info.dfps_update | |
+ == DFPS_IMMEDIATE_CLK_UPDATE_MODE) { | |
+ dsi_ctrl = MIPI_INP((ctrl_pdata->ctrl_base) + | |
+ 0x0004); | |
+ pdata->panel_info.mipi.frame_rate = new_fps; | |
+ dsi_ctrl &= ~0x2; | |
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004, | |
+ dsi_ctrl); | |
+ mdss_dsi_controller_cfg(true, pdata); | |
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); | |
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); | |
+ dsi_ctrl |= 0x2; | |
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004, | |
+ dsi_ctrl); | |
+ } | |
} | |
} else { | |
pr_debug("%s: Panel is already at this FPS\n", __func__); | |
@@ -754,6 +998,15 @@ static int mdss_dsi_ctl_partial_update(struct mdss_panel_data *pdata) | |
return rc; | |
} | |
+int mdss_dsi_register_recovery_handler(struct mdss_dsi_ctrl_pdata *ctrl, | |
+ struct mdss_panel_recovery *recovery) | |
+{ | |
+ mutex_lock(&ctrl->mutex); | |
+ ctrl->recovery = recovery; | |
+ mutex_unlock(&ctrl->mutex); | |
+ return 0; | |
+} | |
+ | |
static int mdss_dsi_event_handler(struct mdss_panel_data *pdata, | |
int event, void *arg) | |
{ | |
@@ -768,6 +1021,8 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata, | |
panel_data); | |
pr_debug("%s+:event=%d\n", __func__, event); | |
+ MDSS_XLOG(event, arg, ctrl_pdata->ndx, 0x3333); | |
+ | |
switch (event) { | |
case MDSS_EVENT_UNBLANK: | |
rc = mdss_dsi_on(pdata); | |
@@ -792,21 +1047,15 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata, | |
rc = mdss_dsi_off(pdata); | |
break; | |
case MDSS_EVENT_CONT_SPLASH_FINISH: | |
+ if (ctrl_pdata->off_cmds.link_state == DSI_LP_MODE) | |
+ rc = mdss_dsi_blank(pdata); | |
ctrl_pdata->ctrl_state &= ~CTRL_STATE_MDP_ACTIVE; | |
- if (ctrl_pdata->on_cmds.link_state == DSI_LP_MODE) { | |
- rc = mdss_dsi_cont_splash_on(pdata); | |
- } else { | |
- pr_debug("%s:event=%d, Dsi On not called: ctrl_state: %d\n", | |
- __func__, event, | |
- ctrl_pdata->on_cmds.link_state); | |
- rc = -EINVAL; | |
- } | |
+ rc = mdss_dsi_cont_splash_on(pdata); | |
break; | |
case MDSS_EVENT_PANEL_CLK_CTRL: | |
mdss_dsi_clk_req(ctrl_pdata, (int)arg); | |
break; | |
case MDSS_EVENT_DSI_CMDLIST_KOFF: | |
- ctrl_pdata->recovery = (struct mdss_panel_recovery *)arg; | |
mdss_dsi_cmdlist_commit(ctrl_pdata, 1); | |
break; | |
case MDSS_EVENT_PANEL_UPDATE_FPS: | |
@@ -825,6 +1074,17 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata, | |
case MDSS_EVENT_ENABLE_PARTIAL_UPDATE: | |
rc = mdss_dsi_ctl_partial_update(pdata); | |
break; | |
+ case MDSS_EVENT_DSI_ULPS_CTRL: | |
+ rc = mdss_dsi_ulps_config(ctrl_pdata, (int)arg); | |
+ break; | |
+ case MDSS_EVENT_REGISTER_RECOVERY_HANDLER: | |
+ rc = mdss_dsi_register_recovery_handler(ctrl_pdata, | |
+ (struct mdss_panel_recovery *)arg); | |
+ break; | |
+ case MDSS_EVENT_DSI_DYNAMIC_SWITCH: | |
+ rc = mdss_dsi_update_panel_config(ctrl_pdata, | |
+ (int)(unsigned long) arg); | |
+ break; | |
default: | |
pr_debug("%s: unhandled event=%d\n", __func__, event); | |
break; | |
@@ -865,35 +1125,39 @@ static struct device_node *mdss_dsi_pref_prim_panel( | |
static struct device_node *mdss_dsi_find_panel_of_node( | |
struct platform_device *pdev, char *panel_cfg) | |
{ | |
- int l; | |
- int ctrl_id = -1; | |
- char *panel_name; | |
+ int len, i; | |
+ int ctrl_id = pdev->id - 1; | |
+ char panel_name[MDSS_MAX_PANEL_LEN]; | |
+ char ctrl_id_stream[3] = "0:"; | |
+ char *stream = NULL, *pan = NULL; | |
struct device_node *dsi_pan_node = NULL, *mdss_node = NULL; | |
- l = strlen(panel_cfg); | |
- if (!l) { | |
+ len = strlen(panel_cfg); | |
+ if (!len) { | |
/* no panel cfg chg, parse dt */ | |
pr_debug("%s:%d: no cmd line cfg present\n", | |
__func__, __LINE__); | |
- dsi_pan_node = mdss_dsi_pref_prim_panel(pdev); | |
+ goto end; | |
} else { | |
- if (panel_cfg[0] == '0') { | |
- pr_debug("%s:%d: DSI ctrl 1\n", __func__, __LINE__); | |
- ctrl_id = 0; | |
- } else if (panel_cfg[0] == '1') { | |
- pr_debug("%s:%d: DSI ctrl 2\n", __func__, __LINE__); | |
- ctrl_id = 1; | |
+ if (ctrl_id == 1) | |
+ strlcpy(ctrl_id_stream, "1:", 3); | |
+ | |
+ stream = strnstr(panel_cfg, ctrl_id_stream, len); | |
+ if (!stream) { | |
+ pr_err("controller config is not present\n"); | |
+ goto end; | |
} | |
- if ((pdev->id - 1) != ctrl_id) { | |
- pr_err("%s:%d:pdev_ID=[%d]\n", | |
- __func__, __LINE__, pdev->id); | |
- return NULL; | |
+ stream += 2; | |
+ | |
+ pan = strnchr(stream, strlen(stream), ':'); | |
+ if (!pan) { | |
+ strlcpy(panel_name, stream, MDSS_MAX_PANEL_LEN); | |
+ } else { | |
+ for (i = 0; (stream + i) < pan; i++) | |
+ panel_name[i] = *(stream + i); | |
+ panel_name[i] = 0; | |
} | |
- /* | |
- * skip first two chars '<dsi_ctrl_id>' and | |
- * ':' to get to the panel name | |
- */ | |
- panel_name = panel_cfg + 2; | |
+ | |
pr_debug("%s:%d:%s:%s\n", __func__, __LINE__, | |
panel_cfg, panel_name); | |
@@ -910,9 +1174,12 @@ static struct device_node *mdss_dsi_find_panel_of_node( | |
if (!dsi_pan_node) { | |
pr_err("%s: invalid pan node, selecting prim panel\n", | |
__func__); | |
- dsi_pan_node = mdss_dsi_pref_prim_panel(pdev); | |
+ goto end; | |
} | |
+ return dsi_pan_node; | |
} | |
+end: | |
+ dsi_pan_node = mdss_dsi_pref_prim_panel(pdev); | |
return dsi_pan_node; | |
} | |
@@ -924,7 +1191,6 @@ static int __devinit mdss_dsi_ctrl_probe(struct platform_device *pdev) | |
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; | |
struct device_node *dsi_pan_node = NULL; | |
char panel_cfg[MDSS_MAX_PANEL_LEN]; | |
- struct resource *mdss_dsi_mres; | |
const char *ctrl_name; | |
bool cmd_cfg_cont_splash = true; | |
@@ -974,30 +1240,13 @@ static int __devinit mdss_dsi_ctrl_probe(struct platform_device *pdev) | |
else | |
pdev->id = 2; | |
- mdss_dsi_mres = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
- if (!mdss_dsi_mres) { | |
- pr_err("%s:%d unable to get the MDSS resources", | |
- __func__, __LINE__); | |
- rc = -ENOMEM; | |
- goto error_no_mem; | |
- } | |
- | |
- mdss_dsi_base = ioremap(mdss_dsi_mres->start, | |
- resource_size(mdss_dsi_mres)); | |
- if (!mdss_dsi_base) { | |
- pr_err("%s:%d unable to remap dsi resources", | |
- __func__, __LINE__); | |
- rc = -ENOMEM; | |
- goto error_no_mem; | |
- } | |
- | |
rc = of_platform_populate(pdev->dev.of_node, | |
NULL, NULL, &pdev->dev); | |
if (rc) { | |
dev_err(&pdev->dev, | |
"%s: failed to add child nodes, rc=%d\n", | |
__func__, rc); | |
- goto error_ioremap; | |
+ goto error_no_mem; | |
} | |
/* Parse the regulator information */ | |
@@ -1044,8 +1293,6 @@ error_pan_node: | |
of_node_put(dsi_pan_node); | |
error_vreg: | |
mdss_dsi_put_dt_vreg_data(&pdev->dev, &ctrl_pdata->power_data); | |
-error_ioremap: | |
- iounmap(mdss_dsi_base); | |
error_no_mem: | |
devm_kfree(&pdev->dev, ctrl_pdata); | |
@@ -1068,7 +1315,9 @@ static int __devexit mdss_dsi_ctrl_remove(struct platform_device *pdev) | |
pr_err("%s: failed to de-init vregs\n", __func__); | |
mdss_dsi_put_dt_vreg_data(&pdev->dev, &ctrl_pdata->power_data); | |
mfd = platform_get_drvdata(pdev); | |
- iounmap(mdss_dsi_base); | |
+ msm_dss_iounmap(&ctrl_pdata->mmss_misc_io); | |
+ msm_dss_iounmap(&ctrl_pdata->phy_io); | |
+ msm_dss_iounmap(&ctrl_pdata->ctrl_io); | |
return 0; | |
} | |
@@ -1079,7 +1328,6 @@ int mdss_dsi_retrieve_ctrl_resources(struct platform_device *pdev, int mode, | |
{ | |
int rc = 0; | |
u32 index; | |
- struct resource *mdss_dsi_mres; | |
rc = of_property_read_u32(pdev->dev.of_node, "cell-index", &index); | |
if (rc) { | |
@@ -1107,25 +1355,33 @@ int mdss_dsi_retrieve_ctrl_resources(struct platform_device *pdev, int mode, | |
return -EPERM; | |
} | |
- mdss_dsi_mres = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
- if (!mdss_dsi_mres) { | |
- pr_err("%s:%d unable to get the DSI ctrl resources", | |
+ rc = msm_dss_ioremap_byname(pdev, &ctrl->ctrl_io, "dsi_ctrl"); | |
+ if (rc) { | |
+ pr_err("%s:%d unable to remap dsi ctrl resources", | |
__func__, __LINE__); | |
- return -ENOMEM; | |
+ return rc; | |
} | |
- ctrl->ctrl_base = ioremap(mdss_dsi_mres->start, | |
- resource_size(mdss_dsi_mres)); | |
- if (!(ctrl->ctrl_base)) { | |
- pr_err("%s:%d unable to remap dsi resources", | |
+ ctrl->ctrl_base = ctrl->ctrl_io.base; | |
+ ctrl->reg_size = ctrl->ctrl_io.len; | |
+ | |
+ rc = msm_dss_ioremap_byname(pdev, &ctrl->phy_io, "dsi_phy"); | |
+ if (rc) { | |
+ pr_err("%s:%d unable to remap dsi phy resources", | |
__func__, __LINE__); | |
- return -ENOMEM; | |
+ return rc; | |
} | |
- ctrl->reg_size = resource_size(mdss_dsi_mres); | |
+ pr_info("%s: ctrl_base=%p ctrl_size=%x phy_base=%p phy_size=%x\n", | |
+ __func__, ctrl->ctrl_base, ctrl->reg_size, ctrl->phy_io.base, | |
+ ctrl->phy_io.len); | |
- pr_info("%s: dsi base=%x size=%x\n", | |
- __func__, (int)ctrl->ctrl_base, ctrl->reg_size); | |
+ rc = msm_dss_ioremap_byname(pdev, &ctrl->mmss_misc_io, | |
+ "mmss_misc_phys"); | |
+ if (rc) { | |
+ pr_debug("%s:%d mmss_misc IO remap failed\n", | |
+ __func__, __LINE__); | |
+ } | |
return 0; | |
} | |
@@ -1236,6 +1492,12 @@ int dsi_panel_device_register(struct device_node *pan_node, | |
DFPS_IMMEDIATE_CLK_UPDATE_MODE; | |
pr_debug("%s: dfps mode: Immediate clk\n", | |
__func__); | |
+ } else if (!strcmp(data, | |
+ "dfps_immediate_porch_mode")) { | |
+ pinfo->dfps_update = | |
+ DFPS_IMMEDIATE_PORCH_UPDATE_MODE; | |
+ pr_debug("%s: dfps mode: Immediate porch\n", | |
+ __func__); | |
} else { | |
pr_debug("%s: dfps to default mode\n", | |
__func__); | |
@@ -1255,21 +1517,14 @@ int dsi_panel_device_register(struct device_node *pan_node, | |
pinfo->new_fps = pinfo->mipi.frame_rate; | |
} | |
+ pinfo->panel_max_fps = mdss_panel_get_framerate(pinfo); | |
+ pinfo->panel_max_vtotal = mdss_panel_get_vtotal(pinfo); | |
ctrl_pdata->disp_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, | |
"qcom,platform-enable-gpio", 0); | |
- if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) { | |
+ if (!gpio_is_valid(ctrl_pdata->disp_en_gpio)) | |
pr_err("%s:%d, Disp_en gpio not specified\n", | |
__func__, __LINE__); | |
- } else { | |
- rc = gpio_request(ctrl_pdata->disp_en_gpio, "disp_enable"); | |
- if (rc) { | |
- pr_err("request reset gpio failed, rc=%d\n", | |
- rc); | |
- gpio_free(ctrl_pdata->disp_en_gpio); | |
- return -ENODEV; | |
- } | |
- } | |
if (pinfo->type == MIPI_CMD_PANEL) { | |
ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, | |
@@ -1286,7 +1541,6 @@ int dsi_panel_device_register(struct device_node *pan_node, | |
if (rc) { | |
pr_err("request TE gpio failed, rc=%d\n", | |
rc); | |
- gpio_free(ctrl_pdata->disp_te_gpio); | |
return -ENODEV; | |
} | |
rc = gpio_tlmm_config(GPIO_CFG( | |
@@ -1316,44 +1570,20 @@ int dsi_panel_device_register(struct device_node *pan_node, | |
ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, | |
"qcom,platform-reset-gpio", 0); | |
- if (!gpio_is_valid(ctrl_pdata->rst_gpio)) { | |
+ if (!gpio_is_valid(ctrl_pdata->rst_gpio)) | |
pr_err("%s:%d, reset gpio not specified\n", | |
__func__, __LINE__); | |
- } else { | |
- rc = gpio_request(ctrl_pdata->rst_gpio, "disp_rst_n"); | |
- if (rc) { | |
- pr_err("request reset gpio failed, rc=%d\n", | |
- rc); | |
- gpio_free(ctrl_pdata->rst_gpio); | |
- if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) | |
- gpio_free(ctrl_pdata->disp_en_gpio); | |
- return -ENODEV; | |
- } | |
- } | |
if (pinfo->mode_gpio_state != MODE_GPIO_NOT_VALID) { | |
ctrl_pdata->mode_gpio = of_get_named_gpio( | |
ctrl_pdev->dev.of_node, | |
"qcom,platform-mode-gpio", 0); | |
- if (!gpio_is_valid(ctrl_pdata->mode_gpio)) { | |
+ if (!gpio_is_valid(ctrl_pdata->mode_gpio)) | |
pr_info("%s:%d, mode gpio not specified\n", | |
__func__, __LINE__); | |
- } else { | |
- rc = gpio_request(ctrl_pdata->mode_gpio, "panel_mode"); | |
- if (rc) { | |
- pr_err("request panel mode gpio failed,rc=%d\n", | |
- rc); | |
- gpio_free(ctrl_pdata->mode_gpio); | |
- if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) | |
- gpio_free(ctrl_pdata->disp_en_gpio); | |
- if (gpio_is_valid(ctrl_pdata->rst_gpio)) | |
- gpio_free(ctrl_pdata->rst_gpio); | |
- if (gpio_is_valid(ctrl_pdata->disp_te_gpio)) | |
- gpio_free(ctrl_pdata->disp_te_gpio); | |
- return -ENODEV; | |
- } | |
- } | |
+ } else { | |
+ ctrl_pdata->mode_gpio = -EINVAL; | |
} | |
if (mdss_dsi_clk_init(ctrl_pdev, ctrl_pdata)) { | |
@@ -1369,8 +1599,16 @@ int dsi_panel_device_register(struct device_node *pan_node, | |
} | |
ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler; | |
- ctrl_pdata->check_status = mdss_dsi_bta_status_check; | |
+ if (ctrl_pdata->status_mode == ESD_REG) | |
+ ctrl_pdata->check_status = mdss_dsi_reg_status_check; | |
+ else if (ctrl_pdata->status_mode == ESD_BTA) | |
+ ctrl_pdata->check_status = mdss_dsi_bta_status_check; | |
+ | |
+ if (ctrl_pdata->status_mode == ESD_MAX) { | |
+ pr_err("%s: Using default BTA for ESD check\n", __func__); | |
+ ctrl_pdata->check_status = mdss_dsi_bta_status_check; | |
+ } | |
if (ctrl_pdata->bklt_ctrl == BL_PWM) | |
mdss_dsi_panel_pwm_cfg(ctrl_pdata); | |
@@ -1394,7 +1632,7 @@ int dsi_panel_device_register(struct device_node *pan_node, | |
return rc; | |
} | |
- mdss_dsi_clk_ctrl(ctrl_pdata, 1); | |
+ mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); | |
ctrl_pdata->ctrl_state |= | |
(CTRL_STATE_PANEL_INIT | CTRL_STATE_MDP_ACTIVE); | |
} else { | |
@@ -1404,10 +1642,6 @@ int dsi_panel_device_register(struct device_node *pan_node, | |
rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data)); | |
if (rc) { | |
pr_err("%s: unable to register MIPI DSI panel\n", __func__); | |
- if (ctrl_pdata->rst_gpio) | |
- gpio_free(ctrl_pdata->rst_gpio); | |
- if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) | |
- gpio_free(ctrl_pdata->disp_en_gpio); | |
return rc; | |
} | |
@@ -1462,7 +1696,6 @@ module_init(mdss_dsi_driver_init); | |
static void __exit mdss_dsi_driver_cleanup(void) | |
{ | |
- iounmap(mdss_dsi_base); | |
platform_driver_unregister(&mdss_dsi_ctrl_driver); | |
} | |
module_exit(mdss_dsi_driver_cleanup); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment