Skip to content

Commit

Permalink
drm/amd/display: Revert W/A for hard hangs on DCN20/DCN21
Browse files Browse the repository at this point in the history
The WA from commit 2a50edb ("drm/amd/display: Apply w/a for hard hang
on HPD") and commit 1bd3bc7 ("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: 2a50edb ("drm/amd/display: Apply w/a for hard hang on HPD")
Fixes: 1bd3bc7 ("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>
  • Loading branch information
Mario Limonciello authored and Alex Deucher committed Jan 14, 2022
1 parent d82ce3c commit c4849f8
Show file tree
Hide file tree
Showing 8 changed files with 3 additions and 79 deletions.
11 changes: 1 addition & 10 deletions drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
11 changes: 1 addition & 10 deletions drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -129,11 +128,9 @@ static 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;

Expand All @@ -150,14 +147,8 @@ static 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;
Expand Down
25 changes: 0 additions & 25 deletions drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 0 additions & 2 deletions drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
25 changes: 0 additions & 25 deletions drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,31 +134,6 @@ static enum dc_irq_source to_dal_irq_source_dcn21(struct irq_service *irq_servic
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)
Expand Down
2 changes: 0 additions & 2 deletions drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/display/dc/irq/irq_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
4 changes: 0 additions & 4 deletions drivers/gpu/drm/amd/display/dc/irq/irq_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit c4849f8

Please sign in to comment.