aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/atombios_dp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_dp.c')
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c64
1 files changed, 42 insertions, 22 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index 99915a682d59..8a133bda00a2 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -321,6 +321,10 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE],
321 train_set[lane] = v | p; 321 train_set[lane] = v | p;
322} 322}
323 323
324union aux_channel_transaction {
325 PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1;
326 PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2;
327};
324 328
325/* radeon aux chan functions */ 329/* radeon aux chan functions */
326bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, 330bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
@@ -329,7 +333,7 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
329{ 333{
330 struct drm_device *dev = chan->dev; 334 struct drm_device *dev = chan->dev;
331 struct radeon_device *rdev = dev->dev_private; 335 struct radeon_device *rdev = dev->dev_private;
332 PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args; 336 union aux_channel_transaction args;
333 int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); 337 int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
334 unsigned char *base; 338 unsigned char *base;
335 int retry_count = 0; 339 int retry_count = 0;
@@ -341,31 +345,33 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
341retry: 345retry:
342 memcpy(base, req_bytes, num_bytes); 346 memcpy(base, req_bytes, num_bytes);
343 347
344 args.lpAuxRequest = 0; 348 args.v1.lpAuxRequest = 0;
345 args.lpDataOut = 16; 349 args.v1.lpDataOut = 16;
346 args.ucDataOutLen = 0; 350 args.v1.ucDataOutLen = 0;
347 args.ucChannelID = chan->rec.i2c_id; 351 args.v1.ucChannelID = chan->rec.i2c_id;
348 args.ucDelay = delay / 10; 352 args.v1.ucDelay = delay / 10;
353 if (ASIC_IS_DCE4(rdev))
354 args.v2.ucHPD_ID = chan->rec.hpd_id;
349 355
350 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 356 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
351 357
352 if (args.ucReplyStatus && !args.ucDataOutLen) { 358 if (args.v1.ucReplyStatus && !args.v1.ucDataOutLen) {
353 if (args.ucReplyStatus == 0x20 && retry_count++ < 10) 359 if (args.v1.ucReplyStatus == 0x20 && retry_count++ < 10)
354 goto retry; 360 goto retry;
355 DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n", 361 DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n",
356 req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], 362 req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3],
357 chan->rec.i2c_id, args.ucReplyStatus, retry_count); 363 chan->rec.i2c_id, args.v1.ucReplyStatus, retry_count);
358 return false; 364 return false;
359 } 365 }
360 366
361 if (args.ucDataOutLen && read_byte && read_buf_len) { 367 if (args.v1.ucDataOutLen && read_byte && read_buf_len) {
362 if (read_buf_len < args.ucDataOutLen) { 368 if (read_buf_len < args.v1.ucDataOutLen) {
363 DRM_ERROR("Buffer to small for return answer %d %d\n", 369 DRM_ERROR("Buffer to small for return answer %d %d\n",
364 read_buf_len, args.ucDataOutLen); 370 read_buf_len, args.v1.ucDataOutLen);
365 return false; 371 return false;
366 } 372 }
367 { 373 {
368 int len = min(read_buf_len, args.ucDataOutLen); 374 int len = min(read_buf_len, args.v1.ucDataOutLen);
369 memcpy(read_byte, base + 16, len); 375 memcpy(read_byte, base + 16, len);
370 } 376 }
371 } 377 }
@@ -626,12 +632,19 @@ void dp_link_train(struct drm_encoder *encoder,
626 dp_set_link_bw_lanes(radeon_connector, link_configuration); 632 dp_set_link_bw_lanes(radeon_connector, link_configuration);
627 /* disable downspread on the sink */ 633 /* disable downspread on the sink */
628 dp_set_downspread(radeon_connector, 0); 634 dp_set_downspread(radeon_connector, 0);
629 /* start training on the source */ 635 if (ASIC_IS_DCE4(rdev)) {
630 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START, 636 /* start training on the source */
631 dig_connector->dp_clock, enc_id, 0); 637 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START);
632 /* set training pattern 1 on the source */ 638 /* set training pattern 1 on the source */
633 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, 639 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1);
634 dig_connector->dp_clock, enc_id, 0); 640 } else {
641 /* start training on the source */
642 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START,
643 dig_connector->dp_clock, enc_id, 0);
644 /* set training pattern 1 on the source */
645 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
646 dig_connector->dp_clock, enc_id, 0);
647 }
635 648
636 /* set initial vs/emph */ 649 /* set initial vs/emph */
637 memset(train_set, 0, 4); 650 memset(train_set, 0, 4);
@@ -691,8 +704,11 @@ void dp_link_train(struct drm_encoder *encoder,
691 /* set training pattern 2 on the sink */ 704 /* set training pattern 2 on the sink */
692 dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2); 705 dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2);
693 /* set training pattern 2 on the source */ 706 /* set training pattern 2 on the source */
694 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, 707 if (ASIC_IS_DCE4(rdev))
695 dig_connector->dp_clock, enc_id, 1); 708 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2);
709 else
710 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
711 dig_connector->dp_clock, enc_id, 1);
696 712
697 /* channel equalization loop */ 713 /* channel equalization loop */
698 tries = 0; 714 tries = 0;
@@ -729,7 +745,11 @@ void dp_link_train(struct drm_encoder *encoder,
729 >> DP_TRAIN_PRE_EMPHASIS_SHIFT); 745 >> DP_TRAIN_PRE_EMPHASIS_SHIFT);
730 746
731 /* disable the training pattern on the sink */ 747 /* disable the training pattern on the sink */
732 dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE); 748 if (ASIC_IS_DCE4(rdev))
749 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);
750 else
751 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
752 dig_connector->dp_clock, enc_id, 0);
733 753
734 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, 754 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
735 dig_connector->dp_clock, enc_id, 0); 755 dig_connector->dp_clock, enc_id, 0);