aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/atombios_dp.c
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-01-12 17:54:34 -0500
committerDave Airlie <airlied@redhat.com>2010-02-08 18:44:02 -0500
commitbcc1c2a1d22974215e39dc87ce746ba9a39223e5 (patch)
tree62ae9dfab266202240307fc3998806c1d4655552 /drivers/gpu/drm/radeon/atombios_dp.c
parente97bd974448ce90f8e4720499d84580bcd6a2f7a (diff)
drm/radeon/kms: add initial Evergreen support (Radeon HD 5xxx)
This adds initial Evergreen KMS support, it doesn't include any acceleration features or interrupt handling yet. Major changes are DCE4 handling for PLLs for the > 2 crtcs. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_dp.c')
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c62
1 files changed, 41 insertions, 21 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index 71060114d5de..0b6f2cef1c52 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 339
@@ -339,29 +343,31 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
339 343
340 memcpy(base, req_bytes, num_bytes); 344 memcpy(base, req_bytes, num_bytes);
341 345
342 args.lpAuxRequest = 0; 346 args.v1.lpAuxRequest = 0;
343 args.lpDataOut = 16; 347 args.v1.lpDataOut = 16;
344 args.ucDataOutLen = 0; 348 args.v1.ucDataOutLen = 0;
345 args.ucChannelID = chan->rec.i2c_id; 349 args.v1.ucChannelID = chan->rec.i2c_id;
346 args.ucDelay = delay / 10; 350 args.v1.ucDelay = delay / 10;
351 if (ASIC_IS_DCE4(rdev))
352 args.v2.ucHPD_ID = chan->rec.hpd_id;
347 353
348 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 354 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
349 355
350 if (args.ucReplyStatus) { 356 if (args.v1.ucReplyStatus) {
351 DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x\n", 357 DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x\n",
352 req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], 358 req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3],
353 chan->rec.i2c_id, args.ucReplyStatus); 359 chan->rec.i2c_id, args.v1.ucReplyStatus);
354 return false; 360 return false;
355 } 361 }
356 362
357 if (args.ucDataOutLen && read_byte && read_buf_len) { 363 if (args.v1.ucDataOutLen && read_byte && read_buf_len) {
358 if (read_buf_len < args.ucDataOutLen) { 364 if (read_buf_len < args.v1.ucDataOutLen) {
359 DRM_ERROR("Buffer to small for return answer %d %d\n", 365 DRM_ERROR("Buffer to small for return answer %d %d\n",
360 read_buf_len, args.ucDataOutLen); 366 read_buf_len, args.v1.ucDataOutLen);
361 return false; 367 return false;
362 } 368 }
363 { 369 {
364 int len = min(read_buf_len, args.ucDataOutLen); 370 int len = min(read_buf_len, args.v1.ucDataOutLen);
365 memcpy(read_byte, base + 16, len); 371 memcpy(read_byte, base + 16, len);
366 } 372 }
367 } 373 }
@@ -622,12 +628,19 @@ void dp_link_train(struct drm_encoder *encoder,
622 dp_set_link_bw_lanes(radeon_connector, link_configuration); 628 dp_set_link_bw_lanes(radeon_connector, link_configuration);
623 /* disable downspread on the sink */ 629 /* disable downspread on the sink */
624 dp_set_downspread(radeon_connector, 0); 630 dp_set_downspread(radeon_connector, 0);
625 /* start training on the source */ 631 if (ASIC_IS_DCE4(rdev)) {
626 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START, 632 /* start training on the source */
627 dig_connector->dp_clock, enc_id, 0); 633 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START);
628 /* set training pattern 1 on the source */ 634 /* set training pattern 1 on the source */
629 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, 635 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1);
630 dig_connector->dp_clock, enc_id, 0); 636 } else {
637 /* start training on the source */
638 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START,
639 dig_connector->dp_clock, enc_id, 0);
640 /* set training pattern 1 on the source */
641 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
642 dig_connector->dp_clock, enc_id, 0);
643 }
631 644
632 /* set initial vs/emph */ 645 /* set initial vs/emph */
633 memset(train_set, 0, 4); 646 memset(train_set, 0, 4);
@@ -687,8 +700,11 @@ void dp_link_train(struct drm_encoder *encoder,
687 /* set training pattern 2 on the sink */ 700 /* set training pattern 2 on the sink */
688 dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2); 701 dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2);
689 /* set training pattern 2 on the source */ 702 /* set training pattern 2 on the source */
690 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, 703 if (ASIC_IS_DCE4(rdev))
691 dig_connector->dp_clock, enc_id, 1); 704 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2);
705 else
706 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
707 dig_connector->dp_clock, enc_id, 1);
692 708
693 /* channel equalization loop */ 709 /* channel equalization loop */
694 tries = 0; 710 tries = 0;
@@ -725,7 +741,11 @@ void dp_link_train(struct drm_encoder *encoder,
725 >> DP_TRAIN_PRE_EMPHASIS_SHIFT); 741 >> DP_TRAIN_PRE_EMPHASIS_SHIFT);
726 742
727 /* disable the training pattern on the sink */ 743 /* disable the training pattern on the sink */
728 dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE); 744 if (ASIC_IS_DCE4(rdev))
745 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);
746 else
747 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
748 dig_connector->dp_clock, enc_id, 0);
729 749
730 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, 750 radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
731 dig_connector->dp_clock, enc_id, 0); 751 dig_connector->dp_clock, enc_id, 0);