aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2832-drm-amd-display-USB-C-thunderbolt-dock-specific-work.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2832-drm-amd-display-USB-C-thunderbolt-dock-specific-work.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2832-drm-amd-display-USB-C-thunderbolt-dock-specific-work.patch134
1 files changed, 134 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2832-drm-amd-display-USB-C-thunderbolt-dock-specific-work.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2832-drm-amd-display-USB-C-thunderbolt-dock-specific-work.patch
new file mode 100644
index 00000000..57de9fdf
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2832-drm-amd-display-USB-C-thunderbolt-dock-specific-work.patch
@@ -0,0 +1,134 @@
+From 1e397cf81c02d335b31dbdeaf70e28a4cf94143a Mon Sep 17 00:00:00 2001
+From: Hersen Wu <hersenxs.wu@amd.com>
+Date: Mon, 20 Nov 2017 12:45:54 -0500
+Subject: [PATCH 2832/4131] drm/amd/display: USB-C / thunderbolt dock specific
+ workaround
+
+reading dpcd 0x600 cause link loss for a particular USB-C dock with
+thurderbolt. workaround by avoiding dcpd 0x600 read unless it's
+necessary.
+
+Signed-off-by: Hersen Wu <hersenxs.wu@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 | 85 +++++++++++-------------
+ 1 file changed, 40 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+index 7962086..00528b2 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+@@ -1509,7 +1509,7 @@ static bool hpd_rx_irq_check_link_loss_status(
+ struct dc_link *link,
+ union hpd_irq_data *hpd_irq_dpcd_data)
+ {
+- uint8_t irq_reg_rx_power_state;
++ uint8_t irq_reg_rx_power_state = 0;
+ enum dc_status dpcd_result = DC_ERROR_UNEXPECTED;
+ union lane_status lane_status;
+ uint32_t lane;
+@@ -1521,60 +1521,55 @@ static bool hpd_rx_irq_check_link_loss_status(
+
+ if (link->cur_link_settings.lane_count == 0)
+ return return_code;
+- /*1. Check that we can handle interrupt: Not in FS DOS,
+- * Not in "Display Timeout" state, Link is trained.
+- */
+
+- dpcd_result = core_link_read_dpcd(link,
+- DP_SET_POWER,
+- &irq_reg_rx_power_state,
+- sizeof(irq_reg_rx_power_state));
++ /*1. Check that Link Status changed, before re-training.*/
+
+- if (dpcd_result != DC_OK) {
+- irq_reg_rx_power_state = DP_SET_POWER_D0;
+- dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ,
+- "%s: DPCD read failed to obtain power state.\n",
+- __func__);
++ /*parse lane status*/
++ for (lane = 0; lane < link->cur_link_settings.lane_count; lane++) {
++ /* check status of lanes 0,1
++ * changed DpcdAddress_Lane01Status (0x202)
++ */
++ lane_status.raw = get_nibble_at_index(
++ &hpd_irq_dpcd_data->bytes.lane01_status.raw,
++ lane);
++
++ if (!lane_status.bits.CHANNEL_EQ_DONE_0 ||
++ !lane_status.bits.CR_DONE_0 ||
++ !lane_status.bits.SYMBOL_LOCKED_0) {
++ /* if one of the channel equalization, clock
++ * recovery or symbol lock is dropped
++ * consider it as (link has been
++ * dropped) dp sink status has changed
++ */
++ sink_status_changed = true;
++ break;
++ }
+ }
+
+- if (irq_reg_rx_power_state == DP_SET_POWER_D0) {
++ /* Check interlane align.*/
++ if (sink_status_changed ||
++ !hpd_irq_dpcd_data->bytes.lane_status_updated.bits.INTERLANE_ALIGN_DONE) {
+
+- /*2. Check that Link Status changed, before re-training.*/
+-
+- /*parse lane status*/
+- for (lane = 0;
+- lane < link->cur_link_settings.lane_count;
+- lane++) {
+-
+- /* check status of lanes 0,1
+- * changed DpcdAddress_Lane01Status (0x202)*/
+- lane_status.raw = get_nibble_at_index(
+- &hpd_irq_dpcd_data->bytes.lane01_status.raw,
+- lane);
+-
+- if (!lane_status.bits.CHANNEL_EQ_DONE_0 ||
+- !lane_status.bits.CR_DONE_0 ||
+- !lane_status.bits.SYMBOL_LOCKED_0) {
+- /* if one of the channel equalization, clock
+- * recovery or symbol lock is dropped
+- * consider it as (link has been
+- * dropped) dp sink status has changed*/
+- sink_status_changed = true;
+- break;
+- }
++ dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ,
++ "%s: Link Status changed.\n", __func__);
+
+- }
++ return_code = true;
+
+- /* Check interlane align.*/
+- if (sink_status_changed ||
+- !hpd_irq_dpcd_data->bytes.lane_status_updated.bits.
+- INTERLANE_ALIGN_DONE) {
++ /*2. Check that we can handle interrupt: Not in FS DOS,
++ * Not in "Display Timeout" state, Link is trained.
++ */
++ dpcd_result = core_link_read_dpcd(link,
++ DP_SET_POWER,
++ &irq_reg_rx_power_state,
++ sizeof(irq_reg_rx_power_state));
+
++ if (dpcd_result != DC_OK) {
+ dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ,
+- "%s: Link Status changed.\n",
++ "%s: DPCD read failed to obtain power state.\n",
+ __func__);
+-
+- return_code = true;
++ } else {
++ if (irq_reg_rx_power_state != DP_SET_POWER_D0)
++ return_code = false;
+ }
+ }
+
+--
+2.7.4
+