Subversion Repositories Kolibri OS

Rev

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

  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. #include <drm/drmP.h>
  25. #include "radeon.h"
  26. #include "sid.h"
  27.  
  28. static u32 dce6_endpoint_rreg(struct radeon_device *rdev,
  29.                               u32 block_offset, u32 reg)
  30. {
  31.         unsigned long flags;
  32.         u32 r;
  33.  
  34.         spin_lock_irqsave(&rdev->end_idx_lock, flags);
  35.         WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
  36.         r = RREG32(AZ_F0_CODEC_ENDPOINT_DATA + block_offset);
  37.         spin_unlock_irqrestore(&rdev->end_idx_lock, flags);
  38.  
  39.         return r;
  40. }
  41.  
  42. static void dce6_endpoint_wreg(struct radeon_device *rdev,
  43.                                u32 block_offset, u32 reg, u32 v)
  44. {
  45.         unsigned long flags;
  46.  
  47.         spin_lock_irqsave(&rdev->end_idx_lock, flags);
  48.         if (ASIC_IS_DCE8(rdev))
  49.                 WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset, reg);
  50.         else
  51.                 WREG32(AZ_F0_CODEC_ENDPOINT_INDEX + block_offset,
  52.                        AZ_ENDPOINT_REG_WRITE_EN | AZ_ENDPOINT_REG_INDEX(reg));
  53.         WREG32(AZ_F0_CODEC_ENDPOINT_DATA + block_offset, v);
  54.         spin_unlock_irqrestore(&rdev->end_idx_lock, flags);
  55. }
  56.  
  57. #define RREG32_ENDPOINT(block, reg) dce6_endpoint_rreg(rdev, (block), (reg))
  58. #define WREG32_ENDPOINT(block, reg, v) dce6_endpoint_wreg(rdev, (block), (reg), (v))
  59.  
  60.  
  61. static void dce6_afmt_get_connected_pins(struct radeon_device *rdev)
  62. {
  63.         int i;
  64.         u32 offset, tmp;
  65.  
  66.         for (i = 0; i < rdev->audio.num_pins; i++) {
  67.                 offset = rdev->audio.pin[i].offset;
  68.                 tmp = RREG32_ENDPOINT(offset,
  69.                                       AZ_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT);
  70.                 if (((tmp & PORT_CONNECTIVITY_MASK) >> PORT_CONNECTIVITY_SHIFT) == 1)
  71.                         rdev->audio.pin[i].connected = false;
  72.                 else
  73.                         rdev->audio.pin[i].connected = true;
  74.         }
  75. }
  76.  
  77. struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev)
  78. {
  79.         int i;
  80.  
  81.         dce6_afmt_get_connected_pins(rdev);
  82.  
  83.         for (i = 0; i < rdev->audio.num_pins; i++) {
  84.                 if (rdev->audio.pin[i].connected)
  85.                         return &rdev->audio.pin[i];
  86.         }
  87.         DRM_ERROR("No connected audio pins found!\n");
  88.         return NULL;
  89. }
  90.  
  91. void dce6_afmt_select_pin(struct drm_encoder *encoder)
  92. {
  93.         struct radeon_device *rdev = encoder->dev->dev_private;
  94.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  95.         struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
  96.         u32 offset;
  97.  
  98.         if (!dig || !dig->afmt || !dig->afmt->pin)
  99.                 return;
  100.  
  101.         offset = dig->afmt->offset;
  102.  
  103.         WREG32(AFMT_AUDIO_SRC_CONTROL + offset,
  104.                AFMT_AUDIO_SRC_SELECT(dig->afmt->pin->id));
  105. }
  106.  
  107. void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
  108.                                     struct drm_display_mode *mode)
  109. {
  110.         struct radeon_device *rdev = encoder->dev->dev_private;
  111.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  112.         struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
  113.         struct drm_connector *connector;
  114.         struct radeon_connector *radeon_connector = NULL;
  115.         u32 tmp = 0, offset;
  116.  
  117.         if (!dig || !dig->afmt || !dig->afmt->pin)
  118.                 return;
  119.  
  120.         offset = dig->afmt->pin->offset;
  121.  
  122.         list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
  123.                 if (connector->encoder == encoder) {
  124.                         radeon_connector = to_radeon_connector(connector);
  125.                         break;
  126.                 }
  127.         }
  128.  
  129.         if (!radeon_connector) {
  130.                 DRM_ERROR("Couldn't find encoder's connector\n");
  131.                 return;
  132.         }
  133.  
  134.         if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
  135.                 if (connector->latency_present[1])
  136.                         tmp = VIDEO_LIPSYNC(connector->video_latency[1]) |
  137.                                 AUDIO_LIPSYNC(connector->audio_latency[1]);
  138.                 else
  139.                         tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0);
  140.         } else {
  141.                 if (connector->latency_present[0])
  142.                         tmp = VIDEO_LIPSYNC(connector->video_latency[0]) |
  143.                                 AUDIO_LIPSYNC(connector->audio_latency[0]);
  144.                 else
  145.                         tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0);
  146.         }
  147.         WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp);
  148. }
  149.  
  150. void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder)
  151. {
  152.         struct radeon_device *rdev = encoder->dev->dev_private;
  153.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  154.         struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
  155.         struct drm_connector *connector;
  156.         struct radeon_connector *radeon_connector = NULL;
  157.         u32 offset, tmp;
  158.         u8 *sadb = NULL;
  159.         int sad_count;
  160.  
  161.         if (!dig || !dig->afmt || !dig->afmt->pin)
  162.                 return;
  163.  
  164.         offset = dig->afmt->pin->offset;
  165.  
  166.         list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
  167.                 if (connector->encoder == encoder) {
  168.                         radeon_connector = to_radeon_connector(connector);
  169.                         break;
  170.                 }
  171.         }
  172.  
  173.         if (!radeon_connector) {
  174.                 DRM_ERROR("Couldn't find encoder's connector\n");
  175.                 return;
  176.         }
  177.  
  178.         sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb);
  179.         if (sad_count < 0) {
  180.                 DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
  181.                 sad_count = 0;
  182.         }
  183.  
  184.         /* program the speaker allocation */
  185.         tmp = RREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
  186.         tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK);
  187.         /* set HDMI mode */
  188.         tmp |= HDMI_CONNECTION;
  189.         if (sad_count)
  190.                 tmp |= SPEAKER_ALLOCATION(sadb[0]);
  191.         else
  192.                 tmp |= SPEAKER_ALLOCATION(5); /* stereo */
  193.         WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, tmp);
  194.  
  195.         kfree(sadb);
  196. }
  197.  
  198. void dce6_afmt_write_sad_regs(struct drm_encoder *encoder)
  199. {
  200.         struct radeon_device *rdev = encoder->dev->dev_private;
  201.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  202.         struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
  203.         u32 offset;
  204.         struct drm_connector *connector;
  205.         struct radeon_connector *radeon_connector = NULL;
  206.         struct cea_sad *sads;
  207.         int i, sad_count;
  208.  
  209.         static const u16 eld_reg_to_type[][2] = {
  210.                 { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM },
  211.                 { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 },
  212.                 { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR2, HDMI_AUDIO_CODING_TYPE_MPEG1 },
  213.                 { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR3, HDMI_AUDIO_CODING_TYPE_MP3 },
  214.                 { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR4, HDMI_AUDIO_CODING_TYPE_MPEG2 },
  215.                 { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR5, HDMI_AUDIO_CODING_TYPE_AAC_LC },
  216.                 { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR6, HDMI_AUDIO_CODING_TYPE_DTS },
  217.                 { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR7, HDMI_AUDIO_CODING_TYPE_ATRAC },
  218.                 { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR9, HDMI_AUDIO_CODING_TYPE_EAC3 },
  219.                 { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR10, HDMI_AUDIO_CODING_TYPE_DTS_HD },
  220.                 { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR11, HDMI_AUDIO_CODING_TYPE_MLP },
  221.                 { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO },
  222.         };
  223.  
  224.         if (!dig || !dig->afmt || !dig->afmt->pin)
  225.                 return;
  226.  
  227.         offset = dig->afmt->pin->offset;
  228.  
  229.         list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
  230.                 if (connector->encoder == encoder) {
  231.                         radeon_connector = to_radeon_connector(connector);
  232.                         break;
  233.                 }
  234.         }
  235.  
  236.         if (!radeon_connector) {
  237.                 DRM_ERROR("Couldn't find encoder's connector\n");
  238.                 return;
  239.         }
  240.  
  241.         sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads);
  242.         if (sad_count <= 0) {
  243.                 DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
  244.                 return;
  245.         }
  246.         BUG_ON(!sads);
  247.  
  248.         for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) {
  249.                 u32 value = 0;
  250.                 u8 stereo_freqs = 0;
  251.                 int max_channels = -1;
  252.                 int j;
  253.  
  254.                 for (j = 0; j < sad_count; j++) {
  255.                         struct cea_sad *sad = &sads[j];
  256.  
  257.                         if (sad->format == eld_reg_to_type[i][1]) {
  258.                                 if (sad->channels > max_channels) {
  259.                                         value = MAX_CHANNELS(sad->channels) |
  260.                                                 DESCRIPTOR_BYTE_2(sad->byte2) |
  261.                                                 SUPPORTED_FREQUENCIES(sad->freq);
  262.                                         max_channels = sad->channels;
  263.                                 }
  264.  
  265.                                 if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM)
  266.                                         stereo_freqs |= sad->freq;
  267.                                 else
  268.                                         break;
  269.                         }
  270.                 }
  271.  
  272.                 value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs);
  273.  
  274.                 WREG32_ENDPOINT(offset, eld_reg_to_type[i][0], value);
  275.         }
  276.  
  277.         kfree(sads);
  278. }
  279.  
  280. static int dce6_audio_chipset_supported(struct radeon_device *rdev)
  281. {
  282.         return !ASIC_IS_NODCE(rdev);
  283. }
  284.  
  285. void dce6_audio_enable(struct radeon_device *rdev,
  286.                        struct r600_audio_pin *pin,
  287.                        u8 enable_mask)
  288. {
  289.         if (!pin)
  290.                 return;
  291.  
  292.         WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
  293.                         enable_mask ? AUDIO_ENABLED : 0);
  294. }
  295.  
  296. static const u32 pin_offsets[7] =
  297. {
  298.         (0x5e00 - 0x5e00),
  299.         (0x5e18 - 0x5e00),
  300.         (0x5e30 - 0x5e00),
  301.         (0x5e48 - 0x5e00),
  302.         (0x5e60 - 0x5e00),
  303.         (0x5e78 - 0x5e00),
  304.         (0x5e90 - 0x5e00),
  305. };
  306.  
  307. int dce6_audio_init(struct radeon_device *rdev)
  308. {
  309.         int i;
  310.  
  311.         if (!radeon_audio || !dce6_audio_chipset_supported(rdev))
  312.                 return 0;
  313.  
  314.         rdev->audio.enabled = true;
  315.  
  316.         if (ASIC_IS_DCE81(rdev)) /* KV: 4 streams, 7 endpoints */
  317.                 rdev->audio.num_pins = 7;
  318.         else if (ASIC_IS_DCE83(rdev)) /* KB: 2 streams, 3 endpoints */
  319.                 rdev->audio.num_pins = 3;
  320.         else if (ASIC_IS_DCE8(rdev)) /* BN/HW: 6 streams, 7 endpoints */
  321.                 rdev->audio.num_pins = 7;
  322.         else if (ASIC_IS_DCE61(rdev)) /* TN: 4 streams, 6 endpoints */
  323.                 rdev->audio.num_pins = 6;
  324.         else if (ASIC_IS_DCE64(rdev)) /* OL: 2 streams, 2 endpoints */
  325.                 rdev->audio.num_pins = 2;
  326.         else /* SI: 6 streams, 6 endpoints */
  327.                 rdev->audio.num_pins = 6;
  328.  
  329.         for (i = 0; i < rdev->audio.num_pins; i++) {
  330.                 rdev->audio.pin[i].channels = -1;
  331.                 rdev->audio.pin[i].rate = -1;
  332.                 rdev->audio.pin[i].bits_per_sample = -1;
  333.                 rdev->audio.pin[i].status_bits = 0;
  334.                 rdev->audio.pin[i].category_code = 0;
  335.                 rdev->audio.pin[i].connected = false;
  336.                 rdev->audio.pin[i].offset = pin_offsets[i];
  337.                 rdev->audio.pin[i].id = i;
  338.                 /* disable audio.  it will be set up later */
  339.                 dce6_audio_enable(rdev, &rdev->audio.pin[i], false);
  340.         }
  341.  
  342.         return 0;
  343. }
  344.  
  345. void dce6_audio_fini(struct radeon_device *rdev)
  346. {
  347.         int i;
  348.  
  349.         if (!rdev->audio.enabled)
  350.                 return;
  351.  
  352.         for (i = 0; i < rdev->audio.num_pins; i++)
  353.                 dce6_audio_enable(rdev, &rdev->audio.pin[i], false);
  354.  
  355.         rdev->audio.enabled = false;
  356. }
  357.