mdss: display-port: fix Display-port disable sequence
Fix the OFF path for display-port driver when cable is disconnected. Check for link clock status before accessing any of the mainlink registers. Use common mutex for DP_ON and DP_OFF sequence. Remove the resource vote when PLL is diabled. Change-Id: I9b81f79043b4ea7355b99ba9d8347d79bed10153 Signed-off-by: Chandan Uddaraju <chandanu@codeaurora.org>
This commit is contained in:
parent
c605e110ab
commit
9ec9267905
4 changed files with 28 additions and 37 deletions
|
@ -583,8 +583,10 @@ int dp_vco_prepare(struct clk *c)
|
|||
mdss_pll_resource_enable(dp_pll_res, false);
|
||||
pr_err("ndx=%d failed to enable dsi pll\n",
|
||||
dp_pll_res->index);
|
||||
goto error;
|
||||
}
|
||||
|
||||
mdss_pll_resource_enable(dp_pll_res, false);
|
||||
error:
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -895,7 +895,7 @@ int mdss_dp_on(struct mdss_panel_data *pdata)
|
|||
panel_data);
|
||||
|
||||
/* wait until link training is completed */
|
||||
mutex_lock(&dp_drv->host_mutex);
|
||||
mutex_lock(&dp_drv->train_mutex);
|
||||
|
||||
pr_debug("Enter++ cont_splash=%d\n", dp_drv->cont_splash);
|
||||
/* Default lane mapping */
|
||||
|
@ -908,7 +908,7 @@ int mdss_dp_on(struct mdss_panel_data *pdata)
|
|||
ret = mdss_dp_clk_ctrl(dp_drv, DP_CORE_PM, true);
|
||||
if (ret) {
|
||||
pr_err("Unabled to start core clocks\n");
|
||||
return ret;
|
||||
goto exit;
|
||||
}
|
||||
mdss_dp_hpd_configure(&dp_drv->ctrl_io, true);
|
||||
|
||||
|
@ -941,7 +941,8 @@ int mdss_dp_on(struct mdss_panel_data *pdata)
|
|||
dp_drv->link_rate, dp_drv->dpcd.max_link_rate);
|
||||
if (!dp_drv->link_rate) {
|
||||
pr_err("Unable to configure required link rate\n");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
pr_debug("link_rate = 0x%x\n", dp_drv->link_rate);
|
||||
|
@ -955,9 +956,8 @@ int mdss_dp_on(struct mdss_panel_data *pdata)
|
|||
|
||||
ret = mdss_dp_clk_ctrl(dp_drv, DP_CTRL_PM, true);
|
||||
if (ret) {
|
||||
mdss_dp_clk_ctrl(dp_drv, DP_CORE_PM, false);
|
||||
pr_err("Unabled to start link clocks\n");
|
||||
return ret;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mdss_dp_mainlink_reset(&dp_drv->ctrl_io);
|
||||
|
@ -985,17 +985,16 @@ int mdss_dp_on(struct mdss_panel_data *pdata)
|
|||
pr_debug("mainlink ready\n");
|
||||
|
||||
dp_drv->power_on = true;
|
||||
|
||||
mutex_unlock(&dp_drv->host_mutex);
|
||||
pr_debug("End-\n");
|
||||
|
||||
exit:
|
||||
mutex_unlock(&dp_drv->train_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mdss_dp_off(struct mdss_panel_data *pdata)
|
||||
{
|
||||
struct mdss_dp_drv_pdata *dp_drv = NULL;
|
||||
int ret = 0;
|
||||
|
||||
dp_drv = container_of(pdata, struct mdss_dp_drv_pdata,
|
||||
panel_data);
|
||||
|
@ -1009,34 +1008,31 @@ int mdss_dp_off(struct mdss_panel_data *pdata)
|
|||
mutex_lock(&dp_drv->train_mutex);
|
||||
|
||||
reinit_completion(&dp_drv->idle_comp);
|
||||
mdss_dp_state_ctrl(&dp_drv->ctrl_io, ST_PUSH_IDLE);
|
||||
|
||||
ret = wait_for_completion_timeout(&dp_drv->idle_comp,
|
||||
msecs_to_jiffies(100));
|
||||
if (ret == 0)
|
||||
pr_err("idle pattern timedout\n");
|
||||
|
||||
mdss_dp_state_ctrl(&dp_drv->ctrl_io, 0);
|
||||
|
||||
mdss_dp_irq_disable(dp_drv);
|
||||
if (dp_drv->link_clks_on)
|
||||
mdss_dp_mainlink_ctrl(&dp_drv->ctrl_io, false);
|
||||
|
||||
mdss_dp_mainlink_reset(&dp_drv->ctrl_io);
|
||||
mdss_dp_mainlink_ctrl(&dp_drv->ctrl_io, false);
|
||||
mdss_dp_aux_ctrl(&dp_drv->ctrl_io, false);
|
||||
|
||||
mdss_dp_irq_disable(dp_drv);
|
||||
|
||||
mdss_dp_config_gpios(dp_drv, false);
|
||||
mdss_dp_pinctrl_set_state(dp_drv, false);
|
||||
|
||||
mdss_dp_aux_ctrl(&dp_drv->ctrl_io, false);
|
||||
/* Make sure DP is disabled before clk disable */
|
||||
wmb();
|
||||
mdss_dp_clk_ctrl(dp_drv, DP_CTRL_PM, false);
|
||||
mdss_dp_clk_ctrl(dp_drv, DP_CORE_PM, false);
|
||||
|
||||
mdss_dp_regulator_ctrl(dp_drv, false);
|
||||
|
||||
pr_debug("End--: state_ctrl=%x\n",
|
||||
dp_read(dp_drv->base + DP_STATE_CTRL));
|
||||
dp_drv->dp_initialized = false;
|
||||
|
||||
dp_drv->power_on = false;
|
||||
mutex_unlock(&dp_drv->train_mutex);
|
||||
pr_debug("DP off done\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1124,6 +1120,10 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata)
|
|||
dp_drv = container_of(pdata, struct mdss_dp_drv_pdata,
|
||||
panel_data);
|
||||
|
||||
if (dp_drv->dp_initialized) {
|
||||
pr_err("%s: host init done already\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
ret = mdss_dp_regulator_ctrl(dp_drv, true);
|
||||
if (ret) {
|
||||
pr_err("failed to enable regulators\n");
|
||||
|
@ -1170,7 +1170,7 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata)
|
|||
}
|
||||
|
||||
mdss_dp_send_cable_notification(dp_drv, true);
|
||||
|
||||
dp_drv->dp_initialized = true;
|
||||
return ret;
|
||||
|
||||
edid_error:
|
||||
|
@ -1781,8 +1781,8 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd,
|
|||
if (cmd_type == SVDM_CMD_TYPE_INITIATOR) {
|
||||
pr_debug("Attention. cmd_type=%d\n",
|
||||
cmd_type);
|
||||
if (!dp_drv->alt_mode.current_state
|
||||
== ENTER_MODE_DONE) {
|
||||
if (!(dp_drv->alt_mode.current_state
|
||||
== ENTER_MODE_DONE)) {
|
||||
pr_debug("sending discover_mode\n");
|
||||
dp_send_events(dp_drv, EV_USBPD_DISCOVER_MODES);
|
||||
break;
|
||||
|
@ -1909,7 +1909,6 @@ static int mdss_dp_probe(struct platform_device *pdev)
|
|||
dp_drv->mask1 = EDP_INTR_MASK1;
|
||||
dp_drv->mask2 = EDP_INTR_MASK2;
|
||||
mutex_init(&dp_drv->emutex);
|
||||
mutex_init(&dp_drv->host_mutex);
|
||||
mutex_init(&dp_drv->pd_msg_mutex);
|
||||
mutex_init(&dp_drv->hdcp_mutex);
|
||||
spin_lock_init(&dp_drv->lock);
|
||||
|
|
|
@ -337,6 +337,7 @@ struct mdss_dp_drv_pdata {
|
|||
struct usbpd *pd;
|
||||
struct usbpd_svid_handler svid_handler;
|
||||
struct dp_alt_mode alt_mode;
|
||||
bool dp_initialized;
|
||||
|
||||
struct mutex emutex;
|
||||
int clk_cnt;
|
||||
|
@ -398,7 +399,6 @@ struct mdss_dp_drv_pdata {
|
|||
struct completion video_comp;
|
||||
struct mutex aux_mutex;
|
||||
struct mutex train_mutex;
|
||||
struct mutex host_mutex;
|
||||
struct mutex pd_msg_mutex;
|
||||
struct mutex hdcp_mutex;
|
||||
bool cable_connected;
|
||||
|
|
|
@ -1312,7 +1312,7 @@ static void dp_clear_training_pattern(struct mdss_dp_drv_pdata *ep)
|
|||
usleep_range(usleep_time, usleep_time);
|
||||
}
|
||||
|
||||
static int dp_aux_link_train(struct mdss_dp_drv_pdata *dp)
|
||||
int mdss_dp_link_train(struct mdss_dp_drv_pdata *dp)
|
||||
{
|
||||
int ret = 0;
|
||||
int usleep_time;
|
||||
|
@ -1412,16 +1412,6 @@ void mdss_dp_fill_link_cfg(struct mdss_dp_drv_pdata *ep)
|
|||
|
||||
}
|
||||
|
||||
int mdss_dp_link_train(struct mdss_dp_drv_pdata *ep)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ep->train_mutex);
|
||||
ret = dp_aux_link_train(ep);
|
||||
mutex_unlock(&ep->train_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mdss_dp_aux_init(struct mdss_dp_drv_pdata *ep)
|
||||
{
|
||||
mutex_init(&ep->aux_mutex);
|
||||
|
|
Loading…
Add table
Reference in a new issue