Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2007-8 Advanced Micro Devices, Inc.
0003  * Copyright 2008 Red Hat Inc.
0004  *
0005  * Permission is hereby granted, free of charge, to any person obtaining a
0006  * copy of this software and associated documentation files (the "Software"),
0007  * to deal in the Software without restriction, including without limitation
0008  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0009  * and/or sell copies of the Software, and to permit persons to whom the
0010  * Software is furnished to do so, subject to the following conditions:
0011  *
0012  * The above copyright notice and this permission notice shall be included in
0013  * all copies or substantial portions of the Software.
0014  *
0015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0018  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0019  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0020  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0021  * OTHER DEALINGS IN THE SOFTWARE.
0022  *
0023  * Authors: Dave Airlie
0024  *          Alex Deucher
0025  */
0026 
0027 #include <linux/pci.h>
0028 
0029 #include <drm/drm_crtc_helper.h>
0030 #include <drm/drm_device.h>
0031 #include <drm/radeon_drm.h>
0032 
0033 #include "radeon.h"
0034 #include "radeon_atombios.h"
0035 #include "radeon_legacy_encoders.h"
0036 #include "atom.h"
0037 
0038 static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
0039 {
0040     struct drm_device *dev = encoder->dev;
0041     struct radeon_device *rdev = dev->dev_private;
0042     struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
0043     struct drm_encoder *clone_encoder;
0044     uint32_t index_mask = 0;
0045     int count;
0046 
0047     /* DIG routing gets problematic */
0048     if (rdev->family >= CHIP_R600)
0049         return index_mask;
0050     /* LVDS/TV are too wacky */
0051     if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
0052         return index_mask;
0053     /* DVO requires 2x ppll clocks depending on tmds chip */
0054     if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
0055         return index_mask;
0056 
0057     count = -1;
0058     list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) {
0059         struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder);
0060         count++;
0061 
0062         if (clone_encoder == encoder)
0063             continue;
0064         if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT))
0065             continue;
0066         if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT)
0067             continue;
0068         else
0069             index_mask |= (1 << count);
0070     }
0071     return index_mask;
0072 }
0073 
0074 void radeon_setup_encoder_clones(struct drm_device *dev)
0075 {
0076     struct drm_encoder *encoder;
0077 
0078     list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
0079         encoder->possible_clones = radeon_encoder_clones(encoder);
0080     }
0081 }
0082 
0083 uint32_t
0084 radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
0085 {
0086     struct radeon_device *rdev = dev->dev_private;
0087     uint32_t ret = 0;
0088 
0089     switch (supported_device) {
0090     case ATOM_DEVICE_CRT1_SUPPORT:
0091     case ATOM_DEVICE_TV1_SUPPORT:
0092     case ATOM_DEVICE_TV2_SUPPORT:
0093     case ATOM_DEVICE_CRT2_SUPPORT:
0094     case ATOM_DEVICE_CV_SUPPORT:
0095         switch (dac) {
0096         case 1: /* dac a */
0097             if ((rdev->family == CHIP_RS300) ||
0098                 (rdev->family == CHIP_RS400) ||
0099                 (rdev->family == CHIP_RS480))
0100                 ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
0101             else if (ASIC_IS_AVIVO(rdev))
0102                 ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1;
0103             else
0104                 ret = ENCODER_INTERNAL_DAC1_ENUM_ID1;
0105             break;
0106         case 2: /* dac b */
0107             if (ASIC_IS_AVIVO(rdev))
0108                 ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1;
0109             else {
0110                 /*if (rdev->family == CHIP_R200)
0111                   ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
0112                   else*/
0113                 ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
0114             }
0115             break;
0116         case 3: /* external dac */
0117             if (ASIC_IS_AVIVO(rdev))
0118                 ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
0119             else
0120                 ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
0121             break;
0122         }
0123         break;
0124     case ATOM_DEVICE_LCD1_SUPPORT:
0125         if (ASIC_IS_AVIVO(rdev))
0126             ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
0127         else
0128             ret = ENCODER_INTERNAL_LVDS_ENUM_ID1;
0129         break;
0130     case ATOM_DEVICE_DFP1_SUPPORT:
0131         if ((rdev->family == CHIP_RS300) ||
0132             (rdev->family == CHIP_RS400) ||
0133             (rdev->family == CHIP_RS480))
0134             ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
0135         else if (ASIC_IS_AVIVO(rdev))
0136             ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1;
0137         else
0138             ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1;
0139         break;
0140     case ATOM_DEVICE_LCD2_SUPPORT:
0141     case ATOM_DEVICE_DFP2_SUPPORT:
0142         if ((rdev->family == CHIP_RS600) ||
0143             (rdev->family == CHIP_RS690) ||
0144             (rdev->family == CHIP_RS740))
0145             ret = ENCODER_INTERNAL_DDI_ENUM_ID1;
0146         else if (ASIC_IS_AVIVO(rdev))
0147             ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
0148         else
0149             ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
0150         break;
0151     case ATOM_DEVICE_DFP3_SUPPORT:
0152         ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
0153         break;
0154     }
0155 
0156     return ret;
0157 }
0158 
0159 static void radeon_encoder_add_backlight(struct radeon_encoder *radeon_encoder,
0160                      struct drm_connector *connector)
0161 {
0162     struct drm_device *dev = radeon_encoder->base.dev;
0163     struct radeon_device *rdev = dev->dev_private;
0164     bool use_bl = false;
0165 
0166     if (!(radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)))
0167         return;
0168 
0169     if (radeon_backlight == 0) {
0170         return;
0171     } else if (radeon_backlight == 1) {
0172         use_bl = true;
0173     } else if (radeon_backlight == -1) {
0174         /* Quirks */
0175         /* Amilo Xi 2550 only works with acpi bl */
0176         if ((rdev->pdev->device == 0x9583) &&
0177             (rdev->pdev->subsystem_vendor == 0x1734) &&
0178             (rdev->pdev->subsystem_device == 0x1107))
0179             use_bl = false;
0180 /* Older PPC macs use on-GPU backlight controller */
0181 #ifndef CONFIG_PPC_PMAC
0182         /* disable native backlight control on older asics */
0183         else if (rdev->family < CHIP_R600)
0184             use_bl = false;
0185 #endif
0186         else
0187             use_bl = true;
0188     }
0189 
0190     if (use_bl) {
0191         if (rdev->is_atom_bios)
0192             radeon_atom_backlight_init(radeon_encoder, connector);
0193         else
0194             radeon_legacy_backlight_init(radeon_encoder, connector);
0195     }
0196 }
0197 
0198 void
0199 radeon_link_encoder_connector(struct drm_device *dev)
0200 {
0201     struct drm_connector *connector;
0202     struct radeon_connector *radeon_connector;
0203     struct drm_encoder *encoder;
0204     struct radeon_encoder *radeon_encoder;
0205 
0206     /* walk the list and link encoders to connectors */
0207     list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
0208         radeon_connector = to_radeon_connector(connector);
0209         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
0210             radeon_encoder = to_radeon_encoder(encoder);
0211             if (radeon_encoder->devices & radeon_connector->devices) {
0212                 drm_connector_attach_encoder(connector, encoder);
0213                 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
0214                     radeon_encoder_add_backlight(radeon_encoder, connector);
0215             }
0216         }
0217     }
0218 }
0219 
0220 void radeon_encoder_set_active_device(struct drm_encoder *encoder)
0221 {
0222     struct drm_device *dev = encoder->dev;
0223     struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
0224     struct drm_connector *connector;
0225 
0226     list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
0227         if (connector->encoder == encoder) {
0228             struct radeon_connector *radeon_connector = to_radeon_connector(connector);
0229             radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices;
0230             DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",
0231                   radeon_encoder->active_device, radeon_encoder->devices,
0232                   radeon_connector->devices, encoder->encoder_type);
0233         }
0234     }
0235 }
0236 
0237 struct drm_connector *
0238 radeon_get_connector_for_encoder(struct drm_encoder *encoder)
0239 {
0240     struct drm_device *dev = encoder->dev;
0241     struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
0242     struct drm_connector *connector;
0243     struct radeon_connector *radeon_connector;
0244 
0245     list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
0246         radeon_connector = to_radeon_connector(connector);
0247         if (radeon_encoder->is_mst_encoder) {
0248             struct radeon_encoder_mst *mst_enc;
0249 
0250             if (!radeon_connector->is_mst_connector)
0251                 continue;
0252 
0253             mst_enc = radeon_encoder->enc_priv;
0254             if (mst_enc->connector == radeon_connector->mst_port)
0255                 return connector;
0256         } else if (radeon_encoder->active_device & radeon_connector->devices)
0257             return connector;
0258     }
0259     return NULL;
0260 }
0261 
0262 struct drm_connector *
0263 radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
0264 {
0265     struct drm_device *dev = encoder->dev;
0266     struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
0267     struct drm_connector *connector;
0268     struct radeon_connector *radeon_connector;
0269 
0270     list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
0271         radeon_connector = to_radeon_connector(connector);
0272         if (radeon_encoder->devices & radeon_connector->devices)
0273             return connector;
0274     }
0275     return NULL;
0276 }
0277 
0278 struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder)
0279 {
0280     struct drm_device *dev = encoder->dev;
0281     struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
0282     struct drm_encoder *other_encoder;
0283     struct radeon_encoder *other_radeon_encoder;
0284 
0285     if (radeon_encoder->is_ext_encoder)
0286         return NULL;
0287 
0288     list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {
0289         if (other_encoder == encoder)
0290             continue;
0291         other_radeon_encoder = to_radeon_encoder(other_encoder);
0292         if (other_radeon_encoder->is_ext_encoder &&
0293             (radeon_encoder->devices & other_radeon_encoder->devices))
0294             return other_encoder;
0295     }
0296     return NULL;
0297 }
0298 
0299 u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder)
0300 {
0301     struct drm_encoder *other_encoder = radeon_get_external_encoder(encoder);
0302 
0303     if (other_encoder) {
0304         struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder);
0305 
0306         switch (radeon_encoder->encoder_id) {
0307         case ENCODER_OBJECT_ID_TRAVIS:
0308         case ENCODER_OBJECT_ID_NUTMEG:
0309             return radeon_encoder->encoder_id;
0310         default:
0311             return ENCODER_OBJECT_ID_NONE;
0312         }
0313     }
0314     return ENCODER_OBJECT_ID_NONE;
0315 }
0316 
0317 void radeon_panel_mode_fixup(struct drm_encoder *encoder,
0318                  struct drm_display_mode *adjusted_mode)
0319 {
0320     struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
0321     struct drm_device *dev = encoder->dev;
0322     struct radeon_device *rdev = dev->dev_private;
0323     struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
0324     unsigned hblank = native_mode->htotal - native_mode->hdisplay;
0325     unsigned vblank = native_mode->vtotal - native_mode->vdisplay;
0326     unsigned hover = native_mode->hsync_start - native_mode->hdisplay;
0327     unsigned vover = native_mode->vsync_start - native_mode->vdisplay;
0328     unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start;
0329     unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start;
0330 
0331     adjusted_mode->clock = native_mode->clock;
0332     adjusted_mode->flags = native_mode->flags;
0333 
0334     if (ASIC_IS_AVIVO(rdev)) {
0335         adjusted_mode->hdisplay = native_mode->hdisplay;
0336         adjusted_mode->vdisplay = native_mode->vdisplay;
0337     }
0338 
0339     adjusted_mode->htotal = native_mode->hdisplay + hblank;
0340     adjusted_mode->hsync_start = native_mode->hdisplay + hover;
0341     adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width;
0342 
0343     adjusted_mode->vtotal = native_mode->vdisplay + vblank;
0344     adjusted_mode->vsync_start = native_mode->vdisplay + vover;
0345     adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width;
0346 
0347     drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
0348 
0349     if (ASIC_IS_AVIVO(rdev)) {
0350         adjusted_mode->crtc_hdisplay = native_mode->hdisplay;
0351         adjusted_mode->crtc_vdisplay = native_mode->vdisplay;
0352     }
0353 
0354     adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank;
0355     adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover;
0356     adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width;
0357 
0358     adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank;
0359     adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover;
0360     adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width;
0361 
0362 }
0363 
0364 bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
0365                     u32 pixel_clock)
0366 {
0367     struct drm_device *dev = encoder->dev;
0368     struct radeon_device *rdev = dev->dev_private;
0369     struct drm_connector *connector;
0370     struct radeon_connector *radeon_connector;
0371     struct radeon_connector_atom_dig *dig_connector;
0372 
0373     connector = radeon_get_connector_for_encoder(encoder);
0374     /* if we don't have an active device yet, just use one of
0375      * the connectors tied to the encoder.
0376      */
0377     if (!connector)
0378         connector = radeon_get_connector_for_encoder_init(encoder);
0379     radeon_connector = to_radeon_connector(connector);
0380 
0381     switch (connector->connector_type) {
0382     case DRM_MODE_CONNECTOR_DVII:
0383     case DRM_MODE_CONNECTOR_HDMIB:
0384         if (radeon_connector->use_digital) {
0385             /* HDMI 1.3 supports up to 340 Mhz over single link */
0386             if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
0387                 if (pixel_clock > 340000)
0388                     return true;
0389                 else
0390                     return false;
0391             } else {
0392                 if (pixel_clock > 165000)
0393                     return true;
0394                 else
0395                     return false;
0396             }
0397         } else
0398             return false;
0399     case DRM_MODE_CONNECTOR_DVID:
0400     case DRM_MODE_CONNECTOR_HDMIA:
0401     case DRM_MODE_CONNECTOR_DisplayPort:
0402         if (radeon_connector->is_mst_connector)
0403             return false;
0404 
0405         dig_connector = radeon_connector->con_priv;
0406         if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
0407             (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
0408             return false;
0409         else {
0410             /* HDMI 1.3 supports up to 340 Mhz over single link */
0411             if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
0412                 if (pixel_clock > 340000)
0413                     return true;
0414                 else
0415                     return false;
0416             } else {
0417                 if (pixel_clock > 165000)
0418                     return true;
0419                 else
0420                     return false;
0421             }
0422         }
0423     default:
0424         return false;
0425     }
0426 }
0427 
0428 bool radeon_encoder_is_digital(struct drm_encoder *encoder)
0429 {
0430     struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
0431     switch (radeon_encoder->encoder_id) {
0432     case ENCODER_OBJECT_ID_INTERNAL_LVDS:
0433     case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
0434     case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
0435     case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
0436     case ENCODER_OBJECT_ID_INTERNAL_DVO1:
0437     case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
0438     case ENCODER_OBJECT_ID_INTERNAL_DDI:
0439     case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
0440     case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
0441     case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
0442     case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
0443     case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
0444         return true;
0445     default:
0446         return false;
0447     }
0448 }