We should be setting the drm_dp_aux_msg::reply field if a NACK or a
SHORT reply happens. Update the error bit handling logic in
ti_sn_aux_transfer() to handle these cases and notify upper layers that
such errors have happened. This helps the retry logic understand that a
timeout has happened, or to shorten the read length if the panel isn't
able to handle the longest read possible.

Cc: Douglas Anderson <diand...@chromium.org>
Cc: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Cc: Jonas Karlman <jo...@kwiboo.se>
Cc: Jernej Skrabec <jernej.skra...@siol.net>
Cc: Sean Paul <seanp...@chromium.org>
Signed-off-by: Stephen Boyd <swb...@chromium.org>
---
 drivers/gpu/drm/bridge/ti-sn65dsi86.c | 31 +++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c 
b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
index 6b6e98ca2881..19737bc01b8f 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
@@ -878,6 +878,7 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux,
        case DP_AUX_NATIVE_READ:
        case DP_AUX_I2C_READ:
                regmap_write(pdata->regmap, SN_AUX_CMD_REG, request_val);
+               msg->reply = 0; /* Assume it's good */
                break;
        default:
                return -EINVAL;
@@ -909,10 +910,32 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux,
        ret = regmap_read(pdata->regmap, SN_AUX_CMD_STATUS_REG, &val);
        if (ret)
                return ret;
-       else if ((val & AUX_IRQ_STATUS_NAT_I2C_FAIL)
-                || (val & AUX_IRQ_STATUS_AUX_RPLY_TOUT)
-                || (val & AUX_IRQ_STATUS_AUX_SHORT))
-               return -ENXIO;
+
+       if (val & AUX_IRQ_STATUS_AUX_RPLY_TOUT) {
+               /*
+                * The hardware tried the message seven times per the DP spec
+                * but it hit a timeout. We ignore defers here because they're
+                * handled in hardware.
+                */
+               return -ETIMEDOUT;
+       }
+       if (val & AUX_IRQ_STATUS_AUX_SHORT) {
+               ret = regmap_read(pdata->regmap, SN_AUX_LENGTH_REG, &len);
+               if (ret)
+                       return ret;
+       } else if (val & AUX_IRQ_STATUS_NAT_I2C_FAIL) {
+               switch (request) {
+               case DP_AUX_I2C_WRITE:
+               case DP_AUX_I2C_READ:
+                       msg->reply |= DP_AUX_I2C_REPLY_NACK;
+                       break;
+               case DP_AUX_NATIVE_READ:
+               case DP_AUX_NATIVE_WRITE:
+                       msg->reply |= DP_AUX_NATIVE_REPLY_NACK;
+                       break;
+               }
+               return 0;
+       }
 
        if (request == DP_AUX_NATIVE_WRITE || request == DP_AUX_I2C_WRITE ||
            len == 0)
-- 
Sent by a computer, using git, on the internet

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to