2022-10-05 18:19:40

by Marijn Suijten

[permalink] [raw]
Subject: [PATCH v2 0/7] drm/msm: Fix math issues in MSM DSC implementation

Various removals of complex yet unnecessary math, fixing all uses of
drm_dsc_config::bits_per_pixel to deal with the fact that this field
includes four fractional bits, and finally making sure that
range_bpg_offset contains values 6-bits wide to prevent overflows in
drm_dsc_pps_payload_pack().

Altogether this series is responsible for solving _all_ Display Stream
Compression issues and artifacts on the Sony Tama (sdm845) Akatsuki
smartphone (2880x1440p).

Changes since v1:

- Propagate r-b's, except (obviously) in patches that were (heavily)
modified;
- Remove accidental debug code in dsi_cmd_dma_add;
- Move Range BPG Offset masking out of DCS PPS packing, back into the
DSI driver when it is assigned to drm_dsc_config (this series is now
strictly focusing on drm/msm again);
- Replace modulo-check resulting in conditional increment with
DIV_ROUND_UP;
- Remove repeated calculation of slice_chunk_size;
- Use u16 instead of int when handling bits_per_pixel;
- Use DRM_DEV_ERROR instead of pr_err in DSI code;
- Also remove redundant target_bpp_x16 variable.

v1: https://lore.kernel.org/linux-arm-msm/[email protected]/T/#u

Marijn Suijten (7):
drm/msm/dsi: Remove useless math in DSC calculations
drm/msm/dsi: Remove repeated calculation of slice_per_intf
drm/msm/dsi: Use DIV_ROUND_UP instead of conditional increment on
modulo
drm/msm/dsi: Reuse earlier computed dsc->slice_chunk_size
drm/msm/dsi: Account for DSC's bits_per_pixel having 4 fractional bits
drm/msm/dpu1: Account for DSC's bits_per_pixel having 4 fractional
bits
drm/msm/dsi: Prevent signed BPG offsets from bleeding into adjacent
bits

drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 11 +----
drivers/gpu/drm/msm/dsi/dsi_host.c | 56 ++++++++++------------
2 files changed, 28 insertions(+), 39 deletions(-)

--
2.38.0


2022-10-05 18:19:46

by Marijn Suijten

[permalink] [raw]
Subject: [PATCH v2 1/7] drm/msm/dsi: Remove useless math in DSC calculations

Multiplying a value by 2 and adding 1 to it always results in a value
that is uneven, and that 1 gets truncated immediately when performing
integer division by 2 again. There is no "rounding" possible here.

After that target_bpp_x16 is used to store a multiplication of
bits_per_pixel by 16 which is only ever read to immediately be divided
by 16 again, and is elided in much the same way.

Fixes: b9080324d6ca ("drm/msm/dsi: add support for dsc data")
Signed-off-by: Marijn Suijten <[email protected]>
---
drivers/gpu/drm/msm/dsi/dsi_host.c | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 8e4bc586c262..70077d1f0f21 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1784,7 +1784,6 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
int hrd_delay;
int pre_num_extra_mux_bits, num_extra_mux_bits;
int slice_bits;
- int target_bpp_x16;
int data;
int final_value, final_scale;
int i;
@@ -1864,14 +1863,7 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
data = 2048 * (dsc->rc_model_size - dsc->initial_offset + num_extra_mux_bits);
dsc->slice_bpg_offset = DIV_ROUND_UP(data, groups_total);

- /* bpp * 16 + 0.5 */
- data = dsc->bits_per_pixel * 16;
- data *= 2;
- data++;
- data /= 2;
- target_bpp_x16 = data;
-
- data = (dsc->initial_xmit_delay * target_bpp_x16) / 16;
+ data = dsc->initial_xmit_delay * dsc->bits_per_pixel;
final_value = dsc->rc_model_size - data + num_extra_mux_bits;
dsc->final_offset = final_value;

--
2.38.0

2022-10-05 18:20:05

by Marijn Suijten

[permalink] [raw]
Subject: [PATCH v2 3/7] drm/msm/dsi: Use DIV_ROUND_UP instead of conditional increment on modulo

This exact same math is used to compute bytes_in_slice above in
dsi_update_dsc_timing(), also used to fill slice_chunk_size.

Fixes: b9080324d6ca ("drm/msm/dsi: add support for dsc data")
Signed-off-by: Marijn Suijten <[email protected]>
---
drivers/gpu/drm/msm/dsi/dsi_host.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index c746ed5d61f9..48c966375ffa 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1829,9 +1829,7 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
* params are calculated
*/
groups_per_line = DIV_ROUND_UP(dsc->slice_width, 3);
- dsc->slice_chunk_size = dsc->slice_width * dsc->bits_per_pixel / 8;
- if ((dsc->slice_width * dsc->bits_per_pixel) % 8)
- dsc->slice_chunk_size++;
+ dsc->slice_chunk_size = DIV_ROUND_UP(dsc->slice_width * dsc->bits_per_pixel, 8);

/* rbs-min */
min_rate_buffer_size = dsc->rc_model_size - dsc->initial_offset +
--
2.38.0

2022-10-05 18:20:18

by Marijn Suijten

[permalink] [raw]
Subject: [PATCH v2 4/7] drm/msm/dsi: Reuse earlier computed dsc->slice_chunk_size

