Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

radeon/audio: enable DP audio

Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Slava Grigorev <slava.grigorev@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Slava Grigorev and committed by
Alex Deucher
e55bca26 ccd4be7e

+147
+6
drivers/gpu/drm/radeon/atombios_encoders.c
··· 665 665 int 666 666 atombios_get_encoder_mode(struct drm_encoder *encoder) 667 667 { 668 + struct drm_device *dev = encoder->dev; 669 + struct radeon_device *rdev = dev->dev_private; 668 670 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 669 671 struct drm_connector *connector; 670 672 struct radeon_connector *radeon_connector; ··· 731 729 dig_connector = radeon_connector->con_priv; 732 730 if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || 733 731 (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { 732 + if (radeon_audio != 0 && ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev)) 733 + return ATOM_ENCODER_MODE_DP_AUDIO; 734 734 return ATOM_ENCODER_MODE_DP; 735 735 } else if (radeon_audio != 0) { 736 736 if (radeon_connector->audio == RADEON_AUDIO_ENABLE) ··· 747 743 } 748 744 break; 749 745 case DRM_MODE_CONNECTOR_eDP: 746 + if (radeon_audio != 0 && ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev)) 747 + return ATOM_ENCODER_MODE_DP_AUDIO; 750 748 return ATOM_ENCODER_MODE_DP; 751 749 case DRM_MODE_CONNECTOR_DVIA: 752 750 case DRM_MODE_CONNECTOR_VGA:
+35
drivers/gpu/drm/radeon/dce6_afmt.c
··· 287 287 WREG32(DCCG_AUDIO_DTO1_PHASE, 24000); 288 288 WREG32(DCCG_AUDIO_DTO1_MODULE, clock); 289 289 } 290 + 291 + void dce6_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable) 292 + { 293 + struct drm_device *dev = encoder->dev; 294 + struct radeon_device *rdev = dev->dev_private; 295 + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 296 + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 297 + uint32_t offset; 298 + 299 + if (!dig || !dig->afmt) 300 + return; 301 + 302 + offset = dig->afmt->offset; 303 + 304 + if (enable) { 305 + if (dig->afmt->enabled) 306 + return; 307 + 308 + WREG32(EVERGREEN_DP_SEC_TIMESTAMP + offset, EVERGREEN_DP_SEC_TIMESTAMP_MODE(1)); 309 + WREG32(EVERGREEN_DP_SEC_CNTL + offset, 310 + EVERGREEN_DP_SEC_ASP_ENABLE | /* Audio packet transmission */ 311 + EVERGREEN_DP_SEC_ATP_ENABLE | /* Audio timestamp packet transmission */ 312 + EVERGREEN_DP_SEC_AIP_ENABLE | /* Audio infoframe packet transmission */ 313 + EVERGREEN_DP_SEC_STREAM_ENABLE); /* Master enable for secondary stream engine */ 314 + radeon_audio_enable(rdev, dig->afmt->pin, true); 315 + } else { 316 + if (!dig->afmt->enabled) 317 + return; 318 + 319 + WREG32(EVERGREEN_DP_SEC_CNTL + offset, 0); 320 + radeon_audio_enable(rdev, dig->afmt->pin, false); 321 + } 322 + 323 + dig->afmt->enabled = enable; 324 + }
+54
drivers/gpu/drm/radeon/evergreen_hdmi.c
··· 424 424 DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n", 425 425 enable ? "En" : "Dis", dig->afmt->offset, radeon_encoder->encoder_id); 426 426 } 427 + 428 + void evergreen_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable) 429 + { 430 + struct drm_device *dev = encoder->dev; 431 + struct radeon_device *rdev = dev->dev_private; 432 + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 433 + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 434 + uint32_t offset; 435 + 436 + if (!dig || !dig->afmt) 437 + return; 438 + 439 + offset = dig->afmt->offset; 440 + 441 + if (enable) { 442 + struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); 443 + struct radeon_connector *radeon_connector = to_radeon_connector(connector); 444 + struct radeon_connector_atom_dig *dig_connector; 445 + uint32_t val; 446 + 447 + if (dig->afmt->enabled) 448 + return; 449 + 450 + WREG32(EVERGREEN_DP_SEC_TIMESTAMP + offset, EVERGREEN_DP_SEC_TIMESTAMP_MODE(1)); 451 + 452 + if (radeon_connector->con_priv) { 453 + dig_connector = radeon_connector->con_priv; 454 + val = RREG32(EVERGREEN_DP_SEC_AUD_N + offset); 455 + val &= ~EVERGREEN_DP_SEC_N_BASE_MULTIPLE(0xf); 456 + 457 + if (dig_connector->dp_clock == 162000) 458 + val |= EVERGREEN_DP_SEC_N_BASE_MULTIPLE(3); 459 + else 460 + val |= EVERGREEN_DP_SEC_N_BASE_MULTIPLE(5); 461 + 462 + WREG32(EVERGREEN_DP_SEC_AUD_N + offset, val); 463 + } 464 + 465 + WREG32(EVERGREEN_DP_SEC_CNTL + offset, 466 + EVERGREEN_DP_SEC_ASP_ENABLE | /* Audio packet transmission */ 467 + EVERGREEN_DP_SEC_ATP_ENABLE | /* Audio timestamp packet transmission */ 468 + EVERGREEN_DP_SEC_AIP_ENABLE | /* Audio infoframe packet transmission */ 469 + EVERGREEN_DP_SEC_STREAM_ENABLE); /* Master enable for secondary stream engine */ 470 + radeon_audio_enable(rdev, dig->afmt->pin, 0xf); 471 + } else { 472 + if (!dig->afmt->enabled) 473 + return; 474 + 475 + WREG32(EVERGREEN_DP_SEC_CNTL + offset, 0); 476 + radeon_audio_enable(rdev, dig->afmt->pin, 0); 477 + } 478 + 479 + dig->afmt->enabled = enable; 480 + }
+15
drivers/gpu/drm/radeon/evergreen_reg.h
··· 251 251 /* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ 252 252 #define EVERGREEN_HDMI_BASE 0x7030 253 253 254 + /* Display Port block */ 255 + #define EVERGREEN_DP_SEC_CNTL 0x7280 256 + # define EVERGREEN_DP_SEC_STREAM_ENABLE (1 << 0) 257 + # define EVERGREEN_DP_SEC_ASP_ENABLE (1 << 4) 258 + # define EVERGREEN_DP_SEC_ATP_ENABLE (1 << 8) 259 + # define EVERGREEN_DP_SEC_AIP_ENABLE (1 << 12) 260 + # define EVERGREEN_DP_SEC_GSP_ENABLE (1 << 20) 261 + # define EVERGREEN_DP_SEC_AVI_ENABLE (1 << 24) 262 + # define EVERGREEN_DP_SEC_MPG_ENABLE (1 << 28) 263 + #define EVERGREEN_DP_SEC_TIMESTAMP 0x72a4 264 + # define EVERGREEN_DP_SEC_TIMESTAMP_MODE(x) (((x) & 0x3) << 0) 265 + #define EVERGREEN_DP_SEC_AUD_N 0x7294 266 + # define EVERGREEN_DP_SEC_N_BASE_MULTIPLE(x) (((x) & 0xf) << 24) 267 + # define EVERGREEN_DP_SEC_SS_EN (1 << 28) 268 + 254 269 #endif
+37
drivers/gpu/drm/radeon/radeon_audio.c
··· 97 97 void dce4_set_mute(struct drm_encoder *encoder, u32 offset, bool mute); 98 98 static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, 99 99 struct drm_display_mode *mode); 100 + static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, 101 + struct drm_display_mode *mode); 100 102 void r600_hdmi_enable(struct drm_encoder *encoder, bool enable); 101 103 void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable); 104 + void evergreen_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable); 105 + void dce6_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable); 102 106 103 107 static const u32 pin_offsets[7] = 104 108 { ··· 182 178 .write_speaker_allocation = dce3_2_afmt_dp_write_speaker_allocation, 183 179 .set_dto = dce3_2_audio_set_dto, 184 180 .set_avi_packet = r600_set_avi_packet, 181 + .set_audio_packet = dce3_2_set_audio_packet, 185 182 }; 186 183 187 184 static struct radeon_audio_funcs dce4_hdmi_funcs = { ··· 208 203 .write_latency_fields = dce4_afmt_write_latency_fields, 209 204 .set_dto = dce4_dp_audio_set_dto, 210 205 .set_avi_packet = evergreen_set_avi_packet, 206 + .set_audio_packet = dce4_set_audio_packet, 207 + .mode_set = radeon_audio_dp_mode_set, 208 + .dpms = evergreen_enable_dp_audio_packets, 211 209 }; 212 210 213 211 static struct radeon_audio_funcs dce6_hdmi_funcs = { ··· 238 230 .write_latency_fields = dce6_afmt_write_latency_fields, 239 231 .set_dto = dce6_dp_audio_set_dto, 240 232 .set_avi_packet = evergreen_set_avi_packet, 233 + .set_audio_packet = dce4_set_audio_packet, 234 + .mode_set = radeon_audio_dp_mode_set, 235 + .dpms = dce6_enable_dp_audio_packets, 241 236 }; 242 237 243 238 static void radeon_audio_interface_init(struct radeon_device *rdev) ··· 712 701 radeon_hdmi_set_color_depth(encoder); 713 702 radeon_audio_set_mute(encoder, false); 714 703 radeon_audio_update_acr(encoder, mode->clock); 704 + radeon_audio_set_audio_packet(encoder); 705 + radeon_audio_select_pin(encoder); 706 + 707 + if (radeon_audio_set_avi_packet(encoder, mode) < 0) 708 + return; 709 + 710 + /* enable audio after to setting up hw */ 711 + radeon_audio_enable(rdev, dig->afmt->pin, 0xf); 712 + } 713 + 714 + static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, 715 + struct drm_display_mode *mode) 716 + { 717 + struct drm_device *dev = encoder->dev; 718 + struct radeon_device *rdev = dev->dev_private; 719 + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 720 + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 721 + 722 + if (!dig || !dig->afmt) 723 + return; 724 + 725 + /* disable audio prior to setting up hw */ 726 + dig->afmt->pin = radeon_audio_get_pin(encoder); 727 + radeon_audio_enable(rdev, dig->afmt->pin, 0); 728 + 729 + radeon_audio_set_dto(encoder, rdev->clock.default_dispclk * 10); 715 730 radeon_audio_set_audio_packet(encoder); 716 731 radeon_audio_select_pin(encoder); 717 732