Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright 2007-8 Advanced Micro Devices, Inc.
  3.  * Copyright 2008 Red Hat Inc.
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9.  * and/or sell copies of the Software, and to permit persons to whom the
  10.  * Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice shall be included in
  13.  * all copies or substantial portions of the Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21.  * OTHER DEALINGS IN THE SOFTWARE.
  22.  *
  23.  * Authors: Dave Airlie
  24.  *          Alex Deucher
  25.  */
  26. #include <drm/drmP.h>
  27. #include <drm/drm_crtc_helper.h>
  28. #include <drm/radeon_drm.h>
  29. #include "radeon.h"
  30. #include "atom.h"
  31.  
  32. extern void
  33. radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
  34.                              struct drm_connector *drm_connector);
  35. extern void
  36. radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
  37.                            struct drm_connector *drm_connector);
  38.  
  39.  
  40. static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
  41. {
  42.         struct drm_device *dev = encoder->dev;
  43.         struct radeon_device *rdev = dev->dev_private;
  44.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  45.         struct drm_encoder *clone_encoder;
  46.         uint32_t index_mask = 0;
  47.         int count;
  48.  
  49.         /* DIG routing gets problematic */
  50.         if (rdev->family >= CHIP_R600)
  51.                 return index_mask;
  52.         /* LVDS/TV are too wacky */
  53.         if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
  54.                 return index_mask;
  55.         /* DVO requires 2x ppll clocks depending on tmds chip */
  56.         if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
  57.                 return index_mask;
  58.  
  59.         count = -1;
  60.         list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) {
  61.                 struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder);
  62.                 count++;
  63.  
  64.                 if (clone_encoder == encoder)
  65.                         continue;
  66.                 if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT))
  67.                         continue;
  68.                 if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT)
  69.                         continue;
  70.                 else
  71.                         index_mask |= (1 << count);
  72.         }
  73.         return index_mask;
  74. }
  75.  
  76. void radeon_setup_encoder_clones(struct drm_device *dev)
  77. {
  78.         struct drm_encoder *encoder;
  79.  
  80.         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
  81.                 encoder->possible_clones = radeon_encoder_clones(encoder);
  82.         }
  83. }
  84.  
  85. uint32_t
  86. radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
  87. {
  88.         struct radeon_device *rdev = dev->dev_private;
  89.         uint32_t ret = 0;
  90.  
  91.         switch (supported_device) {
  92.         case ATOM_DEVICE_CRT1_SUPPORT:
  93.         case ATOM_DEVICE_TV1_SUPPORT:
  94.         case ATOM_DEVICE_TV2_SUPPORT:
  95.         case ATOM_DEVICE_CRT2_SUPPORT:
  96.         case ATOM_DEVICE_CV_SUPPORT:
  97.                 switch (dac) {
  98.                 case 1: /* dac a */
  99.                         if ((rdev->family == CHIP_RS300) ||
  100.                             (rdev->family == CHIP_RS400) ||
  101.                             (rdev->family == CHIP_RS480))
  102.                                 ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
  103.                         else if (ASIC_IS_AVIVO(rdev))
  104.                                 ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1;
  105.                         else
  106.                                 ret = ENCODER_INTERNAL_DAC1_ENUM_ID1;
  107.                         break;
  108.                 case 2: /* dac b */
  109.                         if (ASIC_IS_AVIVO(rdev))
  110.                                 ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1;
  111.                         else {
  112.                                 /*if (rdev->family == CHIP_R200)
  113.                                   ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
  114.                                   else*/
  115.                                 ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
  116.                         }
  117.                         break;
  118.                 case 3: /* external dac */
  119.                         if (ASIC_IS_AVIVO(rdev))
  120.                                 ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
  121.                         else
  122.                                 ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
  123.                         break;
  124.                 }
  125.                 break;
  126.         case ATOM_DEVICE_LCD1_SUPPORT:
  127.                 if (ASIC_IS_AVIVO(rdev))
  128.                         ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
  129.                 else
  130.                         ret = ENCODER_INTERNAL_LVDS_ENUM_ID1;
  131.                 break;
  132.         case ATOM_DEVICE_DFP1_SUPPORT:
  133.                 if ((rdev->family == CHIP_RS300) ||
  134.                     (rdev->family == CHIP_RS400) ||
  135.                     (rdev->family == CHIP_RS480))
  136.                         ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
  137.                 else if (ASIC_IS_AVIVO(rdev))
  138.                         ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1;
  139.                 else
  140.                         ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1;
  141.                 break;
  142.         case ATOM_DEVICE_LCD2_SUPPORT:
  143.         case ATOM_DEVICE_DFP2_SUPPORT:
  144.                 if ((rdev->family == CHIP_RS600) ||
  145.                     (rdev->family == CHIP_RS690) ||
  146.                     (rdev->family == CHIP_RS740))
  147.                         ret = ENCODER_INTERNAL_DDI_ENUM_ID1;
  148.                 else if (ASIC_IS_AVIVO(rdev))
  149.                         ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
  150.                 else
  151.                         ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
  152.                 break;
  153.         case ATOM_DEVICE_DFP3_SUPPORT:
  154.                 ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
  155.                 break;
  156.         }
  157.  
  158.         return ret;
  159. }
  160.  
  161. void
  162. radeon_link_encoder_connector(struct drm_device *dev)
  163. {
  164.         struct radeon_device *rdev = dev->dev_private;
  165.         struct drm_connector *connector;
  166.         struct radeon_connector *radeon_connector;
  167.         struct drm_encoder *encoder;
  168.         struct radeon_encoder *radeon_encoder;
  169.  
  170.         /* walk the list and link encoders to connectors */
  171.         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
  172.                 radeon_connector = to_radeon_connector(connector);
  173.                 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
  174.                         radeon_encoder = to_radeon_encoder(encoder);
  175.                         if (radeon_encoder->devices & radeon_connector->devices) {
  176.                                 drm_mode_connector_attach_encoder(connector, encoder);
  177.                                 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
  178.                                         if (rdev->is_atom_bios)
  179.                                                 radeon_atom_backlight_init(radeon_encoder, connector);
  180.                                         else
  181.                                                 radeon_legacy_backlight_init(radeon_encoder, connector);
  182.                                         rdev->mode_info.bl_encoder = radeon_encoder;
  183.                                 }
  184.                         }
  185.                 }
  186.         }
  187. }
  188.  
  189. void radeon_encoder_set_active_device(struct drm_encoder *encoder)
  190. {
  191.         struct drm_device *dev = encoder->dev;
  192.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  193.         struct drm_connector *connector;
  194.  
  195.         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
  196.                 if (connector->encoder == encoder) {
  197.                         struct radeon_connector *radeon_connector = to_radeon_connector(connector);
  198.                         radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices;
  199.                         DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",
  200.                                   radeon_encoder->active_device, radeon_encoder->devices,
  201.                                   radeon_connector->devices, encoder->encoder_type);
  202.                 }
  203.         }
  204. }
  205.  
  206. struct drm_connector *
  207. radeon_get_connector_for_encoder(struct drm_encoder *encoder)
  208. {
  209.         struct drm_device *dev = encoder->dev;
  210.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  211.         struct drm_connector *connector;
  212.         struct radeon_connector *radeon_connector;
  213.  
  214.         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
  215.                 radeon_connector = to_radeon_connector(connector);
  216.                 if (radeon_encoder->active_device & radeon_connector->devices)
  217.                         return connector;
  218.         }
  219.         return NULL;
  220. }
  221.  
  222. struct drm_connector *
  223. radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
  224. {
  225.         struct drm_device *dev = encoder->dev;
  226.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  227.         struct drm_connector *connector;
  228.         struct radeon_connector *radeon_connector;
  229.  
  230.         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
  231.                 radeon_connector = to_radeon_connector(connector);
  232.                 if (radeon_encoder->devices & radeon_connector->devices)
  233.                         return connector;
  234.         }
  235.         return NULL;
  236. }
  237.  
  238. struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder)
  239. {
  240.         struct drm_device *dev = encoder->dev;
  241.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  242.         struct drm_encoder *other_encoder;
  243.         struct radeon_encoder *other_radeon_encoder;
  244.  
  245.         if (radeon_encoder->is_ext_encoder)
  246.                 return NULL;
  247.  
  248.         list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {
  249.                 if (other_encoder == encoder)
  250.                         continue;
  251.                 other_radeon_encoder = to_radeon_encoder(other_encoder);
  252.                 if (other_radeon_encoder->is_ext_encoder &&
  253.                     (radeon_encoder->devices & other_radeon_encoder->devices))
  254.                         return other_encoder;
  255.         }
  256.         return NULL;
  257. }
  258.  
  259. u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder)
  260. {
  261.         struct drm_encoder *other_encoder = radeon_get_external_encoder(encoder);
  262.  
  263.         if (other_encoder) {
  264.                 struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder);
  265.  
  266.                 switch (radeon_encoder->encoder_id) {
  267.                 case ENCODER_OBJECT_ID_TRAVIS:
  268.                 case ENCODER_OBJECT_ID_NUTMEG:
  269.                         return radeon_encoder->encoder_id;
  270.                 default:
  271.                         return ENCODER_OBJECT_ID_NONE;
  272.                 }
  273.         }
  274.         return ENCODER_OBJECT_ID_NONE;
  275. }
  276.  
  277. void radeon_panel_mode_fixup(struct drm_encoder *encoder,
  278.                              struct drm_display_mode *adjusted_mode)
  279. {
  280.         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  281.         struct drm_device *dev = encoder->dev;
  282.         struct radeon_device *rdev = dev->dev_private;
  283.         struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
  284.         unsigned hblank = native_mode->htotal - native_mode->hdisplay;
  285.         unsigned vblank = native_mode->vtotal - native_mode->vdisplay;
  286.         unsigned hover = native_mode->hsync_start - native_mode->hdisplay;
  287.         unsigned vover = native_mode->vsync_start - native_mode->vdisplay;
  288.         unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start;
  289.         unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start;
  290.  
  291.         adjusted_mode->clock = native_mode->clock;
  292.         adjusted_mode->flags = native_mode->flags;
  293.  
  294.         if (ASIC_IS_AVIVO(rdev)) {
  295.                 adjusted_mode->hdisplay = native_mode->hdisplay;
  296.                 adjusted_mode->vdisplay = native_mode->vdisplay;
  297.         }
  298.  
  299.         adjusted_mode->htotal = native_mode->hdisplay + hblank;
  300.         adjusted_mode->hsync_start = native_mode->hdisplay + hover;
  301.         adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width;
  302.  
  303.         adjusted_mode->vtotal = native_mode->vdisplay + vblank;
  304.         adjusted_mode->vsync_start = native_mode->vdisplay + vover;
  305.         adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width;
  306.  
  307.         drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
  308.  
  309.         if (ASIC_IS_AVIVO(rdev)) {
  310.                 adjusted_mode->crtc_hdisplay = native_mode->hdisplay;
  311.                 adjusted_mode->crtc_vdisplay = native_mode->vdisplay;
  312.         }
  313.  
  314.         adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank;
  315.         adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover;
  316.         adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width;
  317.  
  318.         adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank;
  319.         adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover;
  320.         adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width;
  321.  
  322. }
  323.  
  324. bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
  325.                                     u32 pixel_clock)
  326. {
  327.         struct drm_device *dev = encoder->dev;
  328.         struct radeon_device *rdev = dev->dev_private;
  329.         struct drm_connector *connector;
  330.         struct radeon_connector *radeon_connector;
  331.         struct radeon_connector_atom_dig *dig_connector;
  332.  
  333.         connector = radeon_get_connector_for_encoder(encoder);
  334.         /* if we don't have an active device yet, just use one of
  335.          * the connectors tied to the encoder.
  336.          */
  337.         if (!connector)
  338.                 connector = radeon_get_connector_for_encoder_init(encoder);
  339.         radeon_connector = to_radeon_connector(connector);
  340.  
  341.         switch (connector->connector_type) {
  342.         case DRM_MODE_CONNECTOR_DVII:
  343.         case DRM_MODE_CONNECTOR_HDMIB:
  344.                 if (radeon_connector->use_digital) {
  345.                         /* HDMI 1.3 supports up to 340 Mhz over single link */
  346.                         if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
  347.                                 if (pixel_clock > 340000)
  348.                                         return true;
  349.                         else
  350.                                         return false;
  351.                         } else {
  352.                                 if (pixel_clock > 165000)
  353.                                         return true;
  354.                 else
  355.                                         return false;
  356.                         }
  357.                 } else
  358.                         return false;
  359.         case DRM_MODE_CONNECTOR_DVID:
  360.         case DRM_MODE_CONNECTOR_HDMIA:
  361.         case DRM_MODE_CONNECTOR_DisplayPort:
  362.                 dig_connector = radeon_connector->con_priv;
  363.                 if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
  364.                     (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
  365.                         return false;
  366.         else {
  367.                         /* HDMI 1.3 supports up to 340 Mhz over single link */
  368.                         if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
  369.                                 if (pixel_clock > 340000)
  370.                                         return true;
  371.                 else
  372.                                         return false;
  373.         } else {
  374.                                 if (pixel_clock > 165000)
  375.                                         return true;
  376.                                 else
  377.                 return false;
  378.         }
  379.                 }
  380.                 default:
  381.                         return false;
  382.                 }
  383. }
  384.  
  385.