summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev/msm
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@quicinc.com>2017-10-05 16:09:59 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-10-05 16:09:59 -0700
commit52b59ba4bd3638ad12cda7fd1c32c6c97b25a2db (patch)
treef4846b5301c71438e514333208e38e6e578fdd38 /drivers/video/fbdev/msm
parent92a03ca5370e6bdfc9256dffa3b26e55215e6262 (diff)
parent04e88e68eedf67f5a6e4554f717917605121bf48 (diff)
Merge "msm: mdss: dp: fix handling of device shutdown with cable connected"
Diffstat (limited to 'drivers/video/fbdev/msm')
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c48
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.h6
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_aux.c9
3 files changed, 27 insertions, 36 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index 4c6a5e73406b..bc325a91a9bf 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -68,6 +68,7 @@ static int mdss_dp_process_phy_test_pattern_request(
struct mdss_dp_drv_pdata *dp);
static int mdss_dp_send_audio_notification(
struct mdss_dp_drv_pdata *dp, int val);
+static void mdss_dp_reset_sw_state(struct mdss_dp_drv_pdata *dp);
static inline void mdss_dp_reset_sink_count(struct mdss_dp_drv_pdata *dp)
{
@@ -1489,7 +1490,12 @@ static int mdss_dp_setup_main_link(struct mdss_dp_drv_pdata *dp, bool train)
pr_debug("enter\n");
mdss_dp_mainlink_ctrl(&dp->ctrl_io, true);
- mdss_dp_aux_set_sink_power_state(dp, SINK_POWER_ON);
+ ret = mdss_dp_aux_send_psm_request(dp, false);
+ if (ret) {
+ pr_err("Failed to exit low power mode, rc=%d\n", ret);
+ goto end;
+ }
+
reinit_completion(&dp->video_comp);
if (mdss_dp_is_phy_test_pattern_requested(dp))
@@ -1576,15 +1582,6 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv, bool lt_needed)
dp_drv->power_on = true;
- if (dp_drv->psm_enabled) {
- ret = mdss_dp_aux_send_psm_request(dp_drv, false);
- if (ret) {
- pr_err("Failed to exit low power mode, rc=%d\n",
- ret);
- goto exit_loop;
- }
- }
-
ret = mdss_dp_setup_main_link(dp_drv, lt_needed);
exit_loop:
@@ -1653,15 +1650,6 @@ int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv)
mdss_dp_configure_source_params(dp_drv, ln_map);
- if (dp_drv->psm_enabled) {
- ret = mdss_dp_aux_send_psm_request(dp_drv, false);
- if (ret) {
- pr_err("Failed to exit low power mode, rc=%d\n", ret);
- goto exit;
- }
- }
-
-
link_training:
dp_drv->power_on = true;
@@ -2989,6 +2977,7 @@ static int mdss_dp_sysfs_create(struct mdss_dp_drv_pdata *dp,
static void mdss_dp_mainlink_push_idle(struct mdss_panel_data *pdata)
{
+ bool cable_connected;
struct mdss_dp_drv_pdata *dp_drv = NULL;
const int idle_pattern_completion_timeout_ms = 3 * HZ / 100;
@@ -3009,6 +2998,14 @@ static void mdss_dp_mainlink_push_idle(struct mdss_panel_data *pdata)
return;
}
+ /* power down the sink if cable is still connected */
+ mutex_lock(&dp_drv->attention_lock);
+ cable_connected = dp_drv->cable_connected;
+ mutex_unlock(&dp_drv->attention_lock);
+ if (cable_connected && dp_drv->alt_mode.dp_status.hpd_high) {
+ if (mdss_dp_aux_send_psm_request(dp_drv, true))
+ pr_err("Failed to enter low power mode\n");
+ }
reinit_completion(&dp_drv->idle_comp);
mdss_dp_state_ctrl(&dp_drv->ctrl_io, ST_PUSH_IDLE);
if (!wait_for_completion_timeout(&dp_drv->idle_comp,
@@ -3129,6 +3126,10 @@ static int mdss_dp_event_handler(struct mdss_panel_data *pdata,
pr_err("DP Controller not powered on\n");
break;
}
+ if (!atomic_read(&dp->notification_pending)) {
+ pr_debug("blank when cable is connected\n");
+ kthread_park(dp->ev_thread);
+ }
if (dp_is_hdcp_enabled(dp)) {
dp->hdcp_status = HDCP_STATE_INACTIVE;
@@ -3168,8 +3169,10 @@ static int mdss_dp_event_handler(struct mdss_panel_data *pdata,
* when you connect DP sink while the
* device is in suspend state.
*/
- if ((!dp->power_on) && (dp->dp_initialized))
+ if ((!dp->power_on) && (dp->dp_initialized)) {
rc = mdss_dp_host_deinit(dp);
+ kthread_park(dp->ev_thread);
+ }
/*
* For DP suspend/resume use case, CHECK_PARAMS is
@@ -3181,8 +3184,11 @@ static int mdss_dp_event_handler(struct mdss_panel_data *pdata,
dp->suspend_vic = dp->vic;
break;
case MDSS_EVENT_RESUME:
- if (dp->suspend_vic != HDMI_VFRMT_UNKNOWN)
+ if (dp->suspend_vic != HDMI_VFRMT_UNKNOWN) {
dp_init_panel_info(dp, dp->suspend_vic);
+ mdss_dp_reset_sw_state(dp);
+ kthread_unpark(dp->ev_thread);
+ }
break;
default:
pr_debug("unhandled event=%d\n", event);
diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h
index afa8e3db590f..983f5e34a515 100644
--- a/drivers/video/fbdev/msm/mdss_dp.h
+++ b/drivers/video/fbdev/msm/mdss_dp.h
@@ -218,10 +218,6 @@ struct dp_alt_mode {
#define ST_SEND_VIDEO BIT(7)
#define ST_PUSH_IDLE BIT(8)
-/* sink power state */
-#define SINK_POWER_ON 1
-#define SINK_POWER_OFF 2
-
#define DP_LINK_RATE_162 6 /* 1.62G = 270M * 6 */
#define DP_LINK_RATE_270 10 /* 2.70G = 270M * 10 */
#define DP_LINK_RATE_540 20 /* 5.40G = 270M * 20 */
@@ -1181,11 +1177,9 @@ void dp_aux_native_handler(struct mdss_dp_drv_pdata *dp, u32 isr);
void mdss_dp_aux_init(struct mdss_dp_drv_pdata *ep);
void mdss_dp_fill_link_cfg(struct mdss_dp_drv_pdata *ep);
-void mdss_dp_sink_power_down(struct mdss_dp_drv_pdata *ep);
void mdss_dp_lane_power_ctrl(struct mdss_dp_drv_pdata *ep, int up);
void mdss_dp_config_ctrl(struct mdss_dp_drv_pdata *ep);
char mdss_dp_gen_link_clk(struct mdss_dp_drv_pdata *dp);
-int mdss_dp_aux_set_sink_power_state(struct mdss_dp_drv_pdata *ep, char state);
int mdss_dp_aux_send_psm_request(struct mdss_dp_drv_pdata *dp, bool enable);
void mdss_dp_aux_send_test_response(struct mdss_dp_drv_pdata *ep);
void *mdss_dp_get_hdcp_data(struct device *dev);
diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c
index c0632e8241a0..86946adfeeb0 100644
--- a/drivers/video/fbdev/msm/mdss_dp_aux.c
+++ b/drivers/video/fbdev/msm/mdss_dp_aux.c
@@ -2556,15 +2556,6 @@ static int dp_link_rate_down_shift(struct mdss_dp_drv_pdata *ep)
return ret;
}
-int mdss_dp_aux_set_sink_power_state(struct mdss_dp_drv_pdata *ep, char state)
-{
- int ret;
-
- ret = dp_aux_write_buf(ep, 0x600, &state, 1, 0);
- pr_debug("state=%d ret=%d\n", state, ret);
- return ret;
-}
-
static void dp_clear_training_pattern(struct mdss_dp_drv_pdata *ep)
{
int usleep_time;