drm/amd/display: Correct kdoc formats in dcn32_resource_helpers.c
[linux-block.git] / drivers / gpu / drm / amd / display / dc / dcn32 / dcn32_resource_helpers.c
index eeca16faf31af29b9749dca9b0866c6b671db5f7..a9c41ef0751fbf3f89f8fb49e3ffc59b8f58872c 100644 (file)
@@ -94,18 +94,15 @@ uint32_t dcn32_helper_calculate_mall_bytes_for_cursor(
 }
 
 /**
- * ********************************************************************************************
- * dcn32_helper_calculate_num_ways_for_subvp: Calculate number of ways needed for SubVP
+ * dcn32_helper_calculate_num_ways_for_subvp(): Calculate number of ways needed for SubVP
  *
  * Gets total allocation required for the phantom viewport calculated by DML in bytes and
  * converts to number of cache ways.
  *
- * @param [in] dc: current dc state
- * @param [in] context: new dc state
+ * @dc: current dc state
+ * @context: new dc state
  *
- * @return: number of ways required for SubVP
- *
- * ********************************************************************************************
+ * Return: number of ways required for SubVP
  */
 uint32_t dcn32_helper_calculate_num_ways_for_subvp(
                struct dc *dc,
@@ -258,11 +255,8 @@ bool dcn32_is_psr_capable(struct pipe_ctx *pipe)
        return psr_capable;
 }
 
