Subversion Repositories Kolibri OS

Rev

Rev 2997 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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 a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included in
  14.  * all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20.  * 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 OR
  22.  * OTHER DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors: Christian König
  25.  */
  26. #include "drmP.h"
  27. #include "radeon_drm.h"
  28. #include "radeon.h"
  29. #include "atom.h"
  30.  
  31. /*
  32.  * HDMI color format
  33.  */
  34. enum r600_hdmi_color_format {
  35.         RGB = 0,
  36.         YCC_422 = 1,
  37.         YCC_444 = 2
  38. };
  39.  
  40. /*
  41.  * IEC60958 status bits
  42.  */
  43. enum r600_hdmi_iec_status_bits {
  44.         AUDIO_STATUS_DIG_ENABLE   = 0x01,
  45.         AUDIO_STATUS_V      = 0x02,
  46.         AUDIO_STATUS_VCFG        = 0x04,
  47.         AUDIO_STATUS_EMPHASIS     = 0x08,
  48.         AUDIO_STATUS_COPYRIGHT    = 0x10,
  49.         AUDIO_STATUS_NONAUDIO     = 0x20,
  50.         AUDIO_STATUS_PROFESSIONAL = 0x40,
  51.         AUDIO_STATUS_LEVEL      = 0x80
  52. };
  53.  
  54. struct {
  55.         uint32_t Clock;
  56.  
  57.         int N_32kHz;
  58.         int CTS_32kHz;
  59.  
  60.         int N_44_1kHz;
  61.         int CTS_44_1kHz;
  62.  
  63.         int N_48kHz;
  64.         int CTS_48kHz;
  65.  
  66. } r600_hdmi_ACR[] = {
  67.     /*       32kHz        44.1kHz       48kHz    */
  68.     /* Clock      N     CTS      N     CTS      N     CTS */
  69.     {  25174,  4576,  28125,  7007,  31250,  6864,  28125 }, /*  25,20/1.001 MHz */
  70.     {  25200,  4096,  25200,  6272,  28000,  6144,  25200 }, /*  25.20       MHz */
  71.     {  27000,  4096,  27000,  6272,  30000,  6144,  27000 }, /*  27.00       MHz */
  72.     {  27027,  4096,  27027,  6272,  30030,  6144,  27027 }, /*  27.00*1.001 MHz */
  73.     {  54000,  4096,  54000,  6272,  60000,  6144,  54000 }, /*  54.00       MHz */
  74.     {  54054,  4096,  54054,  6272,  60060,  6144,  54054 }, /*  54.00*1.001 MHz */
  75.     {  74175, 11648, 210937, 17836, 234375, 11648, 140625 }, /*  74.25/1.001 MHz */
  76.     {  74250,  4096,  74250,  6272,  82500,  6144,  74250 }, /*  74.25       MHz */
  77.     { 148351, 11648, 421875,  8918, 234375,  5824, 140625 }, /* 148.50/1.001 MHz */
  78.     { 148500,  4096, 148500,  6272, 165000,  6144, 148500 }, /* 148.50       MHz */
  79.     {      0,  4096,      0,  6272,      0,  6144,      0 }  /* Other */
  80. };
  81.  
  82. /*
  83.  * calculate CTS value if it's not found in the table
  84.  */
  85. static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq)
  86. {
  87.         if (*CTS == 0)
  88.                 *CTS = clock*N/(128*freq)*1000;
  89.         DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",
  90.                   N, *CTS, freq);
  91. }
  92.  
  93. /*
  94.  * update the N and CTS parameters for a given pixel clock rate
  95.  */
  96. static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
  97. {
  98.         struct drm_device *dev = encoder->dev;
  99.         struct radeon_device *rdev = dev->dev_private;
  100.         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
  101.         int CTS;
  102.         int N;
  103.         int i;
  104.  
  105.         for (i = 0; r600_hdmi_ACR[i].Clock != clock && r600_hdmi_ACR[i].Clock != 0; i++);
  106.  
  107.         CTS = r600_hdmi_ACR[i].CTS_32kHz;
  108.         N = r600_hdmi_ACR[i].N_32kHz;
  109.         r600_hdmi_calc_CTS(clock, &CTS, N, 32000);
  110.         WREG32(offset+R600_HDMI_32kHz_CTS, CTS << 12);
  111.         WREG32(offset+R600_HDMI_32kHz_N, N);
  112.  
  113.         CTS = r600_hdmi_ACR[i].CTS_44_1kHz;
  114.         N = r600_hdmi_ACR[i].N_44_1kHz;
  115.         r600_hdmi_calc_CTS(clock, &CTS, N, 44100);
  116.         WREG32(offset+R600_HDMI_44_1kHz_CTS, CTS << 12);
  117.         WREG32(offset+R600_HDMI_44_1kHz_N, N);
  118.  
  119.         CTS = r600_hdmi_ACR[i].CTS_48kHz;
  120.         N = r600_hdmi_ACR[i].N_48kHz;
  121.         r600_hdmi_calc_CTS(clock, &CTS, N, 48000);
  122.         WREG32(offset+R600_HDMI_48kHz_CTS, CTS << 12);
  123.         WREG32(offset+R600_HDMI_48kHz_N, N);
  124. }
  125.  
  126. /*
  127.  * calculate the crc for a given info frame
  128.  */
  129. static void r600_hdmi_infoframe_checksum(uint8_t packetType,
  130.                                          uint8_t versionNumber,
  131.                                          uint8_t length,
  132.                                          uint8_t *frame)
  133. {
  134.     int i;
  135.     frame[0] = packetType + versionNumber + length;
  136.     for (i = 1; i <= length; i++)
  137.         frame[0] += frame[i];
  138.     frame[0] = 0x100 - frame[0];
  139. }
  140.  
  141. /*
  142.  * build a HDMI Video Info Frame
  143.  */
  144. static void r600_hdmi_videoinfoframe(
  145.         struct drm_encoder *encoder,
  146.         enum r600_hdmi_color_format color_format,
  147.         int active_information_present,
  148.         uint8_t active_format_aspect_ratio,
  149.         uint8_t scan_information,
  150.         uint8_t colorimetry,
  151.         uint8_t ex_colorimetry,
  152.         uint8_t quantization,
  153.         int ITC,
  154.         uint8_t picture_aspect_ratio,
  155.         uint8_t video_format_identification,
  156.         uint8_t pixel_repetition,
  157.         uint8_t non_uniform_picture_scaling,
  158.         uint8_t bar_info_data_valid,
  159.         uint16_t top_bar,
  160.         uint16_t bottom_bar,
  161.         uint16_t left_bar,
  162.         uint16_t right_bar
  163. )
  164. {
  165.         struct drm_device *dev = encoder->dev;
  166.         struct radeon_device *rdev = dev->dev_private;
  167.         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
  168.  
  169.         uint8_t frame[14];
  170.  
  171.         frame[0x0] = 0;
  172.         frame[0x1] =
  173.                 (scan_information & 0x3) |
  174.                 ((bar_info_data_valid & 0x3) << 2) |
  175.                 ((active_information_present & 0x1) << 4) |
  176.                 ((color_format & 0x3) << 5);
  177.         frame[0x2] =
  178.                 (active_format_aspect_ratio & 0xF) |
  179.                 ((picture_aspect_ratio & 0x3) << 4) |
  180.                 ((colorimetry & 0x3) << 6);
  181.         frame[0x3] =
  182.                 (non_uniform_picture_scaling & 0x3) |
  183.                 ((quantization & 0x3) << 2) |
  184.                 ((ex_colorimetry & 0x7) << 4) |
  185.                 ((ITC & 0x1) << 7);
  186.         frame[0x4] = (video_format_identification & 0x7F);
  187.         frame[0x5] = (pixel_repetition & 0xF);
  188.         frame[0x6] = (top_bar & 0xFF);
  189.         frame[0x7] = (top_bar >> 8);
  190.         frame[0x8] = (bottom_bar & 0xFF);
  191.         frame[0x9] = (bottom_bar >> 8);
  192.         frame[0xA] = (left_bar & 0xFF);
  193.         frame[0xB] = (left_bar >> 8);
  194.         frame[0xC] = (right_bar & 0xFF);
  195.         frame[0xD] = (right_bar >> 8);
  196.  
  197.         r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame);
  198.  
  199.         WREG32(offset+R600_HDMI_VIDEOINFOFRAME_0,
  200.                 frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
  201.         WREG32(offset+R600_HDMI_VIDEOINFOFRAME_1,
  202.                 frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24));
  203.         WREG32(offset+R600_HDMI_VIDEOINFOFRAME_2,
  204.                 frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
  205.         WREG32(offset+R600_HDMI_VIDEOINFOFRAME_3,
  206.                 frame[0xC] | (frame[0xD] << 8));
  207. }
  208.  
  209. /*
  210.  * build a Audio Info Frame
  211.  */
  212. static void r600_hdmi_audioinfoframe(
  213.         struct drm_encoder *encoder,
  214.         uint8_t channel_count,
  215.         uint8_t coding_type,
  216.         uint8_t sample_size,
  217.         uint8_t sample_frequency,
  218.         uint8_t format,
  219.         uint8_t channel_allocation,
  220.         uint8_t level_shift,
  221.         int downmix_inhibit
  222. )
  223. {
  224.         struct drm_device *dev = encoder->dev;
  225.         struct radeon_device *rdev = dev->dev_private;
  226.         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
  227.  
  228.         uint8_t frame[11];
  229.  
  230.         frame[0x0] = 0;
  231.         frame[0x1] = (channel_count & 0x7) | ((coding_type & 0xF) << 4);
  232.         frame[0x2] = (sample_size & 0x3) | ((sample_frequency & 0x7) << 2);
  233.         frame[0x3] = format;
  234.         frame[0x4] = channel_allocation;
  235.         frame[0x5] = ((level_shift & 0xF) << 3) | ((downmix_inhibit & 0x1) << 7);
  236.         frame[0x6] = 0;
  237.         frame[0x7] = 0;
  238.         frame[0x8] = 0;
  239.         frame[0x9] = 0;
  240.         frame[0xA] = 0;
  241.  
  242.         r600_hdmi_infoframe_checksum(0x84, 0x01, 0x0A, frame);
  243.  
  244.         WREG32(offset+R600_HDMI_AUDIOINFOFRAME_0,
  245.                 frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
  246.         WREG32(offset+R600_HDMI_AUDIOINFOFRAME_1,
  247.                 frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24));
  248. }
  249.  
  250. /*
  251.  * test if audio buffer is filled enough to start playing
  252.  */
  253. static int r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder)
  254. {
  255.         struct drm_device *dev = encoder->dev;
  256.         struct radeon_device *rdev = dev->dev_private;
  257.         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
  258.  
  259.         return (RREG32(offset+R600_HDMI_STATUS) & 0x10) != 0;
  260. }
  261.  
  262. /*
  263.  * have buffer status changed since last call?
  264.  */
  265. int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder)
  266. {
  267.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  268.         int status, result;
  269.  
  270.         if (!radeon_encoder->hdmi_offset)
  271.                 return 0;
  272.  
  273.         status = r600_hdmi_is_audio_buffer_filled(encoder);
  274.         result = radeon_encoder->hdmi_buffer_status != status;
  275.         radeon_encoder->hdmi_buffer_status = status;
  276.  
  277.         return result;
  278. }
  279.  
  280. /*
  281.  * write the audio workaround status to the hardware
  282.  */
  283. void r600_hdmi_audio_workaround(struct drm_encoder *encoder)
  284. {
  285.         struct drm_device *dev = encoder->dev;
  286.         struct radeon_device *rdev = dev->dev_private;
  287.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  288.         uint32_t offset = radeon_encoder->hdmi_offset;
  289.  
  290.         if (!offset)
  291.                 return;
  292.  
  293.         if (r600_hdmi_is_audio_buffer_filled(encoder)) {
  294.                 /* disable audio workaround and start delivering of audio frames */
  295.                 WREG32_P(offset+R600_HDMI_CNTL, 0x00000001, ~0x00001001);
  296.  
  297.         } else if (radeon_encoder->hdmi_audio_workaround) {
  298.                 /* enable audio workaround and start delivering of audio frames */
  299.                 WREG32_P(offset+R600_HDMI_CNTL, 0x00001001, ~0x00001001);
  300.  
  301.         } else {
  302.                 /* disable audio workaround and stop delivering of audio frames */
  303.                 WREG32_P(offset+R600_HDMI_CNTL, 0x00000000, ~0x00001001);
  304.         }
  305. }
  306.  
  307.  
  308. /*
  309.  * update the info frames with the data from the current display mode
  310.  */
  311. void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode)
  312. {
  313.         struct drm_device *dev = encoder->dev;
  314.         struct radeon_device *rdev = dev->dev_private;
  315.         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
  316.  
  317.         if (!offset)
  318.                 return;
  319.  
  320.         r600_audio_set_clock(encoder, mode->clock);
  321.  
  322.         WREG32(offset+R600_HDMI_UNKNOWN_0, 0x1000);
  323.         WREG32(offset+R600_HDMI_UNKNOWN_1, 0x0);
  324.         WREG32(offset+R600_HDMI_UNKNOWN_2, 0x1000);
  325.  
  326.         r600_hdmi_update_ACR(encoder, mode->clock);
  327.  
  328.         WREG32(offset+R600_HDMI_VIDEOCNTL, 0x13);
  329.  
  330.         WREG32(offset+R600_HDMI_VERSION, 0x202);
  331.  
  332.         r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0,
  333.                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  334.  
  335.         /* it's unknown what these bits do excatly, but it's indeed quite usefull for debugging */
  336.         WREG32(offset+R600_HDMI_AUDIO_DEBUG_0, 0x00FFFFFF);
  337.         WREG32(offset+R600_HDMI_AUDIO_DEBUG_1, 0x007FFFFF);
  338.         WREG32(offset+R600_HDMI_AUDIO_DEBUG_2, 0x00000001);
  339.         WREG32(offset+R600_HDMI_AUDIO_DEBUG_3, 0x00000001);
  340.  
  341.         r600_hdmi_audio_workaround(encoder);
  342.  
  343.         /* audio packets per line, does anyone know how to calc this ? */
  344.         WREG32_P(offset+R600_HDMI_CNTL, 0x00040000, ~0x001F0000);
  345.  
  346.         /* update? reset? don't realy know */
  347.         WREG32_P(offset+R600_HDMI_CNTL, 0x14000000, ~0x14000000);
  348. }
  349.  
  350. /*
  351.  * update settings with current parameters from audio engine
  352.  */
  353. void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
  354.                                      int channels,
  355.                                      int rate,
  356.                                      int bps,
  357.                                      uint8_t status_bits,
  358.                                      uint8_t category_code)
  359. {
  360.         struct drm_device *dev = encoder->dev;
  361.         struct radeon_device *rdev = dev->dev_private;
  362.         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
  363.  
  364.         uint32_t iec;
  365.  
  366.         if (!offset)
  367.                 return;
  368.  
  369.         DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n",
  370.                  r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped",
  371.                 channels, rate, bps);
  372.         DRM_DEBUG("0x%02X IEC60958 status bits and 0x%02X category code\n",
  373.                   (int)status_bits, (int)category_code);
  374.  
  375.         iec = 0;
  376.         if (status_bits & AUDIO_STATUS_PROFESSIONAL)
  377.                 iec |= 1 << 0;
  378.         if (status_bits & AUDIO_STATUS_NONAUDIO)
  379.                 iec |= 1 << 1;
  380.         if (status_bits & AUDIO_STATUS_COPYRIGHT)
  381.                 iec |= 1 << 2;
  382.         if (status_bits & AUDIO_STATUS_EMPHASIS)
  383.                 iec |= 1 << 3;
  384.  
  385.         iec |= category_code << 8;
  386.  
  387.         switch (rate) {
  388.         case  32000: iec |= 0x3 << 24; break;
  389.         case  44100: iec |= 0x0 << 24; break;
  390.         case  88200: iec |= 0x8 << 24; break;
  391.         case 176400: iec |= 0xc << 24; break;
  392.         case  48000: iec |= 0x2 << 24; break;
  393.         case  96000: iec |= 0xa << 24; break;
  394.         case 192000: iec |= 0xe << 24; break;
  395.         }
  396.  
  397.         WREG32(offset+R600_HDMI_IEC60958_1, iec);
  398.  
  399.         iec = 0;
  400.         switch (bps) {
  401.         case 16: iec |= 0x2; break;
  402.         case 20: iec |= 0x3; break;
  403.         case 24: iec |= 0xb; break;
  404.         }
  405.         if (status_bits & AUDIO_STATUS_V)
  406.                 iec |= 0x5 << 16;
  407.  
  408.         WREG32_P(offset+R600_HDMI_IEC60958_2, iec, ~0x5000f);
  409.  
  410.         /* 0x021 or 0x031 sets the audio frame length */
  411.         WREG32(offset+R600_HDMI_AUDIOCNTL, 0x31);
  412.         r600_hdmi_audioinfoframe(encoder, channels-1, 0, 0, 0, 0, 0, 0, 0);
  413.  
  414.         r600_hdmi_audio_workaround(encoder);
  415.  
  416.         /* update? reset? don't realy know */
  417.         WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000);
  418. }
  419.  
  420. /*
  421.  * enable/disable the HDMI engine
  422.  */
  423. void r600_hdmi_enable(struct drm_encoder *encoder, int enable)
  424. {
  425.         struct drm_device *dev = encoder->dev;
  426.         struct radeon_device *rdev = dev->dev_private;
  427.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  428.         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
  429.  
  430.         if (!offset)
  431.                 return;
  432.  
  433.         DRM_DEBUG("%s HDMI interface @ 0x%04X\n", enable ? "Enabling" : "Disabling", offset);
  434.  
  435.         /* some version of atombios ignore the enable HDMI flag
  436.          * so enabling/disabling HDMI was moved here for TMDS1+2 */
  437.         switch (radeon_encoder->encoder_id) {
  438.         case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
  439.                 WREG32_P(AVIVO_TMDSA_CNTL, enable ? 0x4 : 0x0, ~0x4);
  440.                 WREG32(offset+R600_HDMI_ENABLE, enable ? 0x101 : 0x0);
  441.                 break;
  442.  
  443.         case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
  444.                 WREG32_P(AVIVO_LVTMA_CNTL, enable ? 0x4 : 0x0, ~0x4);
  445.                 WREG32(offset+R600_HDMI_ENABLE, enable ? 0x105 : 0x0);
  446.                 break;
  447.  
  448.         case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
  449.         case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
  450.         case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
  451.         case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
  452.                 /* This part is doubtfull in my opinion */
  453.                 WREG32(offset+R600_HDMI_ENABLE, enable ? 0x110 : 0x0);
  454.                 break;
  455.  
  456.         default:
  457.                 DRM_ERROR("unknown HDMI output type\n");
  458.                 break;
  459.         }
  460. }
  461.  
  462. /*
  463.  * determin at which register offset the HDMI encoder is
  464.  */
  465. void r600_hdmi_init(struct drm_encoder *encoder)
  466. {
  467.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  468.  
  469.         switch (radeon_encoder->encoder_id) {
  470.         case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
  471.         case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
  472.         case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
  473.                 radeon_encoder->hdmi_offset = R600_HDMI_TMDS1;
  474.                 break;
  475.  
  476.         case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
  477.                 switch (r600_audio_tmds_index(encoder)) {
  478.                 case 0:
  479.                         radeon_encoder->hdmi_offset = R600_HDMI_TMDS1;
  480.                         break;
  481.                 case 1:
  482.                         radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;
  483.                         break;
  484.                 default:
  485.                         radeon_encoder->hdmi_offset = 0;
  486.                         break;
  487.                 }
  488.         case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
  489.                 radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;
  490.                 break;
  491.  
  492.         case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
  493.                 radeon_encoder->hdmi_offset = R600_HDMI_DIG;
  494.                 break;
  495.  
  496.         default:
  497.                 radeon_encoder->hdmi_offset = 0;
  498.                 break;
  499.         }
  500.  
  501.         DRM_DEBUG("using HDMI engine at offset 0x%04X for encoder 0x%x\n",
  502.                   radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
  503.  
  504.         /* TODO: make this configureable */
  505.         radeon_encoder->hdmi_audio_workaround = 0;
  506. }
  507.