0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <drm/radeon_drm.h>
0026 #include "radeon.h"
0027 #include "nid.h"
0028
0029 #define AUX_RX_ERROR_FLAGS (AUX_SW_RX_OVERFLOW | \
0030 AUX_SW_RX_HPD_DISCON | \
0031 AUX_SW_RX_PARTIAL_BYTE | \
0032 AUX_SW_NON_AUX_MODE | \
0033 AUX_SW_RX_SYNC_INVALID_L | \
0034 AUX_SW_RX_SYNC_INVALID_H | \
0035 AUX_SW_RX_INVALID_START | \
0036 AUX_SW_RX_RECV_NO_DET | \
0037 AUX_SW_RX_RECV_INVALID_H | \
0038 AUX_SW_RX_RECV_INVALID_V)
0039
0040 #define AUX_SW_REPLY_GET_BYTE_COUNT(x) (((x) >> 24) & 0x1f)
0041
0042 #define BARE_ADDRESS_SIZE 3
0043
0044 static const u32 aux_offset[] =
0045 {
0046 0x6200 - 0x6200,
0047 0x6250 - 0x6200,
0048 0x62a0 - 0x6200,
0049 0x6300 - 0x6200,
0050 0x6350 - 0x6200,
0051 0x63a0 - 0x6200,
0052 };
0053
0054 ssize_t
0055 radeon_dp_aux_transfer_native(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
0056 {
0057 struct radeon_i2c_chan *chan =
0058 container_of(aux, struct radeon_i2c_chan, aux);
0059 struct drm_device *dev = chan->dev;
0060 struct radeon_device *rdev = dev->dev_private;
0061 int ret = 0, i;
0062 uint32_t tmp, ack = 0;
0063 int instance = chan->rec.i2c_id & 0xf;
0064 u8 byte;
0065 u8 *buf = msg->buffer;
0066 int retry_count = 0;
0067 int bytes;
0068 int msize;
0069 bool is_write = false;
0070
0071 if (WARN_ON(msg->size > 16))
0072 return -E2BIG;
0073
0074 switch (msg->request & ~DP_AUX_I2C_MOT) {
0075 case DP_AUX_NATIVE_WRITE:
0076 case DP_AUX_I2C_WRITE:
0077 is_write = true;
0078 break;
0079 case DP_AUX_NATIVE_READ:
0080 case DP_AUX_I2C_READ:
0081 break;
0082 default:
0083 return -EINVAL;
0084 }
0085
0086
0087 msize = 0;
0088 bytes = BARE_ADDRESS_SIZE;
0089 if (msg->size) {
0090 msize = msg->size - 1;
0091 bytes++;
0092 if (is_write)
0093 bytes += msg->size;
0094 }
0095
0096 mutex_lock(&chan->mutex);
0097
0098
0099 tmp = RREG32(chan->rec.mask_clk_reg);
0100 tmp |= (1 << 16);
0101 WREG32(chan->rec.mask_clk_reg, tmp);
0102
0103
0104 tmp = RREG32(AUX_CONTROL + aux_offset[instance]);
0105
0106 tmp &= AUX_HPD_SEL(0x7);
0107 tmp |= AUX_HPD_SEL(chan->rec.hpd);
0108 tmp |= AUX_EN | AUX_LS_READ_EN;
0109
0110 WREG32(AUX_CONTROL + aux_offset[instance], tmp);
0111
0112
0113 WREG32(AUX_SW_CONTROL + aux_offset[instance],
0114 AUX_SW_WR_BYTES(bytes));
0115 WREG32(AUX_SW_CONTROL + aux_offset[instance],
0116 AUX_SW_WR_BYTES(bytes));
0117
0118
0119
0120 byte = (msg->request << 4) | ((msg->address >> 16) & 0xf);
0121 WREG32(AUX_SW_DATA + aux_offset[instance],
0122 AUX_SW_DATA_MASK(byte) | AUX_SW_AUTOINCREMENT_DISABLE);
0123
0124 byte = (msg->address >> 8) & 0xff;
0125 WREG32(AUX_SW_DATA + aux_offset[instance],
0126 AUX_SW_DATA_MASK(byte));
0127
0128 byte = msg->address & 0xff;
0129 WREG32(AUX_SW_DATA + aux_offset[instance],
0130 AUX_SW_DATA_MASK(byte));
0131
0132 byte = msize;
0133 WREG32(AUX_SW_DATA + aux_offset[instance],
0134 AUX_SW_DATA_MASK(byte));
0135
0136
0137 if (is_write) {
0138 for (i = 0; i < msg->size; i++) {
0139 WREG32(AUX_SW_DATA + aux_offset[instance],
0140 AUX_SW_DATA_MASK(buf[i]));
0141 }
0142 }
0143
0144
0145 WREG32(AUX_SW_INTERRUPT_CONTROL + aux_offset[instance], AUX_SW_DONE_ACK);
0146
0147
0148 WREG32(AUX_SW_CONTROL + aux_offset[instance],
0149 AUX_SW_WR_BYTES(bytes) | AUX_SW_GO);
0150
0151
0152 do {
0153 tmp = RREG32(AUX_SW_STATUS + aux_offset[instance]);
0154 if (tmp & AUX_SW_DONE) {
0155 break;
0156 }
0157 usleep_range(100, 200);
0158 } while (retry_count++ < 1000);
0159
0160 if (retry_count >= 1000) {
0161 DRM_ERROR("auxch hw never signalled completion, error %08x\n", tmp);
0162 ret = -EIO;
0163 goto done;
0164 }
0165
0166 if (tmp & AUX_SW_RX_TIMEOUT) {
0167 ret = -ETIMEDOUT;
0168 goto done;
0169 }
0170 if (tmp & AUX_RX_ERROR_FLAGS) {
0171 DRM_DEBUG_KMS_RATELIMITED("dp_aux_ch flags not zero: %08x\n",
0172 tmp);
0173 ret = -EIO;
0174 goto done;
0175 }
0176
0177 bytes = AUX_SW_REPLY_GET_BYTE_COUNT(tmp);
0178 if (bytes) {
0179 WREG32(AUX_SW_DATA + aux_offset[instance],
0180 AUX_SW_DATA_RW | AUX_SW_AUTOINCREMENT_DISABLE);
0181
0182 tmp = RREG32(AUX_SW_DATA + aux_offset[instance]);
0183 ack = (tmp >> 8) & 0xff;
0184
0185 for (i = 0; i < bytes - 1; i++) {
0186 tmp = RREG32(AUX_SW_DATA + aux_offset[instance]);
0187 if (buf)
0188 buf[i] = (tmp >> 8) & 0xff;
0189 }
0190 if (buf)
0191 ret = bytes - 1;
0192 }
0193
0194 WREG32(AUX_SW_INTERRUPT_CONTROL + aux_offset[instance], AUX_SW_DONE_ACK);
0195
0196 if (is_write)
0197 ret = msg->size;
0198 done:
0199 mutex_unlock(&chan->mutex);
0200
0201 if (ret >= 0)
0202 msg->reply = ack >> 4;
0203 return ret;
0204 }