]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amd/display: Migrate DCCG register access from hwseq to dccg component.
authorBhuvanachandra Pinninti <bpinnint@amd.com>
Wed, 17 Dec 2025 13:20:11 +0000 (18:50 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 3 Feb 2026 21:39:09 +0000 (16:39 -0500)
[why]
Direct DCCG register access in hwseq layer was creating register conflicts.

[how]
Migrated DCCG registers from hwseq to dccg component.

Reviewed-by: Martin Leung <martin.leung@amd.com>
Signed-off-by: Bhuvanachandra Pinninti <bpinnint@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
12 files changed:
drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.c
drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h

index 33d8bd91cb014102695a18bbefeb2aec8b9ea2e8..50b98822b6fdb0eb1170570d587682e463f95a68 100644 (file)
@@ -131,6 +131,54 @@ void dccg2_otg_drop_pixel(struct dccg *dccg,
 
 void dccg2_init(struct dccg *dccg)
 {
+       struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+       /* Hardcoded register values for DCN20
+        * These are specific to 100Mhz refclk
+        * Different ASICs with different refclk may override this in their own init
+        */
+       REG_WRITE(MICROSECOND_TIME_BASE_DIV, 0x00120264);
+       REG_WRITE(MILLISECOND_TIME_BASE_DIV, 0x001186a0);
+       REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0x0e01003c);
+
+       if (REG(REFCLK_CNTL))
+               REG_WRITE(REFCLK_CNTL, 0);
+}
+
+void dccg2_refclk_setup(struct dccg *dccg)
+{
+       struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+       /* REFCLK programming that must occur after hubbub initialization */
+       if (REG(REFCLK_CNTL))
+               REG_WRITE(REFCLK_CNTL, 0);
+}
+
+bool dccg2_is_s0i3_golden_init_wa_done(struct dccg *dccg)
+{
+       struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+       return REG_READ(MICROSECOND_TIME_BASE_DIV) == 0x00120464;
+}
+
+void dccg2_allow_clock_gating(struct dccg *dccg, bool allow)
+{
+       struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+       if (allow) {
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+       } else {
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0xFFFFFFFF);
+               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0xFFFFFFFF);
+       }
+}
+
+void dccg2_enable_memory_low_power(struct dccg *dccg, bool enable)
+{
+       struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+       REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, enable ? 0 : 1);
 }
 
 static const struct dccg_funcs dccg2_funcs = {
@@ -139,7 +187,11 @@ static const struct dccg_funcs dccg2_funcs = {
        .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
        .otg_add_pixel = dccg2_otg_add_pixel,
        .otg_drop_pixel = dccg2_otg_drop_pixel,
-       .dccg_init = dccg2_init
+       .dccg_init = dccg2_init,
+       .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */
+       .allow_clock_gating = dccg2_allow_clock_gating,
+       .enable_memory_low_power = dccg2_enable_memory_low_power,
+       .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done
 };
 
 struct dccg *dccg2_create(
index 8bdffd9ff31b1e669fa486acf1e6545c9a8120a1..237a684ded86024377c29077c135247c35f0c83b 100644 (file)
@@ -46,7 +46,9 @@
        DCCG_SRII(PIXEL_RATE_CNTL, OTG, 2),\
        DCCG_SRII(PIXEL_RATE_CNTL, OTG, 3),\
        DCCG_SRII(PIXEL_RATE_CNTL, OTG, 4),\
-       DCCG_SRII(PIXEL_RATE_CNTL, OTG, 5)
+       DCCG_SRII(PIXEL_RATE_CNTL, OTG, 5),\
+       SR(DCCG_GATE_DISABLE_CNTL),\
+       SR(DCCG_GATE_DISABLE_CNTL2)
 
 #define DCCG_SF(reg_name, field_name, post_fix)\
        .field_name = reg_name ## __ ## field_name ## post_fix
@@ -81,7 +83,8 @@
        DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 0, mask_sh),\
        DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 1, mask_sh),\
        DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 0, mask_sh),\
-       DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 1, mask_sh)
+       DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 1, mask_sh),\
+       DCCG_SF(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, mask_sh)
 
 
 
        type DISPCLK_CHG_FWD_CORR_DISABLE;\
        type DISPCLK_FREQ_CHANGE_CNTL;\
        type OTG_ADD_PIXEL[MAX_PIPES];\
