On 07.06.2019 06:45, Andrey Smirnov wrote: > Transfer size of zero means a request to do an address-only > transfer. Since the HW support this, we probably shouldn't be just > ignoring such requests. While at it allow DP_AUX_I2C_MOT flag to pass > through, since it is supported by the HW as well. > > Signed-off-by: Andrey Smirnov <andrew.smirnov@xxxxxxxxx> Reviewed-by: Andrzej Hajda <a.hajda@xxxxxxxxxxx> -- Regards Andrzej > Cc: Andrzej Hajda <a.hajda@xxxxxxxxxxx> > Cc: Laurent Pinchart <Laurent.pinchart@xxxxxxxxxxxxxxxx> > Cc: Tomi Valkeinen <tomi.valkeinen@xxxxxx> > Cc: Andrey Gusakov <andrey.gusakov@xxxxxxxxxxxxxxxxxx> > Cc: Philipp Zabel <p.zabel@xxxxxxxxxxxxxx> > Cc: Cory Tusar <cory.tusar@xxxxxxxx> > Cc: Chris Healy <cphealy@xxxxxxxxx> > Cc: Lucas Stach <l.stach@xxxxxxxxxxxxxx> > Cc: dri-devel@xxxxxxxxxxxxxxxxxxxxx > Cc: linux-kernel@xxxxxxxxxxxxxxx > --- > drivers/gpu/drm/bridge/tc358767.c | 30 +++++++++++++++++++++++------- > 1 file changed, 23 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c > index 7d0fbb12195b..4bb9b15e1324 100644 > --- a/drivers/gpu/drm/bridge/tc358767.c > +++ b/drivers/gpu/drm/bridge/tc358767.c > @@ -145,6 +145,8 @@ > > /* AUX channel */ > #define DP0_AUXCFG0 0x0660 > +#define DP0_AUXCFG0_BSIZE GENMASK(11, 8) > +#define DP0_AUXCFG0_ADDR_ONLY BIT(4) > #define DP0_AUXCFG1 0x0664 > #define AUX_RX_FILTER_EN BIT(16) > > @@ -327,6 +329,18 @@ static int tc_aux_read_data(struct tc_data *tc, void *data, size_t size) > return size; > } > > +static u32 tc_auxcfg0(struct drm_dp_aux_msg *msg, size_t size) > +{ > + u32 auxcfg0 = msg->request; > + > + if (size) > + auxcfg0 |= FIELD_PREP(DP0_AUXCFG0_BSIZE, size - 1); > + else > + auxcfg0 |= DP0_AUXCFG0_ADDR_ONLY; > + > + return auxcfg0; > +} > + > static ssize_t tc_aux_transfer(struct drm_dp_aux *aux, > struct drm_dp_aux_msg *msg) > { > @@ -336,9 +350,6 @@ static ssize_t tc_aux_transfer(struct drm_dp_aux *aux, > u32 auxstatus; > int ret; > > - if (size == 0) > - return 0; > - > ret = tc_aux_wait_busy(tc, 100); > if (ret) > return ret; > @@ -362,8 +373,7 @@ static ssize_t tc_aux_transfer(struct drm_dp_aux *aux, > if (ret) > return ret; > /* Start transfer */ > - ret = regmap_write(tc->regmap, DP0_AUXCFG0, > - ((size - 1) << 8) | request); > + ret = regmap_write(tc->regmap, DP0_AUXCFG0, tc_auxcfg0(msg, size)); > if (ret) > return ret; > > @@ -377,8 +387,14 @@ static ssize_t tc_aux_transfer(struct drm_dp_aux *aux, > > if (auxstatus & AUX_TIMEOUT) > return -ETIMEDOUT; > - > - size = FIELD_GET(AUX_BYTES, auxstatus); > + /* > + * For some reason address-only DP_AUX_I2C_WRITE (MOT), still > + * reports 1 byte transferred in its status. To deal we that > + * we ignore aux_bytes field if we know that this was an > + * address-only transfer > + */ > + if (size) > + size = FIELD_GET(AUX_BYTES, auxstatus); > msg->reply = FIELD_GET(AUX_STATUS, auxstatus); > > switch (request) { _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel