[Intel-gfx] [PATCH v6 4/7] drm/i915: extract intel_bw_check_qgv_points()

Govindapillai, Vinod vinod.govindapillai at intel.com
Tue May 23 13:03:54 UTC 2023


On Tue, 2023-05-23 at 12:05 +0300, Jani Nikula wrote:
> On Tue, 23 May 2023, Vinod Govindapillai <vinod.govindapillai at intel.com> wrote:
> > Extract intel_bw_check_qgv_points() from intel_bw_atomic_check
> > to facilitate future platform variations in handling SAGV
> > configurations.
> > 
> > Signed-off-by: Vinod Govindapillai <vinod.govindapillai at intel.com>
> > Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy at intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_bw.c | 235 +++++++++++++-----------
> >  1 file changed, 130 insertions(+), 105 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
> > index db117638d23b..d83aafd0cc2b 100644
> > --- a/drivers/gpu/drm/i915/display/intel_bw.c
> > +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> > @@ -803,6 +803,128 @@ intel_atomic_get_bw_state(struct intel_atomic_state *state)
> >         return to_intel_bw_state(bw_state);
> >  }
> >  
> > +static int icl_find_qgv_points(struct drm_i915_private *i915,
> > +                              unsigned int data_rate,
> > +                              unsigned int num_active_planes,
> > +                              const struct intel_bw_state *old_bw_state,
> > +                              struct intel_bw_state *new_bw_state)
> > +{
> > +       unsigned int max_bw_point = 0;
> > +       unsigned int max_bw = 0;
> > +       unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points;
> > +       unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points;
> 
> Please just use signed ints whenever you don't have a specific reason
> not to. Ditto for parameters being passed. Mixing signed and unsigned
> will lead to trouble.

Okay. usually I try to follow that. Here all these unsigned ints are needed because of the return
types
> 
> > +       u16 psf_points = 0;
> > +       u16 qgv_points = 0;
> > +       int i;
> > +       int ret;
> > +
> > +       ret = intel_atomic_lock_global_state(&new_bw_state->base);
> > +       if (ret)
> > +               return ret;
> > +
> > +       for (i = 0; i < num_qgv_points; i++) {
> 
> This is signed and unsigned comparison.

I can update that.

Thanks
Vinod
> 
> > +               unsigned int max_data_rate;
> > +
> > +               if (DISPLAY_VER(i915) > 11)
> > +                       max_data_rate = tgl_max_bw(i915, num_active_planes, i);
> > +               else
> > +                       max_data_rate = icl_max_bw(i915, num_active_planes, i);
> > +               /*
> > +                * We need to know which qgv point gives us
> > +                * maximum bandwidth in order to disable SAGV
> > +                * if we find that we exceed SAGV block time
> > +                * with watermarks. By that moment we already
> > +                * have those, as it is calculated earlier in
> > +                * intel_atomic_check,
> > +                */
> > +               if (max_data_rate > max_bw) {
> > +                       max_bw_point = i;
> > +                       max_bw = max_data_rate;
> > +               }
> > +               if (max_data_rate >= data_rate)
> > +                       qgv_points |= BIT(i);
> > +
> > +               drm_dbg_kms(&i915->drm, "QGV point %d: max bw %d required %d\n",
> > +                           i, max_data_rate, data_rate);
> > +       }
> > +
> > +       for (i = 0; i < num_psf_gv_points; i++) {
> > +               unsigned int max_data_rate = adl_psf_bw(i915, i);
> > +
> > +               if (max_data_rate >= data_rate)
> > +                       psf_points |= BIT(i);
> > +
> > +               drm_dbg_kms(&i915->drm, "PSF GV point %d: max bw %d"
> > +                           " required %d\n",
> > +                           i, max_data_rate, data_rate);
> > +       }
> > +
> > +       /*
> > +        * BSpec states that we always should have at least one allowed point
> > +        * left, so if we couldn't - simply reject the configuration for obvious
> > +        * reasons.
> > +        */
> > +       if (qgv_points == 0) {
> > +               drm_dbg_kms(&i915->drm, "No QGV points provide sufficient memory"
> > +                           " bandwidth %d for display configuration(%d active planes).\n",
> > +                           data_rate, num_active_planes);
> > +               return -EINVAL;
> > +       }
> > +
> > +       if (num_psf_gv_points > 0 && psf_points == 0) {
> > +               drm_dbg_kms(&i915->drm, "No PSF GV points provide sufficient memory"
> > +                           " bandwidth %d for display configuration(%d active planes).\n",
> > +                           data_rate, num_active_planes);
> > +               return -EINVAL;
> > +       }
> > +
> > +       /*
> > +        * Leave only single point with highest bandwidth, if
> > +        * we can't enable SAGV due to the increased memory latency it may
> > +        * cause.
> > +        */
> > +       if (!intel_can_enable_sagv(i915, new_bw_state)) {
> > +               qgv_points = BIT(max_bw_point);
> > +               drm_dbg_kms(&i915->drm, "No SAGV, using single QGV point %d\n",
> > +                           max_bw_point);
> > +       }
> > +
> > +       /*
> > +        * We store the ones which need to be masked as that is what PCode
> > +        * actually accepts as a parameter.
> > +        */
> > +       new_bw_state->qgv_points_mask =
> > +               ~(ICL_PCODE_REQ_QGV_PT(qgv_points) |
> > +                 ADLS_PCODE_REQ_PSF_PT(psf_points)) &
> > +               icl_qgv_points_mask(i915);
> > +
> > +       /*
> > +        * If the actual mask had changed we need to make sure that
> > +        * the commits are serialized(in case this is a nomodeset, nonblocking)
> > +        */
> > +       if (new_bw_state->qgv_points_mask != old_bw_state->qgv_points_mask) {
> > +               ret = intel_atomic_serialize_global_state(&new_bw_state->base);
> > +               if (ret)
> > +                       return ret;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +static int intel_bw_check_qgv_points(struct drm_i915_private *i915,
> > +                                    const struct intel_bw_state *old_bw_state,
> > +                                    struct intel_bw_state *new_bw_state)
> > +{
> > +       unsigned int data_rate = intel_bw_data_rate(i915, new_bw_state);
> > +       unsigned int num_active_planes =
> > +                       intel_bw_num_active_planes(i915, new_bw_state);
> > +
> > +       data_rate = DIV_ROUND_UP(data_rate, 1000);
> > +
> > +       return icl_find_qgv_points(i915, data_rate, num_active_planes,
> > +                                  old_bw_state, new_bw_state);
> > +}
> > +
> >  static bool intel_bw_state_changed(struct drm_i915_private *i915,
> >                                    const struct intel_bw_state *old_bw_state,
> >                                    const struct intel_bw_state *new_bw_state)
> > @@ -1049,20 +1171,14 @@ static int intel_bw_check_data_rate(struct intel_atomic_state *state,
> > bool *chan
> >  
> >  int intel_bw_atomic_check(struct intel_atomic_state *state)
> >  {
> > -       struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> > -       const struct intel_bw_state *old_bw_state;
> > -       struct intel_bw_state *new_bw_state;
> > -       unsigned int data_rate;
> > -       unsigned int num_active_planes;
> > -       int i, ret;
> > -       u16 qgv_points = 0, psf_points = 0;
> > -       unsigned int max_bw_point = 0, max_bw = 0;
> > -       unsigned int num_qgv_points = dev_priv->display.bw.max[0].num_qgv_points;
> > -       unsigned int num_psf_gv_points = dev_priv->display.bw.max[0].num_psf_gv_points;
> >         bool changed = false;
> > +       struct drm_i915_private *i915 = to_i915(state->base.dev);
> > +       struct intel_bw_state *new_bw_state;
> > +       const struct intel_bw_state *old_bw_state;
> > +       int ret;
> >  
> >         /* FIXME earlier gens need some checks too */
> > -       if (DISPLAY_VER(dev_priv) < 11)
> > +       if (DISPLAY_VER(i915) < 11)
> >                 return 0;
> >  
> >         ret = intel_bw_check_data_rate(state, &changed);
> > @@ -1073,8 +1189,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
> >         new_bw_state = intel_atomic_get_new_bw_state(state);
> >  
> >         if (new_bw_state &&
> > -           intel_can_enable_sagv(dev_priv, old_bw_state) !=
> > -           intel_can_enable_sagv(dev_priv, new_bw_state))
> > +           intel_can_enable_sagv(i915, old_bw_state) !=
> > +           intel_can_enable_sagv(i915, new_bw_state))
> >                 changed = true;
> >  
> >         /*
> > @@ -1084,101 +1200,10 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
> >         if (!changed)
> >                 return 0;
> >  
> > -       ret = intel_atomic_lock_global_state(&new_bw_state->base);
> > +       ret = intel_bw_check_qgv_points(i915, old_bw_state, new_bw_state);
> >         if (ret)
> >                 return ret;
> >  
> > -       data_rate = intel_bw_data_rate(dev_priv, new_bw_state);
> > -       data_rate = DIV_ROUND_UP(data_rate, 1000);
> > -
> > -       num_active_planes = intel_bw_num_active_planes(dev_priv, new_bw_state);
> > -
> > -       for (i = 0; i < num_qgv_points; i++) {
> > -               unsigned int max_data_rate;
> > -
> > -               if (DISPLAY_VER(dev_priv) > 11)
> > -                       max_data_rate = tgl_max_bw(dev_priv, num_active_planes, i);
> > -               else
> > -                       max_data_rate = icl_max_bw(dev_priv, num_active_planes, i);
> > -               /*
> > -                * We need to know which qgv point gives us
> > -                * maximum bandwidth in order to disable SAGV
> > -                * if we find that we exceed SAGV block time
> > -                * with watermarks. By that moment we already
> > -                * have those, as it is calculated earlier in
> > -                * intel_atomic_check,
> > -                */
> > -               if (max_data_rate > max_bw) {
> > -                       max_bw_point = i;
> > -                       max_bw = max_data_rate;
> > -               }
> > -               if (max_data_rate >= data_rate)
> > -                       qgv_points |= BIT(i);
> > -
> > -               drm_dbg_kms(&dev_priv->drm, "QGV point %d: max bw %d required %d\n",
> > -                           i, max_data_rate, data_rate);
> > -       }
> > -
> > -       for (i = 0; i < num_psf_gv_points; i++) {
> > -               unsigned int max_data_rate = adl_psf_bw(dev_priv, i);
> > -
> > -               if (max_data_rate >= data_rate)
> > -                       psf_points |= BIT(i);
> > -
> > -               drm_dbg_kms(&dev_priv->drm, "PSF GV point %d: max bw %d"
> > -                           " required %d\n",
> > -                           i, max_data_rate, data_rate);
> > -       }
> > -
> > -       /*
> > -        * BSpec states that we always should have at least one allowed point
> > -        * left, so if we couldn't - simply reject the configuration for obvious
> > -        * reasons.
> > -        */
> > -       if (qgv_points == 0) {
> > -               drm_dbg_kms(&dev_priv->drm, "No QGV points provide sufficient memory"
> > -                           " bandwidth %d for display configuration(%d active planes).\n",
> > -                           data_rate, num_active_planes);
> > -               return -EINVAL;
> > -       }
> > -
> > -       if (num_psf_gv_points > 0 && psf_points == 0) {
> > -               drm_dbg_kms(&dev_priv->drm, "No PSF GV points provide sufficient memory"
> > -                           " bandwidth %d for display configuration(%d active planes).\n",
> > -                           data_rate, num_active_planes);
> > -               return -EINVAL;
> > -       }
> > -
> > -       /*
> > -        * Leave only single point with highest bandwidth, if
> > -        * we can't enable SAGV due to the increased memory latency it may
> > -        * cause.
> > -        */
> > -       if (!intel_can_enable_sagv(dev_priv, new_bw_state)) {
> > -               qgv_points = BIT(max_bw_point);
> > -               drm_dbg_kms(&dev_priv->drm, "No SAGV, using single QGV point %d\n",
> > -                           max_bw_point);
> > -       }
> > -
> > -       /*
> > -        * We store the ones which need to be masked as that is what PCode
> > -        * actually accepts as a parameter.
> > -        */
> > -       new_bw_state->qgv_points_mask =
> > -               ~(ICL_PCODE_REQ_QGV_PT(qgv_points) |
> > -                 ADLS_PCODE_REQ_PSF_PT(psf_points)) &
> > -               icl_qgv_points_mask(dev_priv);
> > -
> > -       /*
> > -        * If the actual mask had changed we need to make sure that
> > -        * the commits are serialized(in case this is a nomodeset, nonblocking)
> > -        */
> > -       if (new_bw_state->qgv_points_mask != old_bw_state->qgv_points_mask) {
> > -               ret = intel_atomic_serialize_global_state(&new_bw_state->base);
> > -               if (ret)
> > -                       return ret;
> > -       }
> > -
> >         return 0;
> >  }
> 



More information about the Intel-gfx mailing list