-       type OTG_DROP_PIXEL[MAX_PIPES];
+       type OTG_DROP_PIXEL[MAX_PIPES];\
+       type DC_MEM_GLOBAL_PWR_REQ_DIS;
 
 #define DCCG3_REG_FIELD_LIST(type) \
        type HDMICHARCLK0_EN;\
@@ -515,6 +519,14 @@ void dccg2_otg_drop_pixel(struct dccg *dccg,
 
 void dccg2_init(struct dccg *dccg);
 
+void dccg2_refclk_setup(struct dccg *dccg);
+
+bool dccg2_is_s0i3_golden_init_wa_done(struct dccg *dccg);
+
+void dccg2_allow_clock_gating(struct dccg *dccg, bool allow);
+
+void dccg2_enable_memory_low_power(struct dccg *dccg, bool enable);
+
 struct dccg *dccg2_create(
        struct dc_context *ctx,
        const struct dccg_registers *regs,
index c1586364ecd45086d19819098036685b00f37ccf..f89b2f5a9bbd37635a53e70e168d56fe8ce4e798 100644 (file)
@@ -1885,9 +1885,8 @@ void dcn10_init_hw(struct dc *dc)
 
        if (!dc->debug.disable_clock_gate) {
                /* enable all DCN clock gating */
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+               if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating)
+                       dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true);
 
                REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
        }
index a76436dcbe401f2ab109ce0d92fda7476f32dfc4..87a1dc27def4a2d5a30a2f6a6226f94a2ade1c49 100644 (file)
@@ -357,26 +357,10 @@ void dcn20_enable_power_gating_plane(
 
 void dcn20_dccg_init(struct dce_hwseq *hws)
 {
-       /*
-        * set MICROSECOND_TIME_BASE_DIV
-        * 100Mhz refclk -> 0x120264
-        * 27Mhz refclk -> 0x12021b
-        * 48Mhz refclk -> 0x120230
-        *
-        */
-       REG_WRITE(MICROSECOND_TIME_BASE_DIV, 0x120264);
+       struct dc *dc = hws->ctx->dc;
 
-       /*
-        * set MILLISECOND_TIME_BASE_DIV
-        * 100Mhz refclk -> 0x1186a0
-        * 27Mhz refclk -> 0x106978
-        * 48Mhz refclk -> 0x10bb80
-        *
-        */
-       REG_WRITE(MILLISECOND_TIME_BASE_DIV, 0x1186a0);
-
-       /* This value is dependent on the hardware pipeline delay so set once per SOC */
-       REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0xe01003c);
+       if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->dccg_init)
+               dc->res_pool->dccg->funcs->dccg_init(dc->res_pool->dccg);
 }
 
 void dcn20_disable_vga(
@@ -3155,8 +3139,11 @@ void dcn20_fpga_init_hw(struct dc *dc)
        REG_WRITE(RBBMIF_TIMEOUT_DIS_2, 0xFFFFFFFF);
 
        dcn10_hubbub_global_timer_enable(dc->res_pool->hubbub, true, 2);
-       if (REG(REFCLK_CNTL))
-               REG_WRITE(REFCLK_CNTL, 0);
+
+       hws->funcs.dccg_init(hws);
+
+       if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->refclk_setup)
+               dc->res_pool->dccg->funcs->refclk_setup(dc->res_pool->dccg);
        //
 
 
index 482053c4ad22a0cc3b24af9ce1a72eff9b6c3df5..7cd225a6cf6cbcefef4f7b92f61f0a8ba458d9b7 100644 (file)
@@ -364,9 +364,8 @@ void dcn201_init_hw(struct dc *dc)
 
        if (!dc->debug.disable_clock_gate) {
                /* enable all DCN clock gating */
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+               if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating)
+                       dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true);
 
                REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
        }
index e2269211553ce1f12eb9185da08ddca94bba37fb..062745389d9a404eb94c161ac474b169f2737020 100644 (file)
@@ -33,6 +33,7 @@
 #include "vmid.h"
 #include "reg_helper.h"
 #include "hw/clk_mgr.h"