dsi_populate_dsc_params() is called prior to dsi_update_dsc_timing() and
already computes a value for slice_chunk_size, whose value doesn't need
to be recomputed and re-set here.

Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration")
Signed-off-by: Marijn Suijten <[email protected]>
---
drivers/gpu/drm/msm/dsi/dsi_host.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 48c966375ffa..f42794cdd4c1 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -845,7 +845,6 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
u32 reg, reg_ctrl, reg_ctrl2;
u32 slice_per_intf, total_bytes_per_intf;
u32 pkt_per_line;
- u32 bytes_in_slice;
u32 eol_byte_num;

/* first calculate dsc parameters and then program
@@ -860,11 +859,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
if (slice_per_intf > dsc->slice_count)
dsc->slice_count = 1;

- bytes_in_slice = DIV_ROUND_UP(dsc->slice_width * dsc->bits_per_pixel, 8);
-
- dsc->slice_chunk_size = bytes_in_slice;
-
- total_bytes_per_intf = bytes_in_slice * slice_per_intf;
+ total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;

eol_byte_num = total_bytes_per_intf % 3;
pkt_per_line = slice_per_intf / dsc->slice_count;
@@ -890,7 +885,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
reg_ctrl |= reg;

reg_ctrl2 &= ~DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH__MASK;
- reg_ctrl2 |= DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH(bytes_in_slice);
+ reg_ctrl2 |= DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH(dsc->slice_chunk_size);

dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, reg_ctrl);
dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, reg_ctrl2);
--
2.38.0

2022-10-05 18:20:21

by Marijn Suijten

[permalink] [raw]
Subject: [PATCH v2 5/7] drm/msm/dsi: Account for DSC's bits_per_pixel having 4 fractional bits

drm_dsc_config's bits_per_pixel field holds a fractional value with 4
bits, which all panel drivers should adhere to for
drm_dsc_pps_payload_pack() to generate a valid payload. All code in the
DSI driver here seems to assume that this field doesn't contain any
fractional bits, hence resulting in the wrong values being computed.
Since none of the calculations leave any room for fractional bits or
seem to indicate any possible area of support, disallow such values
altogether.

Fixes: b9080324d6ca ("drm/msm/dsi: add support for dsc data")
Signed-off-by: Marijn Suijten <[email protected]>
---
drivers/gpu/drm/msm/dsi/dsi_host.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index f42794cdd4c1..4717d49d76be 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -33,7 +33,7 @@

#define DSI_RESET_TOGGLE_DELAY_MS 20

-static int dsi_populate_dsc_params(struct drm_dsc_config *dsc);
+static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc);

static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor)
{
@@ -908,6 +908,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
u32 va_end = va_start + mode->vdisplay;
u32 hdisplay = mode->hdisplay;
u32 wc;
+ int ret;

DBG("");

@@ -943,7 +944,9 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
/* we do the calculations for dsc parameters here so that
* panel can use these parameters
*/
- dsi_populate_dsc_params(dsc);
+ ret = dsi_populate_dsc_params(msm_host, dsc);
+ if (ret)
+ return;

/* Divide the display by 3 but keep back/font porch and
* pulse width same
@@ -1769,7 +1772,7 @@ static char bpg_offset[DSC_NUM_BUF_RANGES] = {
2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12
};

-static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
+static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc)
{
int mux_words_size;
int groups_per_line, groups_total;
@@ -1780,6 +1783,12 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
int data;
int final_value, final_scale;
int i;
+ u16 bpp = dsc->bits_per_pixel >> 4;
+
+ if (dsc->bits_per_pixel & 0xf) {
+ DRM_DEV_ERROR(&msm_host->pdev->dev, "DSI does not support fractional bits_per_pixel\n");
+ return -EINVAL;
+ }

dsc->rc_model_size = 8192;
dsc->first_line_bpg_offset = 12;
@@ -1801,7 +1810,7 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
}

dsc->initial_offset = 6144; /* Not bpp 12 */
- if (dsc->bits_per_pixel != 8)
+ if (bpp != 8)
dsc->initial_offset = 2048; /* bpp = 12 */

mux_words_size = 48; /* bpc == 8/10 */
@@ -1824,14 +1833,14 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
* params are calculated
*/
groups_per_line = DIV_ROUND_UP(dsc->slice_width, 3);
- dsc->slice_chunk_size = DIV_ROUND_UP(dsc->slice_width * dsc->bits_per_pixel, 8);
+ dsc->slice_chunk_size = DIV_ROUND_UP(dsc->slice_width * bpp, 8);

/* rbs-min */
min_rate_buffer_size = dsc->rc_model_size - dsc->initial_offset +
- dsc->initial_xmit_delay * dsc->bits_per_pixel +
+ dsc->initial_xmit_delay * bpp +
groups_per_line * dsc->first_line_bpg_offset;

- hrd_delay = DIV_ROUND_UP(min_rate_buffer_size, dsc->bits_per_pixel);
+ hrd_delay = DIV_ROUND_UP(min_rate_buffer_size, bpp);

dsc->initial_dec_delay = hrd_delay - dsc->initial_xmit_delay;

@@ -1854,7 +1863,7 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
data = 2048 * (dsc->rc_model_size - dsc->initial_offset + num_extra_mux_bits);
dsc->slice_bpg_offset = DIV_ROUND_UP(data, groups_total);

