diff options
| author | Rafał Miłecki <zajec5@gmail.com> | 2012-05-14 10:52:30 -0400 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2012-05-17 07:16:03 -0400 |
| commit | cfcbd6d3de7f75f7c5a07d3fac8e1949bbbc79e0 (patch) | |
| tree | 7e09519d9a45658bb8ff3df52964ce29dcda9f51 /drivers/gpu | |
| parent | 0783986ad7244e374dd5e86c650811bf4f01290d (diff) | |
drm/radeon/hdmi: use new AFMT structs
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/radeon/atombios_encoders.c | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/evergreen_hdmi.c | 16 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r600_audio.c | 25 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r600_hdmi.c | 153 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 4 |
5 files changed, 107 insertions, 102 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 04be6b114760..e7b1ec5ae8c6 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
| @@ -2084,6 +2084,7 @@ radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder) | |||
| 2084 | 2084 | ||
| 2085 | static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | 2085 | static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) |
| 2086 | { | 2086 | { |
| 2087 | struct radeon_device *rdev = encoder->dev->dev_private; | ||
| 2087 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 2088 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 2088 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 2089 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
| 2089 | 2090 | ||
| @@ -2092,8 +2093,16 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
| 2092 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != | 2093 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != |
| 2093 | ENCODER_OBJECT_ID_NONE)) { | 2094 | ENCODER_OBJECT_ID_NONE)) { |
| 2094 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 2095 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 2095 | if (dig) | 2096 | if (dig) { |
| 2096 | dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); | 2097 | dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); |
| 2098 | if (radeon_encoder->active_device & ATOM_DEVICE_DFP_SUPPORT) { | ||
| 2099 | if (rdev->family >= CHIP_R600) | ||
| 2100 | dig->afmt = rdev->mode_info.afmt[dig->dig_encoder]; | ||
| 2101 | else | ||
| 2102 | /* RS600/690/740 have only 1 afmt block */ | ||
| 2103 | dig->afmt = rdev->mode_info.afmt[0]; | ||
| 2104 | } | ||
| 2105 | } | ||
| 2097 | } | 2106 | } |
| 2098 | 2107 | ||
| 2099 | radeon_atom_output_lock(encoder, true); | 2108 | radeon_atom_output_lock(encoder, true); |
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index e221f15bb489..a51f880985f8 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c | |||
| @@ -39,7 +39,9 @@ static void evergreen_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t cloc | |||
| 39 | struct drm_device *dev = encoder->dev; | 39 | struct drm_device *dev = encoder->dev; |
| 40 | struct radeon_device *rdev = dev->dev_private; | 40 | struct radeon_device *rdev = dev->dev_private; |
| 41 | struct radeon_hdmi_acr acr = r600_hdmi_acr(clock); | 41 | struct radeon_hdmi_acr acr = r600_hdmi_acr(clock); |
| 42 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; | 42 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 43 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 44 | uint32_t offset = dig->afmt->offset; | ||
| 43 | 45 | ||
| 44 | WREG32(HDMI_ACR_32_0 + offset, HDMI_ACR_CTS_32(acr.cts_32khz)); | 46 | WREG32(HDMI_ACR_32_0 + offset, HDMI_ACR_CTS_32(acr.cts_32khz)); |
| 45 | WREG32(HDMI_ACR_32_1 + offset, acr.n_32khz); | 47 | WREG32(HDMI_ACR_32_1 + offset, acr.n_32khz); |
| @@ -92,7 +94,9 @@ static void evergreen_hdmi_videoinfoframe( | |||
| 92 | { | 94 | { |
| 93 | struct drm_device *dev = encoder->dev; | 95 | struct drm_device *dev = encoder->dev; |
| 94 | struct radeon_device *rdev = dev->dev_private; | 96 | struct radeon_device *rdev = dev->dev_private; |
| 95 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; | 97 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 98 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 99 | uint32_t offset = dig->afmt->offset; | ||
| 96 | 100 | ||
| 97 | uint8_t frame[14]; | 101 | uint8_t frame[14]; |
| 98 | 102 | ||
| @@ -148,13 +152,17 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode | |||
| 148 | { | 152 | { |
| 149 | struct drm_device *dev = encoder->dev; | 153 | struct drm_device *dev = encoder->dev; |
| 150 | struct radeon_device *rdev = dev->dev_private; | 154 | struct radeon_device *rdev = dev->dev_private; |
| 151 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; | 155 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 156 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 157 | uint32_t offset; | ||
| 152 | 158 | ||
| 153 | if (ASIC_IS_DCE5(rdev)) | 159 | if (ASIC_IS_DCE5(rdev)) |
| 154 | return; | 160 | return; |
| 155 | 161 | ||
| 156 | if (!to_radeon_encoder(encoder)->hdmi_enabled) | 162 | /* Silent, r600_hdmi_enable will raise WARN for us */ |
| 163 | if (!dig->afmt->enabled) | ||
| 157 | return; | 164 | return; |
| 165 | offset = dig->afmt->offset; | ||
| 158 | 166 | ||
| 159 | r600_audio_set_clock(encoder, mode->clock); | 167 | r600_audio_set_clock(encoder, mode->clock); |
| 160 | 168 | ||
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index b922a3cd90db..b5a602e71c12 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c | |||
| @@ -30,6 +30,29 @@ | |||
| 30 | #include "atom.h" | 30 | #include "atom.h" |
| 31 | 31 | ||
| 32 | /* | 32 | /* |
| 33 | * check if enc_priv stores radeon_encoder_atom_dig | ||
| 34 | */ | ||
| 35 | static bool radeon_dig_encoder(struct drm_encoder *encoder) | ||
| 36 | { | ||
| 37 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 38 | switch (radeon_encoder->encoder_id) { | ||
| 39 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
| 40 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
| 41 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
| 42 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
| 43 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
| 44 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
| 45 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
| 46 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
| 47 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
| 48 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 49 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 50 | return true; | ||
| 51 | } | ||
| 52 | return false; | ||
| 53 | } | ||
| 54 | |||
| 55 | /* | ||
| 33 | * check if the chipset is supported | 56 | * check if the chipset is supported |
| 34 | */ | 57 | */ |
| 35 | static int r600_audio_chipset_supported(struct radeon_device *rdev) | 58 | static int r600_audio_chipset_supported(struct radeon_device *rdev) |
| @@ -135,6 +158,8 @@ void r600_audio_update_hdmi(struct work_struct *work) | |||
| 135 | } | 158 | } |
| 136 | 159 | ||
| 137 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 160 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
| 161 | if (!radeon_dig_encoder(encoder)) | ||
| 162 | continue; | ||
| 138 | if (changes || r600_hdmi_buffer_status_changed(encoder)) | 163 | if (changes || r600_hdmi_buffer_status_changed(encoder)) |
| 139 | r600_hdmi_update_audio_settings(encoder); | 164 | r600_hdmi_update_audio_settings(encoder); |
| 140 | } | 165 | } |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index c308432445a9..31d19509e1d5 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
| @@ -106,7 +106,9 @@ static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock) | |||
| 106 | struct drm_device *dev = encoder->dev; | 106 | struct drm_device *dev = encoder->dev; |
| 107 | struct radeon_device *rdev = dev->dev_private; | 107 | struct radeon_device *rdev = dev->dev_private; |
| 108 | struct radeon_hdmi_acr acr = r600_hdmi_acr(clock); | 108 | struct radeon_hdmi_acr acr = r600_hdmi_acr(clock); |
| 109 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; | 109 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 110 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 111 | uint32_t offset = dig->afmt->offset; | ||
| 110 | 112 | ||
| 111 | WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(acr.cts_32khz)); | 113 | WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(acr.cts_32khz)); |
| 112 | WREG32(HDMI0_ACR_32_1 + offset, acr.n_32khz); | 114 | WREG32(HDMI0_ACR_32_1 + offset, acr.n_32khz); |
| @@ -159,7 +161,9 @@ static void r600_hdmi_videoinfoframe( | |||
| 159 | { | 161 | { |
| 160 | struct drm_device *dev = encoder->dev; | 162 | struct drm_device *dev = encoder->dev; |
| 161 | struct radeon_device *rdev = dev->dev_private; | 163 | struct radeon_device *rdev = dev->dev_private; |
| 162 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; | 164 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 165 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 166 | uint32_t offset = dig->afmt->offset; | ||
| 163 | 167 | ||
| 164 | uint8_t frame[14]; | 168 | uint8_t frame[14]; |
| 165 | 169 | ||
| @@ -225,7 +229,9 @@ static void r600_hdmi_audioinfoframe( | |||
| 225 | { | 229 | { |
| 226 | struct drm_device *dev = encoder->dev; | 230 | struct drm_device *dev = encoder->dev; |
| 227 | struct radeon_device *rdev = dev->dev_private; | 231 | struct radeon_device *rdev = dev->dev_private; |
| 228 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; | 232 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 233 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 234 | uint32_t offset = dig->afmt->offset; | ||
| 229 | 235 | ||
| 230 | uint8_t frame[11]; | 236 | uint8_t frame[11]; |
| 231 | 237 | ||
| @@ -252,11 +258,13 @@ static void r600_hdmi_audioinfoframe( | |||
| 252 | /* | 258 | /* |
| 253 | * test if audio buffer is filled enough to start playing | 259 | * test if audio buffer is filled enough to start playing |
| 254 | */ | 260 | */ |
| 255 | static int r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder) | 261 | static bool r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder) |
| 256 | { | 262 | { |
| 257 | struct drm_device *dev = encoder->dev; | 263 | struct drm_device *dev = encoder->dev; |
| 258 | struct radeon_device *rdev = dev->dev_private; | 264 | struct radeon_device *rdev = dev->dev_private; |
| 259 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; | 265 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 266 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 267 | uint32_t offset = dig->afmt->offset; | ||
| 260 | 268 | ||
| 261 | return (RREG32(HDMI0_STATUS + offset) & 0x10) != 0; | 269 | return (RREG32(HDMI0_STATUS + offset) & 0x10) != 0; |
| 262 | } | 270 | } |
| @@ -267,14 +275,15 @@ static int r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder) | |||
| 267 | int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder) | 275 | int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder) |
| 268 | { | 276 | { |
| 269 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 277 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 278 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 270 | int status, result; | 279 | int status, result; |
| 271 | 280 | ||
| 272 | if (!radeon_encoder->hdmi_enabled) | 281 | if (!dig->afmt || !dig->afmt->enabled) |
| 273 | return 0; | 282 | return 0; |
| 274 | 283 | ||
| 275 | status = r600_hdmi_is_audio_buffer_filled(encoder); | 284 | status = r600_hdmi_is_audio_buffer_filled(encoder); |
| 276 | result = radeon_encoder->hdmi_buffer_status != status; | 285 | result = dig->afmt->last_buffer_filled_status != status; |
| 277 | radeon_encoder->hdmi_buffer_status = status; | 286 | dig->afmt->last_buffer_filled_status = status; |
| 278 | 287 | ||
| 279 | return result; | 288 | return result; |
| 280 | } | 289 | } |
| @@ -282,28 +291,23 @@ int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder) | |||
| 282 | /* | 291 | /* |
| 283 | * write the audio workaround status to the hardware | 292 | * write the audio workaround status to the hardware |
| 284 | */ | 293 | */ |
| 285 | void r600_hdmi_audio_workaround(struct drm_encoder *encoder) | 294 | static void r600_hdmi_audio_workaround(struct drm_encoder *encoder) |
| 286 | { | 295 | { |
| 287 | struct drm_device *dev = encoder->dev; | 296 | struct drm_device *dev = encoder->dev; |
| 288 | struct radeon_device *rdev = dev->dev_private; | 297 | struct radeon_device *rdev = dev->dev_private; |
| 289 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 298 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 290 | uint32_t offset = radeon_encoder->hdmi_offset; | 299 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 291 | 300 | uint32_t offset = dig->afmt->offset; | |
| 292 | if (!radeon_encoder->hdmi_enabled) | 301 | bool hdmi_audio_workaround = false; /* FIXME */ |
| 293 | return; | 302 | u32 value; |
| 294 | 303 | ||
| 295 | if (!radeon_encoder->hdmi_audio_workaround || | 304 | if (!hdmi_audio_workaround || |
| 296 | r600_hdmi_is_audio_buffer_filled(encoder)) { | 305 | r600_hdmi_is_audio_buffer_filled(encoder)) |
| 297 | 306 | value = 0; /* disable workaround */ | |
| 298 | /* disable audio workaround */ | 307 | else |
| 299 | WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, | 308 | value = HDMI0_AUDIO_TEST_EN; /* enable workaround */ |
| 300 | 0, ~HDMI0_AUDIO_TEST_EN); | 309 | WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, |
| 301 | 310 | value, ~HDMI0_AUDIO_TEST_EN); | |
| 302 | } else { | ||
| 303 | /* enable audio workaround */ | ||
| 304 | WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, | ||
| 305 | HDMI0_AUDIO_TEST_EN, ~HDMI0_AUDIO_TEST_EN); | ||
| 306 | } | ||
| 307 | } | 311 | } |
| 308 | 312 | ||
| 309 | 313 | ||
| @@ -314,13 +318,17 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod | |||
| 314 | { | 318 | { |
| 315 | struct drm_device *dev = encoder->dev; | 319 | struct drm_device *dev = encoder->dev; |
| 316 | struct radeon_device *rdev = dev->dev_private; | 320 | struct radeon_device *rdev = dev->dev_private; |
| 317 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; | 321 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 322 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 323 | uint32_t offset; | ||
| 318 | 324 | ||
| 319 | if (ASIC_IS_DCE5(rdev)) | 325 | if (ASIC_IS_DCE5(rdev)) |
| 320 | return; | 326 | return; |
| 321 | 327 | ||
| 322 | if (!to_radeon_encoder(encoder)->hdmi_enabled) | 328 | /* Silent, r600_hdmi_enable will raise WARN for us */ |
| 329 | if (!dig->afmt->enabled) | ||
| 323 | return; | 330 | return; |
| 331 | offset = dig->afmt->offset; | ||
| 324 | 332 | ||
| 325 | r600_audio_set_clock(encoder, mode->clock); | 333 | r600_audio_set_clock(encoder, mode->clock); |
| 326 | 334 | ||
| @@ -388,7 +396,9 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder) | |||
| 388 | { | 396 | { |
| 389 | struct drm_device *dev = encoder->dev; | 397 | struct drm_device *dev = encoder->dev; |
| 390 | struct radeon_device *rdev = dev->dev_private; | 398 | struct radeon_device *rdev = dev->dev_private; |
| 391 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; | 399 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 400 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 401 | uint32_t offset; | ||
| 392 | 402 | ||
| 393 | int channels = r600_audio_channels(rdev); | 403 | int channels = r600_audio_channels(rdev); |
| 394 | int rate = r600_audio_rate(rdev); | 404 | int rate = r600_audio_rate(rdev); |
| @@ -398,8 +408,9 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder) | |||
| 398 | 408 | ||
| 399 | uint32_t iec; | 409 | uint32_t iec; |
| 400 | 410 | ||
| 401 | if (!to_radeon_encoder(encoder)->hdmi_enabled) | 411 | if (!dig->afmt || !dig->afmt->enabled) |
| 402 | return; | 412 | return; |
| 413 | offset = dig->afmt->offset; | ||
| 403 | 414 | ||
| 404 | DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n", | 415 | DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n", |
| 405 | r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped", | 416 | r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped", |
| @@ -466,50 +477,6 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder) | |||
| 466 | r600_hdmi_audio_workaround(encoder); | 477 | r600_hdmi_audio_workaround(encoder); |
| 467 | } | 478 | } |
| 468 | 479 | ||
| 469 | static void r600_hdmi_assign_block(struct drm_encoder *encoder) | ||
| 470 | { | ||
| 471 | struct drm_device *dev = encoder->dev; | ||
| 472 | struct radeon_device *rdev = dev->dev_private; | ||
| 473 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 474 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 475 | |||
| 476 | u16 eg_offsets[] = { | ||
| 477 | EVERGREEN_CRTC0_REGISTER_OFFSET, | ||
| 478 | EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
| 479 | EVERGREEN_CRTC2_REGISTER_OFFSET, | ||
| 480 | EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
| 481 | EVERGREEN_CRTC4_REGISTER_OFFSET, | ||
| 482 | EVERGREEN_CRTC5_REGISTER_OFFSET, | ||
| 483 | }; | ||
| 484 | |||
| 485 | if (!dig) { | ||
| 486 | dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n"); | ||
| 487 | return; | ||
| 488 | } | ||
| 489 | |||
| 490 | if (ASIC_IS_DCE5(rdev)) { | ||
| 491 | /* TODO */ | ||
| 492 | } else if (ASIC_IS_DCE4(rdev)) { | ||
| 493 | if (dig->dig_encoder >= ARRAY_SIZE(eg_offsets)) { | ||
| 494 | dev_err(rdev->dev, "Enabling HDMI on unknown dig\n"); | ||
| 495 | return; | ||
| 496 | } | ||
| 497 | radeon_encoder->hdmi_offset = eg_offsets[dig->dig_encoder]; | ||
| 498 | } else if (ASIC_IS_DCE3(rdev)) { | ||
| 499 | radeon_encoder->hdmi_offset = dig->dig_encoder ? | ||
| 500 | DCE3_HDMI_OFFSET1 : DCE3_HDMI_OFFSET0; | ||
| 501 | } else if (rdev->family >= CHIP_R600) { | ||
| 502 | /* 2 routable blocks, but using dig_encoder should be fine */ | ||
| 503 | radeon_encoder->hdmi_offset = dig->dig_encoder ? | ||
| 504 | DCE2_HDMI_OFFSET1 : DCE2_HDMI_OFFSET0; | ||
| 505 | } else if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 || | ||
| 506 | rdev->family == CHIP_RS740) { | ||
| 507 | /* Only 1 routable block */ | ||
| 508 | radeon_encoder->hdmi_offset = DCE2_HDMI_OFFSET0; | ||
| 509 | } | ||
| 510 | radeon_encoder->hdmi_enabled = true; | ||
| 511 | } | ||
| 512 | |||
| 513 | /* | 480 | /* |
| 514 | * enable the HDMI engine | 481 | * enable the HDMI engine |
| 515 | */ | 482 | */ |
| @@ -518,22 +485,17 @@ void r600_hdmi_enable(struct drm_encoder *encoder) | |||
| 518 | struct drm_device *dev = encoder->dev; | 485 | struct drm_device *dev = encoder->dev; |
| 519 | struct radeon_device *rdev = dev->dev_private; | 486 | struct radeon_device *rdev = dev->dev_private; |
| 520 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 487 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 488 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 521 | uint32_t offset; | 489 | uint32_t offset; |
| 522 | u32 hdmi; | 490 | u32 hdmi; |
| 523 | 491 | ||
| 524 | if (ASIC_IS_DCE5(rdev)) | 492 | if (ASIC_IS_DCE5(rdev)) |
| 525 | return; | 493 | return; |
| 526 | 494 | ||
| 527 | if (!radeon_encoder->hdmi_enabled) { | 495 | /* Silent, r600_hdmi_enable will raise WARN for us */ |
| 528 | r600_hdmi_assign_block(encoder); | 496 | if (dig->afmt->enabled) |
| 529 | if (!radeon_encoder->hdmi_enabled) { | 497 | return; |
| 530 | dev_warn(rdev->dev, "Could not find HDMI block for " | 498 | offset = dig->afmt->offset; |
| 531 | "0x%x encoder\n", radeon_encoder->encoder_id); | ||
| 532 | return; | ||
| 533 | } | ||
| 534 | } | ||
| 535 | |||
| 536 | offset = radeon_encoder->hdmi_offset; | ||
| 537 | 499 | ||
| 538 | /* Older chipsets require setting HDMI and routing manually */ | 500 | /* Older chipsets require setting HDMI and routing manually */ |
| 539 | if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { | 501 | if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { |
| @@ -566,12 +528,14 @@ void r600_hdmi_enable(struct drm_encoder *encoder) | |||
| 566 | 528 | ||
| 567 | if (rdev->irq.installed) { | 529 | if (rdev->irq.installed) { |
| 568 | /* if irq is available use it */ | 530 | /* if irq is available use it */ |
| 569 | rdev->irq.afmt[offset == 0 ? 0 : 1] = true; | 531 | rdev->irq.afmt[dig->afmt->id] = true; |
| 570 | radeon_irq_set(rdev); | 532 | radeon_irq_set(rdev); |
| 571 | } | 533 | } |
| 572 | 534 | ||
| 535 | dig->afmt->enabled = true; | ||
| 536 | |||
| 573 | DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n", | 537 | DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n", |
| 574 | radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); | 538 | offset, radeon_encoder->encoder_id); |
| 575 | } | 539 | } |
| 576 | 540 | ||
| 577 | /* | 541 | /* |
| @@ -582,22 +546,26 @@ void r600_hdmi_disable(struct drm_encoder *encoder) | |||
| 582 | struct drm_device *dev = encoder->dev; | 546 | struct drm_device *dev = encoder->dev; |
| 583 | struct radeon_device *rdev = dev->dev_private; | 547 | struct radeon_device *rdev = dev->dev_private; |
| 584 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 548 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 549 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 585 | uint32_t offset; | 550 | uint32_t offset; |
| 586 | 551 | ||
| 587 | if (ASIC_IS_DCE5(rdev)) | 552 | if (ASIC_IS_DCE5(rdev)) |
| 588 | return; | 553 | return; |
| 589 | 554 | ||
| 590 | offset = radeon_encoder->hdmi_offset; | 555 | /* Called for ATOM_ENCODER_MODE_HDMI only */ |
| 591 | if (!radeon_encoder->hdmi_enabled) { | 556 | if (!dig || !dig->afmt) { |
| 592 | dev_err(rdev->dev, "Disabling not enabled HDMI\n"); | 557 | WARN_ON(1); |
| 593 | return; | 558 | return; |
| 594 | } | 559 | } |
| 560 | if (!dig->afmt->enabled) | ||
| 561 | return; | ||
| 562 | offset = dig->afmt->offset; | ||
| 595 | 563 | ||
| 596 | DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n", | 564 | DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n", |
| 597 | offset, radeon_encoder->encoder_id); | 565 | offset, radeon_encoder->encoder_id); |
| 598 | 566 | ||
| 599 | /* disable irq */ | 567 | /* disable irq */ |
| 600 | rdev->irq.afmt[offset == 0 ? 0 : 1] = false; | 568 | rdev->irq.afmt[dig->afmt->id] = false; |
| 601 | radeon_irq_set(rdev); | 569 | radeon_irq_set(rdev); |
| 602 | 570 | ||
| 603 | /* Older chipsets not handled by AtomBIOS */ | 571 | /* Older chipsets not handled by AtomBIOS */ |
| @@ -624,6 +592,5 @@ void r600_hdmi_disable(struct drm_encoder *encoder) | |||
| 624 | WREG32(HDMI0_CONTROL + offset, HDMI0_ERROR_ACK); | 592 | WREG32(HDMI0_CONTROL + offset, HDMI0_ERROR_ACK); |
| 625 | } | 593 | } |
| 626 | 594 | ||
| 627 | radeon_encoder->hdmi_enabled = false; | 595 | dig->afmt->enabled = false; |
| 628 | radeon_encoder->hdmi_offset = 0; | ||
| 629 | } | 596 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 9583e953d30b..5b10ffd7bb2f 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -394,10 +394,6 @@ struct radeon_encoder { | |||
| 394 | struct drm_display_mode native_mode; | 394 | struct drm_display_mode native_mode; |
| 395 | void *enc_priv; | 395 | void *enc_priv; |
| 396 | int audio_polling_active; | 396 | int audio_polling_active; |
| 397 | bool hdmi_enabled; | ||
| 398 | int hdmi_offset; | ||
| 399 | int hdmi_audio_workaround; | ||
| 400 | int hdmi_buffer_status; | ||
| 401 | bool is_ext_encoder; | 397 | bool is_ext_encoder; |
| 402 | u16 caps; | 398 | u16 caps; |
| 403 | }; | 399 | }; |
