Skip to content

Commit 29ecd47

Browse files
committed
Merge tag 'amd-drm-fixes-6.17-2025-09-24' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes
amd-drm-fixes-6.17-2025-09-24: amdgpu: - Backlight fix - DC preblend fix - DCN 3.5 fix - Cleanup output_tf_change Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://lore.kernel.org/r/20250924200632.531102-1-alexander.deucher@amd.com
2 parents 07e27ad + 41b1f9f commit 29ecd47

File tree

8 files changed

+140
-17
lines changed

8 files changed

+140
-17
lines changed

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,6 +2037,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
20372037

20382038
dc_hardware_init(adev->dm.dc);
20392039

2040+
adev->dm.restore_backlight = true;
2041+
20402042
adev->dm.hpd_rx_offload_wq = hpd_rx_irq_create_workqueue(adev);
20412043
if (!adev->dm.hpd_rx_offload_wq) {
20422044
drm_err(adev_to_drm(adev), "failed to create hpd rx offload workqueue.\n");
@@ -3399,6 +3401,7 @@ static int dm_resume(struct amdgpu_ip_block *ip_block)
33993401
dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
34003402

34013403
dc_resume(dm->dc);
3404+
adev->dm.restore_backlight = true;
34023405

34033406
amdgpu_dm_irq_resume_early(adev);
34043407

@@ -9829,7 +9832,6 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
98299832
bool mode_set_reset_required = false;
98309833
u32 i;
98319834
struct dc_commit_streams_params params = {dc_state->streams, dc_state->stream_count};
9832-
bool set_backlight_level = false;
98339835

98349836
/* Disable writeback */
98359837
for_each_old_connector_in_state(state, connector, old_con_state, i) {
@@ -9949,7 +9951,6 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
99499951
acrtc->hw_mode = new_crtc_state->mode;
99509952
crtc->hwmode = new_crtc_state->mode;
99519953
mode_set_reset_required = true;
9952-
set_backlight_level = true;
99539954
} else if (modereset_required(new_crtc_state)) {
99549955
drm_dbg_atomic(dev,
99559956
"Atomic commit: RESET. crtc id %d:[%p]\n",
@@ -10006,13 +10007,16 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
1000610007
* to fix a flicker issue.
1000710008
* It will cause the dm->actual_brightness is not the current panel brightness
1000810009
* level. (the dm->brightness is the correct panel level)
10009-
* So we set the backlight level with dm->brightness value after set mode
10010+
* So we set the backlight level with dm->brightness value after initial
10011+
* set mode. Use restore_backlight flag to avoid setting backlight level
10012+
* for every subsequent mode set.
1001010013
*/
10011-
if (set_backlight_level) {
10014+
if (dm->restore_backlight) {
1001210015
for (i = 0; i < dm->num_of_edps; i++) {
1001310016
if (dm->backlight_dev[i])
1001410017
amdgpu_dm_backlight_set_level(dm, i, dm->brightness[i]);
1001510018
}
10019+
dm->restore_backlight = false;
1001610020
}
1001710021
}
1001810022

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,13 @@ struct amdgpu_display_manager {
610610
*/
611611
u32 actual_brightness[AMDGPU_DM_MAX_NUM_EDP];
612612

613+
/**
614+
* @restore_backlight:
615+
*
616+
* Flag to indicate whether to restore backlight after modeset.
617+
*/
618+
bool restore_backlight;
619+
613620
/**
614621
* @aux_hpd_discon_quirk:
615622
*

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
821821
struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
822822
const struct drm_color_lut *shaper = NULL, *lut3d = NULL;
823823
uint32_t exp_size, size, dim_size = MAX_COLOR_3DLUT_SIZE;
824-
bool has_3dlut = adev->dm.dc->caps.color.dpp.hw_3d_lut;
824+
bool has_3dlut = adev->dm.dc->caps.color.dpp.hw_3d_lut || adev->dm.dc->caps.color.mpc.preblend;
825825

826826
/* shaper LUT is only available if 3D LUT color caps */
827827
exp_size = has_3dlut ? MAX_COLOR_LUT_ENTRIES : 0;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1633,7 +1633,7 @@ dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
16331633
drm_object_attach_property(&plane->base,
16341634
dm->adev->mode_info.plane_ctm_property, 0);
16351635

1636-
if (dpp_color_caps.hw_3d_lut) {
1636+
if (dpp_color_caps.hw_3d_lut || dm->dc->caps.color.mpc.preblend) {
16371637
drm_object_attach_property(&plane->base,
16381638
mode_info.plane_shaper_lut_property, 0);
16391639
drm_object_attach_property(&plane->base,

drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -587,9 +587,118 @@ bool dcn35_are_clock_states_equal(struct dc_clocks *a,
587587
return true;
588588
}
589589

590-
static void dcn35_dump_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass,
590+
static void dcn35_save_clk_registers_internal(struct dcn35_clk_internal *internal, struct clk_mgr *clk_mgr_base)
591+
{
592+
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
593+
594+
// read dtbclk
595+
internal->CLK1_CLK4_CURRENT_CNT = REG_READ(CLK1_CLK4_CURRENT_CNT);
596+
internal->CLK1_CLK4_BYPASS_CNTL = REG_READ(CLK1_CLK4_BYPASS_CNTL);
597+
598+
// read dcfclk
599+
internal->CLK1_CLK3_CURRENT_CNT = REG_READ(CLK1_CLK3_CURRENT_CNT);
600+
internal->CLK1_CLK3_BYPASS_CNTL = REG_READ(CLK1_CLK3_BYPASS_CNTL);
601+
602+
// read dcf deep sleep divider
603+
internal->CLK1_CLK3_DS_CNTL = REG_READ(CLK1_CLK3_DS_CNTL);
604+
internal->CLK1_CLK3_ALLOW_DS = REG_READ(CLK1_CLK3_ALLOW_DS);
605+
606+
// read dppclk
607+
internal->CLK1_CLK1_CURRENT_CNT = REG_READ(CLK1_CLK1_CURRENT_CNT);
608+
internal->CLK1_CLK1_BYPASS_CNTL = REG_READ(CLK1_CLK1_BYPASS_CNTL);
609+
610+
// read dprefclk
611+
internal->CLK1_CLK2_CURRENT_CNT = REG_READ(CLK1_CLK2_CURRENT_CNT);
612+
internal->CLK1_CLK2_BYPASS_CNTL = REG_READ(CLK1_CLK2_BYPASS_CNTL);
613+
614+
// read dispclk
615+
internal->CLK1_CLK0_CURRENT_CNT = REG_READ(CLK1_CLK0_CURRENT_CNT);
616+
internal->CLK1_CLK0_BYPASS_CNTL = REG_READ(CLK1_CLK0_BYPASS_CNTL);
617+
}
618+
619+
static void dcn35_save_clk_registers(struct clk_state_registers_and_bypass *regs_and_bypass,
591620
struct clk_mgr_dcn35 *clk_mgr)
592621
{
622+
struct dcn35_clk_internal internal = {0};
623+
char *bypass_clks[5] = {"0x0 DFS", "0x1 REFCLK", "0x2 ERROR", "0x3 400 FCH", "0x4 600 FCH"};
624+
625+
dcn35_save_clk_registers_internal(&internal, &clk_mgr->base.base);
626+
627+
regs_and_bypass->dcfclk = internal.CLK1_CLK3_CURRENT_CNT / 10;
628+
regs_and_bypass->dcf_deep_sleep_divider = internal.CLK1_CLK3_DS_CNTL / 10;
629+
regs_and_bypass->dcf_deep_sleep_allow = internal.CLK1_CLK3_ALLOW_DS;
630+
regs_and_bypass->dprefclk = internal.CLK1_CLK2_CURRENT_CNT / 10;
631+
regs_and_bypass->dispclk = internal.CLK1_CLK0_CURRENT_CNT / 10;
632+
regs_and_bypass->dppclk = internal.CLK1_CLK1_CURRENT_CNT / 10;
633+
regs_and_bypass->dtbclk = internal.CLK1_CLK4_CURRENT_CNT / 10;
634+
635+
regs_and_bypass->dppclk_bypass = internal.CLK1_CLK1_BYPASS_CNTL & 0x0007;
636+
if (regs_and_bypass->dppclk_bypass < 0 || regs_and_bypass->dppclk_bypass > 4)
637+
regs_and_bypass->dppclk_bypass = 0;
638+
regs_and_bypass->dcfclk_bypass = internal.CLK1_CLK3_BYPASS_CNTL & 0x0007;
639+
if (regs_and_bypass->dcfclk_bypass < 0 || regs_and_bypass->dcfclk_bypass > 4)
640+
regs_and_bypass->dcfclk_bypass = 0;
641+
regs_and_bypass->dispclk_bypass = internal.CLK1_CLK0_BYPASS_CNTL & 0x0007;
642+
if (regs_and_bypass->dispclk_bypass < 0 || regs_and_bypass->dispclk_bypass > 4)
643+
regs_and_bypass->dispclk_bypass = 0;
644+
regs_and_bypass->dprefclk_bypass = internal.CLK1_CLK2_BYPASS_CNTL & 0x0007;
645+
if (regs_and_bypass->dprefclk_bypass < 0 || regs_and_bypass->dprefclk_bypass > 4)
646+
regs_and_bypass->dprefclk_bypass = 0;
647+
648+
if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
649+
DC_LOG_SMU("clk_type,clk_value,deepsleep_cntl,deepsleep_allow,bypass\n");
650+
651+
DC_LOG_SMU("dcfclk,%d,%d,%d,%s\n",
652+
regs_and_bypass->dcfclk,
653+
regs_and_bypass->dcf_deep_sleep_divider,
654+
regs_and_bypass->dcf_deep_sleep_allow,
655+
bypass_clks[(int) regs_and_bypass->dcfclk_bypass]);
656+
657+
DC_LOG_SMU("dprefclk,%d,N/A,N/A,%s\n",
658+
regs_and_bypass->dprefclk,
659+
bypass_clks[(int) regs_and_bypass->dprefclk_bypass]);
660+
661+
DC_LOG_SMU("dispclk,%d,N/A,N/A,%s\n",
662+
regs_and_bypass->dispclk,
663+
bypass_clks[(int) regs_and_bypass->dispclk_bypass]);
664+
665+
// REGISTER VALUES
666+
DC_LOG_SMU("reg_name,value,clk_type");
667+
668+
DC_LOG_SMU("CLK1_CLK3_CURRENT_CNT,%d,dcfclk",
669+
internal.CLK1_CLK3_CURRENT_CNT);
670+
671+
DC_LOG_SMU("CLK1_CLK4_CURRENT_CNT,%d,dtbclk",
672+
internal.CLK1_CLK4_CURRENT_CNT);
673+
674+
DC_LOG_SMU("CLK1_CLK3_DS_CNTL,%d,dcf_deep_sleep_divider",
675+
internal.CLK1_CLK3_DS_CNTL);
676+
677+
DC_LOG_SMU("CLK1_CLK3_ALLOW_DS,%d,dcf_deep_sleep_allow",
678+
internal.CLK1_CLK3_ALLOW_DS);
679+
680+
DC_LOG_SMU("CLK1_CLK2_CURRENT_CNT,%d,dprefclk",
681+
internal.CLK1_CLK2_CURRENT_CNT);
682+
683+
DC_LOG_SMU("CLK1_CLK0_CURRENT_CNT,%d,dispclk",
684+
internal.CLK1_CLK0_CURRENT_CNT);
685+
686+
DC_LOG_SMU("CLK1_CLK1_CURRENT_CNT,%d,dppclk",
687+
internal.CLK1_CLK1_CURRENT_CNT);
688+
689+
DC_LOG_SMU("CLK1_CLK3_BYPASS_CNTL,%d,dcfclk_bypass",
690+
internal.CLK1_CLK3_BYPASS_CNTL);
691+
692+
DC_LOG_SMU("CLK1_CLK2_BYPASS_CNTL,%d,dprefclk_bypass",
693+
internal.CLK1_CLK2_BYPASS_CNTL);
694+
695+
DC_LOG_SMU("CLK1_CLK0_BYPASS_CNTL,%d,dispclk_bypass",
696+
internal.CLK1_CLK0_BYPASS_CNTL);
697+
698+
DC_LOG_SMU("CLK1_CLK1_BYPASS_CNTL,%d,dppclk_bypass",
699+
internal.CLK1_CLK1_BYPASS_CNTL);
700+
701+
}
593702
}
594703

595704
static bool dcn35_is_spll_ssc_enabled(struct clk_mgr *clk_mgr_base)
@@ -623,6 +732,7 @@ static void init_clk_states(struct clk_mgr *clk_mgr)
623732
void dcn35_init_clocks(struct clk_mgr *clk_mgr)
624733
{
625734
struct clk_mgr_internal *clk_mgr_int = TO_CLK_MGR_INTERNAL(clk_mgr);
735+
struct clk_mgr_dcn35 *clk_mgr_dcn35 = TO_CLK_MGR_DCN35(clk_mgr_int);
626736

627737
init_clk_states(clk_mgr);
628738

@@ -633,6 +743,13 @@ void dcn35_init_clocks(struct clk_mgr *clk_mgr)
633743
else
634744
clk_mgr->dp_dto_source_clock_in_khz = clk_mgr->dprefclk_khz;
635745

746+
dcn35_save_clk_registers(&clk_mgr->boot_snapshot, clk_mgr_dcn35);
747+
748+
clk_mgr->clks.ref_dtbclk_khz = clk_mgr->boot_snapshot.dtbclk * 10;
749+
if (clk_mgr->boot_snapshot.dtbclk > 59000) {
750+
/*dtbclk enabled based on */
751+
clk_mgr->clks.dtbclk_en = true;
752+
}
636753
}
637754
static struct clk_bw_params dcn35_bw_params = {
638755
.vram_type = Ddr4MemType,
@@ -1323,7 +1440,7 @@ void dcn35_clk_mgr_construct(
13231440
dcn35_bw_params.wm_table = ddr5_wm_table;
13241441
}
13251442
/* Saved clocks configured at boot for debug purposes */
1326-
dcn35_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, clk_mgr);
1443+
dcn35_save_clk_registers(&clk_mgr->base.base.boot_snapshot, clk_mgr);
13271444

13281445
clk_mgr->base.base.dprefclk_khz = dcn35_smu_get_dprefclk(&clk_mgr->base);
13291446
clk_mgr->base.base.clks.ref_dtbclk_khz = 600000;

drivers/gpu/drm/amd/display/dc/dc.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1348,7 +1348,6 @@ union surface_update_flags {
13481348
uint32_t in_transfer_func_change:1;
13491349
uint32_t input_csc_change:1;
13501350
uint32_t coeff_reduction_change:1;
1351-
uint32_t output_tf_change:1;
13521351
uint32_t pixel_format_change:1;
13531352
uint32_t plane_size_change:1;
13541353
uint32_t gamut_remap_change:1;

drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,10 +1982,8 @@ static void dcn20_program_pipe(
19821982
* updating on slave planes
19831983
*/
19841984
if (pipe_ctx->update_flags.bits.enable ||
1985-
pipe_ctx->update_flags.bits.plane_changed ||
1986-
pipe_ctx->stream->update_flags.bits.out_tf ||
1987-
(pipe_ctx->plane_state &&
1988-
pipe_ctx->plane_state->update_flags.bits.output_tf_change))
1985+
pipe_ctx->update_flags.bits.plane_changed ||
1986+
pipe_ctx->stream->update_flags.bits.out_tf)
19891987
hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
19901988

19911989
/* If the pipe has been enabled or has a different opp, we

drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,10 +2019,8 @@ void dcn401_program_pipe(
20192019
* updating on slave planes
20202020
*/
20212021
if (pipe_ctx->update_flags.bits.enable ||
2022-
pipe_ctx->update_flags.bits.plane_changed ||
2023-
pipe_ctx->stream->update_flags.bits.out_tf ||
2024-
(pipe_ctx->plane_state &&
2025-
pipe_ctx->plane_state->update_flags.bits.output_tf_change))
2022+
pipe_ctx->update_flags.bits.plane_changed ||
2023+
pipe_ctx->stream->update_flags.bits.out_tf)
20262024
hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
20272025

20282026
/* If the pipe has been enabled or has a different opp, we

0 commit comments

Comments
 (0)