- data = dsc->initial_xmit_delay * dsc->bits_per_pixel;
+ data = dsc->initial_xmit_delay * bpp;
final_value = dsc->rc_model_size - data + num_extra_mux_bits;
dsc->final_offset = final_value;

--
2.38.0

2022-10-05 18:20:26

by Marijn Suijten

[permalink] [raw]
Subject: [PATCH v2 6/7] drm/msm/dpu1: Account for DSC's bits_per_pixel having 4 fractional bits

According to the comment this DPU register contains the bits per pixel
as a 6.4 fractional value, conveniently matching the contents of
bits_per_pixel in struct drm_dsc_config which also uses 4 fractional
bits. However, the downstream source this implementation was
copy-pasted from has its bpp field stored _without_ fractional part.

This makes the entire convoluted math obsolete as it is impossible to
pull those 4 fractional bits out of thin air, by somehow trying to reuse
the lowest 2 bits of a non-fractional bpp (lsb = bpp % 4??).

The rest of the code merely attempts to keep the integer part a multiple
of 4, which is rendered useless thanks to data |= dsc->bits_per_pixel <<
12; already filling up those bits anyway (but not on downstream).

Fixes: c110cfd1753e ("drm/msm/disp/dpu1: Add support for DSC")
Reviewed-by: Abhinav Kumar <[email protected]>
Reviewed-by: Dmitry Baryshkov <[email protected]>
Reviewed-by: Vinod Koul <[email protected]>
Signed-off-by: Marijn Suijten <[email protected]>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
index 46cc2afd2bb9..c63e6eef1ba6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
@@ -47,7 +47,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc,
u32 initial_lines)
{
struct dpu_hw_blk_reg_map *c = &hw_dsc->hw;
- u32 data, lsb, bpp;
+ u32 data;
u32 slice_last_group_size;
u32 det_thresh_flatness;
bool is_cmd_mode = !(mode & DSC_MODE_VIDEO);
@@ -61,14 +61,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc,
data = (initial_lines << 20);
data |= ((slice_last_group_size - 1) << 18);
/* bpp is 6.4 format, 4 LSBs bits are for fractional part */
- data |= dsc->bits_per_pixel << 12;
- lsb = dsc->bits_per_pixel % 4;
- bpp = dsc->bits_per_pixel / 4;
- bpp *= 4;
- bpp <<= 4;
- bpp |= lsb;
-
- data |= bpp << 8;
+ data |= (dsc->bits_per_pixel << 8);
data |= (dsc->block_pred_enable << 7);
data |= (dsc->line_buf_depth << 3);
data |= (dsc->simple_422 << 2);
--
2.38.0

2022-10-05 18:20:31

by Marijn Suijten

[permalink] [raw]
Subject: [PATCH v2 7/7] drm/msm/dsi: Prevent signed BPG offsets from bleeding into adjacent bits

The bpg_offset array contains negative BPG offsets which fill the full 8
bits of a char thanks to two's complement: this however results in those
bits bleeding into the next field when the value is packed into DSC PPS
by the drm_dsc_helper function, which only expects range_bpg_offset to
contain 6-bit wide values. As a consequence random slices appear
corrupted on-screen (tested on a Sony Tama Akatsuki device with sdm845).

Use AND operators to limit these two's complement values to 6 bits,
similar to the AMD and i915 drivers.

Fixes: b9080324d6ca ("drm/msm/dsi: add support for dsc data")
Signed-off-by: Marijn Suijten <[email protected]>
---
drivers/gpu/drm/msm/dsi/dsi_host.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 4717d49d76be..b3cff3d3aa85 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1806,7 +1806,11 @@ static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc
for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
dsc->rc_range_params[i].range_min_qp = min_qp[i];
dsc->rc_range_params[i].range_max_qp = max_qp[i];
- dsc->rc_range_params[i].range_bpg_offset = bpg_offset[i];
+ /*
+ * Range BPG Offset contains two's-complement signed values that fill
+ * 8 bits, yet the registers and DCS PPS field are only 6 bits wide.
+ */
+ dsc->rc_range_params[i].range_bpg_offset = bpg_offset[i] & DSC_RANGE_BPG_OFFSET_MASK;
}

dsc->initial_offset = 6144; /* Not bpp 12 */
--
2.38.0

2022-10-05 18:31:59

by Marijn Suijten

[permalink] [raw]
Subject: [PATCH v2 2/7] drm/msm/dsi: Remove repeated calculation of slice_per_intf

slice_per_intf is already computed for intf_width, which holds the same
value as hdisplay.

Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration")
Reviewed-by: Bjorn Andersson <[email protected]>
Reviewed-by: Konrad Dybcio <[email protected]>
Reviewed-by: Abhinav Kumar <[email protected]>
Reviewed-by: Vinod Koul <[email protected]>
Signed-off-by: Marijn Suijten <[email protected]>
---
drivers/gpu/drm/msm/dsi/dsi_host.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 70077d1f0f21..c746ed5d61f9 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -842,7 +842,7 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable,
static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mode, u32 hdisplay)
{
struct drm_dsc_config *dsc = msm_host->dsc;
- u32 reg, intf_width, reg_ctrl, reg_ctrl2;
+ u32 reg, reg_ctrl, reg_ctrl2;
u32 slice_per_intf, total_bytes_per_intf;
u32 pkt_per_line;
u32 bytes_in_slice;
@@ -851,8 +851,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
/* first calculate dsc parameters and then program
* compress mode registers
*/
- intf_width = hdisplay;
- slice_per_intf = DIV_ROUND_UP(intf_width, dsc->slice_width);
+ slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->slice_width);

