450 lines · c
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 a6 * copy of this software and associated documentation files (the "Software"),7 * to deal in the Software without restriction, including without limitation8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,9 * and/or sell copies of the Software, and to permit persons to whom the10 * Software is furnished to do so, subject to the following conditions:11 *12 * The above copyright notice and this permission notice shall be included in13 * all copies or substantial portions of the Software.14 *15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR19 * 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 OR21 * OTHER DEALINGS IN THE SOFTWARE.22 *23 * Authors: Dave Airlie24 * Alex Deucher25 */26 27#include <linux/pci.h>28 29#include <drm/drm_edid.h>30#include <drm/drm_device.h>31#include <drm/radeon_drm.h>32 33#include <acpi/video.h>34 35#include "radeon.h"36#include "radeon_atombios.h"37#include "radeon_legacy_encoders.h"38#include "atom.h"39 40static 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 = drm_encoder_mask(encoder);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 63 count++;64 65 if (clone_encoder == encoder)66 continue;67 if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT))68 continue;69 if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT)70 continue;71 else72 index_mask |= (1 << count);73 }74 return index_mask;75}76 77void radeon_setup_encoder_clones(struct drm_device *dev)78{79 struct drm_encoder *encoder;80 81 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {82 encoder->possible_clones = radeon_encoder_clones(encoder);83 }84}85 86uint32_t87radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac)88{89 struct radeon_device *rdev = dev->dev_private;90 uint32_t ret = 0;91 92 switch (supported_device) {93 case ATOM_DEVICE_CRT1_SUPPORT:94 case ATOM_DEVICE_TV1_SUPPORT:95 case ATOM_DEVICE_TV2_SUPPORT:96 case ATOM_DEVICE_CRT2_SUPPORT:97 case ATOM_DEVICE_CV_SUPPORT:98 switch (dac) {99 case 1: /* dac a */100 if ((rdev->family == CHIP_RS300) ||101 (rdev->family == CHIP_RS400) ||102 (rdev->family == CHIP_RS480))103 ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;104 else if (ASIC_IS_AVIVO(rdev))105 ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1;106 else107 ret = ENCODER_INTERNAL_DAC1_ENUM_ID1;108 break;109 case 2: /* dac b */110 if (ASIC_IS_AVIVO(rdev))111 ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1;112 else {113 /* if (rdev->family == CHIP_R200)114 * ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;115 * else116 */117 ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;118 }119 break;120 case 3: /* external dac */121 if (ASIC_IS_AVIVO(rdev))122 ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;123 else124 ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;125 break;126 }127 break;128 case ATOM_DEVICE_LCD1_SUPPORT:129 if (ASIC_IS_AVIVO(rdev))130 ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;131 else132 ret = ENCODER_INTERNAL_LVDS_ENUM_ID1;133 break;134 case ATOM_DEVICE_DFP1_SUPPORT:135 if ((rdev->family == CHIP_RS300) ||136 (rdev->family == CHIP_RS400) ||137 (rdev->family == CHIP_RS480))138 ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;139 else if (ASIC_IS_AVIVO(rdev))140 ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1;141 else142 ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1;143 break;144 case ATOM_DEVICE_LCD2_SUPPORT:145 case ATOM_DEVICE_DFP2_SUPPORT:146 if ((rdev->family == CHIP_RS600) ||147 (rdev->family == CHIP_RS690) ||148 (rdev->family == CHIP_RS740))149 ret = ENCODER_INTERNAL_DDI_ENUM_ID1;150 else if (ASIC_IS_AVIVO(rdev))151 ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;152 else153 ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;154 break;155 case ATOM_DEVICE_DFP3_SUPPORT:156 ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;157 break;158 }159 160 return ret;161}162 163static void radeon_encoder_add_backlight(struct radeon_encoder *radeon_encoder,164 struct drm_connector *connector)165{166 struct drm_device *dev = radeon_encoder->base.dev;167 struct radeon_device *rdev = dev->dev_private;168 bool use_bl = false;169 170 if (!(radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)))171 return;172 173 if (radeon_backlight == 0) {174 use_bl = false;175 } else if (radeon_backlight == 1) {176 use_bl = true;177 } else if (radeon_backlight == -1) {178 /* Quirks */179 /* Amilo Xi 2550 only works with acpi bl */180 if ((rdev->pdev->device == 0x9583) &&181 (rdev->pdev->subsystem_vendor == 0x1734) &&182 (rdev->pdev->subsystem_device == 0x1107))183 use_bl = false;184/* Older PPC macs use on-GPU backlight controller */185#ifndef CONFIG_PPC_PMAC186 /* disable native backlight control on older asics */187 else if (rdev->family < CHIP_R600)188 use_bl = false;189#endif190 else191 use_bl = true;192 }193 194 if (use_bl) {195 if (rdev->is_atom_bios)196 radeon_atom_backlight_init(radeon_encoder, connector);197 else198 radeon_legacy_backlight_init(radeon_encoder, connector);199 }200 201 /*202 * If there is no native backlight device (which may happen even when203 * use_bl==true) try registering an ACPI video backlight device instead.204 */205 if (!rdev->mode_info.bl_encoder)206 acpi_video_register_backlight();207}208 209void210radeon_link_encoder_connector(struct drm_device *dev)211{212 struct drm_connector *connector;213 struct radeon_connector *radeon_connector;214 struct drm_encoder *encoder;215 struct radeon_encoder *radeon_encoder;216 217 /* walk the list and link encoders to connectors */218 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {219 radeon_connector = to_radeon_connector(connector);220 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {221 radeon_encoder = to_radeon_encoder(encoder);222 if (radeon_encoder->devices & radeon_connector->devices) {223 drm_connector_attach_encoder(connector, encoder);224 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))225 radeon_encoder_add_backlight(radeon_encoder, connector);226 }227 }228 }229}230 231void radeon_encoder_set_active_device(struct drm_encoder *encoder)232{233 struct drm_device *dev = encoder->dev;234 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);235 struct drm_connector *connector;236 237 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {238 if (connector->encoder == encoder) {239 struct radeon_connector *radeon_connector = to_radeon_connector(connector);240 241 radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices;242 DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",243 radeon_encoder->active_device, radeon_encoder->devices,244 radeon_connector->devices, encoder->encoder_type);245 }246 }247}248 249struct drm_connector *250radeon_get_connector_for_encoder(struct drm_encoder *encoder)251{252 struct drm_device *dev = encoder->dev;253 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);254 struct drm_connector *connector;255 struct radeon_connector *radeon_connector;256 257 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {258 radeon_connector = to_radeon_connector(connector);259 if (radeon_encoder->active_device & radeon_connector->devices)260 return connector;261 }262 return NULL;263}264 265struct drm_connector *266radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)267{268 struct drm_device *dev = encoder->dev;269 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);270 struct drm_connector *connector;271 struct radeon_connector *radeon_connector;272 273 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {274 radeon_connector = to_radeon_connector(connector);275 if (radeon_encoder->devices & radeon_connector->devices)276 return connector;277 }278 return NULL;279}280 281struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder)282{283 struct drm_device *dev = encoder->dev;284 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);285 struct drm_encoder *other_encoder;286 struct radeon_encoder *other_radeon_encoder;287 288 if (radeon_encoder->is_ext_encoder)289 return NULL;290 291 list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {292 if (other_encoder == encoder)293 continue;294 other_radeon_encoder = to_radeon_encoder(other_encoder);295 if (other_radeon_encoder->is_ext_encoder &&296 (radeon_encoder->devices & other_radeon_encoder->devices))297 return other_encoder;298 }299 return NULL;300}301 302u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder)303{304 struct drm_encoder *other_encoder = radeon_get_external_encoder(encoder);305 306 if (other_encoder) {307 struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder);308 309 switch (radeon_encoder->encoder_id) {310 case ENCODER_OBJECT_ID_TRAVIS:311 case ENCODER_OBJECT_ID_NUTMEG:312 return radeon_encoder->encoder_id;313 default:314 return ENCODER_OBJECT_ID_NONE;315 }316 }317 return ENCODER_OBJECT_ID_NONE;318}319 320void radeon_panel_mode_fixup(struct drm_encoder *encoder,321 struct drm_display_mode *adjusted_mode)322{323 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);324 struct drm_device *dev = encoder->dev;325 struct radeon_device *rdev = dev->dev_private;326 struct drm_display_mode *native_mode = &radeon_encoder->native_mode;327 unsigned int hblank = native_mode->htotal - native_mode->hdisplay;328 unsigned int vblank = native_mode->vtotal - native_mode->vdisplay;329 unsigned int hover = native_mode->hsync_start - native_mode->hdisplay;330 unsigned int vover = native_mode->vsync_start - native_mode->vdisplay;331 unsigned int hsync_width = native_mode->hsync_end - native_mode->hsync_start;332 unsigned int vsync_width = native_mode->vsync_end - native_mode->vsync_start;333 334 adjusted_mode->clock = native_mode->clock;335 adjusted_mode->flags = native_mode->flags;336 337 if (ASIC_IS_AVIVO(rdev)) {338 adjusted_mode->hdisplay = native_mode->hdisplay;339 adjusted_mode->vdisplay = native_mode->vdisplay;340 }341 342 adjusted_mode->htotal = native_mode->hdisplay + hblank;343 adjusted_mode->hsync_start = native_mode->hdisplay + hover;344 adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width;345 346 adjusted_mode->vtotal = native_mode->vdisplay + vblank;347 adjusted_mode->vsync_start = native_mode->vdisplay + vover;348 adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width;349 350 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);351 352 if (ASIC_IS_AVIVO(rdev)) {353 adjusted_mode->crtc_hdisplay = native_mode->hdisplay;354 adjusted_mode->crtc_vdisplay = native_mode->vdisplay;355 }356 357 adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank;358 adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover;359 adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width;360 361 adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank;362 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover;363 adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width;364 365}366 367bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,368 u32 pixel_clock)369{370 struct drm_device *dev = encoder->dev;371 struct radeon_device *rdev = dev->dev_private;372 struct drm_connector *connector;373 struct radeon_connector *radeon_connector;374 struct radeon_connector_atom_dig *dig_connector;375 376 connector = radeon_get_connector_for_encoder(encoder);377 /* if we don't have an active device yet, just use one of378 * the connectors tied to the encoder.379 */380 if (!connector)381 connector = radeon_get_connector_for_encoder_init(encoder);382 radeon_connector = to_radeon_connector(connector);383 384 switch (connector->connector_type) {385 case DRM_MODE_CONNECTOR_DVII:386 case DRM_MODE_CONNECTOR_HDMIB:387 if (radeon_connector->use_digital) {388 /* HDMI 1.3 supports up to 340 Mhz over single link */389 if (ASIC_IS_DCE6(rdev) && connector->display_info.is_hdmi) {390 if (pixel_clock > 340000)391 return true;392 else393 return false;394 } else {395 if (pixel_clock > 165000)396 return true;397 else398 return false;399 }400 } else401 return false;402 case DRM_MODE_CONNECTOR_DVID:403 case DRM_MODE_CONNECTOR_HDMIA:404 case DRM_MODE_CONNECTOR_DisplayPort:405 dig_connector = radeon_connector->con_priv;406 if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||407 (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))408 return false;409 else {410 /* HDMI 1.3 supports up to 340 Mhz over single link */411 if (ASIC_IS_DCE6(rdev) && connector->display_info.is_hdmi) {412 if (pixel_clock > 340000)413 return true;414 else415 return false;416 } else {417 if (pixel_clock > 165000)418 return true;419 else420 return false;421 }422 }423 default:424 return false;425 }426}427 428bool radeon_encoder_is_digital(struct drm_encoder *encoder)429{430 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);431 432 switch (radeon_encoder->encoder_id) {433 case ENCODER_OBJECT_ID_INTERNAL_LVDS:434 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:435 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:436 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:437 case ENCODER_OBJECT_ID_INTERNAL_DVO1:438 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:439 case ENCODER_OBJECT_ID_INTERNAL_DDI:440 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:441 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:442 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:443 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:444 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:445 return true;446 default:447 return false;448 }449}450