Loading drivers/video/fbdev/msm/mdss_dp.c +48 −1 Original line number Diff line number Diff line Loading @@ -1568,6 +1568,19 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv, bool lt_needed) { int ret = 0; char ln_map[4]; bool connected; mutex_lock(&dp_drv->attention_lock); connected = dp_drv->cable_connected; mutex_unlock(&dp_drv->attention_lock); /* * If DP cable disconnected, Avoid link training or turning on DP Path */ if (!connected) { pr_err("DP sink not connected\n"); return -EINVAL; } /* wait until link training is completed */ pr_debug("enter, lt_needed=%s\n", lt_needed ? "true" : "false"); Loading Loading @@ -1609,6 +1622,13 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv, bool lt_needed) dp_drv->power_on = true; ret = mdss_dp_setup_main_link(dp_drv, lt_needed); if (ret) { if (ret == -ENODEV || ret == -EINVAL) { pr_err("main link setup failed\n"); mutex_unlock(&dp_drv->train_mutex); return ret; } } exit_loop: mutex_unlock(&dp_drv->train_mutex); Loading Loading @@ -2209,7 +2229,7 @@ static int mdss_dp_process_hpd_high(struct mdss_dp_drv_pdata *dp) ret = mdss_dp_dpcd_cap_read(dp); if (ret || !mdss_dp_aux_is_link_rate_valid(dp->dpcd.max_link_rate) || !mdss_dp_aux_is_lane_count_valid(dp->dpcd.max_lane_count)) { if (ret == EDP_AUX_ERR_TOUT) { if ((ret == -ENODEV) || (ret == EDP_AUX_ERR_TOUT)) { pr_err("DPCD read timedout, skip connect notification\n"); goto end; } Loading Loading @@ -2241,6 +2261,9 @@ static int mdss_dp_process_hpd_high(struct mdss_dp_drv_pdata *dp) read_edid: ret = mdss_dp_edid_read(dp); if (ret) { if (ret == -ENODEV) goto end; pr_err("edid read error, setting default resolution\n"); goto notify; } Loading Loading @@ -3559,9 +3582,33 @@ static void mdss_dp_reset_event_list(struct mdss_dp_drv_pdata *dp) static void mdss_dp_reset_sw_state(struct mdss_dp_drv_pdata *dp) { int ret = 0; pr_debug("enter\n"); mdss_dp_reset_event_list(dp); /* * IRQ_HPD attention event handler first turns on DP path and then * notifies CONNECT_IRQ_HPD and waits for userspace to trigger UNBLANK. * In such cases, before UNBLANK call, if cable is disconnected, if * DISCONNECT is notified immediately, userspace might not sense any * change in connection status, leaving DP controller ON. * * To avoid such cases, wait for the connection event to complete before * sending disconnection event */ if (atomic_read(&dp->notification_pending)) { pr_debug("waiting for the pending notitfication\n"); ret = wait_for_completion_timeout(&dp->notification_comp, HZ); if (ret <= 0) { pr_err("%s timed out\n", mdss_dp_notification_status_to_string( dp->hpd_notification_status)); } } atomic_set(&dp->notification_pending, 0); /* complete any waiting completions */ complete_all(&dp->notification_comp); } Loading drivers/video/fbdev/msm/mdss_dp_aux.c +31 −11 Original line number Diff line number Diff line Loading @@ -411,7 +411,8 @@ retry: if (!connected) { pr_err("dp cable disconnected\n"); break; ret = -ENODEV; goto end; } dp->aux_error_num = EDP_AUX_ERR_NONE; Loading Loading @@ -877,7 +878,7 @@ void dp_extract_edid_detailed_timing_description(struct edp_edid *edid, static int dp_aux_chan_ready(struct mdss_dp_drv_pdata *ep) { int cnt, ret; int cnt, ret = 0; char data = 0; for (cnt = 5; cnt; cnt--) { Loading @@ -886,6 +887,10 @@ static int dp_aux_chan_ready(struct mdss_dp_drv_pdata *ep) ret, mdss_dp_get_aux_error(ep->aux_error_num)); if (ret >= 0) break; if (ret == -ENODEV) return ret; msleep(100); } Loading Loading @@ -973,6 +978,7 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) u32 checksum = 0; bool phy_aux_update_requested = false; bool ext_block_parsing_done = false; bool connected = false; ret = dp_aux_chan_ready(dp); if (ret) { Loading @@ -992,6 +998,15 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) u8 segment; u8 edid_buf[EDID_BLOCK_SIZE] = {0}; mutex_lock(&dp->attention_lock); connected = dp->cable_connected; mutex_unlock(&dp->attention_lock); if (!connected) { pr_err("DP sink not connected\n"); return -ENODEV; } /* * Write the segment first. * Segment = 0, for blocks 0 and 1 Loading Loading @@ -1243,7 +1258,7 @@ int mdss_dp_aux_link_status_read(struct mdss_dp_drv_pdata *ep, int len) rlen = dp_aux_read_buf(ep, 0x202, len, 0); if (rlen < len) { pr_err("edp aux read failed\n"); return 0; return rlen; } rp = &ep->rxp; bp = rp->data; Loading Loading @@ -2459,21 +2474,24 @@ static int dp_start_link_train_1(struct mdss_dp_drv_pdata *ep) usleep_time = ep->dpcd.training_read_interval; usleep_range(usleep_time, usleep_time); mdss_dp_aux_link_status_read(ep, 6); ret = mdss_dp_aux_link_status_read(ep, 6); if (ret == -ENODEV) break; if (mdss_dp_aux_clock_recovery_done(ep)) { ret = 0; break; } if (ep->v_level == DPCD_LINK_VOLTAGE_MAX) { ret = -1; ret = -EAGAIN; break; /* quit */ } if (old_v_level == ep->v_level) { tries++; if (tries >= maximum_retries) { ret = -1; ret = -EAGAIN; break; /* quit */ } } else { Loading Loading @@ -2511,7 +2529,9 @@ static int dp_start_link_train_2(struct mdss_dp_drv_pdata *ep) usleep_time = ep->dpcd.training_read_interval; usleep_range(usleep_time, usleep_time); mdss_dp_aux_link_status_read(ep, 6); ret = mdss_dp_aux_link_status_read(ep, 6); if (ret == -ENODEV) break; if (mdss_dp_aux_channel_eq_done(ep)) { ret = 0; Loading @@ -2519,7 +2539,7 @@ static int dp_start_link_train_2(struct mdss_dp_drv_pdata *ep) } if (tries > maximum_retries) { ret = -1; ret = -EAGAIN; break; } tries++; Loading Loading @@ -2584,7 +2604,7 @@ int mdss_dp_link_train(struct mdss_dp_drv_pdata *dp) ret = dp_start_link_train_1(dp); if (ret < 0) { if (!dp_link_rate_down_shift(dp)) { if ((ret == -EAGAIN) && !dp_link_rate_down_shift(dp)) { pr_debug("retry with lower rate\n"); dp_clear_training_pattern(dp); return -EAGAIN; Loading @@ -2603,7 +2623,7 @@ int mdss_dp_link_train(struct mdss_dp_drv_pdata *dp) ret = dp_start_link_train_2(dp); if (ret < 0) { if (!dp_link_rate_down_shift(dp)) { if ((ret == -EAGAIN) && !dp_link_rate_down_shift(dp)) { pr_debug("retry with lower rate\n"); dp_clear_training_pattern(dp); return -EAGAIN; Loading Loading @@ -2640,7 +2660,7 @@ int mdss_dp_dpcd_status_read(struct mdss_dp_drv_pdata *ep) ret = mdss_dp_aux_link_status_read(ep, 6); if (ret) { if (ret > 0) { sp = &ep->link_status; ret = sp->port_0_in_sync; /* 1 == sync */ } Loading Loading
drivers/video/fbdev/msm/mdss_dp.c +48 −1 Original line number Diff line number Diff line Loading @@ -1568,6 +1568,19 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv, bool lt_needed) { int ret = 0; char ln_map[4]; bool connected; mutex_lock(&dp_drv->attention_lock); connected = dp_drv->cable_connected; mutex_unlock(&dp_drv->attention_lock); /* * If DP cable disconnected, Avoid link training or turning on DP Path */ if (!connected) { pr_err("DP sink not connected\n"); return -EINVAL; } /* wait until link training is completed */ pr_debug("enter, lt_needed=%s\n", lt_needed ? "true" : "false"); Loading Loading @@ -1609,6 +1622,13 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv, bool lt_needed) dp_drv->power_on = true; ret = mdss_dp_setup_main_link(dp_drv, lt_needed); if (ret) { if (ret == -ENODEV || ret == -EINVAL) { pr_err("main link setup failed\n"); mutex_unlock(&dp_drv->train_mutex); return ret; } } exit_loop: mutex_unlock(&dp_drv->train_mutex); Loading Loading @@ -2209,7 +2229,7 @@ static int mdss_dp_process_hpd_high(struct mdss_dp_drv_pdata *dp) ret = mdss_dp_dpcd_cap_read(dp); if (ret || !mdss_dp_aux_is_link_rate_valid(dp->dpcd.max_link_rate) || !mdss_dp_aux_is_lane_count_valid(dp->dpcd.max_lane_count)) { if (ret == EDP_AUX_ERR_TOUT) { if ((ret == -ENODEV) || (ret == EDP_AUX_ERR_TOUT)) { pr_err("DPCD read timedout, skip connect notification\n"); goto end; } Loading Loading @@ -2241,6 +2261,9 @@ static int mdss_dp_process_hpd_high(struct mdss_dp_drv_pdata *dp) read_edid: ret = mdss_dp_edid_read(dp); if (ret) { if (ret == -ENODEV) goto end; pr_err("edid read error, setting default resolution\n"); goto notify; } Loading Loading @@ -3559,9 +3582,33 @@ static void mdss_dp_reset_event_list(struct mdss_dp_drv_pdata *dp) static void mdss_dp_reset_sw_state(struct mdss_dp_drv_pdata *dp) { int ret = 0; pr_debug("enter\n"); mdss_dp_reset_event_list(dp); /* * IRQ_HPD attention event handler first turns on DP path and then * notifies CONNECT_IRQ_HPD and waits for userspace to trigger UNBLANK. * In such cases, before UNBLANK call, if cable is disconnected, if * DISCONNECT is notified immediately, userspace might not sense any * change in connection status, leaving DP controller ON. * * To avoid such cases, wait for the connection event to complete before * sending disconnection event */ if (atomic_read(&dp->notification_pending)) { pr_debug("waiting for the pending notitfication\n"); ret = wait_for_completion_timeout(&dp->notification_comp, HZ); if (ret <= 0) { pr_err("%s timed out\n", mdss_dp_notification_status_to_string( dp->hpd_notification_status)); } } atomic_set(&dp->notification_pending, 0); /* complete any waiting completions */ complete_all(&dp->notification_comp); } Loading
drivers/video/fbdev/msm/mdss_dp_aux.c +31 −11 Original line number Diff line number Diff line Loading @@ -411,7 +411,8 @@ retry: if (!connected) { pr_err("dp cable disconnected\n"); break; ret = -ENODEV; goto end; } dp->aux_error_num = EDP_AUX_ERR_NONE; Loading Loading @@ -877,7 +878,7 @@ void dp_extract_edid_detailed_timing_description(struct edp_edid *edid, static int dp_aux_chan_ready(struct mdss_dp_drv_pdata *ep) { int cnt, ret; int cnt, ret = 0; char data = 0; for (cnt = 5; cnt; cnt--) { Loading @@ -886,6 +887,10 @@ static int dp_aux_chan_ready(struct mdss_dp_drv_pdata *ep) ret, mdss_dp_get_aux_error(ep->aux_error_num)); if (ret >= 0) break; if (ret == -ENODEV) return ret; msleep(100); } Loading Loading @@ -973,6 +978,7 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) u32 checksum = 0; bool phy_aux_update_requested = false; bool ext_block_parsing_done = false; bool connected = false; ret = dp_aux_chan_ready(dp); if (ret) { Loading @@ -992,6 +998,15 @@ int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp) u8 segment; u8 edid_buf[EDID_BLOCK_SIZE] = {0}; mutex_lock(&dp->attention_lock); connected = dp->cable_connected; mutex_unlock(&dp->attention_lock); if (!connected) { pr_err("DP sink not connected\n"); return -ENODEV; } /* * Write the segment first. * Segment = 0, for blocks 0 and 1 Loading Loading @@ -1243,7 +1258,7 @@ int mdss_dp_aux_link_status_read(struct mdss_dp_drv_pdata *ep, int len) rlen = dp_aux_read_buf(ep, 0x202, len, 0); if (rlen < len) { pr_err("edp aux read failed\n"); return 0; return rlen; } rp = &ep->rxp; bp = rp->data; Loading Loading @@ -2459,21 +2474,24 @@ static int dp_start_link_train_1(struct mdss_dp_drv_pdata *ep) usleep_time = ep->dpcd.training_read_interval; usleep_range(usleep_time, usleep_time); mdss_dp_aux_link_status_read(ep, 6); ret = mdss_dp_aux_link_status_read(ep, 6); if (ret == -ENODEV) break; if (mdss_dp_aux_clock_recovery_done(ep)) { ret = 0; break; } if (ep->v_level == DPCD_LINK_VOLTAGE_MAX) { ret = -1; ret = -EAGAIN; break; /* quit */ } if (old_v_level == ep->v_level) { tries++; if (tries >= maximum_retries) { ret = -1; ret = -EAGAIN; break; /* quit */ } } else { Loading Loading @@ -2511,7 +2529,9 @@ static int dp_start_link_train_2(struct mdss_dp_drv_pdata *ep) usleep_time = ep->dpcd.training_read_interval; usleep_range(usleep_time, usleep_time); mdss_dp_aux_link_status_read(ep, 6); ret = mdss_dp_aux_link_status_read(ep, 6); if (ret == -ENODEV) break; if (mdss_dp_aux_channel_eq_done(ep)) { ret = 0; Loading @@ -2519,7 +2539,7 @@ static int dp_start_link_train_2(struct mdss_dp_drv_pdata *ep) } if (tries > maximum_retries) { ret = -1; ret = -EAGAIN; break; } tries++; Loading Loading @@ -2584,7 +2604,7 @@ int mdss_dp_link_train(struct mdss_dp_drv_pdata *dp) ret = dp_start_link_train_1(dp); if (ret < 0) { if (!dp_link_rate_down_shift(dp)) { if ((ret == -EAGAIN) && !dp_link_rate_down_shift(dp)) { pr_debug("retry with lower rate\n"); dp_clear_training_pattern(dp); return -EAGAIN; Loading @@ -2603,7 +2623,7 @@ int mdss_dp_link_train(struct mdss_dp_drv_pdata *dp) ret = dp_start_link_train_2(dp); if (ret < 0) { if (!dp_link_rate_down_shift(dp)) { if ((ret == -EAGAIN) && !dp_link_rate_down_shift(dp)) { pr_debug("retry with lower rate\n"); dp_clear_training_pattern(dp); return -EAGAIN; Loading Loading @@ -2640,7 +2660,7 @@ int mdss_dp_dpcd_status_read(struct mdss_dp_drv_pdata *ep) ret = mdss_dp_aux_link_status_read(ep, 6); if (ret) { if (ret > 0) { sp = &ep->link_status; ret = sp->port_0_in_sync; /* 1 == sync */ } Loading