aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2010-03-08 17:14:01 -0500
committerDave Airlie <airlied@redhat.com>2010-03-14 20:03:57 -0400
commit2cd6218cb8043ef4360b561e726cd081f8a380cc (patch)
tree440158ba82c5f14c6dc528dbc76e1223cd286a1b /drivers/gpu/drm
parent808032ee296ee7b37a6df090be40a330e09ae30e (diff)
drm/radeon/kms: clean assigning HDMI blocks to encoders
We almost always used first HDMI block for first encoder and second for sencod. Exception was KLDSCP_LVTMA. Analyzing code picking DIG encoder shows the same behaviour. It shows HDMI block are related to DIGs, which relation we now use. Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/radeon/r600_audio.c7
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c114
-rw-r--r--drivers/gpu/drm/radeon/radeon.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c10
4 files changed, 62 insertions, 72 deletions
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c
index db928016d034..baf222faf158 100644
--- a/drivers/gpu/drm/radeon/r600_audio.c
+++ b/drivers/gpu/drm/radeon/r600_audio.c
@@ -224,6 +224,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
224 struct drm_device *dev = encoder->dev; 224 struct drm_device *dev = encoder->dev;
225 struct radeon_device *rdev = dev->dev_private; 225 struct radeon_device *rdev = dev->dev_private;
226 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 226 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
227 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
227 int base_rate = 48000; 228 int base_rate = 48000;
228 229
229 switch (radeon_encoder->encoder_id) { 230 switch (radeon_encoder->encoder_id) {
@@ -245,7 +246,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
245 return; 246 return;
246 } 247 }
247 248
248 switch (r600_audio_tmds_index(encoder)) { 249 switch (dig->dig_encoder) {
249 case 0: 250 case 0:
250 WREG32(R600_AUDIO_PLL1_MUL, base_rate*50); 251 WREG32(R600_AUDIO_PLL1_MUL, base_rate*50);
251 WREG32(R600_AUDIO_PLL1_DIV, clock*100); 252 WREG32(R600_AUDIO_PLL1_DIV, clock*100);
@@ -257,6 +258,10 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
257 WREG32(R600_AUDIO_PLL2_DIV, clock*100); 258 WREG32(R600_AUDIO_PLL2_DIV, clock*100);
258 WREG32(R600_AUDIO_CLK_SRCSEL, 1); 259 WREG32(R600_AUDIO_CLK_SRCSEL, 1);
259 break; 260 break;
261 default:
262 dev_err(rdev->dev, "Unsupported DIG on encoder 0x%02X\n",
263 radeon_encoder->encoder_id);
264 return;
260 } 265 }
261} 266}
262 267
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index 4d09973ad6a6..5275a81b1df3 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -417,90 +417,74 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
417 WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000); 417 WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000);
418} 418}
419 419
420/* 420static void r600_hdmi_assign_block(struct drm_encoder *encoder)
421 * enable/disable the HDMI engine
422 */
423void r600_hdmi_enable(struct drm_encoder *encoder, int enable)
424{ 421{
425 struct drm_device *dev = encoder->dev; 422 struct drm_device *dev = encoder->dev;
426 struct radeon_device *rdev = dev->dev_private; 423 struct radeon_device *rdev = dev->dev_private;
427 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 424 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
428 uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; 425 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
429 426
430 if (!offset) 427 if (!dig) {
428 dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n");
431 return; 429 return;
430 }
432 431
433 DRM_DEBUG("%s HDMI interface @ 0x%04X\n", enable ? "Enabling" : "Disabling", offset); 432 if (ASIC_IS_DCE4(rdev)) {
434 433 /* TODO */
435 /* some version of atombios ignore the enable HDMI flag 434 } else if (ASIC_IS_DCE3(rdev)) {
436 * so enabling/disabling HDMI was moved here for TMDS1+2 */ 435 radeon_encoder->hdmi_offset = dig->dig_encoder ?
437 switch (radeon_encoder->encoder_id) { 436 R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1;
438 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: 437 if (ASIC_IS_DCE32(rdev))
439 WREG32_P(AVIVO_TMDSA_CNTL, enable ? 0x4 : 0x0, ~0x4); 438 radeon_encoder->hdmi_config_offset = dig->dig_encoder ?
440 WREG32(offset+R600_HDMI_ENABLE, enable ? 0x101 : 0x0); 439 R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1;
441 break;
442
443 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
444 WREG32_P(AVIVO_LVTMA_CNTL, enable ? 0x4 : 0x0, ~0x4);
445 WREG32(offset+R600_HDMI_ENABLE, enable ? 0x105 : 0x0);
446 break;
447
448 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
449 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
450 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
451 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
452 /* This part is doubtfull in my opinion */
453 WREG32(offset+R600_HDMI_ENABLE, enable ? 0x110 : 0x0);
454 break;
455
456 default:
457 DRM_ERROR("unknown HDMI output type\n");
458 break;
459 } 440 }
460} 441}
461 442
462/* 443/*
463 * determin at which register offset the HDMI encoder is 444 * enable the HDMI engine
464 */ 445 */
465void r600_hdmi_init(struct drm_encoder *encoder) 446void r600_hdmi_enable(struct drm_encoder *encoder)
466{ 447{
448 struct drm_device *dev = encoder->dev;
449 struct radeon_device *rdev = dev->dev_private;
467 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 450 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
468 451
469 switch (radeon_encoder->encoder_id) { 452 if (!radeon_encoder->hdmi_offset) {
470 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: 453 r600_hdmi_assign_block(encoder);
471 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: 454 if (!radeon_encoder->hdmi_offset) {
472 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: 455 dev_warn(rdev->dev, "Could not find HDMI block for "
473 radeon_encoder->hdmi_offset = R600_HDMI_BLOCK1; 456 "0x%x encoder\n", radeon_encoder->encoder_id);
474 break; 457 return;
475
476 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
477 switch (r600_audio_tmds_index(encoder)) {
478 case 0:
479 radeon_encoder->hdmi_offset = R600_HDMI_BLOCK1;
480 break;
481 case 1:
482 radeon_encoder->hdmi_offset = R600_HDMI_BLOCK2;
483 break;
484 default:
485 radeon_encoder->hdmi_offset = 0;
486 break;
487 } 458 }
488 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: 459 }
489 radeon_encoder->hdmi_offset = R600_HDMI_BLOCK2;
490 break;
491 460
492 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: 461 if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev))
493 radeon_encoder->hdmi_offset = R600_HDMI_BLOCK3; 462 WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1);
494 break; 463
464 DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n",
465 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
466}
495 467
496 default: 468/*
497 radeon_encoder->hdmi_offset = 0; 469 * disable the HDMI engine
498 break; 470 */
471void r600_hdmi_disable(struct drm_encoder *encoder)
472{
473 struct drm_device *dev = encoder->dev;
474 struct radeon_device *rdev = dev->dev_private;
475 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
476
477 if (!radeon_encoder->hdmi_offset) {
478 dev_err(rdev->dev, "Disabling not enabled HDMI\n");
479 return;
499 } 480 }
500 481
501 DRM_DEBUG("using HDMI engine at offset 0x%04X for encoder 0x%x\n", 482 DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n",
502 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); 483 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
484
485 if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev))
486 WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1);
503 487
504 /* TODO: make this configureable */ 488 radeon_encoder->hdmi_offset = 0;
505 radeon_encoder->hdmi_audio_workaround = 0; 489 radeon_encoder->hdmi_config_offset = 0;
506} 490}
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 829e26e8a4bb..ba93e5a20b29 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1322,7 +1322,8 @@ extern int r600_audio_tmds_index(struct drm_encoder *encoder);
1322extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock); 1322extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock);
1323extern void r600_audio_fini(struct radeon_device *rdev); 1323extern void r600_audio_fini(struct radeon_device *rdev);
1324extern void r600_hdmi_init(struct drm_encoder *encoder); 1324extern void r600_hdmi_init(struct drm_encoder *encoder);
1325extern void r600_hdmi_enable(struct drm_encoder *encoder, int enable); 1325extern void r600_hdmi_enable(struct drm_encoder *encoder);
1326extern void r600_hdmi_disable(struct drm_encoder *encoder);
1326extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); 1327extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
1327extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); 1328extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder);
1328extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder, 1329extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index 4eae30cc5213..a236c75496c4 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -593,7 +593,6 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
593 } 593 }
594 594
595 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 595 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
596 r600_hdmi_enable(encoder, hdmi_detected);
597} 596}
598 597
599int 598int
@@ -1389,9 +1388,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
1389 } 1388 }
1390 atombios_apply_encoder_quirks(encoder, adjusted_mode); 1389 atombios_apply_encoder_quirks(encoder, adjusted_mode);
1391 1390
1392 /* XXX */ 1391 if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
1393 if (!ASIC_IS_DCE4(rdev)) 1392 r600_hdmi_enable(encoder);
1394 r600_hdmi_setmode(encoder, adjusted_mode); 1393 r600_hdmi_setmode(encoder, adjusted_mode);
1394 }
1395} 1395}
1396 1396
1397static bool 1397static bool
@@ -1514,6 +1514,8 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
1514 radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); 1514 radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
1515 1515
1516 if (radeon_encoder_is_digital(encoder)) { 1516 if (radeon_encoder_is_digital(encoder)) {
1517 if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI)
1518 r600_hdmi_disable(encoder);
1517 dig = radeon_encoder->enc_priv; 1519 dig = radeon_encoder->enc_priv;
1518 dig->dig_encoder = -1; 1520 dig->dig_encoder = -1;
1519 } 1521 }
@@ -1664,6 +1666,4 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
1664 drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); 1666 drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
1665 break; 1667 break;
1666 } 1668 }
1667
1668 r600_hdmi_init(encoder);
1669} 1669}