Needed for proper i2c over aux handling for certain
monitors and configurations (e.g., dp bridges or
adapters).

Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/radeon/atombios_dp.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/atombios_dp.c 
b/drivers/gpu/drm/radeon/atombios_dp.c
index 8b0ab17..f143128 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -143,6 +143,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan 
*chan,
 }

 #define HEADER_SIZE 4
+#define BARE_ADDRESS_SIZE 3

 static ssize_t
 radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
@@ -165,8 +166,12 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct 
drm_dp_aux_msg *msg)
        switch (msg->request & ~DP_AUX_I2C_MOT) {
        case DP_AUX_NATIVE_WRITE:
        case DP_AUX_I2C_WRITE:
+               /* handle bare */
                tx_size = HEADER_SIZE + msg->size;
-               tx_buf[3] |= tx_size << 4;
+               if (msg->flags & DRM_DP_AUX_MSG_FLAGS_BARE_ADDRESS)
+                       tx_buf[3] |= BARE_ADDRESS_SIZE << 4;
+               else
+                       tx_buf[3] |= tx_size << 4;
                memcpy(tx_buf + HEADER_SIZE, msg->buffer, msg->size);
                ret = radeon_process_aux_ch(chan,
                                            tx_buf, tx_size, NULL, 0, delay, 
&ack);
@@ -177,9 +182,15 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct 
drm_dp_aux_msg *msg)
        case DP_AUX_NATIVE_READ:
        case DP_AUX_I2C_READ:
                tx_size = HEADER_SIZE;
-               tx_buf[3] |= tx_size << 4;
+               if (msg->flags & DRM_DP_AUX_MSG_FLAGS_BARE_ADDRESS)
+                       tx_buf[3] |= BARE_ADDRESS_SIZE << 4;
+               else
+                       tx_buf[3] |= tx_size << 4;
                ret = radeon_process_aux_ch(chan,
                                            tx_buf, tx_size, msg->buffer, 
msg->size, delay, &ack);
+               /* sending just the address transfers 0 bytes */
+               if ((msg->flags & DRM_DP_AUX_MSG_FLAGS_BARE_ADDRESS) && (ret == 
0))
+                       ret++;
                break;
        default:
                ret = -EINVAL;
-- 
1.8.3.1

Reply via email to