Message ID | 20231024010925.3949910-9-imre.deak@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/i915: Improve BW management on MST links | expand |
Hi Imre, kernel test robot noticed the following build warnings: [auto build test WARNING on drm-tip/drm-tip] url: https://github.com/intel-lab-lkp/linux/commits/Imre-Deak/drm-dp_mst-Fix-fractional-DSC-bpp-handling/20231024-091920 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip patch link: https://lore.kernel.org/r/20231024010925.3949910-9-imre.deak%40intel.com patch subject: [Intel-gfx] [PATCH 08/29] drm/dp: Add helpers to calculate the link BW overhead config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20231024/202310241055.Pz9vy06V-lkp@intel.com/config) compiler: m68k-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231024/202310241055.Pz9vy06V-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202310241055.Pz9vy06V-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/gpu/drm/display/drm_dp_helper.c:4002: warning: Function parameter or member 'is_uhbr' not described in 'drm_dp_bw_channel_coding_efficiency' >> drivers/gpu/drm/display/drm_dp_helper.c:4002: warning: expecting prototype for Returns the efficiency in the 100%/coding(). Prototype was for drm_dp_bw_channel_coding_efficiency() instead vim +4002 drivers/gpu/drm/display/drm_dp_helper.c 3996 3997 /** 3998 * Returns the efficiency in the 100%/coding-overhead% ratio in 3999 * 1ppm units. 4000 */ 4001 int drm_dp_bw_channel_coding_efficiency(bool is_uhbr) > 4002 { 4003 if (is_uhbr) 4004 return 967100; 4005 else 4006 /* 4007 * Note that on 8b/10b MST the efficiency is only 4008 * 78.75% due to the 1 out of 64 MTPH packet overhead, 4009 * not accounted for here. 4010 */ 4011 return 800000; 4012 } 4013 EXPORT_SYMBOL(drm_dp_bw_channel_coding_efficiency); 4014
Hi Imre,
kernel test robot noticed the following build errors:
[auto build test ERROR on drm-tip/drm-tip]
url: https://github.com/intel-lab-lkp/linux/commits/Imre-Deak/drm-dp_mst-Fix-fractional-DSC-bpp-handling/20231024-091920
base: git://anongit.freedesktop.org/drm/drm-tip drm-tip
patch link: https://lore.kernel.org/r/20231024010925.3949910-9-imre.deak%40intel.com
patch subject: [Intel-gfx] [PATCH 08/29] drm/dp: Add helpers to calculate the link BW overhead
config: x86_64-buildonly-randconfig-003-20231024 (https://download.01.org/0day-ci/archive/20231024/202310242019.Hp2KseM1-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-12) 11.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231024/202310242019.Hp2KseM1-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202310242019.Hp2KseM1-lkp@intel.com/
All errors (new ones prefixed by >>):
ld: drivers/gpu/drm/display/drm_dp_mst_topology.o: in function `drm_dp_calc_pbn_mode':
>> drm_dp_mst_topology.c:(.text+0x1403): undefined reference to `drm_dp_bw_overhead'
Hi Imre, kernel test robot noticed the following build errors: [auto build test ERROR on drm-tip/drm-tip] url: https://github.com/intel-lab-lkp/linux/commits/Imre-Deak/drm-dp_mst-Fix-fractional-DSC-bpp-handling/20231024-091920 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip patch link: https://lore.kernel.org/r/20231024010925.3949910-9-imre.deak%40intel.com patch subject: [Intel-gfx] [PATCH 08/29] drm/dp: Add helpers to calculate the link BW overhead config: arm-s5pv210_defconfig (https://download.01.org/0day-ci/archive/20231025/202310252345.i0qKzGuh-lkp@intel.com/config) compiler: arm-linux-gnueabi-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231025/202310252345.i0qKzGuh-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202310252345.i0qKzGuh-lkp@intel.com/ All errors (new ones prefixed by >>): arm-linux-gnueabi-ld: drivers/gpu/drm/display/drm_dp_mst_topology.o: in function `drm_dp_calc_pbn_mode': >> drivers/gpu/drm/display/drm_dp_mst_topology.c:4745:(.text+0x12b0): undefined reference to `drm_dp_bw_overhead' vim +4745 drivers/gpu/drm/display/drm_dp_mst_topology.c 4718 4719 /** 4720 * drm_dp_calc_pbn_mode() - Calculate the PBN for a mode. 4721 * @clock: dot clock 4722 * @bpp: bpp as .4 binary fixed point 4723 * 4724 * This uses the formula in the spec to calculate the PBN value for a mode. 4725 */ 4726 int drm_dp_calc_pbn_mode(int clock, int bpp) 4727 { 4728 /* 4729 * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on 4730 * common multiplier to render an integer PBN for all link rate/lane 4731 * counts combinations 4732 * calculate 4733 * peak_kbps = clock * bpp / 16 4734 * peak_kbps *= SSC overhead / 1000000 4735 * peak_kbps /= 8 convert to Kbytes 4736 * peak_kBps *= (64/54) / 1000 convert to PBN 4737 */ 4738 /* 4739 * TODO: Use the actual link and mode parameters to calculate 4740 * the overhead. For now it's assumed that these are 4741 * 4 link lanes, 4096 hactive pixels, which don't add any 4742 * significant data padding overhead and that there is no DSC 4743 * or FEC overhead. 4744 */ > 4745 int overhead = drm_dp_bw_overhead(4, 4096, 0, bpp, 4746 DRM_DP_BW_OVERHEAD_MST | 4747 DRM_DP_BW_OVERHEAD_SSC); 4748 4749 return DIV64_U64_ROUND_UP(mul_u32_u32(clock * bpp, 64 * overhead >> 4), 4750 1000000ULL * 8 * 54 * 1000); 4751 } 4752 EXPORT_SYMBOL(drm_dp_calc_pbn_mode); 4753
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index e5d7970a9ddd0..98c533b74ac89 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -3899,4 +3899,117 @@ int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux) } EXPORT_SYMBOL(drm_panel_dp_aux_backlight); +/* See DP Standard v2.1 2.6.4.4.1.1, 2.8.4.4, 2.8.7 */ +static int drm_dp_link_symbol_cycles(int lane_count, int pixels, int bpp_x16, + int symbol_size, bool is_mst) +{ + int cycles = DIV_ROUND_UP(pixels * bpp_x16, 16 * symbol_size * lane_count); + int align = is_mst ? 4 / lane_count : 1; + + return ALIGN(cycles, align); +} + +static int drm_dp_link_dsc_symbol_cycles(int lane_count, int pixels, int slice_count, + int bpp_x16, int symbol_size, bool is_mst) +{ + int slice_pixels = DIV_ROUND_UP(pixels, slice_count); + int slice_data_cycles = drm_dp_link_symbol_cycles(lane_count, slice_pixels, + bpp_x16, symbol_size, is_mst); + int slice_eoc_cycles = is_mst ? 4 / lane_count : 1; + + return slice_count * (slice_data_cycles + slice_eoc_cycles); +} + +/** + * drm_dp_bw_overhead - Calculate the BW overhead of a DP link stream + * @lane_count: DP link lane count + * @hactive: pixel count of the active period in one scanline of the stream + * @dsc_slice_count: DSC slice count if @flags/DRM_DP_LINK_BW_OVERHEAD_DSC is set + * @bpp_x16: bits per pixel in .4 binary fixed point + * @flags: DRM_DP_OVERHEAD_x flags + * + * Calculate the BW allocation overhead of a DP link stream, depending + * on the link's + * - @lane_count + * - SST/MST mode (@flags / %DRM_DP_OVERHEAD_MST) + * - symbol size (@flags / %DRM_DP_OVERHEAD_UHBR) + * - FEC mode (@flags / %DRM_DP_OVERHEAD_FEC) + * - SSC mode (@flags / %DRM_DP_OVERHEAD_SSC) + * as well as the stream's + * - @hactive timing + * - @bpp_x16 color depth + * - compression mode (@flags / %DRM_DP_OVERHEAD_DSC). + * Note that this overhead doesn't account for the 8b/10b, 128b/132b + * channel coding efficiency, for that see + * @drm_dp_link_bw_channel_coding_efficiency(). + * + * Returns the overhead as 100% + overhead% in 1ppm units. + */ +int drm_dp_bw_overhead(int lane_count, int hactive, + int dsc_slice_count, + int bpp_x16, unsigned long flags) +{ + int symbol_size = flags & DRM_DP_BW_OVERHEAD_UHBR ? 32 : 8; + bool is_mst = flags & DRM_DP_BW_OVERHEAD_MST; + u32 overhead = 1000000; + int symbol_cycles; + + /* + * DP Standard v2.1 2.6.4.1 + * SSC downspread and ref clock variation margin: + * 5300ppm + 300ppm ~ 0.6% + */ + if (flags & DRM_DP_BW_OVERHEAD_SSC) + overhead += 6000; + + /* + * DP Standard v2.1 2.6.4.1.1: + * FEC symbol insertions for 8b/10b channel coding: + * 2.4% + */ + if (flags & DRM_DP_BW_OVERHEAD_FEC) + overhead += 24000; + + /* + * DP Standard v2.1 2.7.9, 5.9.7 + * The FEC overhead for UHBR is accounted for in its 96.71% channel + * coding efficiency. + */ + WARN_ON((flags & DRM_DP_BW_OVERHEAD_UHBR) && + (flags & DRM_DP_BW_OVERHEAD_FEC)); + + if (flags & DRM_DP_BW_OVERHEAD_DSC) + symbol_cycles = drm_dp_link_dsc_symbol_cycles(lane_count, hactive, + dsc_slice_count, + bpp_x16, symbol_size, + is_mst); + else + symbol_cycles = drm_dp_link_symbol_cycles(lane_count, hactive, + bpp_x16, symbol_size, + is_mst); + + return DIV_ROUND_UP_ULL(mul_u32_u32(symbol_cycles * symbol_size * lane_count, + overhead * 16), + hactive * bpp_x16); +} +EXPORT_SYMBOL(drm_dp_bw_overhead); + +/** + * Returns the efficiency in the 100%/coding-overhead% ratio in + * 1ppm units. + */ +int drm_dp_bw_channel_coding_efficiency(bool is_uhbr) +{ + if (is_uhbr) + return 967100; + else + /* + * Note that on 8b/10b MST the efficiency is only + * 78.75% due to the 1 out of 64 MTPH packet overhead, + * not accounted for here. + */ + return 800000; +} +EXPORT_SYMBOL(drm_dp_bw_channel_coding_efficiency); + #endif diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index cc0a8fe84d290..d7383f2fd6cfe 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4726,17 +4726,28 @@ EXPORT_SYMBOL(drm_dp_check_act_status); int drm_dp_calc_pbn_mode(int clock, int bpp) { /* - * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006 * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on * common multiplier to render an integer PBN for all link rate/lane * counts combinations * calculate - * peak_kbps *= (1006/1000) - * peak_kbps *= (64/54) - * peak_kbps *= 8 convert to bytes + * peak_kbps = clock * bpp / 16 + * peak_kbps *= SSC overhead / 1000000 + * peak_kbps /= 8 convert to Kbytes + * peak_kBps *= (64/54) / 1000 convert to PBN */ - return DIV_ROUND_UP_ULL(mul_u32_u32(clock * bpp, 64 * 1006 >> 4), - 1000 * 8 * 54 * 1000); + /* + * TODO: Use the actual link and mode parameters to calculate + * the overhead. For now it's assumed that these are + * 4 link lanes, 4096 hactive pixels, which don't add any + * significant data padding overhead and that there is no DSC + * or FEC overhead. + */ + int overhead = drm_dp_bw_overhead(4, 4096, 0, bpp, + DRM_DP_BW_OVERHEAD_MST | + DRM_DP_BW_OVERHEAD_SSC); + + return DIV64_U64_ROUND_UP(mul_u32_u32(clock * bpp, 64 * overhead >> 4), + 1000000ULL * 8 * 54 * 1000); } EXPORT_SYMBOL(drm_dp_calc_pbn_mode); diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 351f38d5cc351..010cb5a3b39e0 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -788,4 +788,15 @@ bool drm_dp_downstream_rgb_to_ycbcr_conversion(const u8 dpcd[DP_RECEIVER_CAP_SIZ const u8 port_cap[4], u8 color_spc); int drm_dp_pcon_convert_rgb_to_ycbcr(struct drm_dp_aux *aux, u8 color_spc); +#define DRM_DP_BW_OVERHEAD_MST BIT(0) +#define DRM_DP_BW_OVERHEAD_UHBR BIT(1) +#define DRM_DP_BW_OVERHEAD_SSC BIT(2) +#define DRM_DP_BW_OVERHEAD_FEC BIT(3) +#define DRM_DP_BW_OVERHEAD_DSC BIT(4) + +int drm_dp_bw_overhead(int lane_count, int hactive, + int dsc_slice_count, + int bpp_x16, unsigned long flags); +int drm_dp_bw_channel_coding_efficiency(bool is_uhbr); + #endif /* _DRM_DP_HELPER_H_ */
Add helpers drivers can use to calculate the BW allocation overhead - due to SSC, FEC, DSC and data alignment on symbol cycles - and the channel coding efficiency - due to the 8b/10b, 128b/132b encoding. On 128b/132b links the FEC overhead is part of the coding efficiency, so not accounted for in the BW allocation overhead. The drivers can use these functions to calculate a ratio, controlling the stream symbol insertion rate of the source device in each SST TU or MST MTP frame. Drivers can calculate this m/n = drm_dp_bw_overhead() / drm_dp_bw_channel_coding_efficiency() ratio for a given stream and with that the mtp_count = CEIL(64 * m / n) allocated MTPs for the stream in a frame and pbn = CEIL(64 * dm_mst_get_pbn_divider() * m / n) allocated PBNs for the stream on the MST link path. Take drm_dp_bw_overhead() into use in drm_dp_calc_pbn_mode(), for drivers calculating the PBN value directly. Cc: Lyude Paul <lyude@redhat.com> Signed-off-by: Imre Deak <imre.deak@intel.com> --- drivers/gpu/drm/display/drm_dp_helper.c | 113 ++++++++++++++++++ drivers/gpu/drm/display/drm_dp_mst_topology.c | 23 +++- include/drm/display/drm_dp_helper.h | 11 ++ 3 files changed, 141 insertions(+), 6 deletions(-)