Re: [PATCH v3 3/3] drm/bridge: parade-ps8640: Add support for AUX channel

From: Philip Chen
Date: Fri Sep 17 2021 - 18:55:55 EST


Hi

On Thu, Sep 16, 2021 at 1:31 PM Doug Anderson <dianders@xxxxxxxxxxxx> wrote:
>
> Hi,
>
> On Thu, Sep 16, 2021 at 1:15 PM Stephen Boyd <swboyd@xxxxxxxxxxxx> wrote:
> >
> > > > > + return ret;
> > > > > + }
> > > > > +
> > > > > + /* Assume it's good */
> > > > > + msg->reply = 0;
> > > > > +
> > > > > + addr_len[0] = msg->address & 0xff;
> > > > > + addr_len[1] = (msg->address >> 8) & 0xff;
> > > > > + addr_len[2] = ((msg->request << 4) & SWAUX_CMD_MASK) |
> > > > > + ((msg->address >> 16) & SWAUX_ADDR_19_16_MASK);
> > > >
> > > > It really feels like this out to be possible with some sort of
> > > > cpu_to_le32() API. We're shoving msg->address into 3 bytes and then
> > > > adding in the request and some length. So we could do something like:
> > > >
> > > > u32 addr_len;
> > > >
> > > > addr_len = FIELD_PREP(SWAUX_ADDR_MASK, msg->address);
> > > > addr_len |= FIELD_PREP(SWAUX_CMD_MASK, msg->request);
> > > > if (len)
> > > > addr_len |= FIELD_PREP(LEN_MASK, len - 1);
> > > > else
> > > > addr_len |= FIELD_PREP(LEN_MASK, SWAUX_NO_PAYLOAD );
> > > >
> > > > cpu_to_le32s(&addr_len);
> > > >
> > > > regmap_bulk_write(map, PAGE0_SWAUX_ADDR_7_0, &addr_len, sizeof(addr_len));
> > >
> > > You're arguing that your version of the code is more efficient? Easier
> > > to understand? Something else? To me, Philip's initial version is
> > > crystal clear and easy to map to the bridge datasheet but I need to
> > > think more to confirm that your version is right. Thinking is hard and
> > > I like to avoid it when possible.
> > >
> > > In any case, it's definitely bikeshedding and I'll yield if everyone
> > > likes the other version better. ;-)
> >
> > Yeah it's bikeshedding. I don't really care about this either but I find
> > it easier to read when the assignment isn't wrapped across multiple
> > lines. If the buffer approach is preferable then maybe use the address
> > macros to clarify which register is being set?
> >
> > unsigned int base = PAGE0_SWAUX_ADDR_7_0;
> >
> > addr_len[PAGE0_SWAUX_ADDR_7_0 - base] = msg->address;
> > addr_len[PAGE0_SWAUX_ADDR_15_8 - base] = msg->address >> 8;
> > addr_len[PAGE0_SWAUX_ADDR_23_16 - base] = msg->address >> 16;
> > addr_len[PAGE0_SWAUX_ADDR_23_16 - base] |= msg->request << 4;
>
> Sure, this looks nice to me. :-)
Thanks.
Implemented the fix in v4.
PTAL.

>
>
> > > > > + return ret;
> > > > > + }
> > > > > +
> > > > > + switch (data & SWAUX_STATUS_MASK) {
> > > > > + /* Ignore the DEFER cases as they are already handled in hardware */
> > > > > + case SWAUX_STATUS_NACK:
> > > > > + case SWAUX_STATUS_I2C_NACK:
> > > > > + /*
> > > > > + * The programming guide is not clear about whether a I2C NACK
> > > > > + * would trigger SWAUX_STATUS_NACK or SWAUX_STATUS_I2C_NACK. So
> > > > > + * we handle both cases together.
> > > > > + */
> > > > > + if (is_native_aux)
> > > > > + msg->reply |= DP_AUX_NATIVE_REPLY_NACK;
> > > > > + else
> > > > > + msg->reply |= DP_AUX_I2C_REPLY_NACK;
> > > > > +
> > > > > + len = data & SWAUX_M_MASK;
> > > > > + return len;
> > > >
> > > > Why no 'return data & SWAUX_M_MASK;' and skip the assignment?
> > >
> > > Actually, I think it's the "return" that's a bug, isn't it? If we're
> > > doing a "read" and we're returning a positive number of bytes then we
> > > need to actually _read_ them. Reading happens below, doesn't it?
> > >
> >
> > Oh I missed that. We're still supposed to return data to upper
> > layers on a NACKed read?
>
> It seems highly likely not to matter in practice, but:
>
> * The docs from parade clearly state that when a NAK is returned that
> the number of bytes transferred before the NAK will be provided to us.
>
> * The i2c interface specifies NAK not as a return code but as a bit in
> the "reply". That presumably is to let us return the number of bytes
> transferred before the NAK to the next level up.
>
> * If we're returning the number of bytes and it's a read then we'd
> better return the data too!
>
> It looks like we handled this OK in the TI bridge driver. From reading
> the TI docs we'll get both AUX_IRQ_STATUS_AUX_SHORT and
> AUX_IRQ_STATUS_NAT_I2C_FAIL in the case of a partial transfer and so
> we'll do the right thing.

Thanks for catching the bug.
In v4, I made SWAUX_STATUS_I2C_NACK fall through to SWAUX_STATUS_ACKM and
store the number of read/written bytes in len w/o returning immediately.
PTAL.

>
> -Doug