diff options
author | Tatenda Chipeperekwa <tatendac@codeaurora.org> | 2016-10-18 11:46:13 -0700 |
---|---|---|
committer | Ajay Singh Parmar <aparmar@codeaurora.org> | 2016-10-22 15:17:03 -0700 |
commit | 7d2ad0bd3ba327e48f137a971efb3cb43148a5a4 (patch) | |
tree | f53887808e7a931a12558e1098ab71f079e6d63f /drivers | |
parent | 40135e1fa5835c5cf11f1d87e971c08fc159e80f (diff) |
msm: mdss: dp: parse all sink/link status fields on HPD IRQ
Parse all the sink/link status fields on HPD IRQ. These
fields contain update sink/link status and are needed in
order to determine whether link re-training will be
required. Furthermore, this action is mandatory as per
CTS compliance specification 1.2a.
CRs-Fixed: 1076516
Change-Id: I8c8fef768fa22c1a52f42596e3707e9b0e2c8e4d
Signed-off-by: Tatenda Chipeperekwa <tatendac@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/fbdev/msm/mdss_dp.c | 6 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_dp.h | 8 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_dp_aux.c | 48 |
3 files changed, 50 insertions, 12 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c index bbd4642b34da..dbf6f16d735f 100644 --- a/drivers/video/fbdev/msm/mdss_dp.c +++ b/drivers/video/fbdev/msm/mdss_dp.c @@ -2297,11 +2297,11 @@ static void mdss_dp_process_hpd_irq_high(struct mdss_dp_drv_pdata *dp) dp->hpd_irq_on = true; - mdss_dp_aux_parse_test_request(dp); - - mdss_dp_send_test_response(dp); + mdss_dp_aux_parse_sink_status_field(dp); if (mdss_dp_is_link_training_requested(dp)) { + mdss_dp_send_test_response(dp); + pr_info("%s requested: link rate = 0x%x, lane count = 0x%x\n", mdss_dp_get_test_name(TEST_LINK_TRAINING), dp->test_data.test_link_rate, diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h index a4e8902d0bf3..f6af1f011f7b 100644 --- a/drivers/video/fbdev/msm/mdss_dp.h +++ b/drivers/video/fbdev/msm/mdss_dp.h @@ -261,6 +261,11 @@ struct dpcd_test_request { u32 response; }; +struct dpcd_sink_count { + u32 count; + bool cp_ready; +}; + struct display_timing_desc { u32 pclk; u32 h_addressable; /* addressable + boder = active */ @@ -463,6 +468,7 @@ struct mdss_dp_drv_pdata { void *hdcp_data; struct hdcp_ops *hdcp_ops; struct dpcd_test_request test_data; + struct dpcd_sink_count sink_count; }; enum dp_lane_count { @@ -549,7 +555,7 @@ void mdss_dp_phy_initialize(struct mdss_dp_drv_pdata *dp); void mdss_dp_dpcd_cap_read(struct mdss_dp_drv_pdata *dp); int mdss_dp_dpcd_status_read(struct mdss_dp_drv_pdata *dp); -void mdss_dp_aux_parse_test_request(struct mdss_dp_drv_pdata *dp); +void mdss_dp_aux_parse_sink_status_field(struct mdss_dp_drv_pdata *dp); int mdss_dp_edid_read(struct mdss_dp_drv_pdata *dp); int mdss_dp_link_train(struct mdss_dp_drv_pdata *dp); void dp_aux_i2c_handler(struct mdss_dp_drv_pdata *dp, u32 isr); diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c index 0ccd727dc5e8..a1668ea0d3f8 100644 --- a/drivers/video/fbdev/msm/mdss_dp_aux.c +++ b/drivers/video/fbdev/msm/mdss_dp_aux.c @@ -953,10 +953,10 @@ static int dp_link_status_read(struct mdss_dp_drv_pdata *ep, int len) } /** - * dp_sink_send_test_response() - sends a test response to the sink + * mdss_dp_aux_send_test_response() - sends a test response to the sink * @dp: Display Port Driver data */ -static void dp_sink_send_test_response(struct mdss_dp_drv_pdata *dp) +void mdss_dp_aux_send_test_response(struct mdss_dp_drv_pdata *dp) { char test_response[4]; @@ -1059,6 +1059,41 @@ exit: } /** + * dp_sink_parse_sink_count() - parses the sink count + * @ep: Display Port Driver data + * + * Parses the DPCD to check if there is an update to the sink count + * (Byte 0x200), and whether all the sink devices connected have Content + * Protection enabled. + */ +static void dp_sink_parse_sink_count(struct mdss_dp_drv_pdata *ep) +{ + char *bp; + char data; + struct edp_buf *rp; + int rlen; + int const param_len = 0x1; + int const sink_count_addr = 0x200; + + rlen = dp_aux_read_buf(ep, sink_count_addr, param_len, 0); + if (rlen < param_len) { + pr_err("failed to read sink count\n"); + return; + } + rp = &ep->rxp; + bp = rp->data; + data = *bp++; + + /* BIT 7, BIT 5:0 */ + ep->sink_count.count = (data & BIT(7)) << 6 | (data & 0x63); + /* BIT 6*/ + ep->sink_count.cp_ready = data & BIT(6); + + pr_debug("sink_count = 0x%x, cp_ready = 0x%x\n", + ep->sink_count.count, ep->sink_count.cp_ready); +} + +/** * dp_is_test_supported() - checks if test requested by sink is supported * @test_requested: test requested by the sink * @@ -1611,14 +1646,11 @@ void mdss_dp_dpcd_cap_read(struct mdss_dp_drv_pdata *ep) dp_sink_capability_read(ep, 16); } -void mdss_dp_aux_parse_test_request(struct mdss_dp_drv_pdata *ep) +void mdss_dp_aux_parse_sink_status_field(struct mdss_dp_drv_pdata *ep) { + dp_sink_parse_sink_count(ep); dp_sink_parse_test_request(ep); -} - -void mdss_dp_aux_send_test_response(struct mdss_dp_drv_pdata *ep) -{ - dp_sink_send_test_response(ep); + dp_link_status_read(ep, 6); } int mdss_dp_dpcd_status_read(struct mdss_dp_drv_pdata *ep) |