diff options
| author | Dave Airlie <airlied@redhat.com> | 2012-01-03 04:43:28 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2012-01-03 04:45:12 -0500 |
| commit | 7a7e8734ac3235efafd34819b27fbdf5417e6d60 (patch) | |
| tree | 8e34492eaef018bd87065bb7552de15b6a1f0fa5 /drivers/gpu | |
| parent | 2318fcd65c1fb1e842f860c1e3fe4dba7e55cd11 (diff) | |
| parent | 93a4ed878a22b8489723bc3ab89dd401128bbc9e (diff) | |
Merge branch 'drm-radeon-testing' of ../drm-radeon-next into drm-core-next
This merges the evergreen HDMI audio support.
* 'drm-radeon-testing' of ../drm-radeon-next:
drm/radeon/kms: define TMDS/LVTM HDMI enabling bits
drm/radeon/kms: workaround invalid AVI infoframe checksum issue
drm/radeon/kms: setup HDMI mode on Evergreen encoders
drm/radeon/kms: support for audio on Evergreen
drm/radeon/kms: minor HDMI audio cleanups
drm/radeon/kms: do not force DVI mode on DCE4 if audio is on
ridge
Conflicts:
drivers/gpu/drm/radeon/evergreen.c
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/radeon/atombios_encoders.c | 35 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/evergreen_reg.h | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r500_reg.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r600_audio.c | 57 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r600_hdmi.c | 65 |
6 files changed, 125 insertions, 54 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 39c04c1b8472..f1f06ca9f1f5 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
| @@ -409,8 +409,6 @@ int | |||
| 409 | atombios_get_encoder_mode(struct drm_encoder *encoder) | 409 | atombios_get_encoder_mode(struct drm_encoder *encoder) |
| 410 | { | 410 | { |
| 411 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 411 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 412 | struct drm_device *dev = encoder->dev; | ||
| 413 | struct radeon_device *rdev = dev->dev_private; | ||
| 414 | struct drm_connector *connector; | 412 | struct drm_connector *connector; |
| 415 | struct radeon_connector *radeon_connector; | 413 | struct radeon_connector *radeon_connector; |
| 416 | struct radeon_connector_atom_dig *dig_connector; | 414 | struct radeon_connector_atom_dig *dig_connector; |
| @@ -434,13 +432,10 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 434 | switch (connector->connector_type) { | 432 | switch (connector->connector_type) { |
| 435 | case DRM_MODE_CONNECTOR_DVII: | 433 | case DRM_MODE_CONNECTOR_DVII: |
| 436 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ | 434 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ |
| 437 | if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | 435 | if (drm_detect_monitor_audio(radeon_connector->edid) && |
| 438 | /* fix me */ | 436 | radeon_audio) |
| 439 | if (ASIC_IS_DCE4(rdev)) | 437 | return ATOM_ENCODER_MODE_HDMI; |
| 440 | return ATOM_ENCODER_MODE_DVI; | 438 | else if (radeon_connector->use_digital) |
| 441 | else | ||
| 442 | return ATOM_ENCODER_MODE_HDMI; | ||
| 443 | } else if (radeon_connector->use_digital) | ||
| 444 | return ATOM_ENCODER_MODE_DVI; | 439 | return ATOM_ENCODER_MODE_DVI; |
| 445 | else | 440 | else |
| 446 | return ATOM_ENCODER_MODE_CRT; | 441 | return ATOM_ENCODER_MODE_CRT; |
| @@ -448,13 +443,10 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 448 | case DRM_MODE_CONNECTOR_DVID: | 443 | case DRM_MODE_CONNECTOR_DVID: |
| 449 | case DRM_MODE_CONNECTOR_HDMIA: | 444 | case DRM_MODE_CONNECTOR_HDMIA: |
| 450 | default: | 445 | default: |
| 451 | if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | 446 | if (drm_detect_monitor_audio(radeon_connector->edid) && |
| 452 | /* fix me */ | 447 | radeon_audio) |
| 453 | if (ASIC_IS_DCE4(rdev)) | 448 | return ATOM_ENCODER_MODE_HDMI; |
| 454 | return ATOM_ENCODER_MODE_DVI; | 449 | else |
| 455 | else | ||
| 456 | return ATOM_ENCODER_MODE_HDMI; | ||
| 457 | } else | ||
| 458 | return ATOM_ENCODER_MODE_DVI; | 450 | return ATOM_ENCODER_MODE_DVI; |
| 459 | break; | 451 | break; |
| 460 | case DRM_MODE_CONNECTOR_LVDS: | 452 | case DRM_MODE_CONNECTOR_LVDS: |
| @@ -465,13 +457,10 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 465 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 457 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
| 466 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | 458 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) |
| 467 | return ATOM_ENCODER_MODE_DP; | 459 | return ATOM_ENCODER_MODE_DP; |
| 468 | else if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) { | 460 | else if (drm_detect_monitor_audio(radeon_connector->edid) && |
| 469 | /* fix me */ | 461 | radeon_audio) |
| 470 | if (ASIC_IS_DCE4(rdev)) | 462 | return ATOM_ENCODER_MODE_HDMI; |
| 471 | return ATOM_ENCODER_MODE_DVI; | 463 | else |
| 472 | else | ||
| 473 | return ATOM_ENCODER_MODE_HDMI; | ||
| 474 | } else | ||
| 475 | return ATOM_ENCODER_MODE_DVI; | 464 | return ATOM_ENCODER_MODE_DVI; |
| 476 | break; | 465 | break; |
| 477 | case DRM_MODE_CONNECTOR_eDP: | 466 | case DRM_MODE_CONNECTOR_eDP: |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 1934728e2465..ccde2c9540e2 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -3190,6 +3190,11 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
| 3190 | if (r) { | 3190 | if (r) { |
| 3191 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); | 3191 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); |
| 3192 | rdev->accel_working = false; | 3192 | rdev->accel_working = false; |
| 3193 | } | ||
| 3194 | |||
| 3195 | r = r600_audio_init(rdev); | ||
| 3196 | if (r) { | ||
| 3197 | DRM_ERROR("radeon: audio init failed\n"); | ||
| 3193 | return r; | 3198 | return r; |
| 3194 | } | 3199 | } |
| 3195 | 3200 | ||
| @@ -3227,6 +3232,7 @@ int evergreen_suspend(struct radeon_device *rdev) | |||
| 3227 | { | 3232 | { |
| 3228 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 3233 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
| 3229 | 3234 | ||
| 3235 | r600_audio_fini(rdev); | ||
| 3230 | /* FIXME: we should wait for ring to be empty */ | 3236 | /* FIXME: we should wait for ring to be empty */ |
| 3231 | radeon_ib_pool_suspend(rdev); | 3237 | radeon_ib_pool_suspend(rdev); |
| 3232 | r600_blit_suspend(rdev); | 3238 | r600_blit_suspend(rdev); |
| @@ -3342,6 +3348,7 @@ int evergreen_init(struct radeon_device *rdev) | |||
| 3342 | 3348 | ||
| 3343 | void evergreen_fini(struct radeon_device *rdev) | 3349 | void evergreen_fini(struct radeon_device *rdev) |
| 3344 | { | 3350 | { |
| 3351 | r600_audio_fini(rdev); | ||
| 3345 | r600_blit_fini(rdev); | 3352 | r600_blit_fini(rdev); |
| 3346 | r700_cp_fini(rdev); | 3353 | r700_cp_fini(rdev); |
| 3347 | r600_irq_fini(rdev); | 3354 | r600_irq_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index 7d7f2155e34c..4215de95477e 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h | |||
| @@ -35,6 +35,14 @@ | |||
| 35 | #define EVERGREEN_P1PLL_SS_CNTL 0x414 | 35 | #define EVERGREEN_P1PLL_SS_CNTL 0x414 |
| 36 | #define EVERGREEN_P2PLL_SS_CNTL 0x454 | 36 | #define EVERGREEN_P2PLL_SS_CNTL 0x454 |
| 37 | # define EVERGREEN_PxPLL_SS_EN (1 << 12) | 37 | # define EVERGREEN_PxPLL_SS_EN (1 << 12) |
| 38 | |||
| 39 | #define EVERGREEN_AUDIO_PLL1_MUL 0x5b0 | ||
| 40 | #define EVERGREEN_AUDIO_PLL1_DIV 0x5b4 | ||
| 41 | #define EVERGREEN_AUDIO_PLL1_UNK 0x5bc | ||
| 42 | |||
| 43 | #define EVERGREEN_AUDIO_ENABLE 0x5e78 | ||
| 44 | #define EVERGREEN_AUDIO_VENDOR_ID 0x5ec0 | ||
| 45 | |||
| 38 | /* GRPH blocks at 0x6800, 0x7400, 0x10000, 0x10c00, 0x11800, 0x12400 */ | 46 | /* GRPH blocks at 0x6800, 0x7400, 0x10000, 0x10c00, 0x11800, 0x12400 */ |
| 39 | #define EVERGREEN_GRPH_ENABLE 0x6800 | 47 | #define EVERGREEN_GRPH_ENABLE 0x6800 |
| 40 | #define EVERGREEN_GRPH_CONTROL 0x6804 | 48 | #define EVERGREEN_GRPH_CONTROL 0x6804 |
| @@ -220,4 +228,9 @@ | |||
| 220 | #define EVERGREEN_DC_GPIO_HPD_EN 0x64b8 | 228 | #define EVERGREEN_DC_GPIO_HPD_EN 0x64b8 |
| 221 | #define EVERGREEN_DC_GPIO_HPD_Y 0x64bc | 229 | #define EVERGREEN_DC_GPIO_HPD_Y 0x64bc |
| 222 | 230 | ||
| 231 | /* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ | ||
| 232 | #define EVERGREEN_HDMI_BASE 0x7030 | ||
| 233 | |||
| 234 | #define EVERGREEN_HDMI_CONFIG_OFFSET 0xf0 | ||
| 235 | |||
| 223 | #endif | 236 | #endif |
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h index fc437059918f..3bd8f1b1c606 100644 --- a/drivers/gpu/drm/radeon/r500_reg.h +++ b/drivers/gpu/drm/radeon/r500_reg.h | |||
| @@ -573,6 +573,7 @@ | |||
| 573 | 573 | ||
| 574 | #define AVIVO_TMDSA_CNTL 0x7880 | 574 | #define AVIVO_TMDSA_CNTL 0x7880 |
| 575 | # define AVIVO_TMDSA_CNTL_ENABLE (1 << 0) | 575 | # define AVIVO_TMDSA_CNTL_ENABLE (1 << 0) |
| 576 | # define AVIVO_TMDSA_CNTL_HDMI_EN (1 << 2) | ||
| 576 | # define AVIVO_TMDSA_CNTL_HPD_MASK (1 << 4) | 577 | # define AVIVO_TMDSA_CNTL_HPD_MASK (1 << 4) |
| 577 | # define AVIVO_TMDSA_CNTL_HPD_SELECT (1 << 8) | 578 | # define AVIVO_TMDSA_CNTL_HPD_SELECT (1 << 8) |
| 578 | # define AVIVO_TMDSA_CNTL_SYNC_PHASE (1 << 12) | 579 | # define AVIVO_TMDSA_CNTL_SYNC_PHASE (1 << 12) |
| @@ -633,6 +634,7 @@ | |||
| 633 | 634 | ||
| 634 | #define AVIVO_LVTMA_CNTL 0x7a80 | 635 | #define AVIVO_LVTMA_CNTL 0x7a80 |
| 635 | # define AVIVO_LVTMA_CNTL_ENABLE (1 << 0) | 636 | # define AVIVO_LVTMA_CNTL_ENABLE (1 << 0) |
| 637 | # define AVIVO_LVTMA_CNTL_HDMI_EN (1 << 2) | ||
| 636 | # define AVIVO_LVTMA_CNTL_HPD_MASK (1 << 4) | 638 | # define AVIVO_LVTMA_CNTL_HPD_MASK (1 << 4) |
| 637 | # define AVIVO_LVTMA_CNTL_HPD_SELECT (1 << 8) | 639 | # define AVIVO_LVTMA_CNTL_HPD_SELECT (1 << 8) |
| 638 | # define AVIVO_LVTMA_CNTL_SYNC_PHASE (1 << 12) | 640 | # define AVIVO_LVTMA_CNTL_SYNC_PHASE (1 << 12) |
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index 846fae576399..ba66f3093d46 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c | |||
| @@ -36,7 +36,7 @@ | |||
| 36 | */ | 36 | */ |
| 37 | static int r600_audio_chipset_supported(struct radeon_device *rdev) | 37 | static int r600_audio_chipset_supported(struct radeon_device *rdev) |
| 38 | { | 38 | { |
| 39 | return (rdev->family >= CHIP_R600 && rdev->family < CHIP_CEDAR) | 39 | return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE5(rdev)) |
| 40 | || rdev->family == CHIP_RS600 | 40 | || rdev->family == CHIP_RS600 |
| 41 | || rdev->family == CHIP_RS690 | 41 | || rdev->family == CHIP_RS690 |
| 42 | || rdev->family == CHIP_RS740; | 42 | || rdev->family == CHIP_RS740; |
| @@ -161,8 +161,18 @@ static void r600_audio_update_hdmi(unsigned long param) | |||
| 161 | */ | 161 | */ |
| 162 | static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable) | 162 | static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable) |
| 163 | { | 163 | { |
| 164 | u32 value = 0; | ||
| 164 | DRM_INFO("%s audio support\n", enable ? "Enabling" : "Disabling"); | 165 | DRM_INFO("%s audio support\n", enable ? "Enabling" : "Disabling"); |
| 165 | WREG32_P(R600_AUDIO_ENABLE, enable ? 0x81000000 : 0x0, ~0x81000000); | 166 | if (ASIC_IS_DCE4(rdev)) { |
| 167 | if (enable) { | ||
| 168 | value |= 0x81000000; /* Required to enable audio */ | ||
| 169 | value |= 0x0e1000f0; /* fglrx sets that too */ | ||
| 170 | } | ||
| 171 | WREG32(EVERGREEN_AUDIO_ENABLE, value); | ||
| 172 | } else { | ||
| 173 | WREG32_P(R600_AUDIO_ENABLE, | ||
| 174 | enable ? 0x81000000 : 0x0, ~0x81000000); | ||
| 175 | } | ||
| 166 | rdev->audio_enabled = enable; | 176 | rdev->audio_enabled = enable; |
| 167 | } | 177 | } |
| 168 | 178 | ||
| @@ -248,22 +258,33 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) | |||
| 248 | return; | 258 | return; |
| 249 | } | 259 | } |
| 250 | 260 | ||
| 251 | switch (dig->dig_encoder) { | 261 | if (ASIC_IS_DCE4(rdev)) { |
| 252 | case 0: | 262 | /* TODO: other PLLs? */ |
| 253 | WREG32(R600_AUDIO_PLL1_MUL, base_rate * 50); | 263 | WREG32(EVERGREEN_AUDIO_PLL1_MUL, base_rate * 10); |
| 254 | WREG32(R600_AUDIO_PLL1_DIV, clock * 100); | 264 | WREG32(EVERGREEN_AUDIO_PLL1_DIV, clock * 10); |
| 255 | WREG32(R600_AUDIO_CLK_SRCSEL, 0); | 265 | WREG32(EVERGREEN_AUDIO_PLL1_UNK, 0x00000071); |
| 256 | break; | 266 | |
| 257 | 267 | /* Some magic trigger or src sel? */ | |
| 258 | case 1: | 268 | WREG32_P(0x5ac, 0x01, ~0x77); |
| 259 | WREG32(R600_AUDIO_PLL2_MUL, base_rate * 50); | 269 | } else { |
| 260 | WREG32(R600_AUDIO_PLL2_DIV, clock * 100); | 270 | switch (dig->dig_encoder) { |
| 261 | WREG32(R600_AUDIO_CLK_SRCSEL, 1); | 271 | case 0: |
| 262 | break; | 272 | WREG32(R600_AUDIO_PLL1_MUL, base_rate * 50); |
| 263 | default: | 273 | WREG32(R600_AUDIO_PLL1_DIV, clock * 100); |
| 264 | dev_err(rdev->dev, "Unsupported DIG on encoder 0x%02X\n", | 274 | WREG32(R600_AUDIO_CLK_SRCSEL, 0); |
| 265 | radeon_encoder->encoder_id); | 275 | break; |
| 266 | return; | 276 | |
| 277 | case 1: | ||
| 278 | WREG32(R600_AUDIO_PLL2_MUL, base_rate * 50); | ||
| 279 | WREG32(R600_AUDIO_PLL2_DIV, clock * 100); | ||
| 280 | WREG32(R600_AUDIO_CLK_SRCSEL, 1); | ||
| 281 | break; | ||
| 282 | default: | ||
| 283 | dev_err(rdev->dev, | ||
| 284 | "Unsupported DIG on encoder 0x%02X\n", | ||
| 285 | radeon_encoder->encoder_id); | ||
| 286 | return; | ||
| 287 | } | ||
| 267 | } | 288 | } |
| 268 | } | 289 | } |
| 269 | 290 | ||
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index f5ac7e788d81..0b5920671450 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
| @@ -196,6 +196,13 @@ static void r600_hdmi_videoinfoframe( | |||
| 196 | frame[0xD] = (right_bar >> 8); | 196 | frame[0xD] = (right_bar >> 8); |
| 197 | 197 | ||
| 198 | r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame); | 198 | r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame); |
| 199 | /* Our header values (type, version, length) should be alright, Intel | ||
| 200 | * is using the same. Checksum function also seems to be OK, it works | ||
| 201 | * fine for audio infoframe. However calculated value is always lower | ||
| 202 | * by 2 in comparison to fglrx. It breaks displaying anything in case | ||
| 203 | * of TVs that strictly check the checksum. Hack it manually here to | ||
| 204 | * workaround this issue. */ | ||
| 205 | frame[0x0] += 2; | ||
| 199 | 206 | ||
| 200 | WREG32(offset+R600_HDMI_VIDEOINFOFRAME_0, | 207 | WREG32(offset+R600_HDMI_VIDEOINFOFRAME_0, |
| 201 | frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); | 208 | frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); |
| @@ -313,7 +320,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod | |||
| 313 | struct radeon_device *rdev = dev->dev_private; | 320 | struct radeon_device *rdev = dev->dev_private; |
| 314 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; | 321 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; |
| 315 | 322 | ||
| 316 | if (ASIC_IS_DCE4(rdev)) | 323 | if (ASIC_IS_DCE5(rdev)) |
| 317 | return; | 324 | return; |
| 318 | 325 | ||
| 319 | if (!offset) | 326 | if (!offset) |
| @@ -455,13 +462,31 @@ static void r600_hdmi_assign_block(struct drm_encoder *encoder) | |||
| 455 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 462 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 456 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 463 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 457 | 464 | ||
| 465 | u16 eg_offsets[] = { | ||
| 466 | EVERGREEN_CRTC0_REGISTER_OFFSET, | ||
| 467 | EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
| 468 | EVERGREEN_CRTC2_REGISTER_OFFSET, | ||
| 469 | EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
| 470 | EVERGREEN_CRTC4_REGISTER_OFFSET, | ||
| 471 | EVERGREEN_CRTC5_REGISTER_OFFSET, | ||
| 472 | }; | ||
| 473 | |||
| 458 | if (!dig) { | 474 | if (!dig) { |
| 459 | dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n"); | 475 | dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n"); |
| 460 | return; | 476 | return; |
| 461 | } | 477 | } |
| 462 | 478 | ||
| 463 | if (ASIC_IS_DCE4(rdev)) { | 479 | if (ASIC_IS_DCE5(rdev)) { |
| 464 | /* TODO */ | 480 | /* TODO */ |
| 481 | } else if (ASIC_IS_DCE4(rdev)) { | ||
| 482 | if (dig->dig_encoder >= ARRAY_SIZE(eg_offsets)) { | ||
| 483 | dev_err(rdev->dev, "Enabling HDMI on unknown dig\n"); | ||
| 484 | return; | ||
| 485 | } | ||
| 486 | radeon_encoder->hdmi_offset = EVERGREEN_HDMI_BASE + | ||
| 487 | eg_offsets[dig->dig_encoder]; | ||
| 488 | radeon_encoder->hdmi_config_offset = radeon_encoder->hdmi_offset | ||
| 489 | + EVERGREEN_HDMI_CONFIG_OFFSET; | ||
| 465 | } else if (ASIC_IS_DCE3(rdev)) { | 490 | } else if (ASIC_IS_DCE3(rdev)) { |
| 466 | radeon_encoder->hdmi_offset = dig->dig_encoder ? | 491 | radeon_encoder->hdmi_offset = dig->dig_encoder ? |
| 467 | R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1; | 492 | R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1; |
| @@ -484,7 +509,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder) | |||
| 484 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 509 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 485 | uint32_t offset; | 510 | uint32_t offset; |
| 486 | 511 | ||
| 487 | if (ASIC_IS_DCE4(rdev)) | 512 | if (ASIC_IS_DCE5(rdev)) |
| 488 | return; | 513 | return; |
| 489 | 514 | ||
| 490 | if (!radeon_encoder->hdmi_offset) { | 515 | if (!radeon_encoder->hdmi_offset) { |
| @@ -497,16 +522,24 @@ void r600_hdmi_enable(struct drm_encoder *encoder) | |||
| 497 | } | 522 | } |
| 498 | 523 | ||
| 499 | offset = radeon_encoder->hdmi_offset; | 524 | offset = radeon_encoder->hdmi_offset; |
| 500 | if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) { | 525 | if (ASIC_IS_DCE5(rdev)) { |
| 526 | /* TODO */ | ||
| 527 | } else if (ASIC_IS_DCE4(rdev)) { | ||
| 528 | WREG32_P(radeon_encoder->hdmi_config_offset + 0xc, 0x1, ~0x1); | ||
| 529 | } else if (ASIC_IS_DCE32(rdev)) { | ||
| 501 | WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1); | 530 | WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1); |
| 502 | } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { | 531 | } else if (ASIC_IS_DCE3(rdev)) { |
| 532 | /* TODO */ | ||
| 533 | } else if (rdev->family >= CHIP_R600) { | ||
| 503 | switch (radeon_encoder->encoder_id) { | 534 | switch (radeon_encoder->encoder_id) { |
| 504 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | 535 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: |
| 505 | WREG32_P(AVIVO_TMDSA_CNTL, 0x4, ~0x4); | 536 | WREG32_P(AVIVO_TMDSA_CNTL, AVIVO_TMDSA_CNTL_HDMI_EN, |
| 537 | ~AVIVO_TMDSA_CNTL_HDMI_EN); | ||
| 506 | WREG32(offset + R600_HDMI_ENABLE, 0x101); | 538 | WREG32(offset + R600_HDMI_ENABLE, 0x101); |
| 507 | break; | 539 | break; |
| 508 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | 540 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: |
| 509 | WREG32_P(AVIVO_LVTMA_CNTL, 0x4, ~0x4); | 541 | WREG32_P(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN, |
| 542 | ~AVIVO_LVTMA_CNTL_HDMI_EN); | ||
| 510 | WREG32(offset + R600_HDMI_ENABLE, 0x105); | 543 | WREG32(offset + R600_HDMI_ENABLE, 0x105); |
| 511 | break; | 544 | break; |
| 512 | default: | 545 | default: |
| @@ -518,8 +551,8 @@ void r600_hdmi_enable(struct drm_encoder *encoder) | |||
| 518 | if (rdev->irq.installed | 551 | if (rdev->irq.installed |
| 519 | && rdev->family != CHIP_RS600 | 552 | && rdev->family != CHIP_RS600 |
| 520 | && rdev->family != CHIP_RS690 | 553 | && rdev->family != CHIP_RS690 |
| 521 | && rdev->family != CHIP_RS740) { | 554 | && rdev->family != CHIP_RS740 |
| 522 | 555 | && !ASIC_IS_DCE4(rdev)) { | |
| 523 | /* if irq is available use it */ | 556 | /* if irq is available use it */ |
| 524 | rdev->irq.hdmi[offset == R600_HDMI_BLOCK1 ? 0 : 1] = true; | 557 | rdev->irq.hdmi[offset == R600_HDMI_BLOCK1 ? 0 : 1] = true; |
| 525 | radeon_irq_set(rdev); | 558 | radeon_irq_set(rdev); |
| @@ -544,7 +577,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder) | |||
| 544 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 577 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 545 | uint32_t offset; | 578 | uint32_t offset; |
| 546 | 579 | ||
| 547 | if (ASIC_IS_DCE4(rdev)) | 580 | if (ASIC_IS_DCE5(rdev)) |
| 548 | return; | 581 | return; |
| 549 | 582 | ||
| 550 | offset = radeon_encoder->hdmi_offset; | 583 | offset = radeon_encoder->hdmi_offset; |
| @@ -563,16 +596,22 @@ void r600_hdmi_disable(struct drm_encoder *encoder) | |||
| 563 | /* disable polling */ | 596 | /* disable polling */ |
| 564 | r600_audio_disable_polling(encoder); | 597 | r600_audio_disable_polling(encoder); |
| 565 | 598 | ||
| 566 | if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) { | 599 | if (ASIC_IS_DCE5(rdev)) { |
| 600 | /* TODO */ | ||
| 601 | } else if (ASIC_IS_DCE4(rdev)) { | ||
| 602 | WREG32_P(radeon_encoder->hdmi_config_offset + 0xc, 0, ~0x1); | ||
| 603 | } else if (ASIC_IS_DCE32(rdev)) { | ||
| 567 | WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1); | 604 | WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1); |
| 568 | } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { | 605 | } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { |
| 569 | switch (radeon_encoder->encoder_id) { | 606 | switch (radeon_encoder->encoder_id) { |
| 570 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | 607 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: |
| 571 | WREG32_P(AVIVO_TMDSA_CNTL, 0, ~0x4); | 608 | WREG32_P(AVIVO_TMDSA_CNTL, 0, |
| 609 | ~AVIVO_TMDSA_CNTL_HDMI_EN); | ||
| 572 | WREG32(offset + R600_HDMI_ENABLE, 0); | 610 | WREG32(offset + R600_HDMI_ENABLE, 0); |
| 573 | break; | 611 | break; |
| 574 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | 612 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: |
| 575 | WREG32_P(AVIVO_LVTMA_CNTL, 0, ~0x4); | 613 | WREG32_P(AVIVO_LVTMA_CNTL, 0, |
| 614 | ~AVIVO_LVTMA_CNTL_HDMI_EN); | ||
| 576 | WREG32(offset + R600_HDMI_ENABLE, 0); | 615 | WREG32(offset + R600_HDMI_ENABLE, 0); |
| 577 | break; | 616 | break; |
| 578 | default: | 617 | default: |
