mdss: Display: Send panel OFF commands for first frame update

For continuous splash screen feature, the DSI panel is
turned on in bootloader. Add changes to send panel "off" commands
when we get the first frame update.
Add PANEL_INIT state and MDP_ACTIVE state as part of the
controller state machine.

Change-Id: Ifadb21795b98672de94d6994087f5196fa85951a
CRs-Fixed: 476922
Signed-off-by: Chandan Uddaraju <chandanu@codeaurora.org>
This commit is contained in:
Chandan Uddaraju 2013-04-23 12:24:05 -07:00 committed by Stephen Boyd
parent 85725bda14
commit 28a6afc93a
5 changed files with 80 additions and 48 deletions

View file

@ -432,42 +432,6 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata)
return ret;
}
int mdss_dsi_cont_splash_on(struct mdss_panel_data *pdata)
{
int ret = 0;
struct mipi_panel_info *mipi;
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
pr_info("%s:%d DSI on for continuous splash.\n", __func__, __LINE__);
if (pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
return -EINVAL;
}
mipi = &pdata->panel_info.mipi;
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);
WARN(ctrl_pdata->panel_state != UNKNOWN_STATE,
"incorrect panel state=%d\n", ctrl_pdata->panel_state);
mdss_dsi_sw_reset(pdata);
mdss_dsi_host_init(mipi, pdata);
mdss_dsi_op_mode_config(mipi->mode, pdata);
ctrl_pdata->panel_state = PANEL_ON;
pr_debug("%s-:End\n", __func__);
return ret;
}
int mdss_dsi_on(struct mdss_panel_data *pdata)
{
int ret = 0;
@ -618,14 +582,14 @@ static int mdss_dsi_unblank(struct mdss_panel_data *pdata)
panel_data);
mipi = &pdata->panel_info.mipi;
if (ctrl_pdata->panel_state != PANEL_ON) {
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",
__func__);
return ret;
}
ctrl_pdata->panel_state = PANEL_ON;
ctrl_pdata->ctrl_state |= CTRL_STATE_PANEL_INIT;
}
mdss_dsi_op_mode_config(mipi->mode, pdata);
@ -651,18 +615,58 @@ static int mdss_dsi_blank(struct mdss_panel_data *pdata)
mdss_dsi_op_mode_config(DSI_CMD_MODE, pdata);
if (ctrl_pdata->panel_state == PANEL_ON) {
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;
}
ctrl_pdata->panel_state = PANEL_OFF;
ctrl_pdata->ctrl_state &= ~CTRL_STATE_PANEL_INIT;
}
pr_debug("%s-:End\n", __func__);
return ret;
}
int mdss_dsi_cont_splash_on(struct mdss_panel_data *pdata)
{
int ret = 0;
struct mipi_panel_info *mipi;
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
pr_info("%s:%d DSI on for continuous splash.\n", __func__, __LINE__);
if (pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
return -EINVAL;
}
mipi = &pdata->panel_info.mipi;
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);
WARN((ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT),
"Incorrect Ctrl state=0x%x\n", ctrl_pdata->ctrl_state);
mdss_dsi_sw_reset(pdata);
mdss_dsi_host_init(mipi, pdata);
if (ctrl_pdata->on_cmds.link_state == DSI_LP_MODE) {
mdss_dsi_op_mode_config(DSI_CMD_MODE, pdata);
ret = mdss_dsi_unblank(pdata);
if (ret) {
pr_err("%s: unblank failed\n", __func__);
return ret;
}
}
pr_debug("%s-:End\n", __func__);
return ret;
}
static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
int event, void *arg)
{
@ -684,6 +688,7 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
rc = mdss_dsi_unblank(pdata);
break;
case MDSS_EVENT_PANEL_ON:
ctrl_pdata->ctrl_state |= CTRL_STATE_MDP_ACTIVE;
if (ctrl_pdata->on_cmds.link_state == DSI_HS_MODE)
rc = mdss_dsi_unblank(pdata);
break;
@ -692,11 +697,13 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
rc = mdss_dsi_blank(pdata);
break;
case MDSS_EVENT_PANEL_OFF:
ctrl_pdata->ctrl_state &= ~CTRL_STATE_MDP_ACTIVE;
if (ctrl_pdata->off_cmds.link_state == DSI_LP_MODE)
rc = mdss_dsi_blank(pdata);
rc = mdss_dsi_off(pdata);
break;
case MDSS_EVENT_CONT_SPLASH_FINISH:
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 {
@ -712,6 +719,12 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
case MDSS_EVENT_DSI_CMDLIST_KOFF:
mdss_dsi_cmdlist_commit(ctrl_pdata, 1);
break;
case MDSS_EVENT_CONT_SPLASH_BEGIN:
if (ctrl_pdata->off_cmds.link_state == DSI_HS_MODE) {
/* Panel is Enabled in Bootloader */
rc = mdss_dsi_blank(pdata);
}
break;
default:
pr_debug("%s: unhandled event=%d\n", __func__, event);
break;
@ -1110,6 +1123,7 @@ int dsi_panel_device_register(struct platform_device *pdev,
pr_debug("%s: pclk=%d, bclk=%d\n", __func__,
ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate);
ctrl_pdata->ctrl_state = CTRL_STATE_UNKNOWN;
cont_splash_enabled = of_property_read_bool(pdev->dev.of_node,
"qcom,cont-splash-enabled");
if (!cont_splash_enabled) {
@ -1139,6 +1153,8 @@ int dsi_panel_device_register(struct platform_device *pdev,
}
mdss_dsi_clk_ctrl(ctrl_pdata, 1);
ctrl_pdata->ctrl_state |=
(CTRL_STATE_PANEL_INIT | CTRL_STATE_MDP_ACTIVE);
}
rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data));
@ -1164,7 +1180,6 @@ int dsi_panel_device_register(struct platform_device *pdev,
ctrl_pdata->ndx = 1;
}
ctrl_pdata->panel_state = UNKNOWN_STATE;
pr_debug("%s: Panal data initialized\n", __func__);
return 0;
}

