lkml.org 
[lkml]   [2021]   [Jan]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 03/15] drm/vc4: hdmi: Fix register offset with longer CEC messages
    Date
    From: Dom Cobley <popcornmix@gmail.com>

    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")
    Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
    Signed-off-by: Dom Cobley <popcornmix@gmail.com>
    Signed-off-by: Maxime Ripard <maxime@cerno.tech>
    ---
    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 cb4594e7df6f..7945dbcee78c 100644
    --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
    +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
    @@ -1443,13 +1443,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;
    @@ -1542,11 +1549,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.29.2
    \
     
     \ /
      Last update: 2021-01-11 15:24    [W:5.273 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site