Hi Dom & Maxime On Thu, 10 Dec 2020 at 13:46, Maxime Ripard <maxime@xxxxxxxxxx> wrote: > > From: Dom Cobley <popcornmix@xxxxxxxxx> > > The code prior to 311e305fdb4e ("drm/vc4: hdmi: Implement a register > layout abstraction") was relying on the fact that the register offset > was incremented by 4 for each readl call. That worked since the register > width is 4 bytes. > > However, since that commit the HDMI_READ macro is now taking an enum, > and the offset doesn't increment by 4 but 1 now. Divide the index by 4 > to fix this. > > Fixes: 311e305fdb4e ("drm/vc4: hdmi: Implement a register layout abstraction") > Signed-off-by: Dom Cobley <popcornmix@xxxxxxxxx> > Signed-off-by: Maxime Ripard <maxime@xxxxxxxxxx> Reviewed-by: Dave Stevenson <dave.stevenson@xxxxxxxxxxxxxxx> > --- > drivers/gpu/drm/vc4/vc4_hdmi.c | 17 +++++++++++++++-- > 1 file changed, 15 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c > index 3df1747dd917..28b78ea885ea 100644 > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c > @@ -1434,13 +1434,20 @@ static irqreturn_t vc4_cec_irq_handler_thread(int irq, void *priv) > > static void vc4_cec_read_msg(struct vc4_hdmi *vc4_hdmi, u32 cntrl1) > { > + struct drm_device *dev = vc4_hdmi->connector.dev; > struct cec_msg *msg = &vc4_hdmi->cec_rx_msg; > unsigned int i; > > msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >> > VC4_HDMI_CEC_REC_WRD_CNT_SHIFT); > + > + if (msg->len > 16) { > + drm_err(dev, "Attempting to read too much data (%d)\n", msg->len); > + return; > + } > + > for (i = 0; i < msg->len; i += 4) { > - u32 val = HDMI_READ(HDMI_CEC_RX_DATA_1 + i); > + u32 val = HDMI_READ(HDMI_CEC_RX_DATA_1 + (i >> 2)); > > msg->msg[i] = val & 0xff; > msg->msg[i + 1] = (val >> 8) & 0xff; > @@ -1533,11 +1540,17 @@ static int vc4_hdmi_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, > u32 signal_free_time, struct cec_msg *msg) > { > struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap); > + struct drm_device *dev = vc4_hdmi->connector.dev; > u32 val; > unsigned int i; > > + if (msg->len > 16) { > + drm_err(dev, "Attempting to transmit too much data (%d)\n", msg->len); > + return -ENOMEM; > + } > + > for (i = 0; i < msg->len; i += 4) > - HDMI_WRITE(HDMI_CEC_TX_DATA_1 + i, > + HDMI_WRITE(HDMI_CEC_TX_DATA_1 + (i >> 2), > (msg->msg[i]) | > (msg->msg[i + 1] << 8) | > (msg->msg[i + 2] << 16) | > -- > 2.28.0 >