/* If slice_per_pkt is greater than slice_per_intf
* then default to 1. This can happen during partial
@@ -861,7 +860,6 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
if (slice_per_intf > dsc->slice_count)
dsc->slice_count = 1;

- slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->slice_width);
bytes_in_slice = DIV_ROUND_UP(dsc->slice_width * dsc->bits_per_pixel, 8);

dsc->slice_chunk_size = bytes_in_slice;
--
2.38.0

2022-10-05 20:21:34

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 5/7] drm/msm/dsi: Account for DSC's bits_per_pixel having 4 fractional bits

On Wed, 5 Oct 2022 at 21:17, Marijn Suijten
<[email protected]> wrote:
>
> drm_dsc_config's bits_per_pixel field holds a fractional value with 4
> bits, which all panel drivers should adhere to for
> drm_dsc_pps_payload_pack() to generate a valid payload. All code in the
> DSI driver here seems to assume that this field doesn't contain any
> fractional bits, hence resulting in the wrong values being computed.
> Since none of the calculations leave any room for fractional bits or
> seem to indicate any possible area of support, disallow such values
> altogether.
>
> Fixes: b9080324d6ca ("drm/msm/dsi: add support for dsc data")
> Signed-off-by: Marijn Suijten <[email protected]>
> ---
> drivers/gpu/drm/msm/dsi/dsi_host.c | 25 +++++++++++++++++--------
> 1 file changed, 17 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index f42794cdd4c1..4717d49d76be 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -33,7 +33,7 @@
>
> #define DSI_RESET_TOGGLE_DELAY_MS 20
>
> -static int dsi_populate_dsc_params(struct drm_dsc_config *dsc);
> +static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc);
>
> static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor)
> {
> @@ -908,6 +908,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
> u32 va_end = va_start + mode->vdisplay;
> u32 hdisplay = mode->hdisplay;
> u32 wc;
> + int ret;
>
> DBG("");
>
> @@ -943,7 +944,9 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
> /* we do the calculations for dsc parameters here so that
> * panel can use these parameters
> */
> - dsi_populate_dsc_params(dsc);
> + ret = dsi_populate_dsc_params(msm_host, dsc);
> + if (ret)
> + return;
>
> /* Divide the display by 3 but keep back/font porch and
> * pulse width same
> @@ -1769,7 +1772,7 @@ static char bpg_offset[DSC_NUM_BUF_RANGES] = {
> 2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12
> };
>
> -static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
> +static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc)
> {
> int mux_words_size;
> int groups_per_line, groups_total;
> @@ -1780,6 +1783,12 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
> int data;
> int final_value, final_scale;
> int i;
> + u16 bpp = dsc->bits_per_pixel >> 4;
> +
> + if (dsc->bits_per_pixel & 0xf) {
> + DRM_DEV_ERROR(&msm_host->pdev->dev, "DSI does not support fractional bits_per_pixel\n");
> + return -EINVAL;
> + }
>
> dsc->rc_model_size = 8192;
> dsc->first_line_bpg_offset = 12;
> @@ -1801,7 +1810,7 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
> }
>
> dsc->initial_offset = 6144; /* Not bpp 12 */
> - if (dsc->bits_per_pixel != 8)
> + if (bpp != 8)
> dsc->initial_offset = 2048; /* bpp = 12 */
>
> mux_words_size = 48; /* bpc == 8/10 */
> @@ -1824,14 +1833,14 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
> * params are calculated
> */
> groups_per_line = DIV_ROUND_UP(dsc->slice_width, 3);
> - dsc->slice_chunk_size = DIV_ROUND_UP(dsc->slice_width * dsc->bits_per_pixel, 8);
> + dsc->slice_chunk_size = DIV_ROUND_UP(dsc->slice_width * bpp, 8);

I'd still prefer if we can get closer to drm_dsc_compute_rc_parameters().
The mentioned function has the following code:

vdsc_cfg->slice_chunk_size = DIV_ROUND_UP(vdsc_cfg->slice_width *

vdsc_cfg->bits_per_pixel,
(8 * 16));

In fact, could you please take a look if we can switch to using this
function and drop our code?

>
> /* rbs-min */
> min_rate_buffer_size = dsc->rc_model_size - dsc->initial_offset +
> - dsc->initial_xmit_delay * dsc->bits_per_pixel +
> + dsc->initial_xmit_delay * bpp +
> groups_per_line * dsc->first_line_bpg_offset;
>
> - hrd_delay = DIV_ROUND_UP(min_rate_buffer_size, dsc->bits_per_pixel);
> + hrd_delay = DIV_ROUND_UP(min_rate_buffer_size, bpp);
>
> dsc->initial_dec_delay = hrd_delay - dsc->initial_xmit_delay;
>
> @@ -1854,7 +1863,7 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
> data = 2048 * (dsc->rc_model_size - dsc->initial_offset + num_extra_mux_bits);
> dsc->slice_bpg_offset = DIV_ROUND_UP(data, groups_total);
>
> - data = dsc->initial_xmit_delay * dsc->bits_per_pixel;
> + data = dsc->initial_xmit_delay * bpp;
> final_value = dsc->rc_model_size - data + num_extra_mux_bits;
> dsc->final_offset = final_value;
>
> --
> 2.38.0
>


