From: Ville Syrjälä Date: Fri, 22 May 2026 20:03:43 +0000 (+0300) Subject: drm/i915/bw: Fix/unify peakbw calculations X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b85fe7e7b0f347a1d39984c086d9ba3d1aa39fa;p=thirdparty%2Fkernel%2Flinux.git drm/i915/bw: Fix/unify peakbw calculations We have several copies of the same memory peak bandwidth calculations, and the rounding directions are all over the place in some of them. Unify it all into one small function (with rounding matching what Bspec says). Note that 'channel_width' is always a multiple of 8 anyway, so for 'channel_width / 8' the rounding direction doesn't actually matter. Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20260522200346.17377-8-ville.syrjala@linux.intel.com Reviewed-by: Vinod Govindapillai --- diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 6ebf33e6e343e..f1af6f2f7d4c2 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -578,6 +578,11 @@ static int icl_get_bw_info(struct intel_display *display, return 0; } +static int tgl_peakbw(int num_channels, int channel_width, int dclk) +{ + return num_channels * (channel_width / 8) * dclk; +} + static int tgl_get_bw_info(struct intel_display *display, const struct dram_info *dram_info, const struct intel_soc_bw_params *soc_bw_params, @@ -587,7 +592,6 @@ static int tgl_get_bw_info(struct intel_display *display, bool is_y_tile = true; /* assume y tile may be used */ int num_channels = max_t(u8, 1, dram_info->num_channels); int ipqdepth, ipqdepthpch = 16; - int dclk_max; int maxdebw, peakbw; int clperchgroup; int num_groups = ARRAY_SIZE(display->bw.max); @@ -614,9 +618,7 @@ static int tgl_get_bw_info(struct intel_display *display, if (qi.max_numchannels != 0) num_channels = min_t(u8, num_channels, qi.max_numchannels); - dclk_max = icl_sagv_max_dclk(&qi); - - peakbw = num_channels * DIV_ROUND_UP(qi.channel_width, 8) * dclk_max; + peakbw = tgl_peakbw(num_channels, qi.channel_width, icl_sagv_max_dclk(&qi)); maxdebw = min(soc_bw_params->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 100); ipqdepth = min(ipqdepthpch, display_bw_params->displayrtids / num_channels); @@ -662,9 +664,7 @@ static int tgl_get_bw_info(struct intel_display *display, bi->deratedbw[j] = min(maxdebw, bw * (100 - soc_bw_params->derating) / 100); - bi->peakbw[j] = DIV_ROUND_CLOSEST(sp->dclk * - num_channels * - qi.channel_width, 8); + bi->peakbw[j] = tgl_peakbw(num_channels, qi.channel_width, sp->dclk); drm_dbg_kms(display->drm, "BW%d / QGV %d: num_planes=%d deratedbw=%u peakbw: %u\n", @@ -737,12 +737,12 @@ static int xe2_hpd_get_bw_info(struct intel_display *display, return ret; } - peakbw = num_channels * qi.channel_width / 8 * icl_sagv_max_dclk(&qi); + peakbw = tgl_peakbw(num_channels, qi.channel_width, icl_sagv_max_dclk(&qi)); maxdebw = min(soc_bw_params->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 100); 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; + const struct intel_qgv_point *sp = &qi.points[i]; + int bw = tgl_peakbw(num_channels, qi.channel_width, sp->dclk); display->bw.max[0].deratedbw[i] = min(maxdebw, (100 - soc_bw_params->derating) * bw / 100);