root/drivers/gpu/drm/radeon/radeon_encoders.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. radeon_encoder_clones
  2. radeon_setup_encoder_clones
  3. radeon_get_encoder_enum
  4. radeon_encoder_add_backlight
  5. radeon_link_encoder_connector
  6. radeon_encoder_set_active_device
  7. radeon_get_connector_for_encoder
  8. radeon_get_connector_for_encoder_init
  9. radeon_get_external_encoder
  10. radeon_encoder_get_dp_bridge_encoder_id
  11. radeon_panel_mode_fixup
  12. radeon_dig_monitor_is_duallink
  13. radeon_encoder_is_digital

   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 
  27 #include <drm/drm_crtc_helper.h>
  28 #include <drm/drm_device.h>
  29 #include <drm/drm_pci.h>
  30 #include <drm/radeon_drm.h>
  31 
  32 #include "radeon.h"
  33 #include "atom.h"
  34 
  35 extern void
  36 radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
  37                              struct drm_connector *drm_connector);
  38 extern void
  39 radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
  40                            struct drm_connector *drm_connector);
  41 
  42 
  43 static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
  44 {
  45         struct drm_device *dev = encoder->dev;
  46         struct radeon_device *rdev = dev->dev_private;
  47         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  48         struct drm_encoder *clone_encoder;
  49         uint32_t index_mask = 0;
  50         int count;
  51 
  52         /* DIG routing gets problematic */
  53         if (rdev->family >= CHIP_R600)
  54                 return index_mask;
  55         /* LVDS/TV are too wacky */
  56         if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
  57                 return index_mask;
  58         /* DVO requires 2x ppll clocks depending on tmds chip */
  59         if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
  60                 return index_mask;
  61 
  62         count = -1;
  63         list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) {
  64                 struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder);
  65                 count++;
  66 
  67                 if (clone_encoder == encoder)
  68                         continue;
  69                 if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT))
  70                         continue;
  71                 if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT)
  72                         continue;
  73                 else
  74                         index_mask |= (1 << count);
  75         }
  76         return index_mask;
  77 }
  78 
  79 void radeon_setup_encoder_clones(struct drm_device *dev)
  80 {
  81         struct drm_encoder *encoder;
  82 
  83         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
  84                 encoder->possible_clones = radeon_encoder_clones(encoder);
  85         }
  86 }
  87 
  88 uint32_t
  89 radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
  90 {
  91         struct radeon_device *rdev = dev->dev_private;
  92         uint32_t ret = 0;
  93 
  94         switch (supported_device) {
  95         case ATOM_DEVICE_CRT1_SUPPORT:
  96         case ATOM_DEVICE_TV1_SUPPORT:
  97         case ATOM_DEVICE_TV2_SUPPORT:
  98         case ATOM_DEVICE_CRT2_SUPPORT:
  99         case ATOM_DEVICE_CV_SUPPORT:
 100                 switch (dac) {
 101                 case 1: /* dac a */
 102                         if ((rdev->family == CHIP_RS300) ||
 103                             (rdev->family == CHIP_RS400) ||
 104                             (rdev->family == CHIP_RS480))
 105                                 ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
 106                         else if (ASIC_IS_AVIVO(rdev))
 107                                 ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1;
 108                         else
 109                                 ret = ENCODER_INTERNAL_DAC1_ENUM_ID1;
 110                         break;
 111                 case 2: /* dac b */
 112                         if (ASIC_IS_AVIVO(rdev))
 113                                 ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1;
 114                         else {
 115                                 /*if (rdev->family == CHIP_R200)
 116                                   ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
 117                                   else*/
 118                                 ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
 119                         }
 120                         break;
 121                 case 3: /* external dac */
 122                         if (ASIC_IS_AVIVO(rdev))
 123                                 ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
 124                         else
 125                                 ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
 126                         break;
 127                 }
 128                 break;
 129         case ATOM_DEVICE_LCD1_SUPPORT:
 130                 if (ASIC_IS_AVIVO(rdev))
 131                         ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
 132                 else
 133                         ret = ENCODER_INTERNAL_LVDS_ENUM_ID1;
 134                 break;
 135         case ATOM_DEVICE_DFP1_SUPPORT:
 136                 if ((rdev->family == CHIP_RS300) ||
 137                     (rdev->family == CHIP_RS400) ||
 138                     (rdev->family == CHIP_RS480))
 139                         ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
 140                 else if (ASIC_IS_AVIVO(rdev))
 141                         ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1;
 142                 else
 143                         ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1;
 144                 break;
 145         case ATOM_DEVICE_LCD2_SUPPORT:
 146         case ATOM_DEVICE_DFP2_SUPPORT:
 147                 if ((rdev->family == CHIP_RS600) ||
 148                     (rdev->family == CHIP_RS690) ||
 149                     (rdev->family == CHIP_RS740))
 150                         ret = ENCODER_INTERNAL_DDI_ENUM_ID1;
 151                 else if (ASIC_IS_AVIVO(rdev))
 152                         ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
 153                 else
 154                         ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
 155                 break;
 156         case ATOM_DEVICE_DFP3_SUPPORT:
 157                 ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
 158                 break;
 159         }
 160 
 161         return ret;
 162 }
 163 
 164 static void radeon_encoder_add_backlight(struct radeon_encoder *radeon_encoder,
 165                                          struct drm_connector *connector)
 166 {
 167         struct drm_device *dev = radeon_encoder->base.dev;
 168         struct radeon_device *rdev = dev->dev_private;
 169         bool use_bl = false;
 170 
 171         if (!(radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)))
 172                 return;
 173 
 174         if (radeon_backlight == 0) {
 175                 return;
 176         } else if (radeon_backlight == 1) {
 177                 use_bl = true;
 178         } else if (radeon_backlight == -1) {
 179                 /* Quirks */
 180                 /* Amilo Xi 2550 only works with acpi bl */
 181                 if ((rdev->pdev->device == 0x9583) &&
 182                     (rdev->pdev->subsystem_vendor == 0x1734) &&
 183                     (rdev->pdev->subsystem_device == 0x1107))
 184                         use_bl = false;
 185 /* Older PPC macs use on-GPU backlight controller */
 186 #ifndef CONFIG_PPC_PMAC
 187                 /* disable native backlight control on older asics */
 188                 else if (rdev->family < CHIP_R600)
 189                         use_bl = false;
 190 #endif
 191                 else
 192                         use_bl = true;
 193         }
 194 
 195         if (use_bl) {
 196                 if (rdev->is_atom_bios)
 197                         radeon_atom_backlight_init(radeon_encoder, connector);
 198                 else
 199                         radeon_legacy_backlight_init(radeon_encoder, connector);
 200         }
 201 }
 202 
 203 void
 204 radeon_link_encoder_connector(struct drm_device *dev)
 205 {
 206         struct drm_connector *connector;
 207         struct radeon_connector *radeon_connector;
 208         struct drm_encoder *encoder;
 209         struct radeon_encoder *radeon_encoder;
 210 
 211         /* walk the list and link encoders to connectors */
 212         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 213                 radeon_connector = to_radeon_connector(connector);
 214                 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 215                         radeon_encoder = to_radeon_encoder(encoder);
 216                         if (radeon_encoder->devices & radeon_connector->devices) {
 217                                 drm_connector_attach_encoder(connector, encoder);
 218                                 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
 219                                         radeon_encoder_add_backlight(radeon_encoder, connector);
 220                         }
 221                 }
 222         }
 223 }
 224 
 225 void radeon_encoder_set_active_device(struct drm_encoder *encoder)
 226 {
 227         struct drm_device *dev = encoder->dev;
 228         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 229         struct drm_connector *connector;
 230 
 231         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 232                 if (connector->encoder == encoder) {
 233                         struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 234                         radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices;
 235                         DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",
 236                                   radeon_encoder->active_device, radeon_encoder->devices,
 237                                   radeon_connector->devices, encoder->encoder_type);
 238                 }
 239         }
 240 }
 241 
 242 struct drm_connector *
 243 radeon_get_connector_for_encoder(struct drm_encoder *encoder)
 244 {
 245         struct drm_device *dev = encoder->dev;
 246         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 247         struct drm_connector *connector;
 248         struct radeon_connector *radeon_connector;
 249 
 250         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 251                 radeon_connector = to_radeon_connector(connector);
 252                 if (radeon_encoder->is_mst_encoder) {
 253                         struct radeon_encoder_mst *mst_enc;
 254 
 255                         if (!radeon_connector->is_mst_connector)
 256                                 continue;
 257 
 258                         mst_enc = radeon_encoder->enc_priv;
 259                         if (mst_enc->connector == radeon_connector->mst_port)
 260                                 return connector;
 261                 } else if (radeon_encoder->active_device & radeon_connector->devices)
 262                         return connector;
 263         }
 264         return NULL;
 265 }
 266 
 267 struct drm_connector *
 268 radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
 269 {
 270         struct drm_device *dev = encoder->dev;
 271         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 272         struct drm_connector *connector;
 273         struct radeon_connector *radeon_connector;
 274 
 275         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 276                 radeon_connector = to_radeon_connector(connector);
 277                 if (radeon_encoder->devices & radeon_connector->devices)
 278                         return connector;
 279         }
 280         return NULL;
 281 }
 282 
 283 struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder)
 284 {
 285         struct drm_device *dev = encoder->dev;
 286         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 287         struct drm_encoder *other_encoder;
 288         struct radeon_encoder *other_radeon_encoder;
 289 
 290         if (radeon_encoder->is_ext_encoder)
 291                 return NULL;
 292 
 293         list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {
 294                 if (other_encoder == encoder)
 295                         continue;
 296                 other_radeon_encoder = to_radeon_encoder(other_encoder);
 297                 if (other_radeon_encoder->is_ext_encoder &&
 298                     (radeon_encoder->devices & other_radeon_encoder->devices))
 299                         return other_encoder;
 300         }
 301         return NULL;
 302 }
 303 
 304 u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder)
 305 {
 306         struct drm_encoder *other_encoder = radeon_get_external_encoder(encoder);
 307 
 308         if (other_encoder) {
 309                 struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder);
 310 
 311                 switch (radeon_encoder->encoder_id) {
 312                 case ENCODER_OBJECT_ID_TRAVIS:
 313                 case ENCODER_OBJECT_ID_NUTMEG:
 314                         return radeon_encoder->encoder_id;
 315                 default:
 316                         return ENCODER_OBJECT_ID_NONE;
 317                 }
 318         }
 319         return ENCODER_OBJECT_ID_NONE;
 320 }
 321 
 322 void radeon_panel_mode_fixup(struct drm_encoder *encoder,
 323                              struct drm_display_mode *adjusted_mode)
 324 {
 325         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 326         struct drm_device *dev = encoder->dev;
 327         struct radeon_device *rdev = dev->dev_private;
 328         struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
 329         unsigned hblank = native_mode->htotal - native_mode->hdisplay;
 330         unsigned vblank = native_mode->vtotal - native_mode->vdisplay;
 331         unsigned hover = native_mode->hsync_start - native_mode->hdisplay;
 332         unsigned vover = native_mode->vsync_start - native_mode->vdisplay;
 333         unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start;
 334         unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start;
 335 
 336         adjusted_mode->clock = native_mode->clock;
 337         adjusted_mode->flags = native_mode->flags;
 338 
 339         if (ASIC_IS_AVIVO(rdev)) {
 340                 adjusted_mode->hdisplay = native_mode->hdisplay;
 341                 adjusted_mode->vdisplay = native_mode->vdisplay;
 342         }
 343 
 344         adjusted_mode->htotal = native_mode->hdisplay + hblank;
 345         adjusted_mode->hsync_start = native_mode->hdisplay + hover;
 346         adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width;
 347 
 348         adjusted_mode->vtotal = native_mode->vdisplay + vblank;
 349         adjusted_mode->vsync_start = native_mode->vdisplay + vover;
 350         adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width;
 351 
 352         drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
 353 
 354         if (ASIC_IS_AVIVO(rdev)) {
 355                 adjusted_mode->crtc_hdisplay = native_mode->hdisplay;
 356                 adjusted_mode->crtc_vdisplay = native_mode->vdisplay;
 357         }
 358 
 359         adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank;
 360         adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover;
 361         adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width;
 362 
 363         adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank;
 364         adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover;
 365         adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width;
 366 
 367 }
 368 
 369 bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
 370                                     u32 pixel_clock)
 371 {
 372         struct drm_device *dev = encoder->dev;
 373         struct radeon_device *rdev = dev->dev_private;
 374         struct drm_connector *connector;
 375         struct radeon_connector *radeon_connector;
 376         struct radeon_connector_atom_dig *dig_connector;
 377 
 378         connector = radeon_get_connector_for_encoder(encoder);
 379         /* if we don't have an active device yet, just use one of
 380          * the connectors tied to the encoder.
 381          */
 382         if (!connector)
 383                 connector = radeon_get_connector_for_encoder_init(encoder);
 384         radeon_connector = to_radeon_connector(connector);
 385 
 386         switch (connector->connector_type) {
 387         case DRM_MODE_CONNECTOR_DVII:
 388         case DRM_MODE_CONNECTOR_HDMIB:
 389                 if (radeon_connector->use_digital) {
 390                         /* HDMI 1.3 supports up to 340 Mhz over single link */
 391                         if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
 392                                 if (pixel_clock > 340000)
 393                                         return true;
 394                                 else
 395                                         return false;
 396                         } else {
 397                                 if (pixel_clock > 165000)
 398                                         return true;
 399                                 else
 400                                         return false;
 401                         }
 402                 } else
 403                         return false;
 404         case DRM_MODE_CONNECTOR_DVID:
 405         case DRM_MODE_CONNECTOR_HDMIA:
 406         case DRM_MODE_CONNECTOR_DisplayPort:
 407                 if (radeon_connector->is_mst_connector)
 408                         return false;
 409 
 410                 dig_connector = radeon_connector->con_priv;
 411                 if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
 412                     (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
 413                         return false;
 414                 else {
 415                         /* HDMI 1.3 supports up to 340 Mhz over single link */
 416                         if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
 417                                 if (pixel_clock > 340000)
 418                                         return true;
 419                                 else
 420                                         return false;
 421                         } else {
 422                                 if (pixel_clock > 165000)
 423                                         return true;
 424                                 else
 425                                         return false;
 426                         }
 427                 }
 428         default:
 429                 return false;
 430         }
 431 }
 432 
 433 bool radeon_encoder_is_digital(struct drm_encoder *encoder)
 434 {
 435         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 436         switch (radeon_encoder->encoder_id) {
 437         case ENCODER_OBJECT_ID_INTERNAL_LVDS:
 438         case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
 439         case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
 440         case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
 441         case ENCODER_OBJECT_ID_INTERNAL_DVO1:
 442         case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
 443         case ENCODER_OBJECT_ID_INTERNAL_DDI:
 444         case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 445         case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 446         case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 447         case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
 448         case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
 449                 return true;
 450         default:
 451                 return false;
 452         }
 453 }

/* [<][>][^][v][top][bottom][index][help] */