537 lines · c
1/*2 * Copyright 2008 Advanced Micro Devices, Inc.3 * Copyright 2008 Red Hat Inc.4 * Copyright 2009 Christian König.5 *6 * Permission is hereby granted, free of charge, to any person obtaining a7 * copy of this software and associated documentation files (the "Software"),8 * to deal in the Software without restriction, including without limitation9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,10 * and/or sell copies of the Software, and to permit persons to whom the11 * Software is furnished to do so, subject to the following conditions:12 *13 * The above copyright notice and this permission notice shall be included in14 * all copies or substantial portions of the Software.15 *16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR22 * OTHER DEALINGS IN THE SOFTWARE.23 *24 * Authors: Christian König25 */26#include <linux/hdmi.h>27#include <linux/gcd.h>28 29#include <drm/radeon_drm.h>30#include "radeon.h"31#include "radeon_asic.h"32#include "radeon_audio.h"33#include "r600.h"34#include "r600d.h"35#include "atom.h"36 37/*38 * HDMI color format39 */40enum r600_hdmi_color_format {41 RGB = 0,42 YCC_422 = 1,43 YCC_444 = 244};45 46/*47 * IEC60958 status bits48 */49enum r600_hdmi_iec_status_bits {50 AUDIO_STATUS_DIG_ENABLE = 0x01,51 AUDIO_STATUS_V = 0x02,52 AUDIO_STATUS_VCFG = 0x04,53 AUDIO_STATUS_EMPHASIS = 0x08,54 AUDIO_STATUS_COPYRIGHT = 0x10,55 AUDIO_STATUS_NONAUDIO = 0x20,56 AUDIO_STATUS_PROFESSIONAL = 0x40,57 AUDIO_STATUS_LEVEL = 0x8058};59 60static struct r600_audio_pin r600_audio_status(struct radeon_device *rdev)61{62 struct r600_audio_pin status = {};63 uint32_t value;64 65 value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL);66 67 /* number of channels */68 status.channels = (value & 0x7) + 1;69 70 /* bits per sample */71 switch ((value & 0xF0) >> 4) {72 case 0x0:73 status.bits_per_sample = 8;74 break;75 case 0x1:76 status.bits_per_sample = 16;77 break;78 case 0x2:79 status.bits_per_sample = 20;80 break;81 case 0x3:82 status.bits_per_sample = 24;83 break;84 case 0x4:85 status.bits_per_sample = 32;86 break;87 default:88 dev_err(rdev->dev, "Unknown bits per sample 0x%x, using 16\n",89 (int)value);90 status.bits_per_sample = 16;91 }92 93 /* current sampling rate in HZ */94 if (value & 0x4000)95 status.rate = 44100;96 else97 status.rate = 48000;98 status.rate *= ((value >> 11) & 0x7) + 1;99 status.rate /= ((value >> 8) & 0x7) + 1;100 101 value = RREG32(R600_AUDIO_STATUS_BITS);102 103 /* iec 60958 status bits */104 status.status_bits = value & 0xff;105 106 /* iec 60958 category code */107 status.category_code = (value >> 8) & 0xff;108 109 return status;110}111 112/*113 * update all hdmi interfaces with current audio parameters114 */115void r600_audio_update_hdmi(struct work_struct *work)116{117 struct radeon_device *rdev = container_of(work, struct radeon_device,118 audio_work);119 struct drm_device *dev = rdev_to_drm(rdev);120 struct r600_audio_pin audio_status = r600_audio_status(rdev);121 struct drm_encoder *encoder;122 bool changed = false;123 124 if (rdev->audio.pin[0].channels != audio_status.channels ||125 rdev->audio.pin[0].rate != audio_status.rate ||126 rdev->audio.pin[0].bits_per_sample != audio_status.bits_per_sample ||127 rdev->audio.pin[0].status_bits != audio_status.status_bits ||128 rdev->audio.pin[0].category_code != audio_status.category_code) {129 rdev->audio.pin[0] = audio_status;130 changed = true;131 }132 133 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {134 if (!radeon_encoder_is_digital(encoder))135 continue;136 if (changed || r600_hdmi_buffer_status_changed(encoder))137 r600_hdmi_update_audio_settings(encoder);138 }139}140 141/* enable the audio stream */142void r600_audio_enable(struct radeon_device *rdev,143 struct r600_audio_pin *pin,144 u8 enable_mask)145{146 u32 tmp = RREG32(AZ_HOT_PLUG_CONTROL);147 148 if (!pin)149 return;150 151 if (enable_mask) {152 tmp |= AUDIO_ENABLED;153 if (enable_mask & 1)154 tmp |= PIN0_AUDIO_ENABLED;155 if (enable_mask & 2)156 tmp |= PIN1_AUDIO_ENABLED;157 if (enable_mask & 4)158 tmp |= PIN2_AUDIO_ENABLED;159 if (enable_mask & 8)160 tmp |= PIN3_AUDIO_ENABLED;161 } else {162 tmp &= ~(AUDIO_ENABLED |163 PIN0_AUDIO_ENABLED |164 PIN1_AUDIO_ENABLED |165 PIN2_AUDIO_ENABLED |166 PIN3_AUDIO_ENABLED);167 }168 169 WREG32(AZ_HOT_PLUG_CONTROL, tmp);170}171 172struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev)173{174 /* only one pin on 6xx-NI */175 return &rdev->audio.pin[0];176}177 178void r600_hdmi_update_acr(struct drm_encoder *encoder, long offset,179 const struct radeon_hdmi_acr *acr)180{181 struct drm_device *dev = encoder->dev;182 struct radeon_device *rdev = dev->dev_private;183 184 /* DCE 3.0 uses register that's normally for CRC_CONTROL */185 uint32_t acr_ctl = ASIC_IS_DCE3(rdev) ? DCE3_HDMI0_ACR_PACKET_CONTROL :186 HDMI0_ACR_PACKET_CONTROL;187 WREG32_P(acr_ctl + offset,188 HDMI0_ACR_SOURCE | /* select SW CTS value */189 HDMI0_ACR_AUTO_SEND, /* allow hw to sent ACR packets when required */190 ~(HDMI0_ACR_SOURCE |191 HDMI0_ACR_AUTO_SEND));192 193 WREG32_P(HDMI0_ACR_32_0 + offset,194 HDMI0_ACR_CTS_32(acr->cts_32khz),195 ~HDMI0_ACR_CTS_32_MASK);196 WREG32_P(HDMI0_ACR_32_1 + offset,197 HDMI0_ACR_N_32(acr->n_32khz),198 ~HDMI0_ACR_N_32_MASK);199 200 WREG32_P(HDMI0_ACR_44_0 + offset,201 HDMI0_ACR_CTS_44(acr->cts_44_1khz),202 ~HDMI0_ACR_CTS_44_MASK);203 WREG32_P(HDMI0_ACR_44_1 + offset,204 HDMI0_ACR_N_44(acr->n_44_1khz),205 ~HDMI0_ACR_N_44_MASK);206 207 WREG32_P(HDMI0_ACR_48_0 + offset,208 HDMI0_ACR_CTS_48(acr->cts_48khz),209 ~HDMI0_ACR_CTS_48_MASK);210 WREG32_P(HDMI0_ACR_48_1 + offset,211 HDMI0_ACR_N_48(acr->n_48khz),212 ~HDMI0_ACR_N_48_MASK);213}214 215/*216 * build a HDMI Video Info Frame217 */218void r600_set_avi_packet(struct radeon_device *rdev, u32 offset,219 unsigned char *buffer, size_t size)220{221 uint8_t *frame = buffer + 3;222 223 WREG32(HDMI0_AVI_INFO0 + offset,224 frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));225 WREG32(HDMI0_AVI_INFO1 + offset,226 frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24));227 WREG32(HDMI0_AVI_INFO2 + offset,228 frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));229 WREG32(HDMI0_AVI_INFO3 + offset,230 frame[0xC] | (frame[0xD] << 8) | (buffer[1] << 24));231 232 WREG32_OR(HDMI0_INFOFRAME_CONTROL1 + offset,233 HDMI0_AVI_INFO_LINE(2)); /* anything other than 0 */234 235 WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset,236 HDMI0_AVI_INFO_SEND | /* enable AVI info frames */237 HDMI0_AVI_INFO_CONT); /* send AVI info frames every frame/field */238 239}240 241/*242 * build a Audio Info Frame243 */244static void r600_hdmi_update_audio_infoframe(struct drm_encoder *encoder,245 const void *buffer, size_t size)246{247 struct drm_device *dev = encoder->dev;248 struct radeon_device *rdev = dev->dev_private;249 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);250 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;251 uint32_t offset = dig->afmt->offset;252 const u8 *frame = buffer + 3;253 254 WREG32(HDMI0_AUDIO_INFO0 + offset,255 frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));256 WREG32(HDMI0_AUDIO_INFO1 + offset,257 frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24));258}259 260/*261 * test if audio buffer is filled enough to start playing262 */263static bool r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder)264{265 struct drm_device *dev = encoder->dev;266 struct radeon_device *rdev = dev->dev_private;267 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);268 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;269 uint32_t offset = dig->afmt->offset;270 271 return (RREG32(HDMI0_STATUS + offset) & 0x10) != 0;272}273 274/*275 * have buffer status changed since last call?276 */277int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder)278{279 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);280 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;281 int status, result;282 283 if (!dig->afmt || !dig->afmt->enabled)284 return 0;285 286 status = r600_hdmi_is_audio_buffer_filled(encoder);287 result = dig->afmt->last_buffer_filled_status != status;288 dig->afmt->last_buffer_filled_status = status;289 290 return result;291}292 293/*294 * write the audio workaround status to the hardware295 */296void r600_hdmi_audio_workaround(struct drm_encoder *encoder)297{298 struct drm_device *dev = encoder->dev;299 struct radeon_device *rdev = dev->dev_private;300 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);301 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;302 uint32_t offset = dig->afmt->offset;303 bool hdmi_audio_workaround = false; /* FIXME */304 u32 value;305 306 if (!hdmi_audio_workaround ||307 r600_hdmi_is_audio_buffer_filled(encoder))308 value = 0; /* disable workaround */309 else310 value = HDMI0_AUDIO_TEST_EN; /* enable workaround */311 WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,312 value, ~HDMI0_AUDIO_TEST_EN);313}314 315void r600_hdmi_audio_set_dto(struct radeon_device *rdev,316 struct radeon_crtc *crtc, unsigned int clock)317{318 struct radeon_encoder *radeon_encoder;319 struct radeon_encoder_atom_dig *dig;320 321 if (!crtc)322 return;323 324 radeon_encoder = to_radeon_encoder(crtc->encoder);325 dig = radeon_encoder->enc_priv;326 327 if (!dig)328 return;329 330 if (dig->dig_encoder == 0) {331 WREG32(DCCG_AUDIO_DTO0_PHASE, 24000 * 100);332 WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);333 WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */334 } else {335 WREG32(DCCG_AUDIO_DTO1_PHASE, 24000 * 100);336 WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100);337 WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */338 }339}340 341void r600_set_vbi_packet(struct drm_encoder *encoder, u32 offset)342{343 struct drm_device *dev = encoder->dev;344 struct radeon_device *rdev = dev->dev_private;345 346 WREG32_OR(HDMI0_VBI_PACKET_CONTROL + offset,347 HDMI0_NULL_SEND | /* send null packets when required */348 HDMI0_GC_SEND | /* send general control packets */349 HDMI0_GC_CONT); /* send general control packets every frame */350}351 352void r600_set_audio_packet(struct drm_encoder *encoder, u32 offset)353{354 struct drm_device *dev = encoder->dev;355 struct radeon_device *rdev = dev->dev_private;356 357 WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,358 HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */359 HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */360 HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */361 HDMI0_60958_CS_UPDATE, /* allow 60958 channel status fields to be updated */362 ~(HDMI0_AUDIO_SAMPLE_SEND |363 HDMI0_AUDIO_DELAY_EN_MASK |364 HDMI0_AUDIO_PACKETS_PER_LINE_MASK |365 HDMI0_60958_CS_UPDATE));366 367 WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset,368 HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */369 HDMI0_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */370 371 WREG32_P(HDMI0_INFOFRAME_CONTROL1 + offset,372 HDMI0_AUDIO_INFO_LINE(2), /* anything other than 0 */373 ~HDMI0_AUDIO_INFO_LINE_MASK);374 375 WREG32_AND(HDMI0_GENERIC_PACKET_CONTROL + offset,376 ~(HDMI0_GENERIC0_SEND |377 HDMI0_GENERIC0_CONT |378 HDMI0_GENERIC0_UPDATE |379 HDMI0_GENERIC1_SEND |380 HDMI0_GENERIC1_CONT |381 HDMI0_GENERIC0_LINE_MASK |382 HDMI0_GENERIC1_LINE_MASK));383 384 WREG32_P(HDMI0_60958_0 + offset,385 HDMI0_60958_CS_CHANNEL_NUMBER_L(1),386 ~(HDMI0_60958_CS_CHANNEL_NUMBER_L_MASK |387 HDMI0_60958_CS_CLOCK_ACCURACY_MASK));388 389 WREG32_P(HDMI0_60958_1 + offset,390 HDMI0_60958_CS_CHANNEL_NUMBER_R(2),391 ~HDMI0_60958_CS_CHANNEL_NUMBER_R_MASK);392}393 394void r600_set_mute(struct drm_encoder *encoder, u32 offset, bool mute)395{396 struct drm_device *dev = encoder->dev;397 struct radeon_device *rdev = dev->dev_private;398 399 if (mute)400 WREG32_OR(HDMI0_GC + offset, HDMI0_GC_AVMUTE);401 else402 WREG32_AND(HDMI0_GC + offset, ~HDMI0_GC_AVMUTE);403}404 405/**406 * r600_hdmi_update_audio_settings - Update audio infoframe407 *408 * @encoder: drm encoder409 *410 * Gets info about current audio stream and updates audio infoframe.411 */412void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)413{414 struct drm_device *dev = encoder->dev;415 struct radeon_device *rdev = dev->dev_private;416 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);417 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;418 struct r600_audio_pin audio = r600_audio_status(rdev);419 uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];420 struct hdmi_audio_infoframe frame;421 uint32_t offset;422 uint32_t value;423 ssize_t err;424 425 if (!dig->afmt || !dig->afmt->enabled)426 return;427 offset = dig->afmt->offset;428 429 DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n",430 r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped",431 audio.channels, audio.rate, audio.bits_per_sample);432 DRM_DEBUG("0x%02X IEC60958 status bits and 0x%02X category code\n",433 (int)audio.status_bits, (int)audio.category_code);434 435 err = hdmi_audio_infoframe_init(&frame);436 if (err < 0) {437 DRM_ERROR("failed to setup audio infoframe\n");438 return;439 }440 441 frame.channels = audio.channels;442 443 err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));444 if (err < 0) {445 DRM_ERROR("failed to pack audio infoframe\n");446 return;447 }448 449 value = RREG32(HDMI0_AUDIO_PACKET_CONTROL + offset);450 if (value & HDMI0_AUDIO_TEST_EN)451 WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset,452 value & ~HDMI0_AUDIO_TEST_EN);453 454 WREG32_OR(HDMI0_CONTROL + offset,455 HDMI0_ERROR_ACK);456 457 WREG32_AND(HDMI0_INFOFRAME_CONTROL0 + offset,458 ~HDMI0_AUDIO_INFO_SOURCE);459 460 r600_hdmi_update_audio_infoframe(encoder, buffer, sizeof(buffer));461 462 WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset,463 HDMI0_AUDIO_INFO_CONT |464 HDMI0_AUDIO_INFO_UPDATE);465}466 467/*468 * enable the HDMI engine469 */470void r600_hdmi_enable(struct drm_encoder *encoder, bool enable)471{472 struct drm_device *dev = encoder->dev;473 struct radeon_device *rdev = dev->dev_private;474 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);475 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;476 u32 hdmi = HDMI0_ERROR_ACK;477 478 if (!dig || !dig->afmt)479 return;480 481 /* Older chipsets require setting HDMI and routing manually */482 if (!ASIC_IS_DCE3(rdev)) {483 if (enable)484 hdmi |= HDMI0_ENABLE;485 switch (radeon_encoder->encoder_id) {486 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:487 if (enable) {488 WREG32_OR(AVIVO_TMDSA_CNTL, AVIVO_TMDSA_CNTL_HDMI_EN);489 hdmi |= HDMI0_STREAM(HDMI0_STREAM_TMDSA);490 } else {491 WREG32_AND(AVIVO_TMDSA_CNTL, ~AVIVO_TMDSA_CNTL_HDMI_EN);492 }493 break;494 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:495 if (enable) {496 WREG32_OR(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN);497 hdmi |= HDMI0_STREAM(HDMI0_STREAM_LVTMA);498 } else {499 WREG32_AND(AVIVO_LVTMA_CNTL, ~AVIVO_LVTMA_CNTL_HDMI_EN);500 }501 break;502 case ENCODER_OBJECT_ID_INTERNAL_DDI:503 if (enable) {504 WREG32_OR(DDIA_CNTL, DDIA_HDMI_EN);505 hdmi |= HDMI0_STREAM(HDMI0_STREAM_DDIA);506 } else {507 WREG32_AND(DDIA_CNTL, ~DDIA_HDMI_EN);508 }509 break;510 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:511 if (enable)512 hdmi |= HDMI0_STREAM(HDMI0_STREAM_DVOA);513 break;514 default:515 dev_err(rdev->dev, "Invalid encoder for HDMI: 0x%X\n",516 radeon_encoder->encoder_id);517 break;518 }519 WREG32(HDMI0_CONTROL + dig->afmt->offset, hdmi);520 }521 522 if (rdev->irq.installed) {523 /* if irq is available use it */524 /* XXX: shouldn't need this on any asics. Double check DCE2/3 */525 if (enable)526 radeon_irq_kms_enable_afmt(rdev, dig->afmt->id);527 else528 radeon_irq_kms_disable_afmt(rdev, dig->afmt->id);529 }530 531 dig->afmt->enabled = enable;532 533 DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n",534 enable ? "En" : "Dis", dig->afmt->offset, radeon_encoder->encoder_id);535}536 537