drm/amd/display: Revert W/A for hard hangs on DCN20/DCN21
authorMario Limonciello <mario.limonciello@amd.com>
Fri, 7 Jan 2022 16:44:17 +0000 (10:44 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Jan 2022 11:02:46 +0000 (12:02 +0100)
commit c4849f88164b13dd141885e28210f599741b304b upstream.

The WA from commit 2a50edbf10c8 ("drm/amd/display: Apply w/a for hard hang
on HPD") and commit 1bd3bc745e7f ("drm/amd/display: Extend w/a for hard
hang on HPD to dcn20") causes a regression in s0ix where the system will
fail to resume properly on many laptops.  Pull the workarounds out to
avoid that s0ix regression in the common case.  This HPD hang happens with
an external device in special circumstances and a new W/A will need to be
developed for this in the future.

Cc: stable@vger.kernel.org
Cc: Qingqing Zhuo <qingqing.zhuo@amd.com>
Reported-by: Scott Bruce <smbruce@gmail.com>
Reported-by: Chris Hixon <linux-kernel-bugs@hixontech.com>
Reported-by: spasswolf@web.de
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215436
Link: https://gitlab.freedesktop.org/drm/amd/-/issues/1821
Link: https://gitlab.freedesktop.org/drm/amd/-/issues/1852
Fixes: 2a50edbf10c8 ("drm/amd/display: Apply w/a for hard hang on HPD")
Fixes: 1bd3bc745e7f ("drm/amd/display: Extend w/a for hard hang on HPD to dcn20")
Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c
drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.h
drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c
drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.h
drivers/gpu/drm/amd/display/dc/irq/irq_service.c
drivers/gpu/drm/amd/display/dc/irq/irq_service.h

index 2108bff49d4ebf7556b51cc8315754f322360b83..146e6d670899054b5a23765f0c7b1f33abeeb3dd 100644 (file)
@@ -38,7 +38,6 @@
 #include "clk/clk_11_0_0_offset.h"
 #include "clk/clk_11_0_0_sh_mask.h"
 
-#include "irq/dcn20/irq_service_dcn20.h"
 
 #undef FN
 #define FN(reg_name, field_name) \
@@ -223,8 +222,6 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
        bool force_reset = false;
        bool p_state_change_support;
        int total_plane_count;
-       int irq_src;
-       uint32_t hpd_state;
 
        if (dc->work_arounds.skip_clock_update)
                return;
@@ -242,13 +239,7 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
        if (dc->res_pool->pp_smu)
                pp_smu = &dc->res_pool->pp_smu->nv_funcs;
 
-       for (irq_src = DC_IRQ_SOURCE_HPD1; irq_src <= DC_IRQ_SOURCE_HPD6; irq_src++) {
-               hpd_state = dc_get_hpd_state_dcn20(dc->res_pool->irqs, irq_src);
-               if (hpd_state)
-                       break;
-       }
-
-       if (display_count == 0 && !hpd_state)
+       if (display_count == 0)
                enter_display_off = true;
 
        if (enter_display_off == safe_to_lower) {
index ac2d4c4f04e48705742257097d16f81e236c7bee..d3c8db65ff454151c9f79023eeb771d03156ea36 100644 (file)
@@ -42,7 +42,6 @@
 #include "clk/clk_10_0_2_sh_mask.h"
 #include "renoir_ip_offset.h"
 
-#include "irq/dcn21/irq_service_dcn21.h"
 
 /* Constants */
 
@@ -130,11 +129,9 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
        struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
        struct dc *dc = clk_mgr_base->ctx->dc;
        int display_count;
-       int irq_src;
        bool update_dppclk = false;
        bool update_dispclk = false;
        bool dpp_clock_lowered = false;
-       uint32_t hpd_state;
 
        struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu;
 
@@ -151,14 +148,8 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
 
                        display_count = rn_get_active_display_cnt_wa(dc, context);
 
-                       for (irq_src = DC_IRQ_SOURCE_HPD1; irq_src <= DC_IRQ_SOURCE_HPD5; irq_src++) {
-                               hpd_state = dc_get_hpd_state_dcn21(dc->res_pool->irqs, irq_src);
-                               if (hpd_state)
-                                       break;
-                       }
-
                        /* if we can go lower, go lower */
-                       if (display_count == 0 && !hpd_state) {
+                       if (display_count == 0) {
                                rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_LOW_POWER);
                                /* update power state */
                                clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER;
index 9ccafe007b23a175b2a55a53550a06db504c3195..c4b067d0189565f8801a8c3d35be2529fb07e9b0 100644 (file)
@@ -132,31 +132,6 @@ enum dc_irq_source to_dal_irq_source_dcn20(
        }
 }
 
-uint32_t dc_get_hpd_state_dcn20(struct irq_service *irq_service, enum dc_irq_source source)
-{
-       const struct irq_source_info *info;
-       uint32_t addr;
-       uint32_t value;
-       uint32_t current_status;
-
-       info = find_irq_source_info(irq_service, source);
-       if (!info)
-               return 0;
-
-       addr = info->status_reg;
-       if (!addr)
-               return 0;
-
-       value = dm_read_reg(irq_service->ctx, addr);
-       current_status =
-               get_reg_field_value(
-                       value,
-                       HPD0_DC_HPD_INT_STATUS,
-                       DC_HPD_SENSE);
-
-       return current_status;
-}
-
 static bool hpd_ack(
        struct irq_service *irq_service,
        const struct irq_source_info *info)
index 4d69ab24ca257d6ec04f6612414cecab1986115d..aee4b37999f19f1c72225cd8dbe28a2ee955e739 100644 (file)
@@ -31,6 +31,4 @@
 struct irq_service *dal_irq_service_dcn20_create(
        struct irq_service_init_data *init_data);
 
-uint32_t dc_get_hpd_state_dcn20(struct irq_service *irq_service, enum dc_irq_source source);
-
 #endif
index 78940cb20e10fdf2440e2fe52b01f8b4d79b2509..ed54e1c819beda7b13e371249f21adf65205133b 100644 (file)
@@ -135,31 +135,6 @@ enum dc_irq_source to_dal_irq_source_dcn21(
        return DC_IRQ_SOURCE_INVALID;
 }
 
-uint32_t dc_get_hpd_state_dcn21(struct irq_service *irq_service, enum dc_irq_source source)
-{
-       const struct irq_source_info *info;
-       uint32_t addr;
-       uint32_t value;
-       uint32_t current_status;
-
-       info = find_irq_source_info(irq_service, source);
-       if (!info)
-               return 0;
-
-       addr = info->status_reg;
-       if (!addr)
-               return 0;
-
-       value = dm_read_reg(irq_service->ctx, addr);
-       current_status =
-               get_reg_field_value(
-                       value,
-                       HPD0_DC_HPD_INT_STATUS,
-                       DC_HPD_SENSE);
-
-       return current_status;
-}
-
 static bool hpd_ack(
        struct irq_service *irq_service,
        const struct irq_source_info *info)
index 616470e323803cb6bf1dfdd499d27973e4287e8a..da2bd0e93d7ad9451260011a723b1a7609d97469 100644 (file)
@@ -31,6 +31,4 @@
 struct irq_service *dal_irq_service_dcn21_create(
        struct irq_service_init_data *init_data);
 
-uint32_t dc_get_hpd_state_dcn21(struct irq_service *irq_service, enum dc_irq_source source);
-
 #endif
index 4db1133e4466be1f9146d7b87f85ed58aa218dca..a2a4fbeb83f86c3d4620fb996e417a892b704ee9 100644 (file)
@@ -79,7 +79,7 @@ void dal_irq_service_destroy(struct irq_service **irq_service)
        *irq_service = NULL;
 }
 
-const struct irq_source_info *find_irq_source_info(
+static const struct irq_source_info *find_irq_source_info(
        struct irq_service *irq_service,
        enum dc_irq_source source)
 {
index e60b824800932c48ea9b0ea89cd6b6e7c3421788..dbfcb096eedd684593cddb66a151d812b68ab50a 100644 (file)
@@ -69,10 +69,6 @@ struct irq_service {
        const struct irq_service_funcs *funcs;
 };
 
-const struct irq_source_info *find_irq_source_info(
-       struct irq_service *irq_service,
-       enum dc_irq_source source);
-
 void dal_irq_service_construct(
        struct irq_service *irq_service,
        struct irq_service_init_data *init_data);