[PATCH 3/3] drm/amd/display: Fix DCE 6.0 and 6.4 PLL programming.
Rodrigo Siqueira
siqueira at igalia.com
Thu Jul 24 22:55:16 UTC 2025
On 07/22, Timur Kristóf wrote:
> Apparently, both DCE 6.0 and 6.4 have 3 PLLs, but PLL0 can only
> be used for DP. Make sure to initialize the correct amount of PLLs
> in DC for these DCE versions and use PLL0 only for DP.
>
> Also, on DCE 6.0 and 6.4, the PLL0 needs to be powered on at
> initialization as opposed to DCE 6.1 and 7.x which use a different
> clock source for DFS.
>
> The following functions were used as reference from the old
> radeon driver implementation of DCE 6.x:
> - radeon_atom_pick_pll
> - atombios_crtc_set_disp_eng_pll
>
> Signed-off-by: Timur Kristóf <timur.kristof at gmail.com>
> ---
> .../display/dc/clk_mgr/dce100/dce_clk_mgr.c | 5 +++
> .../dc/resource/dce60/dce60_resource.c | 34 +++++++++++--------
> 2 files changed, 25 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c
> index 26feefbb8990..f5ad0a177038 100644
> --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c
> +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c
> @@ -245,6 +245,11 @@ int dce_set_clock(
> pxl_clk_params.target_pixel_clock_100hz = requested_clk_khz * 10;
> pxl_clk_params.pll_id = CLOCK_SOURCE_ID_DFS;
>
> + /* DCE 6.0, DCE 6.4: engine clock is the same as PLL0 */
> + if (clk_mgr_base->ctx->dce_version == DCE_VERSION_6_0 ||
> + clk_mgr_base->ctx->dce_version == DCE_VERSION_6_4)
> + pxl_clk_params.pll_id = CLOCK_SOURCE_ID_PLL0;
> +
> if (clk_mgr_dce->dfs_bypass_active)
> pxl_clk_params.flags.SET_DISPCLK_DFS_BYPASS = true;
>
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
> index 58b59d52dc9d..53b60044653f 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
> @@ -373,7 +373,7 @@ static const struct resource_caps res_cap = {
> .num_timing_generator = 6,
> .num_audio = 6,
> .num_stream_encoder = 6,
> - .num_pll = 2,
> + .num_pll = 3,
> .num_ddc = 6,
> };
>
> @@ -389,7 +389,7 @@ static const struct resource_caps res_cap_64 = {
> .num_timing_generator = 2,
> .num_audio = 2,
> .num_stream_encoder = 2,
> - .num_pll = 2,
> + .num_pll = 3,
> .num_ddc = 2,
> };
>
> @@ -973,21 +973,24 @@ static bool dce60_construct(
>
> if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) {
> pool->base.dp_clock_source =
> - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
> + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
>
> + /* DCE 6.0 and 6.4: PLL0 can only be used with DP. Don't initialize it here. */
> pool->base.clock_sources[0] =
> - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false);
> + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
> pool->base.clock_sources[1] =
> - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
> + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
> pool->base.clk_src_count = 2;
>
> } else {
> pool->base.dp_clock_source =
> - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true);
> + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true);
>
> pool->base.clock_sources[0] =
> - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
> - pool->base.clk_src_count = 1;
> + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
> + pool->base.clock_sources[1] =
> + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
> + pool->base.clk_src_count = 2;
> }
>
> if (pool->base.dp_clock_source == NULL) {
> @@ -1365,21 +1368,24 @@ static bool dce64_construct(
>
> if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) {
> pool->base.dp_clock_source =
> - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
> + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
>
> + /* DCE 6.0 and 6.4: PLL0 can only be used with DP. Don't initialize it here. */
> pool->base.clock_sources[0] =
> - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[0], false);
> + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
> pool->base.clock_sources[1] =
> - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[1], false);
> + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
> pool->base.clk_src_count = 2;
>
> } else {
> pool->base.dp_clock_source =
> - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[0], true);
> + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true);
>
> pool->base.clock_sources[0] =
> - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[1], false);
> - pool->base.clk_src_count = 1;
> + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
> + pool->base.clock_sources[1] =
> + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
> + pool->base.clk_src_count = 2;
> }
>
> if (pool->base.dp_clock_source == NULL) {
> --
> 2.50.1
>
Reviewed-by: Rodrigo Siqueira <siqueira at igalia.com>
Again, I'm adding other displays folks for further review.
Thanks
--
Rodrigo Siqueira
More information about the amd-gfx
mailing list