--
With best wishes
Dmitry

2022-10-05 21:03:40

by Marijn Suijten

[permalink] [raw]
Subject: Re: [PATCH v2 5/7] drm/msm/dsi: Account for DSC's bits_per_pixel having 4 fractional bits

On 2022-10-05 22:31:43, Dmitry Baryshkov wrote:
> On Wed, 5 Oct 2022 at 21:17, Marijn Suijten
> <[email protected]> wrote:
> >
> > drm_dsc_config's bits_per_pixel field holds a fractional value with 4
> > bits, which all panel drivers should adhere to for
> > drm_dsc_pps_payload_pack() to generate a valid payload. All code in the
> > DSI driver here seems to assume that this field doesn't contain any
> > fractional bits, hence resulting in the wrong values being computed.
> > Since none of the calculations leave any room for fractional bits or
> > seem to indicate any possible area of support, disallow such values
> > altogether.
> >
> > Fixes: b9080324d6ca ("drm/msm/dsi: add support for dsc data")
> > Signed-off-by: Marijn Suijten <[email protected]>
> > ---
> > drivers/gpu/drm/msm/dsi/dsi_host.c | 25 +++++++++++++++++--------
> > 1 file changed, 17 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
> > index f42794cdd4c1..4717d49d76be 100644
> > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> > @@ -33,7 +33,7 @@
> >
> > #define DSI_RESET_TOGGLE_DELAY_MS 20
> >
> > -static int dsi_populate_dsc_params(struct drm_dsc_config *dsc);
> > +static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc);
> >
> > static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor)
> > {
> > @@ -908,6 +908,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
> > u32 va_end = va_start + mode->vdisplay;
> > u32 hdisplay = mode->hdisplay;
> > u32 wc;
> > + int ret;
> >
> > DBG("");
> >
> > @@ -943,7 +944,9 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
> > /* we do the calculations for dsc parameters here so that
> > * panel can use these parameters
> > */
> > - dsi_populate_dsc_params(dsc);
> > + ret = dsi_populate_dsc_params(msm_host, dsc);
> > + if (ret)
> > + return;
> >
> > /* Divide the display by 3 but keep back/font porch and
> > * pulse width same
> > @@ -1769,7 +1772,7 @@ static char bpg_offset[DSC_NUM_BUF_RANGES] = {
> > 2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12
> > };
> >
> > -static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
> > +static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc)
> > {
> > int mux_words_size;
> > int groups_per_line, groups_total;
> > @@ -1780,6 +1783,12 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
> > int data;
> > int final_value, final_scale;
> > int i;
> > + u16 bpp = dsc->bits_per_pixel >> 4;
> > +
> > + if (dsc->bits_per_pixel & 0xf) {
> > + DRM_DEV_ERROR(&msm_host->pdev->dev, "DSI does not support fractional bits_per_pixel\n");
> > + return -EINVAL;
> > + }
> >
> > dsc->rc_model_size = 8192;
> > dsc->first_line_bpg_offset = 12;
> > @@ -1801,7 +1810,7 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
> > }
> >
> > dsc->initial_offset = 6144; /* Not bpp 12 */
> > - if (dsc->bits_per_pixel != 8)
> > + if (bpp != 8)
> > dsc->initial_offset = 2048; /* bpp = 12 */
> >
> > mux_words_size = 48; /* bpc == 8/10 */
> > @@ -1824,14 +1833,14 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
> > * params are calculated
> > */
> > groups_per_line = DIV_ROUND_UP(dsc->slice_width, 3);
> > - dsc->slice_chunk_size = DIV_ROUND_UP(dsc->slice_width * dsc->bits_per_pixel, 8);
> > + dsc->slice_chunk_size = DIV_ROUND_UP(dsc->slice_width * bpp, 8);
>
> I'd still prefer if we can get closer to drm_dsc_compute_rc_parameters().
> The mentioned function has the following code:
>
> vdsc_cfg->slice_chunk_size = DIV_ROUND_UP(vdsc_cfg->slice_width *
>
> vdsc_cfg->bits_per_pixel,
> (8 * 16));

Fwiw this discussion happened in dsi_update_dsc_timing() where a similar
calculation was the sole user of bits_per_pixel. This function,
dsi_populate_dsc_params(), has more uses of bits_per_pixel so it made
more sense to compute and document this "discrepancy" up front.
drm_dsc_compute_rc_parameters() doesn't document where this "16" comes
from, unfortunately (requiring knowledge of the contents of the struct).

> In fact, could you please take a look if we can switch to using this
> function and drop our code?

There's alread a:

/* FIXME: need to call drm_dsc_compute_rc_parameters() so that rest of
* params are calculated
*/

And it was trivial to replace everything below that comment with this
function call; I have not checked the math in detail but it assigns
_every_ field that was also assigned here, and the resulting values
provide an identical DCS PPS (which I happened to be printing to compare
to downstream, leading to find all the issues solved in this series) and
working phone screen.

Makes me wonder why this wasn't caught in review and replaced from the
get-go...

Do you want me to do this in a v3, before applying this fractional-bits
fix? At that point this becomes the only user of bits_per_pixel:

dsc->initial_offset = 6144; /* Not bpp 12 */
if (bpp != 8)
dsc->initial_offset = 2048; /* bpp = 12 */

Note that intel_vdsc.c has the exact same code right where they fill
vdsc_cfg->initial_offset:

int bpp = vdsc_cfg->bits_per_pixel >> 4;

I'm inclined to leave this as it is.

- Marijn

2022-10-05 21:16:14

by Marijn Suijten

[permalink] [raw]
Subject: Re: [PATCH v2 5/7] drm/msm/dsi: Account for DSC's bits_per_pixel having 4 fractional bits

On 2022-10-05 22:58:48, Marijn Suijten wrote:
> On 2022-10-05 22:31:43, Dmitry Baryshkov wrote:
> > [..]
> > In fact, could you please take a look if we can switch to using this
> > function and drop our code?
>
> [..]
>
> Do you want me to do this in a v3, before applying this fractional-bits
> fix? [..]

One thing to note:

/* bpc 8 */
dsc->flatness_min_qp = 3;
dsc->flatness_max_qp = 12;
dsc->rc_quant_incr_limit0 = 11;
dsc->rc_quant_incr_limit1 = 11;
dsc->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC;

Here a bunch of properties are hardcoded, seemingly for bpc = 8.
mux_word_size is only ever read in drm_dsc_compute_rc_parameters() so
only becomes relevant _after_ the migration, and is currently dealt with
correctly by:

mux_words_size = 48; /* bpc == 8/10 */
if (dsc->bits_per_component == 12)
mux_words_size = 64;

Aside fixing that to assign these values (through the proper constants)
to dsc->mux_word_size, is it worth looking for the right parameters for
other bpc or return -EINVAL if bpc isn't 8, to uphold this comment until
support for other bpc is validated?

- Marijn

2022-10-05 21:19:55

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 5/7] drm/msm/dsi: Account for DSC's bits_per_pixel having 4 fractional bits

