0001
0002
0003
0004
0005
0006 #include <linux/delay.h>
0007 #include <drm/drm_print.h>
0008
0009 #include "dp_reg.h"
0010 #include "dp_aux.h"
0011
0012 enum msm_dp_aux_err {
0013 DP_AUX_ERR_NONE,
0014 DP_AUX_ERR_ADDR,
0015 DP_AUX_ERR_TOUT,
0016 DP_AUX_ERR_NACK,
0017 DP_AUX_ERR_DEFER,
0018 DP_AUX_ERR_NACK_DEFER,
0019 DP_AUX_ERR_PHY,
0020 };
0021
0022 struct dp_aux_private {
0023 struct device *dev;
0024 struct dp_catalog *catalog;
0025
0026 struct mutex mutex;
0027 struct completion comp;
0028
0029 enum msm_dp_aux_err aux_error_num;
0030 u32 retry_cnt;
0031 bool cmd_busy;
0032 bool native;
0033 bool read;
0034 bool no_send_addr;
0035 bool no_send_stop;
0036 bool initted;
0037 bool is_edp;
0038 u32 offset;
0039 u32 segment;
0040
0041 struct drm_dp_aux dp_aux;
0042 };
0043
0044 #define MAX_AUX_RETRIES 5
0045
0046 static ssize_t dp_aux_write(struct dp_aux_private *aux,
0047 struct drm_dp_aux_msg *msg)
0048 {
0049 u8 data[4];
0050 u32 reg;
0051 ssize_t len;
0052 u8 *msgdata = msg->buffer;
0053 int const AUX_CMD_FIFO_LEN = 128;
0054 int i = 0;
0055
0056 if (aux->read)
0057 len = 0;
0058 else
0059 len = msg->size;
0060
0061
0062
0063
0064
0065 if (len > AUX_CMD_FIFO_LEN - 4) {
0066 DRM_ERROR("buf size greater than allowed size of 128 bytes\n");
0067 return -EINVAL;
0068 }
0069
0070
0071 data[0] = (msg->address >> 16) & 0xf;
0072 if (aux->read)
0073 data[0] |= BIT(4);
0074
0075 data[1] = msg->address >> 8;
0076 data[2] = msg->address;
0077 data[3] = msg->size - 1;
0078
0079 for (i = 0; i < len + 4; i++) {
0080 reg = (i < 4) ? data[i] : msgdata[i - 4];
0081 reg <<= DP_AUX_DATA_OFFSET;
0082 reg &= DP_AUX_DATA_MASK;
0083 reg |= DP_AUX_DATA_WRITE;
0084
0085 if (i == 0)
0086 reg |= DP_AUX_DATA_INDEX_WRITE;
0087 aux->catalog->aux_data = reg;
0088 dp_catalog_aux_write_data(aux->catalog);
0089 }
0090
0091 dp_catalog_aux_clear_trans(aux->catalog, false);
0092 dp_catalog_aux_clear_hw_interrupts(aux->catalog);
0093
0094 reg = 0;
0095 if (!aux->native) {
0096 reg |= DP_AUX_TRANS_CTRL_I2C;
0097
0098 if (aux->no_send_addr)
0099 reg |= DP_AUX_TRANS_CTRL_NO_SEND_ADDR;
0100
0101 if (aux->no_send_stop)
0102 reg |= DP_AUX_TRANS_CTRL_NO_SEND_STOP;
0103 }
0104
0105 reg |= DP_AUX_TRANS_CTRL_GO;
0106 aux->catalog->aux_data = reg;
0107 dp_catalog_aux_write_trans(aux->catalog);
0108
0109 return len;
0110 }
0111
0112 static ssize_t dp_aux_cmd_fifo_tx(struct dp_aux_private *aux,
0113 struct drm_dp_aux_msg *msg)
0114 {
0115 ssize_t ret;
0116 unsigned long time_left;
0117
0118 reinit_completion(&aux->comp);
0119
0120 ret = dp_aux_write(aux, msg);
0121 if (ret < 0)
0122 return ret;
0123
0124 time_left = wait_for_completion_timeout(&aux->comp,
0125 msecs_to_jiffies(250));
0126 if (!time_left)
0127 return -ETIMEDOUT;
0128
0129 return ret;
0130 }
0131
0132 static ssize_t dp_aux_cmd_fifo_rx(struct dp_aux_private *aux,
0133 struct drm_dp_aux_msg *msg)
0134 {
0135 u32 data;
0136 u8 *dp;
0137 u32 i, actual_i;
0138 u32 len = msg->size;
0139
0140 dp_catalog_aux_clear_trans(aux->catalog, true);
0141
0142 data = DP_AUX_DATA_INDEX_WRITE;
0143 data |= DP_AUX_DATA_READ;
0144
0145 aux->catalog->aux_data = data;
0146 dp_catalog_aux_write_data(aux->catalog);
0147
0148 dp = msg->buffer;
0149
0150
0151 data = dp_catalog_aux_read_data(aux->catalog);
0152
0153 for (i = 0; i < len; i++) {
0154 data = dp_catalog_aux_read_data(aux->catalog);
0155 *dp++ = (u8)((data >> DP_AUX_DATA_OFFSET) & 0xff);
0156
0157 actual_i = (data >> DP_AUX_DATA_INDEX_OFFSET) & 0xFF;
0158 if (i != actual_i)
0159 break;
0160 }
0161
0162 return i;
0163 }
0164
0165 static void dp_aux_native_handler(struct dp_aux_private *aux, u32 isr)
0166 {
0167 if (isr & DP_INTR_AUX_I2C_DONE)
0168 aux->aux_error_num = DP_AUX_ERR_NONE;
0169 else if (isr & DP_INTR_WRONG_ADDR)
0170 aux->aux_error_num = DP_AUX_ERR_ADDR;
0171 else if (isr & DP_INTR_TIMEOUT)
0172 aux->aux_error_num = DP_AUX_ERR_TOUT;
0173 if (isr & DP_INTR_NACK_DEFER)
0174 aux->aux_error_num = DP_AUX_ERR_NACK;
0175 if (isr & DP_INTR_AUX_ERROR) {
0176 aux->aux_error_num = DP_AUX_ERR_PHY;
0177 dp_catalog_aux_clear_hw_interrupts(aux->catalog);
0178 }
0179 }
0180
0181 static void dp_aux_i2c_handler(struct dp_aux_private *aux, u32 isr)
0182 {
0183 if (isr & DP_INTR_AUX_I2C_DONE) {
0184 if (isr & (DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER))
0185 aux->aux_error_num = DP_AUX_ERR_NACK;
0186 else
0187 aux->aux_error_num = DP_AUX_ERR_NONE;
0188 } else {
0189 if (isr & DP_INTR_WRONG_ADDR)
0190 aux->aux_error_num = DP_AUX_ERR_ADDR;
0191 else if (isr & DP_INTR_TIMEOUT)
0192 aux->aux_error_num = DP_AUX_ERR_TOUT;
0193 if (isr & DP_INTR_NACK_DEFER)
0194 aux->aux_error_num = DP_AUX_ERR_NACK_DEFER;
0195 if (isr & DP_INTR_I2C_NACK)
0196 aux->aux_error_num = DP_AUX_ERR_NACK;
0197 if (isr & DP_INTR_I2C_DEFER)
0198 aux->aux_error_num = DP_AUX_ERR_DEFER;
0199 if (isr & DP_INTR_AUX_ERROR) {
0200 aux->aux_error_num = DP_AUX_ERR_PHY;
0201 dp_catalog_aux_clear_hw_interrupts(aux->catalog);
0202 }
0203 }
0204 }
0205
0206 static void dp_aux_update_offset_and_segment(struct dp_aux_private *aux,
0207 struct drm_dp_aux_msg *input_msg)
0208 {
0209 u32 edid_address = 0x50;
0210 u32 segment_address = 0x30;
0211 bool i2c_read = input_msg->request &
0212 (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
0213 u8 *data;
0214
0215 if (aux->native || i2c_read || ((input_msg->address != edid_address) &&
0216 (input_msg->address != segment_address)))
0217 return;
0218
0219
0220 data = input_msg->buffer;
0221 if (input_msg->address == segment_address)
0222 aux->segment = *data;
0223 else
0224 aux->offset = *data;
0225 }
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239 static void dp_aux_transfer_helper(struct dp_aux_private *aux,
0240 struct drm_dp_aux_msg *input_msg,
0241 bool send_seg)
0242 {
0243 struct drm_dp_aux_msg helper_msg;
0244 u32 message_size = 0x10;
0245 u32 segment_address = 0x30;
0246 u32 const edid_block_length = 0x80;
0247 bool i2c_mot = input_msg->request & DP_AUX_I2C_MOT;
0248 bool i2c_read = input_msg->request &
0249 (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
0250
0251 if (!i2c_mot || !i2c_read || (input_msg->size == 0))
0252 return;
0253
0254
0255
0256
0257
0258
0259
0260 if (!(aux->offset % edid_block_length) || !send_seg)
0261 goto end;
0262
0263 aux->read = false;
0264 aux->cmd_busy = true;
0265 aux->no_send_addr = true;
0266 aux->no_send_stop = true;
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276 if (aux->segment) {
0277 memset(&helper_msg, 0, sizeof(helper_msg));
0278 helper_msg.address = segment_address;
0279 helper_msg.buffer = &aux->segment;
0280 helper_msg.size = 1;
0281 dp_aux_cmd_fifo_tx(aux, &helper_msg);
0282 }
0283
0284
0285
0286
0287
0288
0289
0290
0291 memset(&helper_msg, 0, sizeof(helper_msg));
0292 helper_msg.address = input_msg->address;
0293 helper_msg.buffer = &aux->offset;
0294 helper_msg.size = 1;
0295 dp_aux_cmd_fifo_tx(aux, &helper_msg);
0296
0297 end:
0298 aux->offset += message_size;
0299 if (aux->offset == 0x80 || aux->offset == 0x100)
0300 aux->segment = 0x0;
0301 }
0302
0303
0304
0305
0306
0307
0308 static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux,
0309 struct drm_dp_aux_msg *msg)
0310 {
0311 ssize_t ret;
0312 int const aux_cmd_native_max = 16;
0313 int const aux_cmd_i2c_max = 128;
0314 struct dp_aux_private *aux;
0315
0316 aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
0317
0318 aux->native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
0319
0320
0321 if (msg->size == 0 || !msg->buffer) {
0322 msg->reply = aux->native ?
0323 DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
0324 return msg->size;
0325 }
0326
0327
0328 if ((aux->native && msg->size > aux_cmd_native_max) ||
0329 msg->size > aux_cmd_i2c_max) {
0330 DRM_ERROR("%s: invalid msg: size(%zu), request(%x)\n",
0331 __func__, msg->size, msg->request);
0332 return -EINVAL;
0333 }
0334
0335 mutex_lock(&aux->mutex);
0336 if (!aux->initted) {
0337 ret = -EIO;
0338 goto exit;
0339 }
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349 if (aux->is_edp) {
0350 ret = dp_catalog_aux_wait_for_hpd_connect_state(aux->catalog);
0351 if (ret) {
0352 DRM_DEBUG_DP("Panel not ready for aux transactions\n");
0353 goto exit;
0354 }
0355 }
0356
0357 dp_aux_update_offset_and_segment(aux, msg);
0358 dp_aux_transfer_helper(aux, msg, true);
0359
0360 aux->read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
0361 aux->cmd_busy = true;
0362
0363 if (aux->read) {
0364 aux->no_send_addr = true;
0365 aux->no_send_stop = false;
0366 } else {
0367 aux->no_send_addr = true;
0368 aux->no_send_stop = true;
0369 }
0370
0371 ret = dp_aux_cmd_fifo_tx(aux, msg);
0372 if (ret < 0) {
0373 if (aux->native) {
0374 aux->retry_cnt++;
0375 if (!(aux->retry_cnt % MAX_AUX_RETRIES))
0376 dp_catalog_aux_update_cfg(aux->catalog);
0377 }
0378
0379 if (dp_catalog_link_is_connected(aux->catalog))
0380 dp_catalog_aux_reset(aux->catalog);
0381 } else {
0382 aux->retry_cnt = 0;
0383 switch (aux->aux_error_num) {
0384 case DP_AUX_ERR_NONE:
0385 if (aux->read)
0386 ret = dp_aux_cmd_fifo_rx(aux, msg);
0387 msg->reply = aux->native ? DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
0388 break;
0389 case DP_AUX_ERR_DEFER:
0390 msg->reply = aux->native ? DP_AUX_NATIVE_REPLY_DEFER : DP_AUX_I2C_REPLY_DEFER;
0391 break;
0392 case DP_AUX_ERR_PHY:
0393 case DP_AUX_ERR_ADDR:
0394 case DP_AUX_ERR_NACK:
0395 case DP_AUX_ERR_NACK_DEFER:
0396 msg->reply = aux->native ? DP_AUX_NATIVE_REPLY_NACK : DP_AUX_I2C_REPLY_NACK;
0397 break;
0398 case DP_AUX_ERR_TOUT:
0399 ret = -ETIMEDOUT;
0400 break;
0401 }
0402 }
0403
0404 aux->cmd_busy = false;
0405
0406 exit:
0407 mutex_unlock(&aux->mutex);
0408
0409 return ret;
0410 }
0411
0412 void dp_aux_isr(struct drm_dp_aux *dp_aux)
0413 {
0414 u32 isr;
0415 struct dp_aux_private *aux;
0416
0417 if (!dp_aux) {
0418 DRM_ERROR("invalid input\n");
0419 return;
0420 }
0421
0422 aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
0423
0424 isr = dp_catalog_aux_get_irq(aux->catalog);
0425
0426 if (!aux->cmd_busy)
0427 return;
0428
0429 if (aux->native)
0430 dp_aux_native_handler(aux, isr);
0431 else
0432 dp_aux_i2c_handler(aux, isr);
0433
0434 complete(&aux->comp);
0435 }
0436
0437 void dp_aux_reconfig(struct drm_dp_aux *dp_aux)
0438 {
0439 struct dp_aux_private *aux;
0440
0441 aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
0442
0443 dp_catalog_aux_update_cfg(aux->catalog);
0444 dp_catalog_aux_reset(aux->catalog);
0445 }
0446
0447 void dp_aux_init(struct drm_dp_aux *dp_aux)
0448 {
0449 struct dp_aux_private *aux;
0450
0451 if (!dp_aux) {
0452 DRM_ERROR("invalid input\n");
0453 return;
0454 }
0455
0456 aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
0457
0458 mutex_lock(&aux->mutex);
0459
0460 dp_catalog_aux_enable(aux->catalog, true);
0461 aux->retry_cnt = 0;
0462 aux->initted = true;
0463
0464 mutex_unlock(&aux->mutex);
0465 }
0466
0467 void dp_aux_deinit(struct drm_dp_aux *dp_aux)
0468 {
0469 struct dp_aux_private *aux;
0470
0471 aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
0472
0473 mutex_lock(&aux->mutex);
0474
0475 aux->initted = false;
0476 dp_catalog_aux_enable(aux->catalog, false);
0477
0478 mutex_unlock(&aux->mutex);
0479 }
0480
0481 int dp_aux_register(struct drm_dp_aux *dp_aux)
0482 {
0483 struct dp_aux_private *aux;
0484 int ret;
0485
0486 if (!dp_aux) {
0487 DRM_ERROR("invalid input\n");
0488 return -EINVAL;
0489 }
0490
0491 aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
0492
0493 aux->dp_aux.name = "dpu_dp_aux";
0494 aux->dp_aux.dev = aux->dev;
0495 aux->dp_aux.transfer = dp_aux_transfer;
0496 ret = drm_dp_aux_register(&aux->dp_aux);
0497 if (ret) {
0498 DRM_ERROR("%s: failed to register drm aux: %d\n", __func__,
0499 ret);
0500 return ret;
0501 }
0502
0503 return 0;
0504 }
0505
0506 void dp_aux_unregister(struct drm_dp_aux *dp_aux)
0507 {
0508 drm_dp_aux_unregister(dp_aux);
0509 }
0510
0511 struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog,
0512 bool is_edp)
0513 {
0514 struct dp_aux_private *aux;
0515
0516 if (!catalog) {
0517 DRM_ERROR("invalid input\n");
0518 return ERR_PTR(-ENODEV);
0519 }
0520
0521 aux = devm_kzalloc(dev, sizeof(*aux), GFP_KERNEL);
0522 if (!aux)
0523 return ERR_PTR(-ENOMEM);
0524
0525 init_completion(&aux->comp);
0526 aux->cmd_busy = false;
0527 aux->is_edp = is_edp;
0528 mutex_init(&aux->mutex);
0529
0530 aux->dev = dev;
0531 aux->catalog = catalog;
0532 aux->retry_cnt = 0;
0533
0534 return &aux->dp_aux;
0535 }
0536
0537 void dp_aux_put(struct drm_dp_aux *dp_aux)
0538 {
0539 struct dp_aux_private *aux;
0540
0541 if (!dp_aux)
0542 return;
0543
0544 aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
0545
0546 mutex_destroy(&aux->mutex);
0547
0548 devm_kfree(aux->dev, aux);
0549 }