Re: [PATCH v2 08/29] drm/dp: Add helpers to calculate the link BW overhead

2023-10-27 Thread Imre Deak
On Fri, Oct 27, 2023 at 06:48:44PM +0300, Ville Syrjälä wrote:
> On Tue, Oct 24, 2023 at 01:22:17PM +0300, Imre Deak wrote:
> > 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 = (pixel_data_rate * drm_dp_bw_overhead()) /
> >   (link_data_rate * drm_dp_bw_channel_coding_efficiency())
> > 
> > ratio for a given link and pixel stream and with that the
> > 
> > mtp_count = CEIL(64 * m / n)
> > 
> > allocated MTPs for the stream in a link 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.
> > 
> > v2:
> > - Add dockbook description to drm_dp_bw_channel_coding_efficiency().
> >   (LKP).
> > - Clarify the way m/n ratio is calculated in the commit log.
> > 
> > Cc: Lyude Paul 
> > Cc: kernel test robot 
> > Cc: dri-devel@lists.freedesktop.org
> > Signed-off-by: Imre Deak 
> > ---
> >  drivers/gpu/drm/display/drm_dp_helper.c   | 124 ++
> >  drivers/gpu/drm/display/drm_dp_mst_topology.c |  23 +++-
> >  include/drm/display/drm_dp_helper.h   |  11 ++
> >  3 files changed, 152 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
> > b/drivers/gpu/drm/display/drm_dp_helper.c
> > index e5d7970a9ddd0..79629bf7547bf 100644
> > --- a/drivers/gpu/drm/display/drm_dp_helper.c
> > +++ b/drivers/gpu/drm/display/drm_dp_helper.c
> > @@ -3899,4 +3899,128 @@ 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 = 100;
> > +   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)
> 
> Maybe the flag name should reflect that it accounts for both 
> downspread and ref clk difference.

Ok, will rename it.

> 

Re: [PATCH v2 08/29] drm/dp: Add helpers to calculate the link BW overhead

2023-10-27 Thread Ville Syrjälä
On Tue, Oct 24, 2023 at 01:22:17PM +0300, Imre Deak wrote:
> 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 = (pixel_data_rate * drm_dp_bw_overhead()) /
>   (link_data_rate * drm_dp_bw_channel_coding_efficiency())
> 
> ratio for a given link and pixel stream and with that the
> 
> mtp_count = CEIL(64 * m / n)
> 
> allocated MTPs for the stream in a link 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.
> 
> v2:
> - Add dockbook description to drm_dp_bw_channel_coding_efficiency().
>   (LKP).
> - Clarify the way m/n ratio is calculated in the commit log.
> 
> Cc: Lyude Paul 
> Cc: kernel test robot 
> Cc: dri-devel@lists.freedesktop.org
> Signed-off-by: Imre Deak 
> ---
>  drivers/gpu/drm/display/drm_dp_helper.c   | 124 ++
>  drivers/gpu/drm/display/drm_dp_mst_topology.c |  23 +++-
>  include/drm/display/drm_dp_helper.h   |  11 ++
>  3 files changed, 152 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
> b/drivers/gpu/drm/display/drm_dp_helper.c
> index e5d7970a9ddd0..79629bf7547bf 100644
> --- a/drivers/gpu/drm/display/drm_dp_helper.c
> +++ b/drivers/gpu/drm/display/drm_dp_helper.c
> @@ -3899,4 +3899,128 @@ 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 = 100;
> + 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)

Maybe the flag name should reflect that it accounts for both 
downspread and ref clk difference.

> + 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 

Re: [Intel-gfx] [PATCH v2 08/29] drm/dp: Add helpers to calculate the link BW overhead

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 01:22:17PM +0300, Imre Deak wrote:
> 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 = (pixel_data_rate * drm_dp_bw_overhead()) /
>   (link_data_rate * drm_dp_bw_channel_coding_efficiency())
> 
> ratio for a given link and pixel stream and with that the
> 
> mtp_count = CEIL(64 * m / n)
> 
> allocated MTPs for the stream in a link 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.
> 
> v2:
> - Add dockbook description to drm_dp_bw_channel_coding_efficiency().
>   (LKP).
> - Clarify the way m/n ratio is calculated in the commit log.

Could not spot any obivous issues here, but wondering, whether someone
could also take a look, as this seems to be affecting quite a lot.

Anyways, from my side:

Reviewed-by: Stanislav Lisovskiy 

> 
> Cc: Lyude Paul 
> Cc: kernel test robot 
> Cc: dri-devel@lists.freedesktop.org
> Signed-off-by: Imre Deak 
> ---
>  drivers/gpu/drm/display/drm_dp_helper.c   | 124 ++
>  drivers/gpu/drm/display/drm_dp_mst_topology.c |  23 +++-
>  include/drm/display/drm_dp_helper.h   |  11 ++
>  3 files changed, 152 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
> b/drivers/gpu/drm/display/drm_dp_helper.c
> index e5d7970a9ddd0..79629bf7547bf 100644
> --- a/drivers/gpu/drm/display/drm_dp_helper.c
> +++ b/drivers/gpu/drm/display/drm_dp_helper.c
> @@ -3899,4 +3899,128 @@ 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 = 100;
> + 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 

[PATCH v2 08/29] drm/dp: Add helpers to calculate the link BW overhead

2023-10-24 Thread Imre Deak
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 = (pixel_data_rate * drm_dp_bw_overhead()) /
  (link_data_rate * drm_dp_bw_channel_coding_efficiency())

ratio for a given link and pixel stream and with that the

mtp_count = CEIL(64 * m / n)

allocated MTPs for the stream in a link 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.

v2:
- Add dockbook description to drm_dp_bw_channel_coding_efficiency().
  (LKP).
- Clarify the way m/n ratio is calculated in the commit log.

Cc: Lyude Paul 
Cc: kernel test robot 
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Imre Deak 
---
 drivers/gpu/drm/display/drm_dp_helper.c   | 124 ++
 drivers/gpu/drm/display/drm_dp_mst_topology.c |  23 +++-
 include/drm/display/drm_dp_helper.h   |  11 ++
 3 files changed, 152 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index e5d7970a9ddd0..79629bf7547bf 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -3899,4 +3899,128 @@ 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 = 100;
+   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 =