Skip to content

Commit 22a555e

Browse files
popcornmixgregkh
authored andcommitted
drm/vc4: hdmi: Fix register offset with longer CEC messages
[ Upstream commit 4a59ed5 ] The code prior to 311e305 ("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: 311e305 ("drm/vc4: hdmi: Implement a register layout abstraction") Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com> Signed-off-by: Dom Cobley <popcornmix@gmail.com> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Acked-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Tested-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Link: https://patchwork.freedesktop.org/patch/msgid/20210111142309.193441-4-maxime@cerno.tech (cherry picked from commit e9c9481) Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent e750620 commit 22a555e

1 file changed

Lines changed: 15 additions & 2 deletions

File tree

drivers/gpu/drm/vc4/vc4_hdmi.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,13 +1313,20 @@ static irqreturn_t vc4_cec_irq_handler_thread(int irq, void *priv)
13131313

13141314
static void vc4_cec_read_msg(struct vc4_hdmi *vc4_hdmi, u32 cntrl1)
13151315
{
1316+
struct drm_device *dev = vc4_hdmi->connector.dev;
13161317
struct cec_msg *msg = &vc4_hdmi->cec_rx_msg;
13171318
unsigned int i;
13181319

13191320
msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >>
13201321
VC4_HDMI_CEC_REC_WRD_CNT_SHIFT);
1322+
1323+
if (msg->len > 16) {
1324+
drm_err(dev, "Attempting to read too much data (%d)\n", msg->len);
1325+
return;
1326+
}
1327+
13211328
for (i = 0; i < msg->len; i += 4) {
1322-
u32 val = HDMI_READ(HDMI_CEC_RX_DATA_1 + i);
1329+
u32 val = HDMI_READ(HDMI_CEC_RX_DATA_1 + (i >> 2));
13231330

13241331
msg->msg[i] = val & 0xff;
13251332
msg->msg[i + 1] = (val >> 8) & 0xff;
@@ -1412,11 +1419,17 @@ static int vc4_hdmi_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
14121419
u32 signal_free_time, struct cec_msg *msg)
14131420
{
14141421
struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap);
1422+
struct drm_device *dev = vc4_hdmi->connector.dev;
14151423
u32 val;
14161424
unsigned int i;
14171425

1426+
if (msg->len > 16) {
1427+
drm_err(dev, "Attempting to transmit too much data (%d)\n", msg->len);
1428+
return -ENOMEM;
1429+
}
1430+
14181431
for (i = 0; i < msg->len; i += 4)
1419-
HDMI_WRITE(HDMI_CEC_TX_DATA_1 + i,
1432+
HDMI_WRITE(HDMI_CEC_TX_DATA_1 + (i >> 2),
14201433
(msg->msg[i]) |
14211434
(msg->msg[i + 1] << 8) |
14221435
(msg->msg[i + 2] << 16) |

0 commit comments

Comments
 (0)