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/drm/radeon | |
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/drm/radeon')
-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 | }; |