Message ID | 20210305163853.66157-1-carsten.haitzler@foss.arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/komeda: Fix off-by-1 when with readback conn due to rounding | expand |
Hi Carsten, (+James for komeda) Thanks for typing this up. On Fri, Mar 05, 2021 at 04:38:53PM +0000, carsten.haitzler@foss.arm.com wrote: > From: Carsten Haitzler <carsten.haitzler@arm.com> > > When setting up a readback conenctor that writes data back to memory s/readback conenctor/writeback connector/ (similar in the subject) > rather than to an actual output device (HDMI etc.), rounding was ses s/ses/set/ > to round-down. As the DPU uses a higher internal number of bits when "round-down" isn't really accurate - the rounding mode "rounds" based on the most-significant discarded bit - so can round-up too. Come to think of it, I can't explain 0xff becoming 0xfe, but still, truncation is likely fine. > generating a color value, this round-down back to 8bit ended up with > everything being off-by one. e.g. #ffffff became #fefefe. This sets > rounding to "round" so things end up correct by turning on the round > flag (LW_TRC). LW_TRC is the truncation flag. 0: Round, 1: Truncate > > Signed-off-by: Carsten Haitzler <carsten.haitzler@arm.com> > --- > drivers/gpu/drm/arm/display/komeda/d71/d71_component.c | 6 +++++- > drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h | 1 + > 2 files changed, 6 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c > index 8a02ade369db..d551e79fa0f1 100644 > --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c > +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c > @@ -468,7 +468,11 @@ static void d71_wb_layer_update(struct komeda_component *c, > struct komeda_layer_state *st = to_layer_st(state); > struct drm_connector_state *conn_st = state->wb_conn->state; > struct komeda_fb *kfb = to_kfb(conn_st->writeback_job->fb); > - u32 ctrl = L_EN | LW_OFM, mask = L_EN | LW_OFM | LW_TBU_EN; > + /* LW_TRC sets rounding to round not truncate which is needed for > + * the output of writeback to match the input in the most common > + * use cases like RGB888 -> RGB888, so set this bit by default */ /* * Comment style should be like this */ Same as above though - your description is inverted. By setting the LW_TRC bit, you're forcing the hardware to truncate instead of round. > + u32 ctrl = L_EN | LW_OFM | LW_TRC; > + u32 mask = L_EN | LW_OFM | LW_TBU_EN | LW_TRC; Really nitpicking, but I think it'd be good to keep these in the same order as the bits in the register: L_EN | LW_TRC | LW_OFM | LW_TBU_EN Cheers, -Brian > u32 __iomem *reg = c->reg; > > d71_layer_update_fb(c, kfb, st->addr); > diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h b/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h > index e80172a0b320..a8036689d721 100644 > --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h > +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h > @@ -321,6 +321,7 @@ > #define LAYER_WR_FORMAT 0x0D8 > > /* Layer_WR control bits */ > +#define LW_TRC BIT(1) > #define LW_OFM BIT(4) > #define LW_LALPHA(x) (((x) & 0xFF) << 8) > #define LW_A_WCACHE(x) (((x) & 0xF) << 28) > -- > 2.30.0 > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel
On 3/9/21 11:36 AM, Brian Starkey wrote: > Hi Carsten, (+James for komeda) > > Thanks for typing this up. > > On Fri, Mar 05, 2021 at 04:38:53PM +0000, carsten.haitzler@foss.arm.com wrote: >> From: Carsten Haitzler <carsten.haitzler@arm.com> >> >> When setting up a readback conenctor that writes data back to memory > > s/readback conenctor/writeback connector/ (similar in the subject) > >> rather than to an actual output device (HDMI etc.), rounding was ses > > s/ses/set/ I swear I re-read the log text... I must be auto-correcting in my head as I read. :) >> to round-down. As the DPU uses a higher internal number of bits when > > "round-down" isn't really accurate - the rounding mode "rounds" based > on the most-significant discarded bit - so can round-up too. > > Come to think of it, I can't explain 0xff becoming 0xfe, but still, > truncation is likely fine. Actually it was the other way - I mixed up the src/dest, but TRC does fix it which is the important bit. >> generating a color value, this round-down back to 8bit ended up with >> everything being off-by one. e.g. #ffffff became #fefefe. This sets >> rounding to "round" so things end up correct by turning on the round >> flag (LW_TRC). > > LW_TRC is the truncation flag. 0: Round, 1: Truncate > >> >> Signed-off-by: Carsten Haitzler <carsten.haitzler@arm.com> >> --- >> drivers/gpu/drm/arm/display/komeda/d71/d71_component.c | 6 +++++- >> drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h | 1 + >> 2 files changed, 6 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c >> index 8a02ade369db..d551e79fa0f1 100644 >> --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c >> +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c >> @@ -468,7 +468,11 @@ static void d71_wb_layer_update(struct komeda_component *c, >> struct komeda_layer_state *st = to_layer_st(state); >> struct drm_connector_state *conn_st = state->wb_conn->state; >> struct komeda_fb *kfb = to_kfb(conn_st->writeback_job->fb); >> - u32 ctrl = L_EN | LW_OFM, mask = L_EN | LW_OFM | LW_TBU_EN; >> + /* LW_TRC sets rounding to round not truncate which is needed for >> + * the output of writeback to match the input in the most common >> + * use cases like RGB888 -> RGB888, so set this bit by default */ > > /* > * Comment style should be like this > */ > > Same as above though - your description is inverted. By setting the > LW_TRC bit, you're forcing the hardware to truncate instead of round. Yeah - inverted. But the source does have mixed comment styles with some /* * xxxx */ and some /* xxxx */ and some /* xxxx */ with the last 2 most common. >> + u32 ctrl = L_EN | LW_OFM | LW_TRC; >> + u32 mask = L_EN | LW_OFM | LW_TBU_EN | LW_TRC; > > Really nitpicking, but I think it'd be good to keep these in the same > order as the bits in the register: L_EN | LW_TRC | LW_OFM | LW_TBU_EN I can do that. I'll send another with the above. > Cheers, > -Brian > >> u32 __iomem *reg = c->reg; >> >> d71_layer_update_fb(c, kfb, st->addr); >> diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h b/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h >> index e80172a0b320..a8036689d721 100644 >> --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h >> +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h >> @@ -321,6 +321,7 @@ >> #define LAYER_WR_FORMAT 0x0D8 >> >> /* Layer_WR control bits */ >> +#define LW_TRC BIT(1) >> #define LW_OFM BIT(4) >> #define LW_LALPHA(x) (((x) & 0xFF) << 8) >> #define LW_A_WCACHE(x) (((x) & 0xF) << 28) >> -- >> 2.30.0 >> >> _______________________________________________ >> dri-devel mailing list >> dri-devel@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/dri-devel
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c index 8a02ade369db..d551e79fa0f1 100644 --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c @@ -468,7 +468,11 @@ static void d71_wb_layer_update(struct komeda_component *c, struct komeda_layer_state *st = to_layer_st(state); struct drm_connector_state *conn_st = state->wb_conn->state; struct komeda_fb *kfb = to_kfb(conn_st->writeback_job->fb); - u32 ctrl = L_EN | LW_OFM, mask = L_EN | LW_OFM | LW_TBU_EN; + /* LW_TRC sets rounding to round not truncate which is needed for + * the output of writeback to match the input in the most common + * use cases like RGB888 -> RGB888, so set this bit by default */ + u32 ctrl = L_EN | LW_OFM | LW_TRC; + u32 mask = L_EN | LW_OFM | LW_TBU_EN | LW_TRC; u32 __iomem *reg = c->reg; d71_layer_update_fb(c, kfb, st->addr); diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h b/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h index e80172a0b320..a8036689d721 100644 --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h @@ -321,6 +321,7 @@ #define LAYER_WR_FORMAT 0x0D8 /* Layer_WR control bits */ +#define LW_TRC BIT(1) #define LW_OFM BIT(4) #define LW_LALPHA(x) (((x) & 0xFF) << 8) #define LW_A_WCACHE(x) (((x) & 0xF) << 28)