-#define DCN3_2_NEW_DET_OVERRIDE_MIN_MULTIPLIER 7
-
 /**
- * *******************************************************************************************
- * dcn32_determine_det_override: Determine DET allocation for each pipe
+ * dcn32_determine_det_override(): Determine DET allocation for each pipe
  *
  * This function determines how much DET to allocate for each pipe. The total number of
  * DET segments will be split equally among each of the streams, and after that the DET
@@ -271,6 +265,7 @@ bool dcn32_is_psr_capable(struct pipe_ctx *pipe)
  * If there is a plane that's driven by more than 1 pipe (i.e. pipe split), then the
  * number of DET for that given plane will be split among the pipes driving that plane.
  *
+ *
  * High level algorithm:
  * 1. Split total DET among number of streams
  * 2. For each stream, split DET among the planes
@@ -278,25 +273,11 @@ bool dcn32_is_psr_capable(struct pipe_ctx *pipe)
  *    among those pipes.
  * 4. Assign the DET override to the DML pipes.
  *
- * Special cases:
- *
- * For two displays that have a large difference in pixel rate, we may experience
- *  underflow on the larger display when we divide the DET equally. For this, we
- *  will implement a modified algorithm to assign more DET to larger display.
- *
- * 1. Calculate difference in pixel rates ( multiplier ) between two displays
- * 2. If the multiplier exceeds DCN3_2_NEW_DET_OVERRIDE_MIN_MULTIPLIER, then
- *    implement the modified DET override algorithm.
- * 3. Assign smaller DET size for lower pixel display and higher DET size for
- *    higher pixel display
+ * @dc: Current DC state
+ * @context: New DC state to be programmed
+ * @pipes: Array of DML pipes
  *
- * @param [in]: dc: Current DC state
- * @param [in]: context: New DC state to be programmed
- * @param [in]: pipes: Array of DML pipes
- *
- * @return: void
- *
- * *******************************************************************************************
+ * Return: void
  */
 void dcn32_determine_det_override(struct dc *dc,
                struct dc_state *context,
@@ -309,31 +290,10 @@ void dcn32_determine_det_override(struct dc *dc,
        struct dc_plane_state *current_plane = NULL;
        uint8_t stream_count = 0;
 
-       int phy_pix_clk_mult, lower_mode_stream_index;
-       int phy_pix_clk[MAX_PIPES] = {0};
-       bool use_new_det_override_algorithm = false;
-
        for (i = 0; i < context->stream_count; i++) {
                /* Don't count SubVP streams for DET allocation */
-               if (context->streams[i]->mall_stream_config.type != SUBVP_PHANTOM) {
-                       phy_pix_clk[i] = context->streams[i]->phy_pix_clk;
+               if (context->streams[i]->mall_stream_config.type != SUBVP_PHANTOM)
                        stream_count++;
-               }
-       }
-
-       /* Check for special case with two displays, one with much higher pixel rate */
-       if (stream_count == 2) {
-               ASSERT((phy_pix_clk[0] > 0) && (phy_pix_clk[1] > 0));
-               if (phy_pix_clk[0] < phy_pix_clk[1]) {
-                       lower_mode_stream_index = 0;
-                       phy_pix_clk_mult = phy_pix_clk[1] / phy_pix_clk[0];
-               } else {
-                       lower_mode_stream_index = 1;
-                       phy_pix_clk_mult = phy_pix_clk[0] / phy_pix_clk[1];
-               }
-
-               if (phy_pix_clk_mult >= DCN3_2_NEW_DET_OVERRIDE_MIN_MULTIPLIER)
-                       use_new_det_override_algorithm = true;
        }
 
        if (stream_count > 0) {
@@ -342,13 +302,6 @@ void dcn32_determine_det_override(struct dc *dc,
                        if (context->streams[i]->mall_stream_config.type == SUBVP_PHANTOM)
                                continue;
 
-                       if (use_new_det_override_algorithm) {
-                               if (i == lower_mode_stream_index)
-                                       stream_segments = 4;
-                               else
-                                       stream_segments = 14;
-                       }
-
                        if (context->stream_status[i].plane_count > 0)
                                plane_segments = stream_segments / context->stream_status[i].plane_count;
                        else
@@ -432,8 +385,7 @@ void dcn32_set_det_allocations(struct dc *dc, struct dc_state *context,
 }
 
 /**
- * *******************************************************************************************
- * dcn32_save_mall_state: Save MALL (SubVP) state for fast validation cases
+ * dcn32_save_mall_state(): Save MALL (SubVP) state for fast validation cases
  *
  * This function saves the MALL (SubVP) case for fast validation cases. For fast validation,
  * there are situations where a shallow copy of the dc->current_state is created for the
@@ -446,13 +398,11 @@ void dcn32_set_det_allocations(struct dc *dc, struct dc_state *context,
  * NOTE: This function ONLY works if the streams are not moved to a different pipe in the
  *       validation. We don't expect this to happen in fast_validation=1 cases.
  *
- * @param [in]: dc: Current DC state
- * @param [in]: context: New DC state to be programmed
- * @param [out]: temp_config: struct used to cache the existing MALL state
- *
- * @return: void
+ * @dc: Current DC state
+ * @context: New DC state to be programmed
+ * @temp_config: struct used to cache the existing MALL state
  *
- * *******************************************************************************************
+ * Return: void
  */
 void dcn32_save_mall_state(struct dc *dc,
                struct dc_state *context,
@@ -472,18 +422,15 @@ void dcn32_save_mall_state(struct dc *dc,
 }
 
 /**
- * *******************************************************************************************
- * dcn32_restore_mall_state: Restore MALL (SubVP) state for fast validation cases
+ * dcn32_restore_mall_state(): Restore MALL (SubVP) state for fast validation cases
  *
  * Restore the MALL state based on the previously saved state from dcn32_save_mall_state
  *
- * @param [in]: dc: Current DC state
- * @param [in/out]: context: New DC state to be programmed, restore MALL state into here
- * @param [in]: temp_config: struct that has the cached MALL state
+ * @dc: Current DC state
+ * @context: New DC state to be programmed, restore MALL state into here
+ * @temp_config: struct that has the cached MALL state
  *
- * @return: void
- *
- * *******************************************************************************************
+ * Return: void
  */
 void dcn32_restore_mall_state(struct dc *dc,
                struct dc_state *context,
@@ -588,10 +535,11 @@ static int get_refresh_rate(struct dc_stream_state *fpo_candidate_stream)
 }
 
 /**
- * dcn32_can_support_mclk_switch_using_fw_based_vblank_stretch - Determines if config can support FPO
+ * dcn32_can_support_mclk_switch_using_fw_based_vblank_stretch() - Determines if config can
+ *                                                                 support FPO
  *
- * @param [in]: dc - current dc state
- * @param [in]: context - new dc state
+ * @dc: current dc state
+ * @context: new dc state
  *
  * Return: Pointer to FPO stream candidate if config can support FPO, otherwise NULL
  */
@@ -626,7 +574,7 @@ struct dc_stream_state *dcn32_can_support_mclk_switch_using_fw_based_vblank_stre
                DC_FP_END();
 
                DC_FP_START();
-               is_fpo_vactive = dcn32_find_vactive_pipe(dc, context, DCN3_2_MIN_ACTIVE_SWITCH_MARGIN_FPO_US);
+               is_fpo_vactive = dcn32_find_vactive_pipe(dc, context, dc->debug.fpo_vactive_min_active_margin_us);
                DC_FP_END();
                if (!is_fpo_vactive || dc->debug.disable_fpo_vactive)
                        return NULL;
@@ -656,3 +604,120 @@ struct dc_stream_state *dcn32_can_support_mclk_switch_using_fw_based_vblank_stre
 
        return fpo_candidate_stream;
 }
+
+bool dcn32_check_native_scaling_for_res(struct pipe_ctx *pipe, unsigned int width, unsigned int height)
+{
+       bool is_native_scaling = false;
+
+       if (pipe->stream->timing.h_addressable == width &&
+                       pipe->stream->timing.v_addressable == height &&
+                       pipe->plane_state->src_rect.width == width &&
+                       pipe->plane_state->src_rect.height == height &&
+                       pipe->plane_state->dst_rect.width == width &&
+                       pipe->plane_state->dst_rect.height == height)
+               is_native_scaling = true;
+
+       return is_native_scaling;
+}
+
+/**
+ * dcn32_subvp_drr_admissable() - Determine if SubVP + DRR config is admissible
+ *
+ * @dc: Current DC state
+ * @context: New DC state to be programmed
+ *
+ * SubVP + DRR is admissible under the following conditions:
+ * - Config must have 2 displays (i.e., 2 non-phantom master pipes)
+ * - One display is SubVP
+ * - Other display must have Freesync enabled
+ * - The potential DRR display must not be PSR capable
+ *
+ * Return: True if admissible, false otherwise
+ */
+bool dcn32_subvp_drr_admissable(struct dc *dc, struct dc_state *context)
+{
+       bool result = false;
+       uint32_t i;
+       uint8_t subvp_count = 0;
+       uint8_t non_subvp_pipes = 0;
+       bool drr_pipe_found = false;
+       bool drr_psr_capable = false;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (!pipe->stream)
+                       continue;
+
+               if (pipe->plane_state && !pipe->top_pipe) {
+                       if (pipe->stream->mall_stream_config.type == SUBVP_MAIN)
+                               subvp_count++;
+                       if (pipe->stream->mall_stream_config.type == SUBVP_NONE) {
+                               non_subvp_pipes++;
+                               drr_psr_capable = (drr_psr_capable || dcn32_is_psr_capable(pipe));
+                               if (pipe->stream->ignore_msa_timing_param &&
+                                               (pipe->stream->allow_freesync || pipe->stream->vrr_active_variable)) {
+                                       drr_pipe_found = true;
+                               }
+                       }
+               }
+       }
+
+       if (subvp_count == 1 && non_subvp_pipes == 1 && drr_pipe_found && !drr_psr_capable)
+               result = true;
+
+       return result;
+}
+
+/**
+ * dcn32_subvp_vblank_admissable() - Determine if SubVP + Vblank config is admissible
+ *
+ * @dc: Current DC state
+ * @context: New DC state to be programmed
+ * @vlevel: Voltage level calculated by DML
+ *
+ * SubVP + Vblank is admissible under the following conditions:
+ * - Config must have 2 displays (i.e., 2 non-phantom master pipes)
+ * - One display is SubVP
+ * - Other display must not have Freesync capability
+ * - DML must have output DRAM clock change support as SubVP + Vblank
+ * - The potential vblank display must not be PSR capable
+ *
+ * Return: True if admissible, false otherwise
+ */
+bool dcn32_subvp_vblank_admissable(struct dc *dc, struct dc_state *context, int vlevel)
+{
+       bool result = false;
+       uint32_t i;
+       uint8_t subvp_count = 0;
+       uint8_t non_subvp_pipes = 0;
+       bool drr_pipe_found = false;
+       struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
+       bool vblank_psr_capable = false;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (!pipe->stream)
+                       continue;
+
+               if (pipe->plane_state && !pipe->top_pipe) {
+                       if (pipe->stream->mall_stream_config.type == SUBVP_MAIN)
+                               subvp_count++;
+                       if (pipe->stream->mall_stream_config.type == SUBVP_NONE) {
+                               non_subvp_pipes++;
+                               vblank_psr_capable = (vblank_psr_capable || dcn32_is_psr_capable(pipe));
+                               if (pipe->stream->ignore_msa_timing_param &&
+                                               (pipe->stream->allow_freesync || pipe->stream->vrr_active_variable)) {
+                                       drr_pipe_found = true;
+                               }
+                       }
+               }
+       }
+
+       if (subvp_count == 1 && non_subvp_pipes == 1 && !drr_pipe_found && !vblank_psr_capable &&
+                       vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_vblank_w_mall_sub_vp)
+               result = true;
+
+       return result;
+}