]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c
drm/amd/display: fixup DPP programming sequence
[linux.git] / drivers / gpu / drm / amd / display / dc / dcn20 / dcn20_dccg.c
index 31aa6ee5cd5b9c32880570caf5463deb2968dabf..16476ed255363d88cfdb37aa1405c03140125bf3 100644 (file)
 #define DC_LOGGER \
        dccg->ctx->logger
 
-void dccg2_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
+void dccg2_update_dpp_dto(struct dccg *dccg,
+               int dpp_inst,
+               int req_dppclk,
+               bool reduce_divider_only)
 {
        struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
 
        if (dccg->ref_dppclk && req_dppclk) {
                int ref_dppclk = dccg->ref_dppclk;
+               int current_phase, current_modulo;
 
                ASSERT(req_dppclk <= ref_dppclk);
                /* need to clamp to 8 bits */
@@ -61,9 +65,28 @@ void dccg2_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
                        if (req_dppclk > ref_dppclk)
                                req_dppclk = ref_dppclk;
                }
-               REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
-                               DPPCLK0_DTO_PHASE, req_dppclk,
-                               DPPCLK0_DTO_MODULO, ref_dppclk);
+
+               REG_GET_2(DPPCLK_DTO_PARAM[dpp_inst],
+                               DPPCLK0_DTO_PHASE, &current_phase,
+                               DPPCLK0_DTO_MODULO, &current_modulo);
+
+               if (reduce_divider_only) {
+                       // requested phase/modulo greater than current
+                       if (req_dppclk * current_modulo >= current_phase * ref_dppclk) {
+                               REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
+                                               DPPCLK0_DTO_PHASE, req_dppclk,
+                                               DPPCLK0_DTO_MODULO, ref_dppclk);
+                       } else {
+                               REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
+                                               DPPCLK0_DTO_PHASE, current_phase,
+                                               DPPCLK0_DTO_MODULO, current_modulo);
+                       }
+               } else {
+                       REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
+                                       DPPCLK0_DTO_PHASE, req_dppclk,
+                                       DPPCLK0_DTO_MODULO, ref_dppclk);
+               }
+
                REG_UPDATE(DPPCLK_DTO_CTRL,
                                DPPCLK_DTO_ENABLE[dpp_inst], 1);
        } else {