On 05/10/2022 23:58, Marijn Suijten wrote:
> On 2022-10-05 22:31:43, Dmitry Baryshkov wrote:
>> On Wed, 5 Oct 2022 at 21:17, Marijn Suijten
>> <[email protected]> wrote:
>>>
>>> drm_dsc_config's bits_per_pixel field holds a fractional value with 4
>>> bits, which all panel drivers should adhere to for
>>> drm_dsc_pps_payload_pack() to generate a valid payload. All code in the
>>> DSI driver here seems to assume that this field doesn't contain any
>>> fractional bits, hence resulting in the wrong values being computed.
>>> Since none of the calculations leave any room for fractional bits or
>>> seem to indicate any possible area of support, disallow such values
>>> altogether.
>>>
>>> Fixes: b9080324d6ca ("drm/msm/dsi: add support for dsc data")
>>> Signed-off-by: Marijn Suijten <[email protected]>
>>> ---
>>> drivers/gpu/drm/msm/dsi/dsi_host.c | 25 +++++++++++++++++--------
>>> 1 file changed, 17 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
>>> index f42794cdd4c1..4717d49d76be 100644
>>> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
>>> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
>>> @@ -33,7 +33,7 @@
>>>
>>> #define DSI_RESET_TOGGLE_DELAY_MS 20
>>>
>>> -static int dsi_populate_dsc_params(struct drm_dsc_config *dsc);
>>> +static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc);
>>>
>>> static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor)
>>> {
>>> @@ -908,6 +908,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
>>> u32 va_end = va_start + mode->vdisplay;
>>> u32 hdisplay = mode->hdisplay;
>>> u32 wc;
>>> + int ret;
>>>
>>> DBG("");
>>>
>>> @@ -943,7 +944,9 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
>>> /* we do the calculations for dsc parameters here so that
>>> * panel can use these parameters
>>> */
>>> - dsi_populate_dsc_params(dsc);
>>> + ret = dsi_populate_dsc_params(msm_host, dsc);
>>> + if (ret)
>>> + return;
>>>
>>> /* Divide the display by 3 but keep back/font porch and
>>> * pulse width same
>>> @@ -1769,7 +1772,7 @@ static char bpg_offset[DSC_NUM_BUF_RANGES] = {
>>> 2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12
>>> };
>>>
>>> -static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
>>> +static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc)
>>> {
>>> int mux_words_size;
>>> int groups_per_line, groups_total;
>>> @@ -1780,6 +1783,12 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
>>> int data;
>>> int final_value, final_scale;
>>> int i;
>>> + u16 bpp = dsc->bits_per_pixel >> 4;
>>> +
>>> + if (dsc->bits_per_pixel & 0xf) {
>>> + DRM_DEV_ERROR(&msm_host->pdev->dev, "DSI does not support fractional bits_per_pixel\n");
>>> + return -EINVAL;
>>> + }
>>>
>>> dsc->rc_model_size = 8192;
>>> dsc->first_line_bpg_offset = 12;
>>> @@ -1801,7 +1810,7 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
>>> }
>>>
>>> dsc->initial_offset = 6144; /* Not bpp 12 */
>>> - if (dsc->bits_per_pixel != 8)
>>> + if (bpp != 8)
>>> dsc->initial_offset = 2048; /* bpp = 12 */
>>>
>>> mux_words_size = 48; /* bpc == 8/10 */
>>> @@ -1824,14 +1833,14 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
>>> * params are calculated
>>> */
>>> groups_per_line = DIV_ROUND_UP(dsc->slice_width, 3);
>>> - dsc->slice_chunk_size = DIV_ROUND_UP(dsc->slice_width * dsc->bits_per_pixel, 8);
>>> + dsc->slice_chunk_size = DIV_ROUND_UP(dsc->slice_width * bpp, 8);
>>
>> I'd still prefer if we can get closer to drm_dsc_compute_rc_parameters().
>> The mentioned function has the following code:
>>
>> vdsc_cfg->slice_chunk_size = DIV_ROUND_UP(vdsc_cfg->slice_width *
>>
>> vdsc_cfg->bits_per_pixel,
>> (8 * 16));
>
> Fwiw this discussion happened in dsi_update_dsc_timing() where a similar
> calculation was the sole user of bits_per_pixel. This function,
> dsi_populate_dsc_params(), has more uses of bits_per_pixel so it made
> more sense to compute and document this "discrepancy" up front.
> drm_dsc_compute_rc_parameters() doesn't document where this "16" comes
> from, unfortunately (requiring knowledge of the contents of the struct).
>
>> In fact, could you please take a look if we can switch to using this
>> function and drop our code?
>
> There's alread a:
>
> /* FIXME: need to call drm_dsc_compute_rc_parameters() so that rest of
> * params are calculated
> */
>
> And it was trivial to replace everything below that comment with this
> function call; I have not checked the math in detail but it assigns
> _every_ field that was also assigned here, and the resulting values
> provide an identical DCS PPS (which I happened to be printing to compare
> to downstream, leading to find all the issues solved in this series) and
> working phone screen.
>
> Makes me wonder why this wasn't caught in review and replaced from the
> get-go...

Good question. Partially it was because everybody wanted to get DSC
support in to unblock other features. Thus DSC supporting code received
several bumps afterwards.

> Do you want me to do this in a v3, before applying this fractional-bits
> fix? At that point this becomes the only user of bits_per_pixel:

Yes, please. This sounds like a perfect solution.

>
> dsc->initial_offset = 6144; /* Not bpp 12 */
> if (bpp != 8)
> dsc->initial_offset = 2048; /* bpp = 12 */
>
> Note that intel_vdsc.c has the exact same code right where they fill
> vdsc_cfg->initial_offset:
>
> int bpp = vdsc_cfg->bits_per_pixel >> 4;
>
> I'm inclined to leave this as it is.
>
> - Marijn

--
With best wishes
Dmitry

2022-10-05 21:42:33

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 5/7] drm/msm/dsi: Account for DSC's bits_per_pixel having 4 fractional bits

