Rev 5078 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5078 | Rev 5271 | ||
---|---|---|---|
Line 69... | Line 69... | ||
69 | { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */ |
69 | { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */ |
70 | }; |
70 | }; |
Line 71... | Line 71... | ||
71 | 71 | ||
- | 72 | ||
- | 73 | /* |
|
- | 74 | * check if the chipset is supported |
|
- | 75 | */ |
|
- | 76 | static int r600_audio_chipset_supported(struct radeon_device *rdev) |
|
- | 77 | { |
|
- | 78 | return ASIC_IS_DCE2(rdev) && !ASIC_IS_NODCE(rdev); |
|
- | 79 | } |
|
- | 80 | ||
- | 81 | static struct r600_audio_pin r600_audio_status(struct radeon_device *rdev) |
|
- | 82 | { |
|
- | 83 | struct r600_audio_pin status; |
|
- | 84 | uint32_t value; |
|
- | 85 | ||
- | 86 | value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL); |
|
- | 87 | ||
- | 88 | /* number of channels */ |
|
- | 89 | status.channels = (value & 0x7) + 1; |
|
- | 90 | ||
- | 91 | /* bits per sample */ |
|
- | 92 | switch ((value & 0xF0) >> 4) { |
|
- | 93 | case 0x0: |
|
- | 94 | status.bits_per_sample = 8; |
|
- | 95 | break; |
|
- | 96 | case 0x1: |
|
- | 97 | status.bits_per_sample = 16; |
|
- | 98 | break; |
|
- | 99 | case 0x2: |
|
- | 100 | status.bits_per_sample = 20; |
|
- | 101 | break; |
|
- | 102 | case 0x3: |
|
- | 103 | status.bits_per_sample = 24; |
|
- | 104 | break; |
|
- | 105 | case 0x4: |
|
- | 106 | status.bits_per_sample = 32; |
|
- | 107 | break; |
|
- | 108 | default: |
|
- | 109 | dev_err(rdev->dev, "Unknown bits per sample 0x%x, using 16\n", |
|
- | 110 | (int)value); |
|
- | 111 | status.bits_per_sample = 16; |
|
- | 112 | } |
|
- | 113 | ||
- | 114 | /* current sampling rate in HZ */ |
|
- | 115 | if (value & 0x4000) |
|
- | 116 | status.rate = 44100; |
|
- | 117 | else |
|
- | 118 | status.rate = 48000; |
|
- | 119 | status.rate *= ((value >> 11) & 0x7) + 1; |
|
- | 120 | status.rate /= ((value >> 8) & 0x7) + 1; |
|
- | 121 | ||
- | 122 | value = RREG32(R600_AUDIO_STATUS_BITS); |
|
- | 123 | ||
- | 124 | /* iec 60958 status bits */ |
|
- | 125 | status.status_bits = value & 0xff; |
|
- | 126 | ||
- | 127 | /* iec 60958 category code */ |
|
- | 128 | status.category_code = (value >> 8) & 0xff; |
|
- | 129 | ||
- | 130 | return status; |
|
- | 131 | } |
|
- | 132 | ||
- | 133 | /* |
|
- | 134 | * update all hdmi interfaces with current audio parameters |
|
- | 135 | */ |
|
- | 136 | void r600_audio_update_hdmi(struct work_struct *work) |
|
- | 137 | { |
|
- | 138 | struct radeon_device *rdev = container_of(work, struct radeon_device, |
|
- | 139 | audio_work); |
|
- | 140 | struct drm_device *dev = rdev->ddev; |
|
- | 141 | struct r600_audio_pin audio_status = r600_audio_status(rdev); |
|
- | 142 | struct drm_encoder *encoder; |
|
- | 143 | bool changed = false; |
|
- | 144 | ||
- | 145 | if (rdev->audio.pin[0].channels != audio_status.channels || |
|
- | 146 | rdev->audio.pin[0].rate != audio_status.rate || |
|
- | 147 | rdev->audio.pin[0].bits_per_sample != audio_status.bits_per_sample || |
|
- | 148 | rdev->audio.pin[0].status_bits != audio_status.status_bits || |
|
- | 149 | rdev->audio.pin[0].category_code != audio_status.category_code) { |
|
- | 150 | rdev->audio.pin[0] = audio_status; |
|
- | 151 | changed = true; |
|
- | 152 | } |
|
- | 153 | ||
- | 154 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
|
- | 155 | if (!radeon_encoder_is_digital(encoder)) |
|
- | 156 | continue; |
|
- | 157 | if (changed || r600_hdmi_buffer_status_changed(encoder)) |
|
- | 158 | r600_hdmi_update_audio_settings(encoder); |
|
- | 159 | } |
|
- | 160 | } |
|
- | 161 | ||
- | 162 | /* enable the audio stream */ |
|
- | 163 | void r600_audio_enable(struct radeon_device *rdev, |
|
- | 164 | struct r600_audio_pin *pin, |
|
- | 165 | u8 enable_mask) |
|
- | 166 | { |
|
- | 167 | u32 tmp = RREG32(AZ_HOT_PLUG_CONTROL); |
|
- | 168 | ||
- | 169 | if (!pin) |
|
- | 170 | return; |
|
- | 171 | ||
- | 172 | if (enable_mask) { |
|
- | 173 | tmp |= AUDIO_ENABLED; |
|
- | 174 | if (enable_mask & 1) |
|
- | 175 | tmp |= PIN0_AUDIO_ENABLED; |
|
- | 176 | if (enable_mask & 2) |
|
- | 177 | tmp |= PIN1_AUDIO_ENABLED; |
|
- | 178 | if (enable_mask & 4) |
|
- | 179 | tmp |= PIN2_AUDIO_ENABLED; |
|
- | 180 | if (enable_mask & 8) |
|
- | 181 | tmp |= PIN3_AUDIO_ENABLED; |
|
- | 182 | } else { |
|
- | 183 | tmp &= ~(AUDIO_ENABLED | |
|
- | 184 | PIN0_AUDIO_ENABLED | |
|
- | 185 | PIN1_AUDIO_ENABLED | |
|
- | 186 | PIN2_AUDIO_ENABLED | |
|
- | 187 | PIN3_AUDIO_ENABLED); |
|
- | 188 | } |
|
- | 189 | ||
- | 190 | WREG32(AZ_HOT_PLUG_CONTROL, tmp); |
|
- | 191 | } |
|
- | 192 | ||
- | 193 | /* |
|
- | 194 | * initialize the audio vars |
|
- | 195 | */ |
|
- | 196 | int r600_audio_init(struct radeon_device *rdev) |
|
- | 197 | { |
|
- | 198 | if (!radeon_audio || !r600_audio_chipset_supported(rdev)) |
|
- | 199 | return 0; |
|
- | 200 | ||
- | 201 | rdev->audio.enabled = true; |
|
- | 202 | ||
- | 203 | rdev->audio.num_pins = 1; |
|
- | 204 | rdev->audio.pin[0].channels = -1; |
|
- | 205 | rdev->audio.pin[0].rate = -1; |
|
- | 206 | rdev->audio.pin[0].bits_per_sample = -1; |
|
- | 207 | rdev->audio.pin[0].status_bits = 0; |
|
- | 208 | rdev->audio.pin[0].category_code = 0; |
|
- | 209 | rdev->audio.pin[0].id = 0; |
|
- | 210 | /* disable audio. it will be set up later */ |
|
- | 211 | r600_audio_enable(rdev, &rdev->audio.pin[0], 0); |
|
- | 212 | ||
- | 213 | return 0; |
|
- | 214 | } |
|
- | 215 | ||
- | 216 | /* |
|
- | 217 | * release the audio timer |
|
- | 218 | * TODO: How to do this correctly on SMP systems? |
|
- | 219 | */ |
|
- | 220 | void r600_audio_fini(struct radeon_device *rdev) |
|
- | 221 | { |
|
- | 222 | if (!rdev->audio.enabled) |
|
- | 223 | return; |
|
- | 224 | ||
- | 225 | r600_audio_enable(rdev, &rdev->audio.pin[0], 0); |
|
- | 226 | ||
- | 227 | rdev->audio.enabled = false; |
|
- | 228 | } |
|
- | 229 | ||
- | 230 | struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev) |
|
- | 231 | { |
|
- | 232 | /* only one pin on 6xx-NI */ |
|
- | 233 | return &rdev->audio.pin[0]; |
|
- | 234 | } |
|
72 | 235 | ||
73 | /* |
236 | /* |
74 | * calculate CTS and N values if they are not found in the table |
237 | * calculate CTS and N values if they are not found in the table |
75 | */ |
238 | */ |
76 | static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq) |
239 | static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq) |
Line 354... | Line 517... | ||
354 | return; |
517 | return; |
355 | offset = dig->afmt->offset; |
518 | offset = dig->afmt->offset; |
Line 356... | Line 519... | ||
356 | 519 | ||
357 | /* disable audio prior to setting up hw */ |
520 | /* disable audio prior to setting up hw */ |
358 | dig->afmt->pin = r600_audio_get_pin(rdev); |
521 | dig->afmt->pin = r600_audio_get_pin(rdev); |
Line 359... | Line 522... | ||
359 | r600_audio_enable(rdev, dig->afmt->pin, false); |
522 | r600_audio_enable(rdev, dig->afmt->pin, 0xf); |
Line 360... | Line 523... | ||
360 | 523 | ||
361 | r600_audio_set_dto(encoder, mode->clock); |
524 | r600_audio_set_dto(encoder, mode->clock); |
Line 440... | Line 603... | ||
440 | WREG32(HDMI0_RAMP_CONTROL1 + offset, 0x007FFFFF); |
603 | WREG32(HDMI0_RAMP_CONTROL1 + offset, 0x007FFFFF); |
441 | WREG32(HDMI0_RAMP_CONTROL2 + offset, 0x00000001); |
604 | WREG32(HDMI0_RAMP_CONTROL2 + offset, 0x00000001); |
442 | WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); |
605 | WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); |
Line 443... | Line 606... | ||
443 | 606 | ||
444 | /* enable audio after to setting up hw */ |
607 | /* enable audio after to setting up hw */ |
445 | r600_audio_enable(rdev, dig->afmt->pin, true); |
608 | r600_audio_enable(rdev, dig->afmt->pin, 0xf); |
Line 446... | Line 609... | ||
446 | } |
609 | } |
447 | 610 | ||
448 | /** |
611 | /** |
Line 525... | Line 688... | ||
525 | if (enable && dig->afmt->enabled) |
688 | if (enable && dig->afmt->enabled) |
526 | return; |
689 | return; |
527 | if (!enable && !dig->afmt->enabled) |
690 | if (!enable && !dig->afmt->enabled) |
528 | return; |
691 | return; |
Line -... | Line 692... | ||
- | 692 | ||
- | 693 | if (!enable && dig->afmt->pin) { |
|
- | 694 | r600_audio_enable(rdev, dig->afmt->pin, 0); |
|
- | 695 | dig->afmt->pin = NULL; |
|
- | 696 | } |
|
529 | 697 | ||
530 | /* Older chipsets require setting HDMI and routing manually */ |
698 | /* Older chipsets require setting HDMI and routing manually */ |
531 | if (!ASIC_IS_DCE3(rdev)) { |
699 | if (!ASIC_IS_DCE3(rdev)) { |
532 | if (enable) |
700 | if (enable) |
533 | hdmi |= HDMI0_ENABLE; |
701 | hdmi |= HDMI0_ENABLE; |