Subversion Repositories Kolibri OS

Rev

Rev 1403 | Rev 3764 | 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 "radeon_asic.h"
  30. #include "atom.h"
  31.  
  32. /*
  33.  * HDMI color format
  34.  */
  35. enum r600_hdmi_color_format {
  36.         RGB = 0,
  37.         YCC_422 = 1,
  38.         YCC_444 = 2
  39. };
  40.  
  41. /*
  42.  * IEC60958 status bits
  43.  */
  44. enum r600_hdmi_iec_status_bits {
  45.         AUDIO_STATUS_DIG_ENABLE   = 0x01,
  46.         AUDIO_STATUS_V      = 0x02,
  47.         AUDIO_STATUS_VCFG        = 0x04,
  48.         AUDIO_STATUS_EMPHASIS     = 0x08,
  49.         AUDIO_STATUS_COPYRIGHT    = 0x10,
  50.         AUDIO_STATUS_NONAUDIO     = 0x20,
  51.         AUDIO_STATUS_PROFESSIONAL = 0x40,
  52.         AUDIO_STATUS_LEVEL      = 0x80
  53. };
  54.  
  55. struct {
  56.         uint32_t Clock;
  57.  
  58.         int N_32kHz;
  59.         int CTS_32kHz;
  60.  
  61.         int N_44_1kHz;
  62.         int CTS_44_1kHz;
  63.  
  64.         int N_48kHz;
  65.         int CTS_48kHz;
  66.  
  67. } r600_hdmi_ACR[] = {
  68.     /*       32kHz        44.1kHz       48kHz    */
  69.     /* Clock      N     CTS      N     CTS      N     CTS */
  70.     {  25174,  4576,  28125,  7007,  31250,  6864,  28125 }, /*  25,20/1.001 MHz */
  71.     {  25200,  4096,  25200,  6272,  28000,  6144,  25200 }, /*  25.20       MHz */
  72.     {  27000,  4096,  27000,  6272,  30000,  6144,  27000 }, /*  27.00       MHz */
  73.     {  27027,  4096,  27027,  6272,  30030,  6144,  27027 }, /*  27.00*1.001 MHz */
  74.     {  54000,  4096,  54000,  6272,  60000,  6144,  54000 }, /*  54.00       MHz */
  75.     {  54054,  4096,  54054,  6272,  60060,  6144,  54054 }, /*  54.00*1.001 MHz */
  76.     {  74175, 11648, 210937, 17836, 234375, 11648, 140625 }, /*  74.25/1.001 MHz */
  77.     {  74250,  4096,  74250,  6272,  82500,  6144,  74250 }, /*  74.25       MHz */
  78.     { 148351, 11648, 421875,  8918, 234375,  5824, 140625 }, /* 148.50/1.001 MHz */
  79.     { 148500,  4096, 148500,  6272, 165000,  6144, 148500 }, /* 148.50       MHz */
  80.     {      0,  4096,      0,  6272,      0,  6144,      0 }  /* Other */
  81. };
  82.  
  83. /*
  84.  * calculate CTS value if it's not found in the table
  85.  */
  86. static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq)
  87. {
  88.         if (*CTS == 0)
  89.                 *CTS = clock * N / (128 * freq) * 1000;
  90.         DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",
  91.                   N, *CTS, freq);
  92. }
  93.  
  94. /*
  95.  * update the N and CTS parameters for a given pixel clock rate
  96.  */
  97. static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
  98. {
  99.         struct drm_device *dev = encoder->dev;
  100.         struct radeon_device *rdev = dev->dev_private;
  101.         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
  102.         int CTS;
  103.         int N;
  104.         int i;
  105.  
  106.         for (i = 0; r600_hdmi_ACR[i].Clock != clock && r600_hdmi_ACR[i].Clock != 0; i++);
  107.  
  108.         CTS = r600_hdmi_ACR[i].CTS_32kHz;
  109.         N = r600_hdmi_ACR[i].N_32kHz;
  110.         r600_hdmi_calc_CTS(clock, &CTS, N, 32000);
  111.         WREG32(offset+R600_HDMI_32kHz_CTS, CTS << 12);
  112.         WREG32(offset+R600_HDMI_32kHz_N, N);
  113.  
  114.         CTS = r600_hdmi_ACR[i].CTS_44_1kHz;
  115.         N = r600_hdmi_ACR[i].N_44_1kHz;
  116.         r600_hdmi_calc_CTS(clock, &CTS, N, 44100);
  117.         WREG32(offset+R600_HDMI_44_1kHz_CTS, CTS << 12);
  118.         WREG32(offset+R600_HDMI_44_1kHz_N, N);
  119.  
  120.         CTS = r600_hdmi_ACR[i].CTS_48kHz;
  121.         N = r600_hdmi_ACR[i].N_48kHz;
  122.         r600_hdmi_calc_CTS(clock, &CTS, N, 48000);
  123.         WREG32(offset+R600_HDMI_48kHz_CTS, CTS << 12);
  124.         WREG32(offset+R600_HDMI_48kHz_N, N);
  125. }
  126.  
  127. /*
  128.  * calculate the crc for a given info frame
  129.  */
  130. static void r600_hdmi_infoframe_checksum(uint8_t packetType,
  131.                                          uint8_t versionNumber,
  132.                                          uint8_t length,
  133.                                          uint8_t *frame)
  134. {
  135.     int i;
  136.     frame[0] = packetType + versionNumber + length;
  137.     for (i = 1; i <= length; i++)
  138.         frame[0] += frame[i];
  139.     frame[0] = 0x100 - frame[0];
  140. }
  141.  
  142. /*
  143.  * build a HDMI Video Info Frame
  144.  */
  145. static void r600_hdmi_videoinfoframe(
  146.         struct drm_encoder *encoder,
  147.         enum r600_hdmi_color_format color_format,
  148.         int active_information_present,
  149.         uint8_t active_format_aspect_ratio,
  150.         uint8_t scan_information,
  151.         uint8_t colorimetry,
  152.         uint8_t ex_colorimetry,
  153.         uint8_t quantization,
  154.         int ITC,
  155.         uint8_t picture_aspect_ratio,
  156.         uint8_t video_format_identification,
  157.         uint8_t pixel_repetition,
  158.         uint8_t non_uniform_picture_scaling,
  159.         uint8_t bar_info_data_valid,
  160.         uint16_t top_bar,
  161.         uint16_t bottom_bar,
  162.         uint16_t left_bar,
  163.         uint16_t right_bar
  164. )
  165. {
  166.         struct drm_device *dev = encoder->dev;
  167.         struct radeon_device *rdev = dev->dev_private;
  168.         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
  169.  
  170.         uint8_t frame[14];
  171.  
  172.         frame[0x0] = 0;
  173.         frame[0x1] =
  174.                 (scan_information & 0x3) |
  175.                 ((bar_info_data_valid & 0x3) << 2) |
  176.                 ((active_information_present & 0x1) << 4) |
  177.                 ((color_format & 0x3) << 5);
  178.         frame[0x2] =
  179.                 (active_format_aspect_ratio & 0xF) |
  180.                 ((picture_aspect_ratio & 0x3) << 4) |
  181.                 ((colorimetry & 0x3) << 6);
  182.         frame[0x3] =
  183.                 (non_uniform_picture_scaling & 0x3) |
  184.                 ((quantization & 0x3) << 2) |
  185.                 ((ex_colorimetry & 0x7) << 4) |
  186.                 ((ITC & 0x1) << 7);
  187.         frame[0x4] = (video_format_identification & 0x7F);
  188.         frame[0x5] = (pixel_repetition & 0xF);
  189.         frame[0x6] = (top_bar & 0xFF);
  190.         frame[0x7] = (top_bar >> 8);
  191.         frame[0x8] = (bottom_bar & 0xFF);
  192.         frame[0x9] = (bottom_bar >> 8);
  193.         frame[0xA] = (left_bar & 0xFF);
  194.         frame[0xB] = (left_bar >> 8);
  195.         frame[0xC] = (right_bar & 0xFF);
  196.         frame[0xD] = (right_bar >> 8);
  197.  
  198.         r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame);
  199.  
  200.         WREG32(offset+R600_HDMI_VIDEOINFOFRAME_0,
  201.                 frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
  202.         WREG32(offset+R600_HDMI_VIDEOINFOFRAME_1,
  203.                 frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24));
  204.         WREG32(offset+R600_HDMI_VIDEOINFOFRAME_2,
  205.                 frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
  206.         WREG32(offset+R600_HDMI_VIDEOINFOFRAME_3,
  207.                 frame[0xC] | (frame[0xD] << 8));
  208. }
  209.  
  210. /*
  211.  * build a Audio Info Frame
  212.  */
  213. static void r600_hdmi_audioinfoframe(
  214.         struct drm_encoder *encoder,
  215.         uint8_t channel_count,
  216.         uint8_t coding_type,
  217.         uint8_t sample_size,
  218.         uint8_t sample_frequency,
  219.         uint8_t format,
  220.         uint8_t channel_allocation,
  221.         uint8_t level_shift,
  222.         int downmix_inhibit
  223. )
  224. {
  225.         struct drm_device *dev = encoder->dev;
  226.         struct radeon_device *rdev = dev->dev_private;
  227.         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
  228.  
  229.         uint8_t frame[11];
  230.  
  231.         frame[0x0] = 0;
  232.         frame[0x1] = (channel_count & 0x7) | ((coding_type & 0xF) << 4);
  233.         frame[0x2] = (sample_size & 0x3) | ((sample_frequency & 0x7) << 2);
  234.         frame[0x3] = format;
  235.         frame[0x4] = channel_allocation;
  236.         frame[0x5] = ((level_shift & 0xF) << 3) | ((downmix_inhibit & 0x1) << 7);
  237.         frame[0x6] = 0;
  238.         frame[0x7] = 0;
  239.         frame[0x8] = 0;
  240.         frame[0x9] = 0;
  241.         frame[0xA] = 0;
  242.  
  243.         r600_hdmi_infoframe_checksum(0x84, 0x01, 0x0A, frame);
  244.  
  245.         WREG32(offset+R600_HDMI_AUDIOINFOFRAME_0,
  246.                 frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
  247.         WREG32(offset+R600_HDMI_AUDIOINFOFRAME_1,
  248.                 frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24));
  249. }
  250.  
  251. /*
  252.  * test if audio buffer is filled enough to start playing
  253.  */
  254. static int r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder)
  255. {
  256.         struct drm_device *dev = encoder->dev;
  257.         struct radeon_device *rdev = dev->dev_private;
  258.         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
  259.  
  260.         return (RREG32(offset+R600_HDMI_STATUS) & 0x10) != 0;
  261. }
  262.  
  263. /*
  264.  * have buffer status changed since last call?
  265.  */
  266. int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder)
  267. {
  268.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  269.         int status, result;
  270.  
  271.         if (!radeon_encoder->hdmi_offset)
  272.                 return 0;
  273.  
  274.         status = r600_hdmi_is_audio_buffer_filled(encoder);
  275.         result = radeon_encoder->hdmi_buffer_status != status;
  276.         radeon_encoder->hdmi_buffer_status = status;
  277.  
  278.         return result;
  279. }
  280.  
  281. /*
  282.  * write the audio workaround status to the hardware
  283.  */
  284. void r600_hdmi_audio_workaround(struct drm_encoder *encoder)
  285. {
  286.         struct drm_device *dev = encoder->dev;
  287.         struct radeon_device *rdev = dev->dev_private;
  288.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  289.         uint32_t offset = radeon_encoder->hdmi_offset;
  290.  
  291.         if (!offset)
  292.                 return;
  293.  
  294.         if (!radeon_encoder->hdmi_audio_workaround ||
  295.                 r600_hdmi_is_audio_buffer_filled(encoder)) {
  296.  
  297.                 /* disable audio workaround */
  298.                 WREG32_P(offset+R600_HDMI_CNTL, 0x00000001, ~0x00001001);
  299.  
  300.         } else {
  301.                 /* enable audio workaround */
  302.                 WREG32_P(offset+R600_HDMI_CNTL, 0x00001001, ~0x00001001);
  303.         }
  304. }
  305.  
  306.  
  307. /*
  308.  * update the info frames with the data from the current display mode
  309.  */
  310. void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode)
  311. {
  312.         struct drm_device *dev = encoder->dev;
  313.         struct radeon_device *rdev = dev->dev_private;
  314.         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
  315.  
  316.         if (ASIC_IS_DCE4(rdev))
  317.                 return;
  318.  
  319.         if (!offset)
  320.                 return;
  321.  
  322.         r600_audio_set_clock(encoder, mode->clock);
  323.  
  324.         WREG32(offset+R600_HDMI_UNKNOWN_0, 0x1000);
  325.         WREG32(offset+R600_HDMI_UNKNOWN_1, 0x0);
  326.         WREG32(offset+R600_HDMI_UNKNOWN_2, 0x1000);
  327.  
  328.         r600_hdmi_update_ACR(encoder, mode->clock);
  329.  
  330.         WREG32(offset+R600_HDMI_VIDEOCNTL, 0x13);
  331.  
  332.         WREG32(offset+R600_HDMI_VERSION, 0x202);
  333.  
  334.         r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0,
  335.                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  336.  
  337.         /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
  338.         WREG32(offset+R600_HDMI_AUDIO_DEBUG_0, 0x00FFFFFF);
  339.         WREG32(offset+R600_HDMI_AUDIO_DEBUG_1, 0x007FFFFF);
  340.         WREG32(offset+R600_HDMI_AUDIO_DEBUG_2, 0x00000001);
  341.         WREG32(offset+R600_HDMI_AUDIO_DEBUG_3, 0x00000001);
  342.  
  343.         r600_hdmi_audio_workaround(encoder);
  344.  
  345.         /* audio packets per line, does anyone know how to calc this ? */
  346.         WREG32_P(offset+R600_HDMI_CNTL, 0x00040000, ~0x001F0000);
  347. }
  348.  
  349. /*
  350.  * update settings with current parameters from audio engine
  351.  */
  352. void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)
  353. {
  354.         struct drm_device *dev = encoder->dev;
  355.         struct radeon_device *rdev = dev->dev_private;
  356.         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
  357.  
  358.         int channels = r600_audio_channels(rdev);
  359.         int rate = r600_audio_rate(rdev);
  360.         int bps = r600_audio_bits_per_sample(rdev);
  361.         uint8_t status_bits = r600_audio_status_bits(rdev);
  362.         uint8_t category_code = r600_audio_category_code(rdev);
  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.  
  417. static int r600_hdmi_find_free_block(struct drm_device *dev)
  418. {
  419.         struct radeon_device *rdev = dev->dev_private;
  420.         struct drm_encoder *encoder;
  421.         struct radeon_encoder *radeon_encoder;
  422.         bool free_blocks[3] = { true, true, true };
  423.  
  424.         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
  425.                 radeon_encoder = to_radeon_encoder(encoder);
  426.                 switch (radeon_encoder->hdmi_offset) {
  427.                 case R600_HDMI_BLOCK1:
  428.                         free_blocks[0] = false;
  429.                         break;
  430.                 case R600_HDMI_BLOCK2:
  431.                         free_blocks[1] = false;
  432.                         break;
  433.                 case R600_HDMI_BLOCK3:
  434.                         free_blocks[2] = false;
  435.                         break;
  436.                 }
  437.         }
  438.  
  439.         if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 ||
  440.             rdev->family == CHIP_RS740) {
  441.                 return free_blocks[0] ? R600_HDMI_BLOCK1 : 0;
  442.         } else if (rdev->family >= CHIP_R600) {
  443.                 if (free_blocks[0])
  444.                         return R600_HDMI_BLOCK1;
  445.                 else if (free_blocks[1])
  446.                         return R600_HDMI_BLOCK2;
  447.         }
  448.         return 0;
  449. }
  450.  
  451. static void r600_hdmi_assign_block(struct drm_encoder *encoder)
  452. {
  453.         struct drm_device *dev = encoder->dev;
  454.         struct radeon_device *rdev = dev->dev_private;
  455.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  456.         struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
  457.  
  458.         if (!dig) {
  459.                 dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n");
  460.                 return;
  461.         }
  462.  
  463.         if (ASIC_IS_DCE4(rdev)) {
  464.                 /* TODO */
  465.         } else if (ASIC_IS_DCE3(rdev)) {
  466.                 radeon_encoder->hdmi_offset = dig->dig_encoder ?
  467.                         R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1;
  468.                 if (ASIC_IS_DCE32(rdev))
  469.                         radeon_encoder->hdmi_config_offset = dig->dig_encoder ?
  470.                                 R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1;
  471.         } else if (rdev->family >= CHIP_R600 || rdev->family == CHIP_RS600 ||
  472.                    rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
  473.                 radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev);
  474.         }
  475. }
  476.  
  477. /*
  478.  * enable the HDMI engine
  479.  */
  480. void r600_hdmi_enable(struct drm_encoder *encoder)
  481. {
  482.         struct drm_device *dev = encoder->dev;
  483.         struct radeon_device *rdev = dev->dev_private;
  484.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  485.         uint32_t offset;
  486.  
  487.         if (ASIC_IS_DCE4(rdev))
  488.                 return;
  489.  
  490.         if (!radeon_encoder->hdmi_offset) {
  491.                 r600_hdmi_assign_block(encoder);
  492.                 if (!radeon_encoder->hdmi_offset) {
  493.                         dev_warn(rdev->dev, "Could not find HDMI block for "
  494.                                 "0x%x encoder\n", radeon_encoder->encoder_id);
  495.                 return;
  496.                 }
  497.         }
  498.  
  499.         offset = radeon_encoder->hdmi_offset;
  500.         if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) {
  501.                 WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1);
  502.         } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
  503.         switch (radeon_encoder->encoder_id) {
  504.         case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
  505.                         WREG32_P(AVIVO_TMDSA_CNTL, 0x4, ~0x4);
  506.                         WREG32(offset + R600_HDMI_ENABLE, 0x101);
  507.                 break;
  508.         case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
  509.                         WREG32_P(AVIVO_LVTMA_CNTL, 0x4, ~0x4);
  510.                         WREG32(offset + R600_HDMI_ENABLE, 0x105);
  511.                 break;
  512.         default:
  513.                         dev_err(rdev->dev, "Unknown HDMI output type\n");
  514.                 break;
  515.         }
  516.         }
  517. #if 0
  518.         if (rdev->irq.installed
  519.             && rdev->family != CHIP_RS600
  520.             && rdev->family != CHIP_RS690
  521.             && rdev->family != CHIP_RS740) {
  522.  
  523.                 /* if irq is available use it */
  524.                 rdev->irq.hdmi[offset == R600_HDMI_BLOCK1 ? 0 : 1] = true;
  525.                 radeon_irq_set(rdev);
  526.  
  527.                 r600_audio_disable_polling(encoder);
  528.         } else {
  529.                 /* if not fallback to polling */
  530.                 r600_audio_enable_polling(encoder);
  531.         }
  532. #endif
  533.         DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n",
  534.                 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
  535. }
  536.  
  537. /*
  538.  * disable the HDMI engine
  539.  */
  540. void r600_hdmi_disable(struct drm_encoder *encoder)
  541. {
  542.         struct drm_device *dev = encoder->dev;
  543.         struct radeon_device *rdev = dev->dev_private;
  544.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  545.         uint32_t offset;
  546.  
  547.         if (ASIC_IS_DCE4(rdev))
  548.                 return;
  549.  
  550.         offset = radeon_encoder->hdmi_offset;
  551.         if (!offset) {
  552.                 dev_err(rdev->dev, "Disabling not enabled HDMI\n");
  553.                 return;
  554.         }
  555.  
  556.         DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n",
  557.                 offset, radeon_encoder->encoder_id);
  558.  
  559.         if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) {
  560.                 WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1);
  561.         } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
  562.         switch (radeon_encoder->encoder_id) {
  563.         case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
  564.                         WREG32_P(AVIVO_TMDSA_CNTL, 0, ~0x4);
  565.                         WREG32(offset + R600_HDMI_ENABLE, 0);
  566.                 break;
  567.         case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
  568.                         WREG32_P(AVIVO_LVTMA_CNTL, 0, ~0x4);
  569.                         WREG32(offset + R600_HDMI_ENABLE, 0);
  570.                         break;
  571.                 default:
  572.                         dev_err(rdev->dev, "Unknown HDMI output type\n");
  573.                         break;
  574.                 }
  575.         }
  576.  
  577.                 radeon_encoder->hdmi_offset = 0;
  578.         radeon_encoder->hdmi_config_offset = 0;
  579. }
  580.