View file

@ -84,16 +84,14 @@ enum dsi_panel_bl_ctrl {
UNKNOWN_CTRL,
};
enum dsi_ctrl_state {
enum dsi_ctrl_op_mode {
DSI_LP_MODE,
DSI_HS_MODE,
};
enum dsi_panel_state {
UNKNOWN_STATE,
PANEL_ON,
PANEL_OFF,
};
#define CTRL_STATE_UNKNOWN 0x00
#define CTRL_STATE_PANEL_INIT BIT(0)
#define CTRL_STATE_MDP_ACTIVE BIT(1)
#define DSI_NON_BURST_SYNCH_PULSE 0
#define DSI_NON_BURST_SYNCH_EVENT 1
@ -332,7 +330,7 @@ struct mdss_dsi_ctrl_pdata {
struct clk *byte_clk;
struct clk *esc_clk;
struct clk *pixel_clk;
u8 panel_state;
u8 ctrl_state;
int irq_cnt;
int mdss_dsi_clk_on;
int rst_gpio;

View file

@ -189,6 +189,12 @@ void mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable)
msleep(20);
if (gpio_is_valid(ctrl_pdata->disp_en_gpio))
gpio_set_value((ctrl_pdata->disp_en_gpio), 1);
if (ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT) {
pr_debug("%s: Panel Not properly turned OFF\n",
__func__);
ctrl_pdata->ctrl_state &= ~CTRL_STATE_PANEL_INIT;
pr_debug("%s: Reset panel done\n", __func__);
}
} else {
gpio_set_value((ctrl_pdata->rst_gpio), 0);
if (gpio_is_valid(ctrl_pdata->disp_en_gpio))

View file

@ -562,6 +562,13 @@ int mdss_mdp_video_reconfigure_splash_done(struct mdss_mdp_ctl *ctl)
pdata->panel_info.cont_splash_enabled = 0;
ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_CONT_SPLASH_BEGIN,
NULL);
if (ret) {
pr_err("%s: Failed to handle 'CONT_SPLASH_BEGIN' event\n",
__func__);
return ret;
}
mdss_mdp_ctl_write(ctl, 0, MDSS_MDP_LM_BORDER_COLOR);
off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num);

View file

@ -76,8 +76,13 @@ enum {
* - negative if the configuration is invalid
* - 0 if there is no panel reconfig needed
* - 1 if reconfig is needed to take effect
* @MDSS_EVENT_CONT_SPLASH_BEGIN: Special event used to handle transition of
* display state from boot loader to panel driver.
* The event handler will disable the panel.
* @MDSS_EVENT_CONT_SPLASH_FINISH: Special event used to handle transition of
* display state from boot loader to panel driver.
* The event handler will enable the panel and
* vote for the display clocks.
* @MDSS_EVENT_FB_REGISTERED: Called after fb dev driver has been registered,
* panel driver gets ptr to struct fb_info which
* holds fb dev information.
@ -96,6 +101,7 @@ enum mdss_intf_events {
MDSS_EVENT_SUSPEND,
MDSS_EVENT_RESUME,
MDSS_EVENT_CHECK_PARAMS,
MDSS_EVENT_CONT_SPLASH_BEGIN,
MDSS_EVENT_CONT_SPLASH_FINISH,
MDSS_EVENT_FB_REGISTERED,
MDSS_EVENT_PANEL_CLK_CTRL,