Skip to content

Commit dbb2c3a

Browse files
committed
Merge tag 'amd-drm-fixes-6.17-2025-08-20' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes
amd-drm-fixes-6.17-2025-08-20: amdgpu: - Replay fixes - SMU14 fix - Null check DC fixes - DCE6 DC fixes - Misc DC fixes Signed-off-by: Dave Airlie <[email protected]> From: Alex Deucher <[email protected]> Link: https://lore.kernel.org/r/[email protected]
2 parents 98c4a3f + 297a483 commit dbb2c3a

File tree

15 files changed

+112
-125
lines changed

15 files changed

+112
-125
lines changed

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7792,6 +7792,9 @@ amdgpu_dm_connector_atomic_check(struct drm_connector *conn,
77927792
struct amdgpu_dm_connector *aconn = to_amdgpu_dm_connector(conn);
77937793
int ret;
77947794

7795+
if (WARN_ON(unlikely(!old_con_state || !new_con_state)))
7796+
return -EINVAL;
7797+
77957798
trace_amdgpu_dm_connector_atomic_check(new_con_state);
77967799

77977800
if (conn->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,25 @@ static inline int amdgpu_dm_crtc_set_vblank(struct drm_crtc *crtc, bool enable)
299299
irq_type = amdgpu_display_crtc_idx_to_irq_type(adev, acrtc->crtc_id);
300300

301301
if (enable) {
302+
struct dc *dc = adev->dm.dc;
303+
struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
304+
struct psr_settings *psr = &acrtc_state->stream->link->psr_settings;
305+
struct replay_settings *pr = &acrtc_state->stream->link->replay_settings;
306+
bool sr_supported = (psr->psr_version != DC_PSR_VERSION_UNSUPPORTED) ||
307+
pr->config.replay_supported;
308+
309+
/*
310+
* IPS & self-refresh feature can cause vblank counter resets between
311+
* vblank disable and enable.
312+
* It may cause system stuck due to waiting for the vblank counter.
313+
* Call this function to estimate missed vblanks by using timestamps and
314+
* update the vblank counter in DRM.
315+
*/
316+
if (dc->caps.ips_support &&
317+
dc->config.disable_ips != DMUB_IPS_DISABLE_ALL &&
318+
sr_supported && vblank->config.disable_immediate)
319+
drm_crtc_vblank_restore(crtc);
320+
302321
/* vblank irq on -> Only need vupdate irq in vrr mode */
303322
if (amdgpu_dm_crtc_vrr_active(acrtc_state))
304323
rc = amdgpu_dm_crtc_set_vupdate_irq(crtc, true);

drivers/gpu/drm/amd/display/dc/bios/bios_parser.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,8 @@ static struct graphics_object_id bios_parser_get_connector_id(
174174
return object_id;
175175
}
176176

177-
if (tbl->ucNumberOfObjects <= i) {
178-
dm_error("Can't find connector id %d in connector table of size %d.\n",
179-
i, tbl->ucNumberOfObjects);
177+
if (tbl->ucNumberOfObjects <= i)
180178
return object_id;
181-
}
182179

183180
id = le16_to_cpu(tbl->asObjects[i].usObjectID);
184181
object_id = object_id_from_bios_object_id(id);

drivers/gpu/drm/amd/display/dc/bios/command_table.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -993,7 +993,7 @@ static enum bp_result set_pixel_clock_v3(
993993
allocation.sPCLKInput.usFbDiv =
994994
cpu_to_le16((uint16_t)bp_params->feedback_divider);
995995
allocation.sPCLKInput.ucFracFbDiv =
996-
(uint8_t)bp_params->fractional_feedback_divider;
996+
(uint8_t)(bp_params->fractional_feedback_divider / 100000);
997997
allocation.sPCLKInput.ucPostDiv =
998998
(uint8_t)bp_params->pixel_clock_post_divider;
999999

drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ static const struct state_dependent_clocks dce80_max_clks_by_state[] = {
7272
/* ClocksStateLow */
7373
{ .display_clk_khz = 352000, .pixel_clk_khz = 330000},
7474
/* ClocksStateNominal */
75-
{ .display_clk_khz = 600000, .pixel_clk_khz = 400000 },
75+
{ .display_clk_khz = 625000, .pixel_clk_khz = 400000 },
7676
/* ClocksStatePerformance */
77-
{ .display_clk_khz = 600000, .pixel_clk_khz = 400000 } };
77+
{ .display_clk_khz = 625000, .pixel_clk_khz = 400000 } };
7878

7979
int dentist_get_divider_from_did(int did)
8080
{
@@ -391,8 +391,6 @@ static void dce_pplib_apply_display_requirements(
391391
{
392392
struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg;
393393

394-
pp_display_cfg->avail_mclk_switch_time_us = dce110_get_min_vblank_time_us(context);
395-
396394
dce110_fill_display_configs(context, pp_display_cfg);
397395

398396
if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0)
@@ -405,11 +403,9 @@ static void dce_update_clocks(struct clk_mgr *clk_mgr_base,
405403
{
406404
struct clk_mgr_internal *clk_mgr_dce = TO_CLK_MGR_INTERNAL(clk_mgr_base);
407405
struct dm_pp_power_level_change_request level_change_req;
408-
int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz;
409-
410-
/*TODO: W/A for dal3 linux, investigate why this works */
411-
if (!clk_mgr_dce->dfs_bypass_active)
412-
patched_disp_clk = patched_disp_clk * 115 / 100;
406+
const int max_disp_clk =
407+
clk_mgr_dce->max_clks_by_state[DM_PP_CLOCKS_STATE_PERFORMANCE].display_clk_khz;
408+
int patched_disp_clk = MIN(max_disp_clk, context->bw_ctx.bw.dce.dispclk_khz);
413409

414410
level_change_req.power_level = dce_get_required_clocks_state(clk_mgr_base, context);
415411
/* get max clock state from PPLIB */

drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,15 @@ void dce110_fill_display_configs(
120120
const struct dc_state *context,
121121
struct dm_pp_display_configuration *pp_display_cfg)
122122
{
123+
struct dc *dc = context->clk_mgr->ctx->dc;
123124
int j;
124125
int num_cfgs = 0;
125126

127+
pp_display_cfg->avail_mclk_switch_time_us = dce110_get_min_vblank_time_us(context);
128+
pp_display_cfg->disp_clk_khz = dc->clk_mgr->clks.dispclk_khz;
129+
pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0;
130+
pp_display_cfg->crtc_index = dc->res_pool->res_cap->num_timing_generator;
131+
126132
for (j = 0; j < context->stream_count; j++) {
127133
int k;
128134

@@ -164,6 +170,23 @@ void dce110_fill_display_configs(
164170
cfg->v_refresh /= stream->timing.h_total;
165171
cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total / 2)
166172
/ stream->timing.v_total;
173+
174+
/* Find first CRTC index and calculate its line time.
175+
* This is necessary for DPM on SI GPUs.
176+
*/
177+
if (cfg->pipe_idx < pp_display_cfg->crtc_index) {
178+
const struct dc_crtc_timing *timing =
179+
&context->streams[0]->timing;
180+
181+
pp_display_cfg->crtc_index = cfg->pipe_idx;
182+
pp_display_cfg->line_time_in_us =
183+
timing->h_total * 10000 / timing->pix_clk_100hz;
184+
}
185+
}
186+
187+
if (!num_cfgs) {
188+
pp_display_cfg->crtc_index = 0;
189+
pp_display_cfg->line_time_in_us = 0;
167190
}
168191

169192
pp_display_cfg->display_count = num_cfgs;
@@ -223,25 +246,8 @@ void dce11_pplib_apply_display_requirements(
223246
pp_display_cfg->min_engine_clock_deep_sleep_khz
224247
= context->bw_ctx.bw.dce.sclk_deep_sleep_khz;
225248

226-
pp_display_cfg->avail_mclk_switch_time_us =
227-
dce110_get_min_vblank_time_us(context);
228-
/* TODO: dce11.2*/
229-
pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0;
230-
231-
pp_display_cfg->disp_clk_khz = dc->clk_mgr->clks.dispclk_khz;
232-
233249
dce110_fill_display_configs(context, pp_display_cfg);
234250

235-
/* TODO: is this still applicable?*/
236-
if (pp_display_cfg->display_count == 1) {
237-
const struct dc_crtc_timing *timing =
238-
&context->streams[0]->timing;
239-
240-
pp_display_cfg->crtc_index =
241-
pp_display_cfg->disp_configs[0].pipe_idx;
242-
pp_display_cfg->line_time_in_us = timing->h_total * 10000 / timing->pix_clk_100hz;
243-
}
244-
245251
if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0)
246252
dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg);
247253
}

drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,13 @@ static const struct state_dependent_clocks dce60_max_clks_by_state[] = {
8383
static int dce60_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base)
8484
{
8585
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
86-
int dprefclk_wdivider;
87-
int dp_ref_clk_khz;
88-
int target_div;
86+
struct dc_context *ctx = clk_mgr_base->ctx;
87+
int dp_ref_clk_khz = 0;
8988

90-
/* DCE6 has no DPREFCLK_CNTL to read DP Reference Clock source */
91-
92-
/* Read the mmDENTIST_DISPCLK_CNTL to get the currently
93-
* programmed DID DENTIST_DPREFCLK_WDIVIDER*/
94-
REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, &dprefclk_wdivider);
95-
96-
/* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/
97-
target_div = dentist_get_divider_from_did(dprefclk_wdivider);
98-
99-
/* Calculate the current DFS clock, in kHz.*/
100-
dp_ref_clk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR
101-
* clk_mgr->base.dentist_vco_freq_khz) / target_div;
89+
if (ASIC_REV_IS_TAHITI_P(ctx->asic_id.hw_internal_rev))
90+
dp_ref_clk_khz = ctx->dc_bios->fw_info.default_display_engine_pll_frequency;
91+
else
92+
dp_ref_clk_khz = clk_mgr_base->clks.dispclk_khz;
10293

10394
return dce_adjust_dp_ref_freq_for_ss(clk_mgr, dp_ref_clk_khz);
10495
}
@@ -109,8 +100,6 @@ static void dce60_pplib_apply_display_requirements(
109100
{
110101
struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg;
111102

112-
pp_display_cfg->avail_mclk_switch_time_us = dce110_get_min_vblank_time_us(context);
113-
114103
dce110_fill_display_configs(context, pp_display_cfg);
115104

116105
if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0)
@@ -123,11 +112,9 @@ static void dce60_update_clocks(struct clk_mgr *clk_mgr_base,
123112
{
124113
struct clk_mgr_internal *clk_mgr_dce = TO_CLK_MGR_INTERNAL(clk_mgr_base);
125114
struct dm_pp_power_level_change_request level_change_req;
126-
int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz;
127-
128-
/*TODO: W/A for dal3 linux, investigate why this works */
129-
if (!clk_mgr_dce->dfs_bypass_active)
130-
patched_disp_clk = patched_disp_clk * 115 / 100;
115+
const int max_disp_clk =
116+
clk_mgr_dce->max_clks_by_state[DM_PP_CLOCKS_STATE_PERFORMANCE].display_clk_khz;
117+
int patched_disp_clk = MIN(max_disp_clk, context->bw_ctx.bw.dce.dispclk_khz);
131118

132119
level_change_req.power_level = dce_get_required_clocks_state(clk_mgr_base, context);
133120
/* get max clock state from PPLIB */

drivers/gpu/drm/amd/display/dc/core/dc.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,24 @@ static bool create_links(
217217
connectors_num,
218218
num_virtual_links);
219219

220-
// condition loop on link_count to allow skipping invalid indices
220+
/* When getting the number of connectors, the VBIOS reports the number of valid indices,
221+
* but it doesn't say which indices are valid, and not every index has an actual connector.
222+
* So, if we don't find a connector on an index, that is not an error.
223+
*
224+
* - There is no guarantee that the first N indices will be valid
225+
* - VBIOS may report a higher amount of valid indices than there are actual connectors
226+
* - Some VBIOS have valid configurations for more connectors than there actually are
227+
* on the card. This may be because the manufacturer used the same VBIOS for different
228+
* variants of the same card.
229+
*/
221230
for (i = 0; dc->link_count < connectors_num && i < MAX_LINKS; i++) {
231+
struct graphics_object_id connector_id = bios->funcs->get_connector_id(bios, i);
222232
struct link_init_data link_init_params = {0};
223233
struct dc_link *link;
224234

235+
if (connector_id.id == CONNECTOR_ID_UNKNOWN)
236+
continue;
237+
225238
DC_LOG_DC("BIOS object table - printing link object info for connector number: %d, link_index: %d", i, dc->link_count);
226239

227240
link_init_params.ctx = dc->ctx;

drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -896,13 +896,13 @@ void dce110_link_encoder_construct(
896896
enc110->base.id, &bp_cap_info);
897897

898898
/* Override features with DCE-specific values */
899-
if (BP_RESULT_OK == result) {
899+
if (result == BP_RESULT_OK) {
900900
enc110->base.features.flags.bits.IS_HBR2_CAPABLE =
901901
bp_cap_info.DP_HBR2_EN;
902902
enc110->base.features.flags.bits.IS_HBR3_CAPABLE =
903903
bp_cap_info.DP_HBR3_EN;
904904
enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
905-
} else {
905+
} else if (result != BP_RESULT_NORECORD) {
906906
DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
907907
__func__,
908908
result);
@@ -1798,13 +1798,13 @@ void dce60_link_encoder_construct(
17981798
enc110->base.id, &bp_cap_info);
17991799

18001800
/* Override features with DCE-specific values */
1801-
if (BP_RESULT_OK == result) {
1801+
if (result == BP_RESULT_OK) {
18021802
enc110->base.features.flags.bits.IS_HBR2_CAPABLE =
18031803
bp_cap_info.DP_HBR2_EN;
18041804
enc110->base.features.flags.bits.IS_HBR3_CAPABLE =
18051805
bp_cap_info.DP_HBR3_EN;
18061806
enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
1807-
} else {
1807+
} else if (result != BP_RESULT_NORECORD) {
18081808
DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
18091809
__func__,
18101810
result);

drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c

Lines changed: 3 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
#include "dc.h"
66
#include "dc_dmub_srv.h"
7-
#include "dc_dp_types.h"
87
#include "dmub/dmub_srv.h"
98
#include "core_types.h"
109
#include "dmub_replay.h"
@@ -44,45 +43,21 @@ static void dmub_replay_get_state(struct dmub_replay *dmub, enum replay_state *s
4443
/*
4544
* Enable/Disable Replay.
4645
*/
47-
static void dmub_replay_enable(struct dmub_replay *dmub, bool enable, bool wait, uint8_t panel_inst,
48-
struct dc_link *link)
46+
static void dmub_replay_enable(struct dmub_replay *dmub, bool enable, bool wait, uint8_t panel_inst)
4947
{
5048
union dmub_rb_cmd cmd;
5149
struct dc_context *dc = dmub->ctx;
5250
uint32_t retry_count;
5351
enum replay_state state = REPLAY_STATE_0;
54-
struct pipe_ctx *pipe_ctx = NULL;
55-
struct resource_context *res_ctx = &link->ctx->dc->current_state->res_ctx;
56-
uint8_t i;
5752

5853
memset(&cmd, 0, sizeof(cmd));
5954
cmd.replay_enable.header.type = DMUB_CMD__REPLAY;
6055
cmd.replay_enable.data.panel_inst = panel_inst;
6156

6257
cmd.replay_enable.header.sub_type = DMUB_CMD__REPLAY_ENABLE;
63-
if (enable) {
58+
if (enable)
6459
cmd.replay_enable.data.enable = REPLAY_ENABLE;
65-
// hpo stream/link encoder assignments are not static, need to update everytime we try to enable replay
66-
if (link->cur_link_settings.link_rate >= LINK_RATE_UHBR10) {
67-
for (i = 0; i < MAX_PIPES; i++) {
68-
if (res_ctx &&
69-
res_ctx->pipe_ctx[i].stream &&
70-
res_ctx->pipe_ctx[i].stream->link &&
71-
res_ctx->pipe_ctx[i].stream->link == link &&
72-
res_ctx->pipe_ctx[i].stream->link->connector_signal == SIGNAL_TYPE_EDP) {
73-
pipe_ctx = &res_ctx->pipe_ctx[i];
74-
//TODO: refactor for multi edp support
75-
break;
76-
}
77-
}
78-
79-
if (!pipe_ctx)
80-
return;
81-
82-
cmd.replay_enable.data.hpo_stream_enc_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
83-
cmd.replay_enable.data.hpo_link_enc_inst = pipe_ctx->link_res.hpo_dp_link_enc->inst;
84-
}
85-
} else
60+
else
8661
cmd.replay_enable.data.enable = REPLAY_DISABLE;
8762

8863
cmd.replay_enable.header.payload_bytes = sizeof(struct dmub_rb_cmd_replay_enable_data);
@@ -174,17 +149,6 @@ static bool dmub_replay_copy_settings(struct dmub_replay *dmub,
174149
copy_settings_data->digbe_inst = replay_context->digbe_inst;
175150
copy_settings_data->digfe_inst = replay_context->digfe_inst;
176151

177-
if (link->cur_link_settings.link_rate >= LINK_RATE_UHBR10) {
178-
if (pipe_ctx->stream_res.hpo_dp_stream_enc)
179-
copy_settings_data->hpo_stream_enc_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
180-
else
181-
copy_settings_data->hpo_stream_enc_inst = 0;
182-
if (pipe_ctx->link_res.hpo_dp_link_enc)
183-
copy_settings_data->hpo_link_enc_inst = pipe_ctx->link_res.hpo_dp_link_enc->inst;
184-
else
185-
copy_settings_data->hpo_link_enc_inst = 0;
186-
}
187-
188152
if (pipe_ctx->plane_res.dpp)
189153
copy_settings_data->dpp_inst = pipe_ctx->plane_res.dpp->inst;
190154
else
@@ -247,7 +211,6 @@ static void dmub_replay_set_coasting_vtotal(struct dmub_replay *dmub,
247211
pCmd->header.type = DMUB_CMD__REPLAY;
248212
pCmd->header.sub_type = DMUB_CMD__REPLAY_SET_COASTING_VTOTAL;
249213
pCmd->header.payload_bytes = sizeof(struct dmub_cmd_replay_set_coasting_vtotal_data);
250-
pCmd->replay_set_coasting_vtotal_data.panel_inst = panel_inst;
251214
pCmd->replay_set_coasting_vtotal_data.coasting_vtotal = (coasting_vtotal & 0xFFFF);
252215
pCmd->replay_set_coasting_vtotal_data.coasting_vtotal_high = (coasting_vtotal & 0xFFFF0000) >> 16;
253216

0 commit comments

Comments
 (0)