On 06/10/2022 00:08, Marijn Suijten wrote:
> On 2022-10-05 22:58:48, Marijn Suijten wrote:
>> On 2022-10-05 22:31:43, Dmitry Baryshkov wrote:
>>> [..]
>>> In fact, could you please take a look if we can switch to using this
>>> function and drop our code?
>>
>> [..]
>>
>> Do you want me to do this in a v3, before applying this fractional-bits
>> fix? [..]
>
> One thing to note:
>
> /* bpc 8 */
> dsc->flatness_min_qp = 3;
> dsc->flatness_max_qp = 12;
> dsc->rc_quant_incr_limit0 = 11;
> dsc->rc_quant_incr_limit1 = 11;
> dsc->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC;
>
> Here a bunch of properties are hardcoded, seemingly for bpc = 8.
> mux_word_size is only ever read in drm_dsc_compute_rc_parameters() so
> only becomes relevant _after_ the migration, and is currently dealt with
> correctly by:
>
> mux_words_size = 48; /* bpc == 8/10 */
> if (dsc->bits_per_component == 12)
> mux_words_size = 64;
>
> Aside fixing that to assign these values (through the proper constants)
> to dsc->mux_word_size, is it worth looking for the right parameters for
> other bpc or return -EINVAL if bpc isn't 8, to uphold this comment until
> support for other bpc is validated?

I'd say, return -EINVAL or -EOPNOTSUPP for now, let's fix that later.
It's definitely a separate change. Let's wait for a device with such
panel to be able to test it.

--
With best wishes
Dmitry

2022-10-05 21:44:00

by Marijn Suijten

[permalink] [raw]
Subject: Re: [PATCH v2 5/7] drm/msm/dsi: Account for DSC's bits_per_pixel having 4 fractional bits

On 2022-10-06 00:11:06, Dmitry Baryshkov wrote:
> On 06/10/2022 00:08, Marijn Suijten wrote:
> > [..]
> > Aside fixing that to assign these values (through the proper constants)
> > to dsc->mux_word_size, is it worth looking for the right parameters for
> > other bpc or return -EINVAL if bpc isn't 8, to uphold this comment until
> > support for other bpc is validated?
>
> I'd say, return -EINVAL or -EOPNOTSUPP for now, let's fix that later.
> It's definitely a separate change. Let's wait for a device with such
> panel to be able to test it.

According to [1] these four fields specifically are different for other
BPC; I can add a -EOPNOTSUPP and DRM_DEV_ERROR requesting a test, or
insert the values; there's only 8BPC and 10BPC, no 12BPC.

Aside that we need a different initial_offset = 5632 for other bpp/bpc
pairs.