+#include "hw/dccg.h"
 #include "dc_dmub_srv.h"
 #include "abm.h"
 #include "link_service.h"
@@ -87,12 +88,10 @@ int dcn21_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_
 
 bool dcn21_s0i3_golden_init_wa(struct dc *dc)
 {
-       struct dce_hwseq *hws = dc->hwseq;
-       uint32_t value = 0;
+       if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->is_s0i3_golden_init_wa_done)
+               return !dc->res_pool->dccg->funcs->is_s0i3_golden_init_wa_done(dc->res_pool->dccg);
 
-       value = REG_READ(MICROSECOND_TIME_BASE_DIV);
-
-       return value != 0x00120464;
+       return false;
 }
 
 void dcn21_exit_optimized_pwr_state(
index c02ddada723fc0f8fe200f173321886632eb6a80..3ff15ec9dc17f96c7e3341e4f70dfdbcdb99a639 100644 (file)
@@ -798,9 +798,8 @@ void dcn30_init_hw(struct dc *dc)
 
        if (!dc->debug.disable_clock_gate) {
                /* enable all DCN clock gating */
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+               if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating)
+                       dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true);
 
                REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
        }
index 2adbcc105aa64284dbb15347e0d976a054073530..91a672a46289ff33af659b11768ead13c7b7c7f5 100644 (file)
@@ -249,9 +249,8 @@ void dcn31_init_hw(struct dc *dc)
 
        if (!dc->debug.disable_clock_gate) {
                /* enable all DCN clock gating */
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+               if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating)
+                       dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true);
 
                REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
        }
index 3cd44c6602b32ab0e1b116c3e7cf9787370a15bc..3f76fba7dcccc3489b494ab58fa0bd9d01a35099 100644 (file)
@@ -959,9 +959,8 @@ void dcn32_init_hw(struct dc *dc)
 
        if (!dc->debug.disable_clock_gate) {
                /* enable all DCN clock gating */
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+               if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating)
+                       dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true);
 
                REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
        }
index f7e16fee75943470109dfc9695af268a82451745..1c7263f9ef51d1a914fd5b83dbe75dab1b908a01 100644 (file)
@@ -288,7 +288,8 @@ void dcn35_init_hw(struct dc *dc)
        }
 
        if (dc->debug.disable_mem_low_power) {
-               REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, 1);
+               if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->enable_memory_low_power)
+                       dc->res_pool->dccg->funcs->enable_memory_low_power(dc->res_pool->dccg, false);
        }
        if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
                dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
index 86400938abd2ea0a64da616694b5a79a4cc3fa7e..567ed207d7cd41c34feb2b0beacebd36eed0418f 100644 (file)
@@ -324,9 +324,8 @@ void dcn401_init_hw(struct dc *dc)
 
        if (!dc->debug.disable_clock_gate) {
                /* enable all DCN clock gating */
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
-               REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+               if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating)
+                       dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true);
 
                REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
        }
index 1e6ffd86a4c0a67abe9e7b0ad262c3bae4064009..a26d31ab7cba2a3adbde1d24cd2518fc75147a6a 100644 (file)
@@ -224,6 +224,9 @@ struct dccg_funcs {
        void (*otg_drop_pixel)(struct dccg *dccg,
                        uint32_t otg_inst);
        void (*dccg_init)(struct dccg *dccg);
+       void (*refclk_setup)(struct dccg *dccg); /* Deprecated - for backward compatibility only */
+       void (*allow_clock_gating)(struct dccg *dccg, bool allow);
+       void (*enable_memory_low_power)(struct dccg *dccg, bool enable);
        void (*set_dpstreamclk_root_clock_gating)(
                        struct dccg *dccg,
                        int dp_hpo_inst,
@@ -334,6 +337,7 @@ struct dccg_funcs {
        void (*dccg_root_gate_disable_control)(struct dccg *dccg, uint32_t pipe_idx, uint32_t disable_clock_gating);
        void (*dccg_read_reg_state)(struct dccg *dccg, struct dcn_dccg_reg_state *dccg_reg_state);
        void (*dccg_enable_global_fgcg)(struct dccg *dccg, bool enable);
+       bool (*is_s0i3_golden_init_wa_done)(struct dccg *dccg);
 };
 
 #endif //__DAL_DCCG_H__