1b530602fSAlex Deucher /* 2b530602fSAlex Deucher * Copyright 2013 Advanced Micro Devices, Inc. 3b530602fSAlex Deucher * 4b530602fSAlex Deucher * Permission is hereby granted, free of charge, to any person obtaining a 5b530602fSAlex Deucher * copy of this software and associated documentation files (the "Software"), 6b530602fSAlex Deucher * to deal in the Software without restriction, including without limitation 7b530602fSAlex Deucher * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b530602fSAlex Deucher * and/or sell copies of the Software, and to permit persons to whom the 9b530602fSAlex Deucher * Software is furnished to do so, subject to the following conditions: 10b530602fSAlex Deucher * 11b530602fSAlex Deucher * The above copyright notice and this permission notice shall be included in 12b530602fSAlex Deucher * all copies or substantial portions of the Software. 13b530602fSAlex Deucher * 14b530602fSAlex Deucher * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15b530602fSAlex Deucher * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16b530602fSAlex Deucher * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17b530602fSAlex Deucher * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18b530602fSAlex Deucher * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19b530602fSAlex Deucher * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20b530602fSAlex Deucher * OTHER DEALINGS IN THE SOFTWARE. 21b530602fSAlex Deucher * 22b530602fSAlex Deucher */ 23b530602fSAlex Deucher #include <linux/hdmi.h> 24b530602fSAlex Deucher #include <drm/drmP.h> 25b530602fSAlex Deucher #include "radeon.h" 261a626b68SSlava Grigorev #include "radeon_audio.h" 27b530602fSAlex Deucher #include "sid.h" 28b530602fSAlex Deucher 292afa3265SSlava Grigorev #define DCE8_DCCG_AUDIO_DTO1_PHASE 0x05b8 302afa3265SSlava Grigorev #define DCE8_DCCG_AUDIO_DTO1_MODULE 0x05bc 312afa3265SSlava Grigorev 321a626b68SSlava Grigorev u32 dce6_endpoint_rreg(struct radeon_device *rdev, 33b530602fSAlex Deucher u32 block_offset, u32 reg) 34b530602fSAlex Deucher { 350a5b7b0bSAlex Deucher unsigned long flags; 36b530602fSAlex Deucher u32 r; 37b530602fSAlex Deucher 380a5b7b0bSAlex Deucher spin_lock_irqsave(&rdev->end_idx_lock, flags); 39b530602fSAlex Deucher WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, reg); 40b530602fSAlex Deucher r = RREG32(AZ_F0_CODEC_ENDPOINT_DATA + block_offset); 410a5b7b0bSAlex Deucher spin_unlock_irqrestore(&rdev->end_idx_lock, flags); 420a5b7b0bSAlex Deucher 43b530602fSAlex Deucher return r; 44b530602fSAlex Deucher } 45b530602fSAlex Deucher 461a626b68SSlava Grigorev void dce6_endpoint_wreg(struct radeon_device *rdev, 47b530602fSAlex Deucher u32 block_offset, u32 reg, u32 v) 48b530602fSAlex Deucher { 490a5b7b0bSAlex Deucher unsigned long flags; 500a5b7b0bSAlex Deucher 510a5b7b0bSAlex Deucher spin_lock_irqsave(&rdev->end_idx_lock, flags); 52b530602fSAlex Deucher if (ASIC_IS_DCE8(rdev)) 53b530602fSAlex Deucher WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, reg); 54b530602fSAlex Deucher else 55b530602fSAlex Deucher WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, 56b530602fSAlex Deucher AZ_ENDPOINT_REG_WRITE_EN | AZ_ENDPOINT_REG_INDEX(reg)); 57b530602fSAlex Deucher WREG32(AZ_F0_CODEC_ENDPOINT_DATA + block_offset, v); 580a5b7b0bSAlex Deucher spin_unlock_irqrestore(&rdev->end_idx_lock, flags); 59b530602fSAlex Deucher } 60b530602fSAlex Deucher 61b530602fSAlex Deucher static void dce6_afmt_get_connected_pins(struct radeon_device *rdev) 62b530602fSAlex Deucher { 63b530602fSAlex Deucher int i; 64b530602fSAlex Deucher u32 offset, tmp; 65b530602fSAlex Deucher 66b530602fSAlex Deucher for (i = 0; i < rdev->audio.num_pins; i++) { 67b530602fSAlex Deucher offset = rdev->audio.pin[i].offset; 68b530602fSAlex Deucher tmp = RREG32_ENDPOINT(offset, 69b530602fSAlex Deucher AZ_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT); 70b530602fSAlex Deucher if (((tmp & PORT_CONNECTIVITY_MASK) >> PORT_CONNECTIVITY_SHIFT) == 1) 71b530602fSAlex Deucher rdev->audio.pin[i].connected = false; 72b530602fSAlex Deucher else 73b530602fSAlex Deucher rdev->audio.pin[i].connected = true; 74b530602fSAlex Deucher } 75b530602fSAlex Deucher } 76b530602fSAlex Deucher 77b530602fSAlex Deucher struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev) 78b530602fSAlex Deucher { 79b530602fSAlex Deucher int i; 80b530602fSAlex Deucher 81b530602fSAlex Deucher dce6_afmt_get_connected_pins(rdev); 82b530602fSAlex Deucher 83b530602fSAlex Deucher for (i = 0; i < rdev->audio.num_pins; i++) { 84b530602fSAlex Deucher if (rdev->audio.pin[i].connected) 85b530602fSAlex Deucher return &rdev->audio.pin[i]; 86b530602fSAlex Deucher } 87b530602fSAlex Deucher DRM_ERROR("No connected audio pins found!\n"); 88b530602fSAlex Deucher return NULL; 89b530602fSAlex Deucher } 90b530602fSAlex Deucher 91b530602fSAlex Deucher void dce6_afmt_select_pin(struct drm_encoder *encoder) 92b530602fSAlex Deucher { 93b530602fSAlex Deucher struct radeon_device *rdev = encoder->dev->dev_private; 94b530602fSAlex Deucher struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 95b530602fSAlex Deucher struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 96b530602fSAlex Deucher 97d0ea397eSAlex Deucher if (!dig || !dig->afmt || !dig->pin) 98b530602fSAlex Deucher return; 99b530602fSAlex Deucher 100d0ea397eSAlex Deucher WREG32(AFMT_AUDIO_SRC_CONTROL + dig->afmt->offset, 101d0ea397eSAlex Deucher AFMT_AUDIO_SRC_SELECT(dig->pin->id)); 102b530602fSAlex Deucher } 103b530602fSAlex Deucher 104b1880258SAlex Deucher void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, 105d0ea397eSAlex Deucher struct drm_connector *connector, 106d0ea397eSAlex Deucher struct drm_display_mode *mode) 107b1880258SAlex Deucher { 108b1880258SAlex Deucher struct radeon_device *rdev = encoder->dev->dev_private; 109b1880258SAlex Deucher struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 110b1880258SAlex Deucher struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 111d0ea397eSAlex Deucher u32 tmp = 0; 112b1880258SAlex Deucher 113d0ea397eSAlex Deucher if (!dig || !dig->afmt || !dig->pin) 114b1880258SAlex Deucher return; 115b1880258SAlex Deucher 116b1880258SAlex Deucher if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 117b1880258SAlex Deucher if (connector->latency_present[1]) 118b1880258SAlex Deucher tmp = VIDEO_LIPSYNC(connector->video_latency[1]) | 119b1880258SAlex Deucher AUDIO_LIPSYNC(connector->audio_latency[1]); 120b1880258SAlex Deucher else 121c748990bSStefan Brüns tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0); 122b1880258SAlex Deucher } else { 123b1880258SAlex Deucher if (connector->latency_present[0]) 124b1880258SAlex Deucher tmp = VIDEO_LIPSYNC(connector->video_latency[0]) | 125b1880258SAlex Deucher AUDIO_LIPSYNC(connector->audio_latency[0]); 126b1880258SAlex Deucher else 127c748990bSStefan Brüns tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0); 128b1880258SAlex Deucher } 129d0ea397eSAlex Deucher WREG32_ENDPOINT(dig->pin->offset, 130d0ea397eSAlex Deucher AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp); 131b1880258SAlex Deucher } 132b1880258SAlex Deucher 13300a9d4bcSSlava Grigorev void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, 13400a9d4bcSSlava Grigorev u8 *sadb, int sad_count) 1356159b65aSRafał Miłecki { 1366159b65aSRafał Miłecki struct radeon_device *rdev = encoder->dev->dev_private; 1376159b65aSRafał Miłecki struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1386159b65aSRafał Miłecki struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 139d0ea397eSAlex Deucher u32 tmp; 1406159b65aSRafał Miłecki 141d0ea397eSAlex Deucher if (!dig || !dig->afmt || !dig->pin) 1426159b65aSRafał Miłecki return; 1436159b65aSRafał Miłecki 1446159b65aSRafał Miłecki /* program the speaker allocation */ 145d0ea397eSAlex Deucher tmp = RREG32_ENDPOINT(dig->pin->offset, 146d0ea397eSAlex Deucher AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); 1476159b65aSRafał Miłecki tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); 1486159b65aSRafał Miłecki /* set HDMI mode */ 1496159b65aSRafał Miłecki tmp |= HDMI_CONNECTION; 1506159b65aSRafał Miłecki if (sad_count) 1516159b65aSRafał Miłecki tmp |= SPEAKER_ALLOCATION(sadb[0]); 1526159b65aSRafał Miłecki else 1536159b65aSRafał Miłecki tmp |= SPEAKER_ALLOCATION(5); /* stereo */ 154d0ea397eSAlex Deucher WREG32_ENDPOINT(dig->pin->offset, 155d0ea397eSAlex Deucher AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); 15600a9d4bcSSlava Grigorev } 1576159b65aSRafał Miłecki 15800a9d4bcSSlava Grigorev void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, 15900a9d4bcSSlava Grigorev u8 *sadb, int sad_count) 16000a9d4bcSSlava Grigorev { 16100a9d4bcSSlava Grigorev struct radeon_device *rdev = encoder->dev->dev_private; 16200a9d4bcSSlava Grigorev struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 16300a9d4bcSSlava Grigorev struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 164d0ea397eSAlex Deucher u32 tmp; 16500a9d4bcSSlava Grigorev 166d0ea397eSAlex Deucher if (!dig || !dig->afmt || !dig->pin) 16700a9d4bcSSlava Grigorev return; 16800a9d4bcSSlava Grigorev 16900a9d4bcSSlava Grigorev /* program the speaker allocation */ 170d0ea397eSAlex Deucher tmp = RREG32_ENDPOINT(dig->pin->offset, 171d0ea397eSAlex Deucher AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER); 17200a9d4bcSSlava Grigorev tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK); 17300a9d4bcSSlava Grigorev /* set DP mode */ 17400a9d4bcSSlava Grigorev tmp |= DP_CONNECTION; 17500a9d4bcSSlava Grigorev if (sad_count) 17600a9d4bcSSlava Grigorev tmp |= SPEAKER_ALLOCATION(sadb[0]); 17700a9d4bcSSlava Grigorev else 17800a9d4bcSSlava Grigorev tmp |= SPEAKER_ALLOCATION(5); /* stereo */ 179d0ea397eSAlex Deucher WREG32_ENDPOINT(dig->pin->offset, 180d0ea397eSAlex Deucher AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp); 1816159b65aSRafał Miłecki } 1826159b65aSRafał Miłecki 183070a2e63SAlex Deucher void dce6_afmt_write_sad_regs(struct drm_encoder *encoder, 184070a2e63SAlex Deucher struct cea_sad *sads, int sad_count) 185b530602fSAlex Deucher { 186070a2e63SAlex Deucher int i; 187b530602fSAlex Deucher struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 188b530602fSAlex Deucher struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 189070a2e63SAlex Deucher struct radeon_device *rdev = encoder->dev->dev_private; 190b530602fSAlex Deucher static const u16 eld_reg_to_type[][2] = { 191b530602fSAlex Deucher { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, 192b530602fSAlex Deucher { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 }, 193b530602fSAlex Deucher { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR2, HDMI_AUDIO_CODING_TYPE_MPEG1 }, 194b530602fSAlex Deucher { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR3, HDMI_AUDIO_CODING_TYPE_MP3 }, 195b530602fSAlex Deucher { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR4, HDMI_AUDIO_CODING_TYPE_MPEG2 }, 196b530602fSAlex Deucher { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR5, HDMI_AUDIO_CODING_TYPE_AAC_LC }, 197b530602fSAlex Deucher { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR6, HDMI_AUDIO_CODING_TYPE_DTS }, 198b530602fSAlex Deucher { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR7, HDMI_AUDIO_CODING_TYPE_ATRAC }, 199b530602fSAlex Deucher { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR9, HDMI_AUDIO_CODING_TYPE_EAC3 }, 200b530602fSAlex Deucher { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR10, HDMI_AUDIO_CODING_TYPE_DTS_HD }, 201b530602fSAlex Deucher { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR11, HDMI_AUDIO_CODING_TYPE_MLP }, 202b530602fSAlex Deucher { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, 203b530602fSAlex Deucher }; 204b530602fSAlex Deucher 205d0ea397eSAlex Deucher if (!dig || !dig->afmt || !dig->pin) 206b530602fSAlex Deucher return; 207b530602fSAlex Deucher 208b530602fSAlex Deucher for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { 209b530602fSAlex Deucher u32 value = 0; 2100f57bca9SAnssi Hannula u8 stereo_freqs = 0; 2110f57bca9SAnssi Hannula int max_channels = -1; 212b530602fSAlex Deucher int j; 213b530602fSAlex Deucher 214b530602fSAlex Deucher for (j = 0; j < sad_count; j++) { 215b530602fSAlex Deucher struct cea_sad *sad = &sads[j]; 216b530602fSAlex Deucher 217b530602fSAlex Deucher if (sad->format == eld_reg_to_type[i][1]) { 2180f57bca9SAnssi Hannula if (sad->channels > max_channels) { 219b530602fSAlex Deucher value = MAX_CHANNELS(sad->channels) | 220b530602fSAlex Deucher DESCRIPTOR_BYTE_2(sad->byte2) | 221b530602fSAlex Deucher SUPPORTED_FREQUENCIES(sad->freq); 2220f57bca9SAnssi Hannula max_channels = sad->channels; 2230f57bca9SAnssi Hannula } 2240f57bca9SAnssi Hannula 225b530602fSAlex Deucher if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM) 2260f57bca9SAnssi Hannula stereo_freqs |= sad->freq; 2270f57bca9SAnssi Hannula else 228b530602fSAlex Deucher break; 229b530602fSAlex Deucher } 230b530602fSAlex Deucher } 2310f57bca9SAnssi Hannula 2320f57bca9SAnssi Hannula value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); 2330f57bca9SAnssi Hannula 234d0ea397eSAlex Deucher WREG32_ENDPOINT(dig->pin->offset, eld_reg_to_type[i][0], value); 235b530602fSAlex Deucher } 236b530602fSAlex Deucher } 237b530602fSAlex Deucher 238832eafafSAlex Deucher void dce6_audio_enable(struct radeon_device *rdev, 239b530602fSAlex Deucher struct r600_audio_pin *pin, 240d3d8c141SAlex Deucher u8 enable_mask) 241b530602fSAlex Deucher { 242832eafafSAlex Deucher if (!pin) 243832eafafSAlex Deucher return; 244832eafafSAlex Deucher 245f68fdbe4SAlex Deucher WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, 246d3d8c141SAlex Deucher enable_mask ? AUDIO_ENABLED : 0); 247b530602fSAlex Deucher } 248a85d682aSSlava Grigorev 249a85d682aSSlava Grigorev void dce6_hdmi_audio_set_dto(struct radeon_device *rdev, 250a85d682aSSlava Grigorev struct radeon_crtc *crtc, unsigned int clock) 251a85d682aSSlava Grigorev { 252a85d682aSSlava Grigorev /* Two dtos; generally use dto0 for HDMI */ 253a85d682aSSlava Grigorev u32 value = 0; 254a85d682aSSlava Grigorev 255a85d682aSSlava Grigorev if (crtc) 256a85d682aSSlava Grigorev value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); 257a85d682aSSlava Grigorev 258a85d682aSSlava Grigorev WREG32(DCCG_AUDIO_DTO_SOURCE, value); 259a85d682aSSlava Grigorev 260a85d682aSSlava Grigorev /* Express [24MHz / target pixel clock] as an exact rational 261a85d682aSSlava Grigorev * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE 262a85d682aSSlava Grigorev * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator 263a85d682aSSlava Grigorev */ 264a85d682aSSlava Grigorev WREG32(DCCG_AUDIO_DTO0_PHASE, 24000); 265a85d682aSSlava Grigorev WREG32(DCCG_AUDIO_DTO0_MODULE, clock); 266a85d682aSSlava Grigorev } 267a85d682aSSlava Grigorev 268a85d682aSSlava Grigorev void dce6_dp_audio_set_dto(struct radeon_device *rdev, 269a85d682aSSlava Grigorev struct radeon_crtc *crtc, unsigned int clock) 270a85d682aSSlava Grigorev { 271a85d682aSSlava Grigorev /* Two dtos; generally use dto1 for DP */ 272a85d682aSSlava Grigorev u32 value = 0; 273a85d682aSSlava Grigorev value |= DCCG_AUDIO_DTO_SEL; 274a85d682aSSlava Grigorev 275a85d682aSSlava Grigorev if (crtc) 276a85d682aSSlava Grigorev value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); 277a85d682aSSlava Grigorev 278a85d682aSSlava Grigorev WREG32(DCCG_AUDIO_DTO_SOURCE, value); 279a85d682aSSlava Grigorev 280a85d682aSSlava Grigorev /* Express [24MHz / target pixel clock] as an exact rational 281a85d682aSSlava Grigorev * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE 282a85d682aSSlava Grigorev * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator 283a85d682aSSlava Grigorev */ 2842afa3265SSlava Grigorev if (ASIC_IS_DCE8(rdev)) { 2852afa3265SSlava Grigorev WREG32(DCE8_DCCG_AUDIO_DTO1_PHASE, 24000); 2862afa3265SSlava Grigorev WREG32(DCE8_DCCG_AUDIO_DTO1_MODULE, clock); 2872afa3265SSlava Grigorev } else { 288a85d682aSSlava Grigorev WREG32(DCCG_AUDIO_DTO1_PHASE, 24000); 289a85d682aSSlava Grigorev WREG32(DCCG_AUDIO_DTO1_MODULE, clock); 290a85d682aSSlava Grigorev } 2912afa3265SSlava Grigorev } 292