@@ -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;
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@amd.com> --- drivers/gpu/drm/radeon/atombios_dp.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)