struct drm_dp_aux_msg *msg)
{
struct ti_sn_bridge *pdata = aux_to_ti_sn_bridge(aux);
- u32 request = msg->request & ~DP_AUX_I2C_MOT;
+ u32 request = msg->request & ~(DP_AUX_I2C_MOT | DP_AUX_I2C_WRITE_STATUS_UPDATE);
u32 request_val = AUX_CMD_REQ(msg->request);
u8 *buf = msg->buffer;
unsigned int len = msg->size;
case DP_AUX_NATIVE_READ:
case DP_AUX_I2C_READ:
regmap_write(pdata->regmap, SN_AUX_CMD_REG, request_val);
+ /* Assume it's good */
+ msg->reply = 0;
break;
default:
return -EINVAL;
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)