LGTM, Reviewed-by: Radhakrishna Sripada <radhakrishna.sripada@xxxxxxxxx> > -----Original Message----- > From: Intel-xe <intel-xe-bounces@xxxxxxxxxxxxxxxxxxxxx> On Behalf Of > Balasubramani Vivekanandan > Sent: Monday, April 15, 2024 1:14 AM > To: intel-xe@xxxxxxxxxxxxxxxxxxxxx; intel-gfx@xxxxxxxxxxxxxxxxxxxxx > Cc: De Marchi, Lucas <lucas.demarchi@xxxxxxxxx>; Roper, Matthew D > <matthew.d.roper@xxxxxxxxx>; Jani Nikula <jani.nikula@xxxxxxxxxxxxxxx>; > Vivekanandan, Balasubramani <balasubramani.vivekanandan@xxxxxxxxx> > Subject: [PATCH v3 13/21] drm/i915/xe2hpd: Add max memory bandwidth > algorithm > > From: Matt Roper <matthew.d.roper@xxxxxxxxx> > > Unlike DG2, Xe2_HPD does support multiple GV points with different > maximum memory bandwidths, but uses a much simpler algorithm than igpu > platforms use. > > Bspec: 64631 > CC: Jani Nikula <jani.nikula@xxxxxxxxxxxxxxx> > Signed-off-by: Matt Roper <matthew.d.roper@xxxxxxxxx> > Signed-off-by: Balasubramani Vivekanandan > <balasubramani.vivekanandan@xxxxxxxxx> > --- > drivers/gpu/drm/i915/display/intel_bw.c | 65 ++++++++++++++++++++++++- > drivers/gpu/drm/i915/i915_drv.h | 1 + > drivers/gpu/drm/i915/soc/intel_dram.c | 4 ++ > drivers/gpu/drm/xe/xe_device_types.h | 1 + > 4 files changed, 69 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_bw.c > b/drivers/gpu/drm/i915/display/intel_bw.c > index 7f2a50b4f494..dc9ac4831065 100644 > --- a/drivers/gpu/drm/i915/display/intel_bw.c > +++ b/drivers/gpu/drm/i915/display/intel_bw.c > @@ -22,6 +22,8 @@ struct intel_qgv_point { > u16 dclk, t_rp, t_rdpre, t_rc, t_ras, t_rcd; > }; > > +#define DEPROGBWPCLIMIT 60 > + > struct intel_psf_gv_point { > u8 clk; /* clock in multiples of 16.6666 MHz */ > }; > @@ -239,6 +241,9 @@ static int icl_get_qgv_points(struct drm_i915_private > *dev_priv, > qi->channel_width = 16; > qi->deinterleave = 4; > break; > + case INTEL_DRAM_GDDR: > + qi->channel_width = 32; > + break; > default: > MISSING_CASE(dram_info->type); > return -EINVAL; > @@ -383,6 +388,12 @@ static const struct intel_sa_info mtl_sa_info = { > .derating = 10, > }; > > +static const struct intel_sa_info xe2_hpd_sa_info = { > + .derating = 30, > + .deprogbwlimit = 53, > + /* Other values not used by simplified algorithm */ > +}; > + > static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct > intel_sa_info *sa) > { > struct intel_qgv_info qi = {}; > @@ -489,7 +500,7 @@ static int tgl_get_bw_info(struct drm_i915_private > *dev_priv, const struct intel > dclk_max = icl_sagv_max_dclk(&qi); > > peakbw = num_channels * DIV_ROUND_UP(qi.channel_width, 8) * > dclk_max; > - maxdebw = min(sa->deprogbwlimit * 1000, peakbw * 6 / 10); /* 60% */ > + maxdebw = min(sa->deprogbwlimit * 1000, peakbw * > DEPROGBWPCLIMIT / 100); > > ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels); > /* > @@ -594,6 +605,54 @@ static void dg2_get_bw_info(struct drm_i915_private > *i915) > i915->display.sagv.status = I915_SAGV_NOT_CONTROLLED; > } > > +static int xe2_hpd_get_bw_info(struct drm_i915_private *i915, > + const struct intel_sa_info *sa) > +{ > + struct intel_qgv_info qi = {}; > + int num_channels = i915->dram_info.num_channels; > + int peakbw, maxdebw; > + int ret, i; > + > + ret = icl_get_qgv_points(i915, &qi, true); > + if (ret) { > + drm_dbg_kms(&i915->drm, > + "Failed to get memory subsystem information, ignoring > bandwidth limits"); > + return ret; > + } > + > + peakbw = num_channels * qi.channel_width / 8 * > icl_sagv_max_dclk(&qi); > + maxdebw = min(sa->deprogbwlimit * 1000, peakbw * > DEPROGBWPCLIMIT / 10); > + > + for (i = 0; i < qi.num_points; i++) { > + const struct intel_qgv_point *point = &qi.points[i]; > + int bw = num_channels * (qi.channel_width / 8) * point->dclk; > + > + i915->display.bw.max[0].deratedbw[i] = > + min(maxdebw, (100 - sa->derating) * bw / 100); > + i915->display.bw.max[0].peakbw[i] = bw; > + > + drm_dbg_kms(&i915->drm, "QGV %d: deratedbw=%u peakbw: > %u\n", > + i, i915->display.bw.max[0].deratedbw[i], > + i915->display.bw.max[0].peakbw[i]); > + } > + > + /* Bandwidth does not depend on # of planes; set all groups the same */ > + i915->display.bw.max[0].num_planes = 1; > + i915->display.bw.max[0].num_qgv_points = qi.num_points; > + for (i = 1; i < ARRAY_SIZE(i915->display.bw.max); i++) > + memcpy(&i915->display.bw.max[i], &i915->display.bw.max[0], > + sizeof(i915->display.bw.max[0])); > + > + /* > + * Xe2_HPD should always have exactly two QGV points representing > + * battery and plugged-in operation. > + */ > + drm_WARN_ON(&i915->drm, qi.num_points != 2); > + i915->display.sagv.status = I915_SAGV_ENABLED; > + > + return 0; > +} > + > static unsigned int icl_max_bw_index(struct drm_i915_private *dev_priv, > int num_planes, int qgv_point) > { > @@ -664,7 +723,9 @@ void intel_bw_init_hw(struct drm_i915_private > *dev_priv) > if (!HAS_DISPLAY(dev_priv)) > return; > > - if (DISPLAY_VER(dev_priv) >= 14) > + if (DISPLAY_VER_FULL(dev_priv) >= IP_VER(14, 1) && IS_DGFX(dev_priv)) > + xe2_hpd_get_bw_info(dev_priv, &xe2_hpd_sa_info); > + else if (DISPLAY_VER(dev_priv) >= 14) > tgl_get_bw_info(dev_priv, &mtl_sa_info); > else if (IS_DG2(dev_priv)) > dg2_get_bw_info(dev_priv); > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index 481ddce038b2..d1d21d433766 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -305,6 +305,7 @@ struct drm_i915_private { > INTEL_DRAM_LPDDR4, > INTEL_DRAM_DDR5, > INTEL_DRAM_LPDDR5, > + INTEL_DRAM_GDDR, > } type; > u8 num_qgv_points; > u8 num_psf_gv_points; > diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c > b/drivers/gpu/drm/i915/soc/intel_dram.c > index 15492b69f698..99b541babb31 100644 > --- a/drivers/gpu/drm/i915/soc/intel_dram.c > +++ b/drivers/gpu/drm/i915/soc/intel_dram.c > @@ -640,6 +640,10 @@ static int xelpdp_get_dram_info(struct > drm_i915_private *i915) > case 5: > dram_info->type = INTEL_DRAM_LPDDR3; > break; > + case 8: > + drm_WARN_ON(&i915->drm, !IS_DGFX(i915)); > + dram_info->type = INTEL_DRAM_GDDR; > + break; > default: > MISSING_CASE(val); > return -EINVAL; > diff --git a/drivers/gpu/drm/xe/xe_device_types.h > b/drivers/gpu/drm/xe/xe_device_types.h > index 60ced5f90c2b..d1aef541d1c7 100644 > --- a/drivers/gpu/drm/xe/xe_device_types.h > +++ b/drivers/gpu/drm/xe/xe_device_types.h > @@ -487,6 +487,7 @@ struct xe_device { > INTEL_DRAM_LPDDR4, > INTEL_DRAM_DDR5, > INTEL_DRAM_LPDDR5, > + INTEL_DRAM_GDDR, > } type; > u8 num_qgv_points; > u8 num_psf_gv_points; > -- > 2.25.1