On Fri, Dec 21, 2018 at 07:14:32PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrj...@linux.intel.com>
> 
> On icl+ bspec tells us to calculate a separate minimum ddb
> allocation from the blocks watermark. Both have to be checked
> against the actual ddb allocation, but since we do things the
> other way around we'll just calculat the minimum acceptable
> ddb allocation by taking the maximum of the two values.
> 
> We'll also replace the memcmp() with a full trawl over the
> the watermarks so that it'll ignore the min_ddb_alloc
> because we can't directly read that out from the hw. I suppose
> we could reconstruct it from the other values, but I was
> too lazy to do that now.
> 
> Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>

Matches the bspec.

Reviewed-by: Matt Roper <matthew.d.ro...@intel.com>

> ---
>  drivers/gpu/drm/i915/i915_drv.h |  1 +
>  drivers/gpu/drm/i915/intel_pm.c | 53 +++++++++++++++++++++++++++------
>  2 files changed, 45 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 815db160b966..7668d7197994 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1108,6 +1108,7 @@ struct skl_ddb_values {
>  };
>  
>  struct skl_wm_level {
> +     uint16_t min_ddb_alloc;
>       uint16_t plane_res_b;
>       uint8_t plane_res_l;
>       bool plane_en;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 3c5cba31f055..7464552c05f4 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4371,8 +4371,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>                               continue;
>  
>                       wm = &cstate->wm.skl.optimal.planes[plane_id];
> -                     blocks += wm->wm[level].plane_res_b + 1;
> -                     blocks += wm->uv_wm[level].plane_res_b + 1;
> +                     blocks += wm->wm[level].min_ddb_alloc;
> +                     blocks += wm->uv_wm[level].min_ddb_alloc;
>               }
>  
>               if (blocks < alloc_size) {
> @@ -4413,7 +4413,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>               extra = min_t(u16, alloc_size,
>                             DIV64_U64_ROUND_UP(alloc_size * rate,
>                                                total_data_rate));
> -             total[plane_id] = wm->wm[level].plane_res_b + 1 + extra;
> +             total[plane_id] = wm->wm[level].min_ddb_alloc + extra;
>               alloc_size -= extra;
>               total_data_rate -= rate;
>  
> @@ -4424,7 +4424,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>               extra = min_t(u16, alloc_size,
>                             DIV64_U64_ROUND_UP(alloc_size * rate,
>                                                total_data_rate));
> -             uv_total[plane_id] = wm->uv_wm[level].plane_res_b + 1 + extra;
> +             uv_total[plane_id] = wm->uv_wm[level].min_ddb_alloc + extra;
>               alloc_size -= extra;
>               total_data_rate -= rate;
>       }
> @@ -4696,7 +4696,7 @@ static void skl_compute_plane_wm(const struct 
> intel_crtc_state *cstate,
>       uint32_t latency = dev_priv->wm.skl_latency[level];
>       uint_fixed_16_16_t method1, method2;
>       uint_fixed_16_16_t selected_result;
> -     uint32_t res_blocks, res_lines;
> +     uint32_t res_blocks, res_lines, min_ddb_alloc = 0;
>       struct intel_atomic_state *state =
>               to_intel_atomic_state(cstate->base.state);
>       bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state);
> @@ -4769,6 +4769,24 @@ static void skl_compute_plane_wm(const struct 
> intel_crtc_state *cstate,
>               }
>       }
>  
> +     if (INTEL_GEN(dev_priv) >= 11) {
> +             if (wp->y_tiled) {
> +                     int extra_lines;
> +
> +                     if (res_lines % wp->y_min_scanlines == 0)
> +                             extra_lines = wp->y_min_scanlines;
> +                     else
> +                             extra_lines = wp->y_min_scanlines * 2 -
> +                                     res_lines % wp->y_min_scanlines;
> +
> +                     min_ddb_alloc = mul_round_up_u32_fixed16(res_lines + 
> extra_lines,
> +                                                              
> wp->plane_blocks_per_line);
> +             } else {
> +                     min_ddb_alloc = res_blocks +
> +                             DIV_ROUND_UP(res_blocks, 10);
> +             }
> +     }
> +
>       if (!skl_wm_has_lines(dev_priv, level))
>               res_lines = 0;
>  
> @@ -4783,6 +4801,8 @@ static void skl_compute_plane_wm(const struct 
> intel_crtc_state *cstate,
>        */
>       result->plane_res_b = res_blocks;
>       result->plane_res_l = res_lines;
> +     /* Bspec says: value >= plane ddb allocation -> invalid, hence the +1 
> here */
> +     result->min_ddb_alloc = max(min_ddb_alloc, res_blocks) + 1;
>       result->plane_en = true;
>  }
>  
> @@ -5133,6 +5153,23 @@ static bool skl_plane_wm_equals(struct 
> drm_i915_private *dev_priv,
>       return skl_wm_level_equals(&wm1->trans_wm, &wm2->trans_wm);
>  }
>  
> +static bool skl_pipe_wm_equals(struct intel_crtc *crtc,
> +                            const struct skl_pipe_wm *wm1,
> +                            const struct skl_pipe_wm *wm2)
> +{
> +     struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +     enum plane_id plane_id;
> +
> +     for_each_plane_id_on_crtc(crtc, plane_id) {
> +             if (!skl_plane_wm_equals(dev_priv,
> +                                      &wm1->planes[plane_id],
> +                                      &wm2->planes[plane_id]))
> +                     return false;
> +     }
> +
> +     return wm1->linetime == wm2->linetime;
> +}
> +
>  static inline bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a,
>                                          const struct skl_ddb_entry *b)
>  {
> @@ -5159,16 +5196,14 @@ static int skl_update_pipe_wm(struct intel_crtc_state 
> *cstate,
>                             struct skl_pipe_wm *pipe_wm, /* out */
>                             bool *changed /* out */)
>  {
> +     struct intel_crtc *crtc = to_intel_crtc(cstate->base.crtc);
>       int ret;
>  
>       ret = skl_build_pipe_wm(cstate, pipe_wm);
>       if (ret)
>               return ret;
>  
> -     if (!memcmp(old_pipe_wm, pipe_wm, sizeof(*pipe_wm)))
> -             *changed = false;
> -     else
> -             *changed = true;
> +     *changed = !skl_pipe_wm_equals(crtc, old_pipe_wm, pipe_wm);
>  
>       return 0;
>  }
> -- 
> 2.19.2
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to