drm/amd/display: Optimize DP_SINK_STATUS_ESI range read on HPD
authorNikola Cornij <nikola.cornij@amd.com>
Wed, 9 May 2018 21:07:36 +0000 (17:07 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 15 Jun 2018 17:20:25 +0000 (12:20 -0500)
DP_SINK_STATUS_ESI range data is not continual, but rather than
getting it in two AUX reads, it's quicker to read more bytes in a
AUX read and then memcpy the required fields (it's only 8 more
bytes to read).

Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c

index 1a42ee5113a920dcd182780f7a46c762be325ae3..509f265663d2727a6a5fecdd2903ddac2fbcc94f 100644 (file)
@@ -1647,22 +1647,26 @@ static enum dc_status read_hpd_rx_irq_data(
                        irq_data->raw,
                        sizeof(union hpd_irq_data));
        else {
-               /* Read 2 bytes at this location,... */
+               /* Read 14 bytes in a single read and then copy only the required fields.
+                * This is more efficient than doing it in two separate AUX reads. */
+
+               uint8_t tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI + 1];
+
                retval = core_link_read_dpcd(
                        link,
                        DP_SINK_COUNT_ESI,
-                       irq_data->raw,
-                       2);
+                       tmp,
+                       sizeof(tmp));
 
                if (retval != DC_OK)
                        return retval;
 
-               /* ... then read remaining 4 at the other location */
-               retval = core_link_read_dpcd(
-                       link,
-                       DP_LANE0_1_STATUS_ESI,
-                       &irq_data->raw[2],
-                       4);
+               irq_data->bytes.sink_cnt.raw = tmp[DP_SINK_COUNT_ESI - DP_SINK_COUNT_ESI];
+               irq_data->bytes.device_service_irq.raw = tmp[DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 - DP_SINK_COUNT_ESI];
+               irq_data->bytes.lane01_status.raw = tmp[DP_LANE0_1_STATUS_ESI - DP_SINK_COUNT_ESI];
+               irq_data->bytes.lane23_status.raw = tmp[DP_LANE2_3_STATUS_ESI - DP_SINK_COUNT_ESI];
+               irq_data->bytes.lane_status_updated.raw = tmp[DP_LANE_ALIGN_STATUS_UPDATED_ESI - DP_SINK_COUNT_ESI];
+               irq_data->bytes.sink_status.raw = tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI];
        }
 
        return retval;