linux/drivers/gpu/drm/radeon/dce6_afmt.c
<<
>>
Prefs
   1/*
   2 * Copyright 2013 Advanced Micro Devices, Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 */
  23#include <linux/hdmi.h>
  24
  25#include "dce6_afmt.h"
  26#include "radeon.h"
  27#include "radeon_audio.h"
  28#include "sid.h"
  29
  30#define DCE8_DCCG_AUDIO_DTO1_PHASE      0x05b8
  31#define DCE8_DCCG_AUDIO_DTO1_MODULE     0x05bc
  32
  33u32 dce6_endpoint_rreg(struct radeon_device *rdev,
  34                              u32 block_offset, u32 reg)
  35{
  36        unsigned long flags;
  37        u32 r;
  38
  39        spin_lock_irqsave(&rdev->end_idx_lock, flags);
  40        WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
  41        r = RREG32(AZ_F0_CODEC_ENDPOINT_DATA + block_offset);
  42        spin_unlock_irqrestore(&rdev->end_idx_lock, flags);
  43
  44        return r;
  45}
  46
  47void dce6_endpoint_wreg(struct radeon_device *rdev,
  48                               u32 block_offset, u32 reg, u32 v)
  49{
  50        unsigned long flags;
  51
  52        spin_lock_irqsave(&rdev->end_idx_lock, flags);
  53        if (ASIC_IS_DCE8(rdev))
  54                WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
  55        else
  56                WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset,
  57                       AZ_ENDPOINT_REG_WRITE_EN | AZ_ENDPOINT_REG_INDEX(reg));
  58        WREG32(AZ_F0_CODEC_ENDPOINT_DATA + block_offset, v);
  59        spin_unlock_irqrestore(&rdev->end_idx_lock, flags);
  60}
  61
  62static void dce6_afmt_get_connected_pins(struct radeon_device *rdev)
  63{
  64        int i;
  65        u32 offset, tmp;
  66
  67        for (i = 0; i < rdev->audio.num_pins; i++) {
  68                offset = rdev->audio.pin[i].offset;
  69                tmp = RREG32_ENDPOINT(offset,
  70                                      AZ_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT);
  71                if (((tmp & PORT_CONNECTIVITY_MASK) >> PORT_CONNECTIVITY_SHIFT) == 1)
  72                        rdev->audio.pin[i].connected = false;
  73                else
  74                        rdev->audio.pin[i].connected = true;
  75        }
  76}
  77
  78struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev)
  79{
  80        struct drm_encoder *encoder;
  81        struct radeon_encoder *radeon_encoder;
  82        struct radeon_encoder_atom_dig *dig;
  83        struct r600_audio_pin *pin = NULL;
  84        int i, pin_count;
  85
  86        dce6_afmt_get_connected_pins(rdev);
  87
  88        for (i = 0; i < rdev->audio.num_pins; i++) {
  89                if (rdev->audio.pin[i].connected) {
  90                        pin = &rdev->audio.pin[i];
  91                        pin_count = 0;
  92
  93                        list_for_each_entry(encoder, &rdev->ddev->mode_config.encoder_list, head) {
  94                                if (radeon_encoder_is_digital(encoder)) {
  95                                        radeon_encoder = to_radeon_encoder(encoder);
  96                                        dig = radeon_encoder->enc_priv;
  97                                        if (dig->pin == pin)
  98                                                pin_count++;
  99                                }
 100                        }
 101
 102                        if (pin_count == 0)
 103                                return pin;
 104                }
 105        }
 106        if (!pin)
 107                DRM_ERROR("No connected audio pins found!\n");
 108        return pin;
 109}
 110
 111void dce6_afmt_select_pin(struct drm_encoder *encoder)
 112{
 113        struct radeon_device *rdev = encoder->dev->dev_private;
 114        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 115        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 116
 117        if (!dig || !dig->afmt || !dig->pin)
 118                return;
 119
 120        WREG32(AFMT_AUDIO_SRC_CONTROL +  dig->afmt->offset,
 121               AFMT_AUDIO_SRC_SELECT(dig->pin->id));
 122}
 123
 124void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
 125                                    struct drm_connector *connector,
 126                                    struct drm_display_mode *mode)
 127{
 128        struct radeon_device *rdev = encoder->dev->dev_private;
 129        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 130        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 131        u32 tmp = 0;
 132
 133        if (!dig || !dig->afmt || !dig->pin)
 134                return;
 135
 136        if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
 137                if (connector->latency_present[1])
 138                        tmp = VIDEO_LIPSYNC(connector->video_latency[1]) |
 139                                AUDIO_LIPSYNC(connector->audio_latency[1]);
 140                else
 141                        tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0);
 142        } else {
 143                if (connector->latency_present[0])
 144                        tmp = VIDEO_LIPSYNC(connector->video_latency[0]) |
 145                                AUDIO_LIPSYNC(connector->audio_latency[0]);
 146                else
 147                        tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0);
 148        }
 149        WREG32_ENDPOINT(dig->pin->offset,
 150                        AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp);
 151}
 152
 153void dce6_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder,
 154                                             u8 *sadb, int sad_count)
 155{
 156        struct radeon_device *rdev = encoder->dev->dev_private;
 157        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 158        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 159        u32 tmp;
 160
 161        if (!dig || !dig->afmt || !dig->pin)
 162                return;
 163
 164        /* program the speaker allocation */
 165        tmp = RREG32_ENDPOINT(dig->pin->offset,
 166                              AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
 167        tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK);
 168        /* set HDMI mode */
 169        tmp |= HDMI_CONNECTION;
 170        if (sad_count)
 171                tmp |= SPEAKER_ALLOCATION(sadb[0]);
 172        else
 173                tmp |= SPEAKER_ALLOCATION(5); /* stereo */
 174        WREG32_ENDPOINT(dig->pin->offset,
 175                        AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp);
 176}
 177
 178void dce6_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder,
 179                                           u8 *sadb, int sad_count)
 180{
 181        struct radeon_device *rdev = encoder->dev->dev_private;
 182        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 183        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 184        u32 tmp;
 185
 186        if (!dig || !dig->afmt || !dig->pin)
 187                return;
 188
 189        /* program the speaker allocation */
 190        tmp = RREG32_ENDPOINT(dig->pin->offset,
 191                              AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
 192        tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK);
 193        /* set DP mode */
 194        tmp |= DP_CONNECTION;
 195        if (sad_count)
 196                tmp |= SPEAKER_ALLOCATION(sadb[0]);
 197        else
 198                tmp |= SPEAKER_ALLOCATION(5); /* stereo */
 199        WREG32_ENDPOINT(dig->pin->offset,
 200                        AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp);
 201}
 202
 203void dce6_afmt_write_sad_regs(struct drm_encoder *encoder,
 204                              struct cea_sad *sads, int sad_count)
 205{
 206        int i;
 207        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 208        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 209        struct radeon_device *rdev = encoder->dev->dev_private;
 210        static const u16 eld_reg_to_type[][2] = {
 211                { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM },
 212                { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 },
 213                { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR2, HDMI_AUDIO_CODING_TYPE_MPEG1 },
 214                { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR3, HDMI_AUDIO_CODING_TYPE_MP3 },
 215                { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR4, HDMI_AUDIO_CODING_TYPE_MPEG2 },
 216                { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR5, HDMI_AUDIO_CODING_TYPE_AAC_LC },
 217                { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR6, HDMI_AUDIO_CODING_TYPE_DTS },
 218                { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR7, HDMI_AUDIO_CODING_TYPE_ATRAC },
 219                { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR9, HDMI_AUDIO_CODING_TYPE_EAC3 },
 220                { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR10, HDMI_AUDIO_CODING_TYPE_DTS_HD },
 221                { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR11, HDMI_AUDIO_CODING_TYPE_MLP },
 222                { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO },
 223        };
 224
 225        if (!dig || !dig->afmt || !dig->pin)
 226                return;
 227
 228        for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) {
 229                u32 value = 0;
 230                u8 stereo_freqs = 0;
 231                int max_channels = -1;
 232                int j;
 233
 234                for (j = 0; j < sad_count; j++) {
 235                        struct cea_sad *sad = &sads[j];
 236
 237                        if (sad->format == eld_reg_to_type[i][1]) {
 238                                if (sad->channels > max_channels) {
 239                                        value = MAX_CHANNELS(sad->channels) |
 240                                                DESCRIPTOR_BYTE_2(sad->byte2) |
 241                                                SUPPORTED_FREQUENCIES(sad->freq);
 242                                        max_channels = sad->channels;
 243                                }
 244
 245                                if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM)
 246                                        stereo_freqs |= sad->freq;
 247                                else
 248                                        break;
 249                        }
 250                }
 251
 252                value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs);
 253
 254                WREG32_ENDPOINT(dig->pin->offset, eld_reg_to_type[i][0], value);
 255        }
 256}
 257
 258void dce6_audio_enable(struct radeon_device *rdev,
 259                       struct r600_audio_pin *pin,
 260                       u8 enable_mask)
 261{
 262        if (!pin)
 263                return;
 264
 265        WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
 266                        enable_mask ? AUDIO_ENABLED : 0);
 267}
 268
 269void dce6_hdmi_audio_set_dto(struct radeon_device *rdev,
 270                             struct radeon_crtc *crtc, unsigned int clock)
 271{
 272        /* Two dtos; generally use dto0 for HDMI */
 273        u32 value = 0;
 274
 275        if (crtc)
 276                value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
 277
 278        WREG32(DCCG_AUDIO_DTO_SOURCE, value);
 279
 280        /* Express [24MHz / target pixel clock] as an exact rational
 281         * number (coefficient of two integer numbers.  DCCG_AUDIO_DTOx_PHASE
 282         * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
 283         */
 284        WREG32(DCCG_AUDIO_DTO0_PHASE, 24000);
 285        WREG32(DCCG_AUDIO_DTO0_MODULE, clock);
 286}
 287
 288void dce6_dp_audio_set_dto(struct radeon_device *rdev,
 289                           struct radeon_crtc *crtc, unsigned int clock)
 290{
 291        /* Two dtos; generally use dto1 for DP */
 292        u32 value = 0;
 293        value |= DCCG_AUDIO_DTO_SEL;
 294
 295        if (crtc)
 296                value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
 297
 298        WREG32(DCCG_AUDIO_DTO_SOURCE, value);
 299
 300        /* Express [24MHz / target pixel clock] as an exact rational
 301         * number (coefficient of two integer numbers.  DCCG_AUDIO_DTOx_PHASE
 302         * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
 303         */
 304        if (ASIC_IS_DCE8(rdev)) {
 305                unsigned int div = (RREG32(DENTIST_DISPCLK_CNTL) &
 306                        DENTIST_DPREFCLK_WDIVIDER_MASK) >>
 307                        DENTIST_DPREFCLK_WDIVIDER_SHIFT;
 308                div = radeon_audio_decode_dfs_div(div);
 309
 310                if (div)
 311                        clock = clock * 100 / div;
 312
 313                WREG32(DCE8_DCCG_AUDIO_DTO1_PHASE, 24000);
 314                WREG32(DCE8_DCCG_AUDIO_DTO1_MODULE, clock);
 315        } else {
 316                WREG32(DCCG_AUDIO_DTO1_PHASE, 24000);
 317                WREG32(DCCG_AUDIO_DTO1_MODULE, clock);
 318        }
 319}
 320