[1]: https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/DISPLAY.LA.2.0.r1-08000-WAIPIO.0/msm/sde_dsc_helper.c#L110-139

- Marijn

2022-10-05 21:50:26

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [PATCH v2 1/7] drm/msm/dsi: Remove useless math in DSC calculations



On 10/5/2022 11:16 AM, Marijn Suijten wrote:
> Multiplying a value by 2 and adding 1 to it always results in a value
> that is uneven, and that 1 gets truncated immediately when performing
> integer division by 2 again. There is no "rounding" possible here.
>
> After that target_bpp_x16 is used to store a multiplication of
> bits_per_pixel by 16 which is only ever read to immediately be divided
> by 16 again, and is elided in much the same way.
>
> Fixes: b9080324d6ca ("drm/msm/dsi: add support for dsc data")
> Signed-off-by: Marijn Suijten <[email protected]>
Reviewed-by: Abhinav Kumar <[email protected]>
> ---
> drivers/gpu/drm/msm/dsi/dsi_host.c | 10 +---------
> 1 file changed, 1 insertion(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index 8e4bc586c262..70077d1f0f21 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -1784,7 +1784,6 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
> int hrd_delay;
> int pre_num_extra_mux_bits, num_extra_mux_bits;
> int slice_bits;
> - int target_bpp_x16;
> int data;
> int final_value, final_scale;
> int i;
> @@ -1864,14 +1863,7 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
> data = 2048 * (dsc->rc_model_size - dsc->initial_offset + num_extra_mux_bits);
> dsc->slice_bpg_offset = DIV_ROUND_UP(data, groups_total);
>
> - /* bpp * 16 + 0.5 */
> - data = dsc->bits_per_pixel * 16;
> - data *= 2;
> - data++;
> - data /= 2;
> - target_bpp_x16 = data;
> -
> - data = (dsc->initial_xmit_delay * target_bpp_x16) / 16;
> + data = dsc->initial_xmit_delay * dsc->bits_per_pixel;
> final_value = dsc->rc_model_size - data + num_extra_mux_bits;
> dsc->final_offset = final_value;
>

2022-10-05 21:57:55

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [PATCH v2 4/7] drm/msm/dsi: Reuse earlier computed dsc->slice_chunk_size



On 10/5/2022 11:16 AM, Marijn Suijten wrote:
> dsi_populate_dsc_params() is called prior to dsi_update_dsc_timing() and
> already computes a value for slice_chunk_size, whose value doesn't need
> to be recomputed and re-set here.
>
> Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration")
> Signed-off-by: Marijn Suijten <[email protected]>
Reviewed-by: Abhinav Kumar <[email protected]>
> ---
> drivers/gpu/drm/msm/dsi/dsi_host.c | 9 ++-------
> 1 file changed, 2 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index 48c966375ffa..f42794cdd4c1 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -845,7 +845,6 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
> u32 reg, reg_ctrl, reg_ctrl2;
> u32 slice_per_intf, total_bytes_per_intf;
> u32 pkt_per_line;
> - u32 bytes_in_slice;
> u32 eol_byte_num;
>
> /* first calculate dsc parameters and then program
> @@ -860,11 +859,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
> if (slice_per_intf > dsc->slice_count)
> dsc->slice_count = 1;
>
> - bytes_in_slice = DIV_ROUND_UP(dsc->slice_width * dsc->bits_per_pixel, 8);
> -
> - dsc->slice_chunk_size = bytes_in_slice;
> -
> - total_bytes_per_intf = bytes_in_slice * slice_per_intf;
> + total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
>
> eol_byte_num = total_bytes_per_intf % 3;
> pkt_per_line = slice_per_intf / dsc->slice_count;
> @@ -890,7 +885,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
> reg_ctrl |= reg;
>
> reg_ctrl2 &= ~DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH__MASK;
> - reg_ctrl2 |= DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH(bytes_in_slice);
> + reg_ctrl2 |= DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH(dsc->slice_chunk_size);
>
> dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, reg_ctrl);
> dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, reg_ctrl2);

2022-10-05 21:58:11

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [PATCH v2 3/7] drm/msm/dsi: Use DIV_ROUND_UP instead of conditional increment on modulo



On 10/5/2022 11:16 AM, Marijn Suijten wrote:
> This exact same math is used to compute bytes_in_slice above in
> dsi_update_dsc_timing(), also used to fill slice_chunk_size.
>
> Fixes: b9080324d6ca ("drm/msm/dsi: add support for dsc data")
> Signed-off-by: Marijn Suijten <[email protected]>
Reviewed-by: Abhinav Kumar <[email protected]>
> ---
> drivers/gpu/drm/msm/dsi/dsi_host.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index c746ed5d61f9..48c966375ffa 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -1829,9 +1829,7 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc)
> * params are calculated
> */
> groups_per_line = DIV_ROUND_UP(dsc->slice_width, 3);
> - dsc->slice_chunk_size = dsc->slice_width * dsc->bits_per_pixel / 8;
> - if ((dsc->slice_width * dsc->bits_per_pixel) % 8)
> - dsc->slice_chunk_size++;
> + dsc->slice_chunk_size = DIV_ROUND_UP(dsc->slice_width * dsc->bits_per_pixel, 8);
>
> /* rbs-min */
> min_rate_buffer_size = dsc->rc_model_size - dsc->initial_offset +