drm/amd/display: set dpp dto as per requested clk for lower case.
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / clk_mgr / dcn21 / rn_clk_mgr.c
index 2f8fee0..8d8ee4b 100644 (file)
@@ -103,6 +103,31 @@ void rn_set_low_power_state(struct clk_mgr *clk_mgr_base)
        clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER;
 }
 
+static void rn_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
+               struct dc_state *context, int ref_dpp_clk, bool safe_to_lower)
+{
+       int i;
+
+       clk_mgr->dccg->ref_dppclk = ref_dpp_clk;
+
+       for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
+               int dpp_inst, dppclk_khz, prev_dppclk_khz;
+
+               /* Loop index will match dpp->inst if resource exists,
+                * and we want to avoid dependency on dpp object
+                */
+               dpp_inst = i;
+               dppclk_khz = context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz;
+
+               prev_dppclk_khz = clk_mgr->dccg->pipe_dppclk_khz[i];
+
+               if (safe_to_lower || prev_dppclk_khz < dppclk_khz)
+                       clk_mgr->dccg->funcs->update_dpp_dto(
+                                                       clk_mgr->dccg, dpp_inst, dppclk_khz);
+       }
+}
+
+
 void rn_update_clocks(struct clk_mgr *clk_mgr_base,
                        struct dc_state *context,
                        bool safe_to_lower)
@@ -124,7 +149,7 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
         * if it is safe to lower, but we are already in the lower state, we don't have to do anything
         * also if safe to lower is false, we just go in the higher state
         */
-       if (safe_to_lower) {
+       if (safe_to_lower && !dc->debug.disable_48mhz_pwrdwn) {
                /* check that we're not already in lower */
                if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) {
 
@@ -158,10 +183,8 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
 
        // workaround: Limit dppclk to 100Mhz to avoid lower eDP panel switch to plus 4K monitor underflow.
        // Do not adjust dppclk if dppclk is 0 to avoid unexpected result
-       if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
-               if (new_clocks->dppclk_khz < 100000 && new_clocks->dppclk_khz > 0)
-                       new_clocks->dppclk_khz = 100000;
-       }
+       if (new_clocks->dppclk_khz < 100000 && new_clocks->dppclk_khz > 0)
+               new_clocks->dppclk_khz = 100000;
 
        if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) {
                if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz)
@@ -172,22 +195,42 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
 
        if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
                clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
-               rn_vbios_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
+               clk_mgr_base->clks.actual_dispclk_khz = rn_vbios_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
 
                update_dispclk = true;
        }
 
        if (dpp_clock_lowered) {
-               // increase per DPP DTO before lowering global dppclk
-               dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
-               rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
+               // increase per DPP DTO before lowering global dppclk with requested dppclk
+               rn_update_clocks_update_dpp_dto(
+                               clk_mgr,
+                               context,
+                               clk_mgr_base->clks.dppclk_khz,
+                               safe_to_lower);
+
+               clk_mgr_base->clks.actual_dppclk_khz =
+                               rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
+
+               //update dpp dto with actual dpp clk.
+               rn_update_clocks_update_dpp_dto(
+                               clk_mgr,
+                               context,
+                               clk_mgr_base->clks.actual_dppclk_khz,
+                               safe_to_lower);
+
        } else {
                // increase global DPPCLK before lowering per DPP DTO
                if (update_dppclk || update_dispclk)
-                       rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
+                       clk_mgr_base->clks.actual_dppclk_khz =
+                                       rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
+
                // always update dtos unless clock is lowered and not safe to lower
                if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz)
-                       dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
+                       rn_update_clocks_update_dpp_dto(
+                                       clk_mgr,
+                                       context,
+                                       clk_mgr_base->clks.actual_dppclk_khz,
+                                       safe_to_lower);
        }
 
        if (update_dispclk &&
@@ -198,7 +241,6 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
        }
 }
 
-
 static int get_vco_frequency_from_reg(struct clk_mgr_internal *clk_mgr)
 {
        /* get FbMult value */