2789 lines · c
1/*2 * Copyright 2007-11 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/backlight.h>28#include <linux/dmi.h>29#include <linux/pci.h>30 31#include <drm/drm_crtc_helper.h>32#include <drm/drm_edid.h>33#include <drm/drm_file.h>34#include <drm/drm_modeset_helper_vtables.h>35#include <drm/radeon_drm.h>36 37#include <acpi/video.h>38 39#include "atom.h"40#include "radeon_atombios.h"41#include "radeon.h"42#include "radeon_asic.h"43#include "radeon_audio.h"44 45extern int atom_debug;46 47static u848radeon_atom_get_backlight_level_from_reg(struct radeon_device *rdev)49{50 u8 backlight_level;51 u32 bios_2_scratch;52 53 if (rdev->family >= CHIP_R600)54 bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);55 else56 bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);57 58 backlight_level = ((bios_2_scratch & ATOM_S2_CURRENT_BL_LEVEL_MASK) >>59 ATOM_S2_CURRENT_BL_LEVEL_SHIFT);60 61 return backlight_level;62}63 64static void65radeon_atom_set_backlight_level_to_reg(struct radeon_device *rdev,66 u8 backlight_level)67{68 u32 bios_2_scratch;69 70 if (rdev->family >= CHIP_R600)71 bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);72 else73 bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);74 75 bios_2_scratch &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK;76 bios_2_scratch |= ((backlight_level << ATOM_S2_CURRENT_BL_LEVEL_SHIFT) &77 ATOM_S2_CURRENT_BL_LEVEL_MASK);78 79 if (rdev->family >= CHIP_R600)80 WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch);81 else82 WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch);83}84 85u886atombios_get_backlight_level(struct radeon_encoder *radeon_encoder)87{88 struct drm_device *dev = radeon_encoder->base.dev;89 struct radeon_device *rdev = dev->dev_private;90 91 if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))92 return 0;93 94 return radeon_atom_get_backlight_level_from_reg(rdev);95}96 97void98atombios_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level)99{100 struct drm_encoder *encoder = &radeon_encoder->base;101 struct drm_device *dev = radeon_encoder->base.dev;102 struct radeon_device *rdev = dev->dev_private;103 struct radeon_encoder_atom_dig *dig;104 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;105 int index;106 107 if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))108 return;109 110 if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&111 radeon_encoder->enc_priv) {112 dig = radeon_encoder->enc_priv;113 dig->backlight_level = level;114 radeon_atom_set_backlight_level_to_reg(rdev, dig->backlight_level);115 116 switch (radeon_encoder->encoder_id) {117 case ENCODER_OBJECT_ID_INTERNAL_LVDS:118 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:119 index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);120 if (dig->backlight_level == 0) {121 args.ucAction = ATOM_LCD_BLOFF;122 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));123 } else {124 args.ucAction = ATOM_LCD_BL_BRIGHTNESS_CONTROL;125 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));126 args.ucAction = ATOM_LCD_BLON;127 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));128 }129 break;130 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:131 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:132 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:133 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:134 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:135 if (dig->backlight_level == 0)136 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);137 else {138 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_BL_BRIGHTNESS_CONTROL, 0, 0);139 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);140 }141 break;142 default:143 break;144 }145 }146}147 148static u8 radeon_atom_bl_level(struct backlight_device *bd)149{150 u8 level;151 152 /* Convert brightness to hardware level */153 if (bd->props.brightness < 0)154 level = 0;155 else if (bd->props.brightness > RADEON_MAX_BL_LEVEL)156 level = RADEON_MAX_BL_LEVEL;157 else158 level = bd->props.brightness;159 160 return level;161}162 163static int radeon_atom_backlight_update_status(struct backlight_device *bd)164{165 struct radeon_backlight_privdata *pdata = bl_get_data(bd);166 struct radeon_encoder *radeon_encoder = pdata->encoder;167 168 atombios_set_backlight_level(radeon_encoder, radeon_atom_bl_level(bd));169 170 return 0;171}172 173static int radeon_atom_backlight_get_brightness(struct backlight_device *bd)174{175 struct radeon_backlight_privdata *pdata = bl_get_data(bd);176 struct radeon_encoder *radeon_encoder = pdata->encoder;177 struct drm_device *dev = radeon_encoder->base.dev;178 struct radeon_device *rdev = dev->dev_private;179 180 return radeon_atom_get_backlight_level_from_reg(rdev);181}182 183static const struct backlight_ops radeon_atom_backlight_ops = {184 .get_brightness = radeon_atom_backlight_get_brightness,185 .update_status = radeon_atom_backlight_update_status,186};187 188void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,189 struct drm_connector *drm_connector)190{191 struct drm_device *dev = radeon_encoder->base.dev;192 struct radeon_device *rdev = dev->dev_private;193 struct backlight_device *bd;194 struct backlight_properties props;195 struct radeon_backlight_privdata *pdata;196 struct radeon_encoder_atom_dig *dig;197 char bl_name[16];198 199 /* Mac laptops with multiple GPUs use the gmux driver for backlight200 * so don't register a backlight device201 */202 if ((rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) &&203 (rdev->pdev->device == 0x6741) &&204 !(dmi_match(DMI_PRODUCT_NAME, "iMac12,1") || dmi_match(DMI_PRODUCT_NAME, "iMac12,2")))205 return;206 207 if (!radeon_encoder->enc_priv)208 return;209 210 if (!rdev->is_atom_bios)211 return;212 213 if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))214 return;215 216 if (!acpi_video_backlight_use_native()) {217 drm_info(dev, "Skipping radeon atom DIG backlight registration\n");218 return;219 }220 221 pdata = kmalloc(sizeof(struct radeon_backlight_privdata), GFP_KERNEL);222 if (!pdata) {223 DRM_ERROR("Memory allocation failed\n");224 goto error;225 }226 227 memset(&props, 0, sizeof(props));228 props.max_brightness = RADEON_MAX_BL_LEVEL;229 props.type = BACKLIGHT_RAW;230 snprintf(bl_name, sizeof(bl_name),231 "radeon_bl%d", dev->primary->index);232 bd = backlight_device_register(bl_name, drm_connector->kdev,233 pdata, &radeon_atom_backlight_ops, &props);234 if (IS_ERR(bd)) {235 DRM_ERROR("Backlight registration failed\n");236 goto error;237 }238 239 pdata->encoder = radeon_encoder;240 241 dig = radeon_encoder->enc_priv;242 dig->bl_dev = bd;243 244 bd->props.brightness = radeon_atom_backlight_get_brightness(bd);245 /* Set a reasonable default here if the level is 0 otherwise246 * fbdev will attempt to turn the backlight on after console247 * unblanking and it will try and restore 0 which turns the backlight248 * off again.249 */250 if (bd->props.brightness == 0)251 bd->props.brightness = RADEON_MAX_BL_LEVEL;252 bd->props.power = BACKLIGHT_POWER_ON;253 backlight_update_status(bd);254 255 DRM_INFO("radeon atom DIG backlight initialized\n");256 rdev->mode_info.bl_encoder = radeon_encoder;257 258 return;259 260error:261 kfree(pdata);262 return;263}264 265static void radeon_atom_backlight_exit(struct radeon_encoder *radeon_encoder)266{267 struct drm_device *dev = radeon_encoder->base.dev;268 struct radeon_device *rdev = dev->dev_private;269 struct backlight_device *bd = NULL;270 struct radeon_encoder_atom_dig *dig;271 272 if (!radeon_encoder->enc_priv)273 return;274 275 if (!rdev->is_atom_bios)276 return;277 278 if (!(rdev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))279 return;280 281 dig = radeon_encoder->enc_priv;282 bd = dig->bl_dev;283 dig->bl_dev = NULL;284 285 if (bd) {286 struct radeon_legacy_backlight_privdata *pdata;287 288 pdata = bl_get_data(bd);289 backlight_device_unregister(bd);290 kfree(pdata);291 292 DRM_INFO("radeon atom LVDS backlight unloaded\n");293 }294}295 296static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,297 const struct drm_display_mode *mode,298 struct drm_display_mode *adjusted_mode)299{300 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);301 struct drm_device *dev = encoder->dev;302 struct radeon_device *rdev = dev->dev_private;303 304 /* set the active encoder to connector routing */305 radeon_encoder_set_active_device(encoder);306 drm_mode_set_crtcinfo(adjusted_mode, 0);307 308 /* hw bug */309 if ((mode->flags & DRM_MODE_FLAG_INTERLACE)310 && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))311 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;312 313 /* vertical FP must be at least 1 */314 if (mode->crtc_vsync_start == mode->crtc_vdisplay)315 adjusted_mode->crtc_vsync_start++;316 317 /* get the native mode for scaling */318 if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {319 radeon_panel_mode_fixup(encoder, adjusted_mode);320 } else if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {321 struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;322 if (tv_dac) {323 if (tv_dac->tv_std == TV_STD_NTSC ||324 tv_dac->tv_std == TV_STD_NTSC_J ||325 tv_dac->tv_std == TV_STD_PAL_M)326 radeon_atom_get_tv_timings(rdev, 0, adjusted_mode);327 else328 radeon_atom_get_tv_timings(rdev, 1, adjusted_mode);329 }330 } else if (radeon_encoder->rmx_type != RMX_OFF) {331 radeon_panel_mode_fixup(encoder, adjusted_mode);332 }333 334 if (ASIC_IS_DCE3(rdev) &&335 ((radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) ||336 (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE))) {337 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);338 radeon_dp_set_link_config(connector, adjusted_mode);339 }340 341 return true;342}343 344static void345atombios_dac_setup(struct drm_encoder *encoder, int action)346{347 struct drm_device *dev = encoder->dev;348 struct radeon_device *rdev = dev->dev_private;349 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);350 DAC_ENCODER_CONTROL_PS_ALLOCATION args;351 int index = 0;352 struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;353 354 memset(&args, 0, sizeof(args));355 356 switch (radeon_encoder->encoder_id) {357 case ENCODER_OBJECT_ID_INTERNAL_DAC1:358 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:359 index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);360 break;361 case ENCODER_OBJECT_ID_INTERNAL_DAC2:362 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:363 index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);364 break;365 }366 367 args.ucAction = action;368 369 if (radeon_encoder->active_device & (ATOM_DEVICE_CRT_SUPPORT))370 args.ucDacStandard = ATOM_DAC1_PS2;371 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))372 args.ucDacStandard = ATOM_DAC1_CV;373 else {374 switch (dac_info->tv_std) {375 case TV_STD_PAL:376 case TV_STD_PAL_M:377 case TV_STD_SCART_PAL:378 case TV_STD_SECAM:379 case TV_STD_PAL_CN:380 args.ucDacStandard = ATOM_DAC1_PAL;381 break;382 case TV_STD_NTSC:383 case TV_STD_NTSC_J:384 case TV_STD_PAL_60:385 default:386 args.ucDacStandard = ATOM_DAC1_NTSC;387 break;388 }389 }390 args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);391 392 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));393 394}395 396static void397atombios_tv_setup(struct drm_encoder *encoder, int action)398{399 struct drm_device *dev = encoder->dev;400 struct radeon_device *rdev = dev->dev_private;401 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);402 TV_ENCODER_CONTROL_PS_ALLOCATION args;403 int index = 0;404 struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;405 406 memset(&args, 0, sizeof(args));407 408 index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);409 410 args.sTVEncoder.ucAction = action;411 412 if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))413 args.sTVEncoder.ucTvStandard = ATOM_TV_CV;414 else {415 switch (dac_info->tv_std) {416 case TV_STD_NTSC:417 args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;418 break;419 case TV_STD_PAL:420 args.sTVEncoder.ucTvStandard = ATOM_TV_PAL;421 break;422 case TV_STD_PAL_M:423 args.sTVEncoder.ucTvStandard = ATOM_TV_PALM;424 break;425 case TV_STD_PAL_60:426 args.sTVEncoder.ucTvStandard = ATOM_TV_PAL60;427 break;428 case TV_STD_NTSC_J:429 args.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ;430 break;431 case TV_STD_SCART_PAL:432 args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */433 break;434 case TV_STD_SECAM:435 args.sTVEncoder.ucTvStandard = ATOM_TV_SECAM;436 break;437 case TV_STD_PAL_CN:438 args.sTVEncoder.ucTvStandard = ATOM_TV_PALCN;439 break;440 default:441 args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;442 break;443 }444 }445 446 args.sTVEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);447 448 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));449 450}451 452static u8 radeon_atom_get_bpc(struct drm_encoder *encoder)453{454 int bpc = 8;455 456 if (encoder->crtc) {457 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);458 bpc = radeon_crtc->bpc;459 }460 461 switch (bpc) {462 case 0:463 return PANEL_BPC_UNDEFINE;464 case 6:465 return PANEL_6BIT_PER_COLOR;466 case 8:467 default:468 return PANEL_8BIT_PER_COLOR;469 case 10:470 return PANEL_10BIT_PER_COLOR;471 case 12:472 return PANEL_12BIT_PER_COLOR;473 case 16:474 return PANEL_16BIT_PER_COLOR;475 }476}477 478union dvo_encoder_control {479 ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds;480 DVO_ENCODER_CONTROL_PS_ALLOCATION dvo;481 DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3;482 DVO_ENCODER_CONTROL_PS_ALLOCATION_V1_4 dvo_v4;483};484 485void486atombios_dvo_setup(struct drm_encoder *encoder, int action)487{488 struct drm_device *dev = encoder->dev;489 struct radeon_device *rdev = dev->dev_private;490 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);491 union dvo_encoder_control args;492 int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);493 uint8_t frev, crev;494 495 memset(&args, 0, sizeof(args));496 497 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))498 return;499 500 /* some R4xx chips have the wrong frev */501 if (rdev->family <= CHIP_RV410)502 frev = 1;503 504 switch (frev) {505 case 1:506 switch (crev) {507 case 1:508 /* R4xx, R5xx */509 args.ext_tmds.sXTmdsEncoder.ucEnable = action;510 511 if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))512 args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL;513 514 args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB;515 break;516 case 2:517 /* RS600/690/740 */518 args.dvo.sDVOEncoder.ucAction = action;519 args.dvo.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);520 /* DFP1, CRT1, TV1 depending on the type of port */521 args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX;522 523 if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))524 args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL;525 break;526 case 3:527 /* R6xx */528 args.dvo_v3.ucAction = action;529 args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);530 args.dvo_v3.ucDVOConfig = 0; /* XXX */531 break;532 case 4:533 /* DCE8 */534 args.dvo_v4.ucAction = action;535 args.dvo_v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);536 args.dvo_v4.ucDVOConfig = 0; /* XXX */537 args.dvo_v4.ucBitPerColor = radeon_atom_get_bpc(encoder);538 break;539 default:540 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);541 break;542 }543 break;544 default:545 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);546 break;547 }548 549 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));550}551 552union lvds_encoder_control {553 LVDS_ENCODER_CONTROL_PS_ALLOCATION v1;554 LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2;555};556 557void558atombios_digital_setup(struct drm_encoder *encoder, int action)559{560 struct drm_device *dev = encoder->dev;561 struct radeon_device *rdev = dev->dev_private;562 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);563 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;564 union lvds_encoder_control args;565 int index = 0;566 int hdmi_detected = 0;567 uint8_t frev, crev;568 569 if (!dig)570 return;571 572 if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI)573 hdmi_detected = 1;574 575 memset(&args, 0, sizeof(args));576 577 switch (radeon_encoder->encoder_id) {578 case ENCODER_OBJECT_ID_INTERNAL_LVDS:579 index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);580 break;581 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:582 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:583 index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);584 break;585 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:586 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))587 index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);588 else589 index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);590 break;591 }592 593 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))594 return;595 596 switch (frev) {597 case 1:598 case 2:599 switch (crev) {600 case 1:601 args.v1.ucMisc = 0;602 args.v1.ucAction = action;603 if (hdmi_detected)604 args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;605 args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);606 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {607 if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL)608 args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;609 if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)610 args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;611 } else {612 if (dig->linkb)613 args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;614 if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))615 args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;616 /*if (pScrn->rgbBits == 8) */617 args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;618 }619 break;620 case 2:621 case 3:622 args.v2.ucMisc = 0;623 args.v2.ucAction = action;624 if (crev == 3) {625 if (dig->coherent_mode)626 args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;627 }628 if (hdmi_detected)629 args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;630 args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);631 args.v2.ucTruncate = 0;632 args.v2.ucSpatial = 0;633 args.v2.ucTemporal = 0;634 args.v2.ucFRC = 0;635 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {636 if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL)637 args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;638 if (dig->lcd_misc & ATOM_PANEL_MISC_SPATIAL) {639 args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN;640 if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)641 args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH;642 }643 if (dig->lcd_misc & ATOM_PANEL_MISC_TEMPORAL) {644 args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN;645 if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)646 args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH;647 if (((dig->lcd_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) & 0x3) == 2)648 args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4;649 }650 } else {651 if (dig->linkb)652 args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;653 if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))654 args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;655 }656 break;657 default:658 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);659 break;660 }661 break;662 default:663 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);664 break;665 }666 667 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));668}669 670int671atombios_get_encoder_mode(struct drm_encoder *encoder)672{673 struct drm_device *dev = encoder->dev;674 struct radeon_device *rdev = dev->dev_private;675 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);676 struct drm_connector *connector;677 struct radeon_connector *radeon_connector;678 struct radeon_connector_atom_dig *dig_connector;679 680 /* dp bridges are always DP */681 if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)682 return ATOM_ENCODER_MODE_DP;683 684 /* DVO is always DVO */685 if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DVO1) ||686 (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1))687 return ATOM_ENCODER_MODE_DVO;688 689 connector = radeon_get_connector_for_encoder(encoder);690 /* if we don't have an active device yet, just use one of691 * the connectors tied to the encoder.692 */693 if (!connector)694 connector = radeon_get_connector_for_encoder_init(encoder);695 radeon_connector = to_radeon_connector(connector);696 697 switch (connector->connector_type) {698 case DRM_MODE_CONNECTOR_DVII:699 case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */700 if (radeon_audio != 0) {701 if (radeon_connector->use_digital &&702 (radeon_connector->audio == RADEON_AUDIO_ENABLE))703 return ATOM_ENCODER_MODE_HDMI;704 else if (connector->display_info.is_hdmi &&705 (radeon_connector->audio == RADEON_AUDIO_AUTO))706 return ATOM_ENCODER_MODE_HDMI;707 else if (radeon_connector->use_digital)708 return ATOM_ENCODER_MODE_DVI;709 else710 return ATOM_ENCODER_MODE_CRT;711 } else if (radeon_connector->use_digital) {712 return ATOM_ENCODER_MODE_DVI;713 } else {714 return ATOM_ENCODER_MODE_CRT;715 }716 break;717 case DRM_MODE_CONNECTOR_DVID:718 case DRM_MODE_CONNECTOR_HDMIA:719 default:720 if (radeon_audio != 0) {721 if (radeon_connector->audio == RADEON_AUDIO_ENABLE)722 return ATOM_ENCODER_MODE_HDMI;723 else if (connector->display_info.is_hdmi &&724 (radeon_connector->audio == RADEON_AUDIO_AUTO))725 return ATOM_ENCODER_MODE_HDMI;726 else727 return ATOM_ENCODER_MODE_DVI;728 } else {729 return ATOM_ENCODER_MODE_DVI;730 }731 break;732 case DRM_MODE_CONNECTOR_LVDS:733 return ATOM_ENCODER_MODE_LVDS;734 break;735 case DRM_MODE_CONNECTOR_DisplayPort:736 dig_connector = radeon_connector->con_priv;737 if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||738 (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {739 if (radeon_audio != 0 &&740 connector->display_info.has_audio &&741 ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev))742 return ATOM_ENCODER_MODE_DP_AUDIO;743 return ATOM_ENCODER_MODE_DP;744 } else if (radeon_audio != 0) {745 if (radeon_connector->audio == RADEON_AUDIO_ENABLE)746 return ATOM_ENCODER_MODE_HDMI;747 else if (connector->display_info.is_hdmi &&748 (radeon_connector->audio == RADEON_AUDIO_AUTO))749 return ATOM_ENCODER_MODE_HDMI;750 else751 return ATOM_ENCODER_MODE_DVI;752 } else {753 return ATOM_ENCODER_MODE_DVI;754 }755 break;756 case DRM_MODE_CONNECTOR_eDP:757 if (radeon_audio != 0 &&758 connector->display_info.has_audio &&759 ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev))760 return ATOM_ENCODER_MODE_DP_AUDIO;761 return ATOM_ENCODER_MODE_DP;762 case DRM_MODE_CONNECTOR_DVIA:763 case DRM_MODE_CONNECTOR_VGA:764 return ATOM_ENCODER_MODE_CRT;765 break;766 case DRM_MODE_CONNECTOR_Composite:767 case DRM_MODE_CONNECTOR_SVIDEO:768 case DRM_MODE_CONNECTOR_9PinDIN:769 /* fix me */770 return ATOM_ENCODER_MODE_TV;771 /*return ATOM_ENCODER_MODE_CV;*/772 break;773 }774}775 776/*777 * DIG Encoder/Transmitter Setup778 *779 * DCE 3.0/3.1780 * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA.781 * Supports up to 3 digital outputs782 * - 2 DIG encoder blocks.783 * DIG1 can drive UNIPHY link A or link B784 * DIG2 can drive UNIPHY link B or LVTMA785 *786 * DCE 3.2787 * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B).788 * Supports up to 5 digital outputs789 * - 2 DIG encoder blocks.790 * DIG1/2 can drive UNIPHY0/1/2 link A or link B791 *792 * DCE 4.0/5.0/6.0793 * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B).794 * Supports up to 6 digital outputs795 * - 6 DIG encoder blocks.796 * - DIG to PHY mapping is hardcoded797 * DIG1 drives UNIPHY0 link A, A+B798 * DIG2 drives UNIPHY0 link B799 * DIG3 drives UNIPHY1 link A, A+B800 * DIG4 drives UNIPHY1 link B801 * DIG5 drives UNIPHY2 link A, A+B802 * DIG6 drives UNIPHY2 link B803 *804 * DCE 4.1805 * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B).806 * Supports up to 6 digital outputs807 * - 2 DIG encoder blocks.808 * llano809 * DIG1/2 can drive UNIPHY0/1/2 link A or link B810 * ontario811 * DIG1 drives UNIPHY0/1/2 link A812 * DIG2 drives UNIPHY0/1/2 link B813 *814 * Routing815 * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)816 * Examples:817 * crtc0 -> dig2 -> LVTMA links A+B -> TMDS/HDMI818 * crtc1 -> dig1 -> UNIPHY0 link B -> DP819 * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS820 * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI821 */822 823union dig_encoder_control {824 DIG_ENCODER_CONTROL_PS_ALLOCATION v1;825 DIG_ENCODER_CONTROL_PARAMETERS_V2 v2;826 DIG_ENCODER_CONTROL_PARAMETERS_V3 v3;827 DIG_ENCODER_CONTROL_PARAMETERS_V4 v4;828};829 830void831atombios_dig_encoder_setup2(struct drm_encoder *encoder, int action, int panel_mode, int enc_override)832{833 struct drm_device *dev = encoder->dev;834 struct radeon_device *rdev = dev->dev_private;835 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);836 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;837 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);838 union dig_encoder_control args;839 int index = 0;840 uint8_t frev, crev;841 int dp_clock = 0;842 int dp_lane_count = 0;843 int hpd_id = RADEON_HPD_NONE;844 845 if (connector) {846 struct radeon_connector *radeon_connector = to_radeon_connector(connector);847 struct radeon_connector_atom_dig *dig_connector =848 radeon_connector->con_priv;849 850 dp_clock = dig_connector->dp_clock;851 dp_lane_count = dig_connector->dp_lane_count;852 hpd_id = radeon_connector->hpd.hpd;853 }854 855 /* no dig encoder assigned */856 if (dig->dig_encoder == -1)857 return;858 859 memset(&args, 0, sizeof(args));860 861 if (ASIC_IS_DCE4(rdev))862 index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl);863 else {864 if (dig->dig_encoder)865 index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);866 else867 index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);868 }869 870 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))871 return;872 873 switch (frev) {874 case 1:875 switch (crev) {876 case 1:877 args.v1.ucAction = action;878 args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);879 if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)880 args.v3.ucPanelMode = panel_mode;881 else882 args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder);883 884 if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))885 args.v1.ucLaneNum = dp_lane_count;886 else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))887 args.v1.ucLaneNum = 8;888 else889 args.v1.ucLaneNum = 4;890 891 switch (radeon_encoder->encoder_id) {892 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:893 args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;894 break;895 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:896 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:897 args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;898 break;899 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:900 args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;901 break;902 }903 if (dig->linkb)904 args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;905 else906 args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;907 908 if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000))909 args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;910 911 break;912 case 2:913 case 3:914 args.v3.ucAction = action;915 args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);916 if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)917 args.v3.ucPanelMode = panel_mode;918 else919 args.v3.ucEncoderMode = atombios_get_encoder_mode(encoder);920 921 if (ENCODER_MODE_IS_DP(args.v3.ucEncoderMode))922 args.v3.ucLaneNum = dp_lane_count;923 else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))924 args.v3.ucLaneNum = 8;925 else926 args.v3.ucLaneNum = 4;927 928 if (ENCODER_MODE_IS_DP(args.v3.ucEncoderMode) && (dp_clock == 270000))929 args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;930 if (enc_override != -1)931 args.v3.acConfig.ucDigSel = enc_override;932 else933 args.v3.acConfig.ucDigSel = dig->dig_encoder;934 args.v3.ucBitPerColor = radeon_atom_get_bpc(encoder);935 break;936 case 4:937 args.v4.ucAction = action;938 args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);939 if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)940 args.v4.ucPanelMode = panel_mode;941 else942 args.v4.ucEncoderMode = atombios_get_encoder_mode(encoder);943 944 if (ENCODER_MODE_IS_DP(args.v4.ucEncoderMode))945 args.v4.ucLaneNum = dp_lane_count;946 else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))947 args.v4.ucLaneNum = 8;948 else949 args.v4.ucLaneNum = 4;950 951 if (ENCODER_MODE_IS_DP(args.v4.ucEncoderMode)) {952 if (dp_clock == 540000)953 args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ;954 else if (dp_clock == 324000)955 args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_3_24GHZ;956 else if (dp_clock == 270000)957 args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ;958 else959 args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_1_62GHZ;960 }961 962 if (enc_override != -1)963 args.v4.acConfig.ucDigSel = enc_override;964 else965 args.v4.acConfig.ucDigSel = dig->dig_encoder;966 args.v4.ucBitPerColor = radeon_atom_get_bpc(encoder);967 if (hpd_id == RADEON_HPD_NONE)968 args.v4.ucHPD_ID = 0;969 else970 args.v4.ucHPD_ID = hpd_id + 1;971 break;972 default:973 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);974 break;975 }976 break;977 default:978 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);979 break;980 }981 982 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));983 984}985 986void987atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode)988{989 atombios_dig_encoder_setup2(encoder, action, panel_mode, -1);990}991 992union dig_transmitter_control {993 DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1;994 DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;995 DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3;996 DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4;997 DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 v5;998};999 1000void1001atombios_dig_transmitter_setup2(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set, int fe)1002{1003 struct drm_device *dev = encoder->dev;1004 struct radeon_device *rdev = dev->dev_private;1005 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);1006 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;1007 struct drm_connector *connector;1008 union dig_transmitter_control args;1009 int index = 0;1010 uint8_t frev, crev;1011 bool is_dp = false;1012 int pll_id = 0;1013 int dp_clock = 0;1014 int dp_lane_count = 0;1015 int connector_object_id = 0;1016 int igp_lane_info = 0;1017 int dig_encoder = dig->dig_encoder;1018 int hpd_id = RADEON_HPD_NONE;1019 1020 if (action == ATOM_TRANSMITTER_ACTION_INIT) {1021 connector = radeon_get_connector_for_encoder_init(encoder);1022 /* just needed to avoid bailing in the encoder check. the encoder1023 * isn't used for init1024 */1025 dig_encoder = 0;1026 } else1027 connector = radeon_get_connector_for_encoder(encoder);1028 1029 if (connector) {1030 struct radeon_connector *radeon_connector = to_radeon_connector(connector);1031 struct radeon_connector_atom_dig *dig_connector =1032 radeon_connector->con_priv;1033 1034 hpd_id = radeon_connector->hpd.hpd;1035 dp_clock = dig_connector->dp_clock;1036 dp_lane_count = dig_connector->dp_lane_count;1037 connector_object_id =1038 (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;1039 igp_lane_info = dig_connector->igp_lane_info;1040 }1041 1042 if (encoder->crtc) {1043 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);1044 pll_id = radeon_crtc->pll_id;1045 }1046 1047 /* no dig encoder assigned */1048 if (dig_encoder == -1)1049 return;1050 1051 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)))1052 is_dp = true;1053 1054 memset(&args, 0, sizeof(args));1055 1056 switch (radeon_encoder->encoder_id) {1057 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:1058 index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);1059 break;1060 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:1061 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:1062 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:1063 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:1064 index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);1065 break;1066 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:1067 index = GetIndexIntoMasterTable(COMMAND, LVTMATransmitterControl);1068 break;1069 }1070 1071 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))1072 return;1073 1074 switch (frev) {1075 case 1:1076 switch (crev) {1077 case 1:1078 args.v1.ucAction = action;1079 if (action == ATOM_TRANSMITTER_ACTION_INIT) {1080 args.v1.usInitInfo = cpu_to_le16(connector_object_id);1081 } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {1082 args.v1.asMode.ucLaneSel = lane_num;1083 args.v1.asMode.ucLaneSet = lane_set;1084 } else {1085 if (is_dp)1086 args.v1.usPixelClock = cpu_to_le16(dp_clock / 10);1087 else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))1088 args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);1089 else1090 args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);1091 }1092 1093 args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;1094 1095 if (dig_encoder)1096 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;1097 else1098 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;1099 1100 if ((rdev->flags & RADEON_IS_IGP) &&1101 (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) {1102 if (is_dp ||1103 !radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) {1104 if (igp_lane_info & 0x1)1105 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;1106 else if (igp_lane_info & 0x2)1107 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;1108 else if (igp_lane_info & 0x4)1109 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;1110 else if (igp_lane_info & 0x8)1111 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;1112 } else {1113 if (igp_lane_info & 0x3)1114 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;1115 else if (igp_lane_info & 0xc)1116 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;1117 }1118 }1119 1120 if (dig->linkb)1121 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;1122 else1123 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;1124 1125 if (is_dp)1126 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;1127 else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {1128 if (dig->coherent_mode)1129 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;1130 if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))1131 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;1132 }1133 break;1134 case 2:1135 args.v2.ucAction = action;1136 if (action == ATOM_TRANSMITTER_ACTION_INIT) {1137 args.v2.usInitInfo = cpu_to_le16(connector_object_id);1138 } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {1139 args.v2.asMode.ucLaneSel = lane_num;1140 args.v2.asMode.ucLaneSet = lane_set;1141 } else {1142 if (is_dp)1143 args.v2.usPixelClock = cpu_to_le16(dp_clock / 10);1144 else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))1145 args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);1146 else1147 args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);1148 }1149 1150 args.v2.acConfig.ucEncoderSel = dig_encoder;1151 if (dig->linkb)1152 args.v2.acConfig.ucLinkSel = 1;1153 1154 switch (radeon_encoder->encoder_id) {1155 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:1156 args.v2.acConfig.ucTransmitterSel = 0;1157 break;1158 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:1159 args.v2.acConfig.ucTransmitterSel = 1;1160 break;1161 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:1162 args.v2.acConfig.ucTransmitterSel = 2;1163 break;1164 }1165 1166 if (is_dp) {1167 args.v2.acConfig.fCoherentMode = 1;1168 args.v2.acConfig.fDPConnector = 1;1169 } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {1170 if (dig->coherent_mode)1171 args.v2.acConfig.fCoherentMode = 1;1172 if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))1173 args.v2.acConfig.fDualLinkConnector = 1;1174 }1175 break;1176 case 3:1177 args.v3.ucAction = action;1178 if (action == ATOM_TRANSMITTER_ACTION_INIT) {1179 args.v3.usInitInfo = cpu_to_le16(connector_object_id);1180 } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {1181 args.v3.asMode.ucLaneSel = lane_num;1182 args.v3.asMode.ucLaneSet = lane_set;1183 } else {1184 if (is_dp)1185 args.v3.usPixelClock = cpu_to_le16(dp_clock / 10);1186 else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))1187 args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);1188 else1189 args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);1190 }1191 1192 if (is_dp)1193 args.v3.ucLaneNum = dp_lane_count;1194 else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))1195 args.v3.ucLaneNum = 8;1196 else1197 args.v3.ucLaneNum = 4;1198 1199 if (dig->linkb)1200 args.v3.acConfig.ucLinkSel = 1;1201 if (dig_encoder & 1)1202 args.v3.acConfig.ucEncoderSel = 1;1203 1204 /* Select the PLL for the PHY1205 * DP PHY should be clocked from external src if there is1206 * one.1207 */1208 /* On DCE4, if there is an external clock, it generates the DP ref clock */1209 if (is_dp && rdev->clock.dp_extclk)1210 args.v3.acConfig.ucRefClkSource = 2; /* external src */1211 else1212 args.v3.acConfig.ucRefClkSource = pll_id;1213 1214 switch (radeon_encoder->encoder_id) {1215 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:1216 args.v3.acConfig.ucTransmitterSel = 0;1217 break;1218 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:1219 args.v3.acConfig.ucTransmitterSel = 1;1220 break;1221 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:1222 args.v3.acConfig.ucTransmitterSel = 2;1223 break;1224 }1225 1226 if (is_dp)1227 args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */1228 else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {1229 if (dig->coherent_mode)1230 args.v3.acConfig.fCoherentMode = 1;1231 if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))1232 args.v3.acConfig.fDualLinkConnector = 1;1233 }1234 break;1235 case 4:1236 args.v4.ucAction = action;1237 if (action == ATOM_TRANSMITTER_ACTION_INIT) {1238 args.v4.usInitInfo = cpu_to_le16(connector_object_id);1239 } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {1240 args.v4.asMode.ucLaneSel = lane_num;1241 args.v4.asMode.ucLaneSet = lane_set;1242 } else {1243 if (is_dp)1244 args.v4.usPixelClock = cpu_to_le16(dp_clock / 10);1245 else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))1246 args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);1247 else1248 args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);1249 }1250 1251 if (is_dp)1252 args.v4.ucLaneNum = dp_lane_count;1253 else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))1254 args.v4.ucLaneNum = 8;1255 else1256 args.v4.ucLaneNum = 4;1257 1258 if (dig->linkb)1259 args.v4.acConfig.ucLinkSel = 1;1260 if (dig_encoder & 1)1261 args.v4.acConfig.ucEncoderSel = 1;1262 1263 /* Select the PLL for the PHY1264 * DP PHY should be clocked from external src if there is1265 * one.1266 */1267 /* On DCE5 DCPLL usually generates the DP ref clock */1268 if (is_dp) {1269 if (rdev->clock.dp_extclk)1270 args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_EXTCLK;1271 else1272 args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_DCPLL;1273 } else1274 args.v4.acConfig.ucRefClkSource = pll_id;1275 1276 switch (radeon_encoder->encoder_id) {1277 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:1278 args.v4.acConfig.ucTransmitterSel = 0;1279 break;1280 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:1281 args.v4.acConfig.ucTransmitterSel = 1;1282 break;1283 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:1284 args.v4.acConfig.ucTransmitterSel = 2;1285 break;1286 }1287 1288 if (is_dp)1289 args.v4.acConfig.fCoherentMode = 1; /* DP requires coherent */1290 else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {1291 if (dig->coherent_mode)1292 args.v4.acConfig.fCoherentMode = 1;1293 if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))1294 args.v4.acConfig.fDualLinkConnector = 1;1295 }1296 break;1297 case 5:1298 args.v5.ucAction = action;1299 if (is_dp)1300 args.v5.usSymClock = cpu_to_le16(dp_clock / 10);1301 else1302 args.v5.usSymClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);1303 1304 switch (radeon_encoder->encoder_id) {1305 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:1306 if (dig->linkb)1307 args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYB;1308 else1309 args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYA;1310 break;1311 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:1312 if (dig->linkb)1313 args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYD;1314 else1315 args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYC;1316 break;1317 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:1318 if (dig->linkb)1319 args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYF;1320 else1321 args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYE;1322 break;1323 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:1324 args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYG;1325 break;1326 }1327 if (is_dp)1328 args.v5.ucLaneNum = dp_lane_count;1329 else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))1330 args.v5.ucLaneNum = 8;1331 else1332 args.v5.ucLaneNum = 4;1333 args.v5.ucConnObjId = connector_object_id;1334 args.v5.ucDigMode = atombios_get_encoder_mode(encoder);1335 1336 if (is_dp && rdev->clock.dp_extclk)1337 args.v5.asConfig.ucPhyClkSrcId = ENCODER_REFCLK_SRC_EXTCLK;1338 else1339 args.v5.asConfig.ucPhyClkSrcId = pll_id;1340 1341 if (is_dp)1342 args.v5.asConfig.ucCoherentMode = 1; /* DP requires coherent */1343 else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {1344 if (dig->coherent_mode)1345 args.v5.asConfig.ucCoherentMode = 1;1346 }1347 if (hpd_id == RADEON_HPD_NONE)1348 args.v5.asConfig.ucHPDSel = 0;1349 else1350 args.v5.asConfig.ucHPDSel = hpd_id + 1;1351 args.v5.ucDigEncoderSel = (fe != -1) ? (1 << fe) : (1 << dig_encoder);1352 args.v5.ucDPLaneSet = lane_set;1353 break;1354 default:1355 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);1356 break;1357 }1358 break;1359 default:1360 DRM_ERROR("Unknown table version %d, %d\n", frev, crev);1361 break;1362 }1363 1364 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1365}1366 1367void1368atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set)1369{1370 atombios_dig_transmitter_setup2(encoder, action, lane_num, lane_set, -1);1371}1372 1373bool1374atombios_set_edp_panel_power(struct drm_connector *connector, int action)1375{1376 struct radeon_connector *radeon_connector = to_radeon_connector(connector);1377 struct drm_device *dev = radeon_connector->base.dev;1378 struct radeon_device *rdev = dev->dev_private;1379 union dig_transmitter_control args;1380 int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);1381 uint8_t frev, crev;1382 1383 if (connector->connector_type != DRM_MODE_CONNECTOR_eDP)1384 goto done;1385 1386 if (!ASIC_IS_DCE4(rdev))1387 goto done;1388 1389 if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) &&1390 (action != ATOM_TRANSMITTER_ACTION_POWER_OFF))1391 goto done;1392 1393 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))1394 goto done;1395 1396 memset(&args, 0, sizeof(args));1397 1398 args.v1.ucAction = action;1399 1400 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1401 1402 /* wait for the panel to power up */1403 if (action == ATOM_TRANSMITTER_ACTION_POWER_ON) {1404 int i;1405 1406 for (i = 0; i < 300; i++) {1407 if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))1408 return true;1409 mdelay(1);1410 }1411 return false;1412 }1413done:1414 return true;1415}1416 1417union external_encoder_control {1418 EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1;1419 EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3;1420};1421 1422static void1423atombios_external_encoder_setup(struct drm_encoder *encoder,1424 struct drm_encoder *ext_encoder,1425 int action)1426{1427 struct drm_device *dev = encoder->dev;1428 struct radeon_device *rdev = dev->dev_private;1429 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);1430 struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder);1431 union external_encoder_control args;1432 struct drm_connector *connector;1433 int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);1434 u8 frev, crev;1435 int dp_clock = 0;1436 int dp_lane_count = 0;1437 int connector_object_id = 0;1438 u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;1439 1440 if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT)1441 connector = radeon_get_connector_for_encoder_init(encoder);1442 else1443 connector = radeon_get_connector_for_encoder(encoder);1444 1445 if (connector) {1446 struct radeon_connector *radeon_connector = to_radeon_connector(connector);1447 struct radeon_connector_atom_dig *dig_connector =1448 radeon_connector->con_priv;1449 1450 dp_clock = dig_connector->dp_clock;1451 dp_lane_count = dig_connector->dp_lane_count;1452 connector_object_id =1453 (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;1454 }1455 1456 memset(&args, 0, sizeof(args));1457 1458 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))1459 return;1460 1461 switch (frev) {1462 case 1:1463 /* no params on frev 1 */1464 break;1465 case 2:1466 switch (crev) {1467 case 1:1468 case 2:1469 args.v1.sDigEncoder.ucAction = action;1470 args.v1.sDigEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);1471 args.v1.sDigEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder);1472 1473 if (ENCODER_MODE_IS_DP(args.v1.sDigEncoder.ucEncoderMode)) {1474 if (dp_clock == 270000)1475 args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;1476 args.v1.sDigEncoder.ucLaneNum = dp_lane_count;1477 } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))1478 args.v1.sDigEncoder.ucLaneNum = 8;1479 else1480 args.v1.sDigEncoder.ucLaneNum = 4;1481 break;1482 case 3:1483 args.v3.sExtEncoder.ucAction = action;1484 if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT)1485 args.v3.sExtEncoder.usConnectorId = cpu_to_le16(connector_object_id);1486 else1487 args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);1488 args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder);1489 1490 if (ENCODER_MODE_IS_DP(args.v3.sExtEncoder.ucEncoderMode)) {1491 if (dp_clock == 270000)1492 args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;1493 else if (dp_clock == 540000)1494 args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ;1495 args.v3.sExtEncoder.ucLaneNum = dp_lane_count;1496 } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))1497 args.v3.sExtEncoder.ucLaneNum = 8;1498 else1499 args.v3.sExtEncoder.ucLaneNum = 4;1500 switch (ext_enum) {1501 case GRAPH_OBJECT_ENUM_ID1:1502 args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1;1503 break;1504 case GRAPH_OBJECT_ENUM_ID2:1505 args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2;1506 break;1507 case GRAPH_OBJECT_ENUM_ID3:1508 args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3;1509 break;1510 }1511 args.v3.sExtEncoder.ucBitPerColor = radeon_atom_get_bpc(encoder);1512 break;1513 default:1514 DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);1515 return;1516 }1517 break;1518 default:1519 DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);1520 return;1521 }1522 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1523}1524 1525static void1526atombios_yuv_setup(struct drm_encoder *encoder, bool enable)1527{1528 struct drm_device *dev = encoder->dev;1529 struct radeon_device *rdev = dev->dev_private;1530 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);1531 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);1532 ENABLE_YUV_PS_ALLOCATION args;1533 int index = GetIndexIntoMasterTable(COMMAND, EnableYUV);1534 uint32_t temp, reg;1535 1536 memset(&args, 0, sizeof(args));1537 1538 if (rdev->family >= CHIP_R600)1539 reg = R600_BIOS_3_SCRATCH;1540 else1541 reg = RADEON_BIOS_3_SCRATCH;1542 1543 /* XXX: fix up scratch reg handling */1544 temp = RREG32(reg);1545 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))1546 WREG32(reg, (ATOM_S3_TV1_ACTIVE |1547 (radeon_crtc->crtc_id << 18)));1548 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))1549 WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24)));1550 else1551 WREG32(reg, 0);1552 1553 if (enable)1554 args.ucEnable = ATOM_ENABLE;1555 args.ucCRTC = radeon_crtc->crtc_id;1556 1557 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1558 1559 WREG32(reg, temp);1560}1561 1562static void1563radeon_atom_encoder_dpms_avivo(struct drm_encoder *encoder, int mode)1564{1565 struct drm_device *dev = encoder->dev;1566 struct radeon_device *rdev = dev->dev_private;1567 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);1568 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;1569 int index = 0;1570 1571 memset(&args, 0, sizeof(args));1572 1573 switch (radeon_encoder->encoder_id) {1574 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:1575 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:1576 index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);1577 break;1578 case ENCODER_OBJECT_ID_INTERNAL_DVO1:1579 case ENCODER_OBJECT_ID_INTERNAL_DDI:1580 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:1581 index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);1582 break;1583 case ENCODER_OBJECT_ID_INTERNAL_LVDS:1584 index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);1585 break;1586 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:1587 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))1588 index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);1589 else1590 index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);1591 break;1592 case ENCODER_OBJECT_ID_INTERNAL_DAC1:1593 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:1594 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))1595 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);1596 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))1597 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);1598 else1599 index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);1600 break;1601 case ENCODER_OBJECT_ID_INTERNAL_DAC2:1602 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:1603 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))1604 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);1605 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))1606 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);1607 else1608 index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);1609 break;1610 default:1611 return;1612 }1613 1614 switch (mode) {1615 case DRM_MODE_DPMS_ON:1616 args.ucAction = ATOM_ENABLE;1617 /* workaround for DVOOutputControl on some RS690 systems */1618 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DDI) {1619 u32 reg = RREG32(RADEON_BIOS_3_SCRATCH);1620 WREG32(RADEON_BIOS_3_SCRATCH, reg & ~ATOM_S3_DFP2I_ACTIVE);1621 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1622 WREG32(RADEON_BIOS_3_SCRATCH, reg);1623 } else1624 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1625 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {1626 if (rdev->mode_info.bl_encoder) {1627 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;1628 1629 atombios_set_backlight_level(radeon_encoder, dig->backlight_level);1630 } else {1631 args.ucAction = ATOM_LCD_BLON;1632 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1633 }1634 }1635 break;1636 case DRM_MODE_DPMS_STANDBY:1637 case DRM_MODE_DPMS_SUSPEND:1638 case DRM_MODE_DPMS_OFF:1639 args.ucAction = ATOM_DISABLE;1640 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1641 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {1642 args.ucAction = ATOM_LCD_BLOFF;1643 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1644 }1645 break;1646 }1647}1648 1649static void1650radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)1651{1652 struct drm_device *dev = encoder->dev;1653 struct radeon_device *rdev = dev->dev_private;1654 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);1655 struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);1656 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;1657 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);1658 struct radeon_connector *radeon_connector = NULL;1659 struct radeon_connector_atom_dig *radeon_dig_connector = NULL;1660 bool travis_quirk = false;1661 1662 if (connector) {1663 radeon_connector = to_radeon_connector(connector);1664 radeon_dig_connector = radeon_connector->con_priv;1665 if ((radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==1666 ENCODER_OBJECT_ID_TRAVIS) &&1667 (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&1668 !ASIC_IS_DCE5(rdev))1669 travis_quirk = true;1670 }1671 1672 switch (mode) {1673 case DRM_MODE_DPMS_ON:1674 if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {1675 if (!connector)1676 dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;1677 else1678 dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector);1679 1680 /* setup and enable the encoder */1681 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);1682 atombios_dig_encoder_setup(encoder,1683 ATOM_ENCODER_CMD_SETUP_PANEL_MODE,1684 dig->panel_mode);1685 if (ext_encoder) {1686 if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))1687 atombios_external_encoder_setup(encoder, ext_encoder,1688 EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);1689 }1690 } else if (ASIC_IS_DCE4(rdev)) {1691 /* setup and enable the encoder */1692 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);1693 } else {1694 /* setup and enable the encoder and transmitter */1695 atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0);1696 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);1697 }1698 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {1699 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {1700 atombios_set_edp_panel_power(connector,1701 ATOM_TRANSMITTER_ACTION_POWER_ON);1702 radeon_dig_connector->edp_on = true;1703 }1704 }1705 /* enable the transmitter */1706 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);1707 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {1708 /* DP_SET_POWER_D0 is set in radeon_dp_link_train */1709 radeon_dp_link_train(encoder, connector);1710 if (ASIC_IS_DCE4(rdev))1711 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);1712 }1713 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {1714 if (rdev->mode_info.bl_encoder)1715 atombios_set_backlight_level(radeon_encoder, dig->backlight_level);1716 else1717 atombios_dig_transmitter_setup(encoder,1718 ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);1719 }1720 if (ext_encoder)1721 atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);1722 break;1723 case DRM_MODE_DPMS_STANDBY:1724 case DRM_MODE_DPMS_SUSPEND:1725 case DRM_MODE_DPMS_OFF:1726 1727 if (ASIC_IS_DCE4(rdev)) {1728 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector)1729 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);1730 }1731 if (ext_encoder)1732 atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE);1733 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))1734 atombios_dig_transmitter_setup(encoder,1735 ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);1736 1737 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) &&1738 connector && !travis_quirk)1739 radeon_dp_set_rx_power_state(connector, DP_SET_POWER_D3);1740 if (ASIC_IS_DCE4(rdev)) {1741 /* disable the transmitter */1742 atombios_dig_transmitter_setup(encoder,1743 ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);1744 } else {1745 /* disable the encoder and transmitter */1746 atombios_dig_transmitter_setup(encoder,1747 ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);1748 atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0);1749 }1750 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {1751 if (travis_quirk)1752 radeon_dp_set_rx_power_state(connector, DP_SET_POWER_D3);1753 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {1754 atombios_set_edp_panel_power(connector,1755 ATOM_TRANSMITTER_ACTION_POWER_OFF);1756 radeon_dig_connector->edp_on = false;1757 }1758 }1759 break;1760 }1761}1762 1763static void1764radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)1765{1766 struct drm_device *dev = encoder->dev;1767 struct radeon_device *rdev = dev->dev_private;1768 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);1769 int encoder_mode = atombios_get_encoder_mode(encoder);1770 1771 DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n",1772 radeon_encoder->encoder_id, mode, radeon_encoder->devices,1773 radeon_encoder->active_device);1774 1775 if ((radeon_audio != 0) &&1776 ((encoder_mode == ATOM_ENCODER_MODE_HDMI) ||1777 ENCODER_MODE_IS_DP(encoder_mode)))1778 radeon_audio_dpms(encoder, mode);1779 1780 switch (radeon_encoder->encoder_id) {1781 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:1782 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:1783 case ENCODER_OBJECT_ID_INTERNAL_LVDS:1784 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:1785 case ENCODER_OBJECT_ID_INTERNAL_DVO1:1786 case ENCODER_OBJECT_ID_INTERNAL_DDI:1787 case ENCODER_OBJECT_ID_INTERNAL_DAC2:1788 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:1789 radeon_atom_encoder_dpms_avivo(encoder, mode);1790 break;1791 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:1792 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:1793 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:1794 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:1795 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:1796 radeon_atom_encoder_dpms_dig(encoder, mode);1797 break;1798 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:1799 if (ASIC_IS_DCE5(rdev)) {1800 switch (mode) {1801 case DRM_MODE_DPMS_ON:1802 atombios_dvo_setup(encoder, ATOM_ENABLE);1803 break;1804 case DRM_MODE_DPMS_STANDBY:1805 case DRM_MODE_DPMS_SUSPEND:1806 case DRM_MODE_DPMS_OFF:1807 atombios_dvo_setup(encoder, ATOM_DISABLE);1808 break;1809 }1810 } else if (ASIC_IS_DCE3(rdev))1811 radeon_atom_encoder_dpms_dig(encoder, mode);1812 else1813 radeon_atom_encoder_dpms_avivo(encoder, mode);1814 break;1815 case ENCODER_OBJECT_ID_INTERNAL_DAC1:1816 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:1817 if (ASIC_IS_DCE5(rdev)) {1818 switch (mode) {1819 case DRM_MODE_DPMS_ON:1820 atombios_dac_setup(encoder, ATOM_ENABLE);1821 break;1822 case DRM_MODE_DPMS_STANDBY:1823 case DRM_MODE_DPMS_SUSPEND:1824 case DRM_MODE_DPMS_OFF:1825 atombios_dac_setup(encoder, ATOM_DISABLE);1826 break;1827 }1828 } else1829 radeon_atom_encoder_dpms_avivo(encoder, mode);1830 break;1831 default:1832 return;1833 }1834 1835 radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);1836 1837}1838 1839union crtc_source_param {1840 SELECT_CRTC_SOURCE_PS_ALLOCATION v1;1841 SELECT_CRTC_SOURCE_PARAMETERS_V2 v2;1842};1843 1844static void1845atombios_set_encoder_crtc_source(struct drm_encoder *encoder)1846{1847 struct drm_device *dev = encoder->dev;1848 struct radeon_device *rdev = dev->dev_private;1849 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);1850 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);1851 union crtc_source_param args;1852 int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);1853 uint8_t frev, crev;1854 struct radeon_encoder_atom_dig *dig;1855 1856 memset(&args, 0, sizeof(args));1857 1858 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))1859 return;1860 1861 switch (frev) {1862 case 1:1863 switch (crev) {1864 case 1:1865 default:1866 if (ASIC_IS_AVIVO(rdev))1867 args.v1.ucCRTC = radeon_crtc->crtc_id;1868 else {1869 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1)1870 args.v1.ucCRTC = radeon_crtc->crtc_id;1871 else1872 args.v1.ucCRTC = radeon_crtc->crtc_id << 2;1873 }1874 switch (radeon_encoder->encoder_id) {1875 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:1876 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:1877 args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX;1878 break;1879 case ENCODER_OBJECT_ID_INTERNAL_LVDS:1880 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:1881 if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT)1882 args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX;1883 else1884 args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX;1885 break;1886 case ENCODER_OBJECT_ID_INTERNAL_DVO1:1887 case ENCODER_OBJECT_ID_INTERNAL_DDI:1888 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:1889 args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX;1890 break;1891 case ENCODER_OBJECT_ID_INTERNAL_DAC1:1892 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:1893 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))1894 args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;1895 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))1896 args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;1897 else1898 args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX;1899 break;1900 case ENCODER_OBJECT_ID_INTERNAL_DAC2:1901 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:1902 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))1903 args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;1904 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))1905 args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;1906 else1907 args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX;1908 break;1909 }1910 break;1911 case 2:1912 args.v2.ucCRTC = radeon_crtc->crtc_id;1913 if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE) {1914 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);1915 1916 if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)1917 args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;1918 else if (connector->connector_type == DRM_MODE_CONNECTOR_VGA)1919 args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;1920 else1921 args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);1922 } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {1923 args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;1924 } else {1925 args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);1926 }1927 switch (radeon_encoder->encoder_id) {1928 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:1929 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:1930 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:1931 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:1932 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:1933 dig = radeon_encoder->enc_priv;1934 switch (dig->dig_encoder) {1935 case 0:1936 args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;1937 break;1938 case 1:1939 args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;1940 break;1941 case 2:1942 args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID;1943 break;1944 case 3:1945 args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID;1946 break;1947 case 4:1948 args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID;1949 break;1950 case 5:1951 args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID;1952 break;1953 case 6:1954 args.v2.ucEncoderID = ASIC_INT_DIG7_ENCODER_ID;1955 break;1956 }1957 break;1958 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:1959 args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;1960 break;1961 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:1962 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))1963 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;1964 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))1965 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;1966 else1967 args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;1968 break;1969 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:1970 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))1971 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;1972 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))1973 args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;1974 else1975 args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;1976 break;1977 }1978 break;1979 }1980 break;1981 default:1982 DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);1983 return;1984 }1985 1986 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1987 1988 /* update scratch regs with new routing */1989 radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);1990}1991 1992static void1993atombios_apply_encoder_quirks(struct drm_encoder *encoder,1994 struct drm_display_mode *mode)1995{1996 struct drm_device *dev = encoder->dev;1997 struct radeon_device *rdev = dev->dev_private;1998 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);1999 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);2000 2001 /* Funky macbooks */2002 if ((rdev->pdev->device == 0x71C5) &&2003 (rdev->pdev->subsystem_vendor == 0x106b) &&2004 (rdev->pdev->subsystem_device == 0x0080)) {2005 if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {2006 uint32_t lvtma_bit_depth_control = RREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL);2007 2008 lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN;2009 lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN;2010 2011 WREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL, lvtma_bit_depth_control);2012 }2013 }2014 2015 /* set scaler clears this on some chips */2016 if (ASIC_IS_AVIVO(rdev) &&2017 (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) {2018 if (ASIC_IS_DCE8(rdev)) {2019 if (mode->flags & DRM_MODE_FLAG_INTERLACE)2020 WREG32(CIK_LB_DATA_FORMAT + radeon_crtc->crtc_offset,2021 CIK_INTERLEAVE_EN);2022 else2023 WREG32(CIK_LB_DATA_FORMAT + radeon_crtc->crtc_offset, 0);2024 } else if (ASIC_IS_DCE4(rdev)) {2025 if (mode->flags & DRM_MODE_FLAG_INTERLACE)2026 WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset,2027 EVERGREEN_INTERLEAVE_EN);2028 else2029 WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0);2030 } else {2031 if (mode->flags & DRM_MODE_FLAG_INTERLACE)2032 WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,2033 AVIVO_D1MODE_INTERLEAVE_EN);2034 else2035 WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0);2036 }2037 }2038}2039 2040void radeon_atom_release_dig_encoder(struct radeon_device *rdev, int enc_idx)2041{2042 if (enc_idx < 0)2043 return;2044 rdev->mode_info.active_encoders &= ~(1 << enc_idx);2045}2046 2047int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder, int fe_idx)2048{2049 struct drm_device *dev = encoder->dev;2050 struct radeon_device *rdev = dev->dev_private;2051 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);2052 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);2053 struct drm_encoder *test_encoder;2054 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;2055 uint32_t dig_enc_in_use = 0;2056 int enc_idx = -1;2057 2058 if (fe_idx >= 0) {2059 enc_idx = fe_idx;2060 goto assigned;2061 }2062 if (ASIC_IS_DCE6(rdev)) {2063 /* DCE6 */2064 switch (radeon_encoder->encoder_id) {2065 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:2066 if (dig->linkb)2067 enc_idx = 1;2068 else2069 enc_idx = 0;2070 break;2071 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:2072 if (dig->linkb)2073 enc_idx = 3;2074 else2075 enc_idx = 2;2076 break;2077 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:2078 if (dig->linkb)2079 enc_idx = 5;2080 else2081 enc_idx = 4;2082 break;2083 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:2084 enc_idx = 6;2085 break;2086 }2087 goto assigned;2088 } else if (ASIC_IS_DCE4(rdev)) {2089 /* DCE4/5 */2090 if (ASIC_IS_DCE41(rdev) && !ASIC_IS_DCE61(rdev)) {2091 /* ontario follows DCE4 */2092 if (rdev->family == CHIP_PALM) {2093 if (dig->linkb)2094 enc_idx = 1;2095 else2096 enc_idx = 0;2097 } else2098 /* llano follows DCE3.2 */2099 enc_idx = radeon_crtc->crtc_id;2100 } else {2101 switch (radeon_encoder->encoder_id) {2102 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:2103 if (dig->linkb)2104 enc_idx = 1;2105 else2106 enc_idx = 0;2107 break;2108 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:2109 if (dig->linkb)2110 enc_idx = 3;2111 else2112 enc_idx = 2;2113 break;2114 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:2115 if (dig->linkb)2116 enc_idx = 5;2117 else2118 enc_idx = 4;2119 break;2120 }2121 }2122 goto assigned;2123 }2124 2125 /*2126 * On DCE32 any encoder can drive any block so usually just use crtc id,2127 * but Apple thinks different at least on iMac10,1 and iMac11,2, so there use linkb,2128 * otherwise the internal eDP panel will stay dark.2129 */2130 if (ASIC_IS_DCE32(rdev)) {2131 if (dmi_match(DMI_PRODUCT_NAME, "iMac10,1") ||2132 dmi_match(DMI_PRODUCT_NAME, "iMac11,2"))2133 enc_idx = (dig->linkb) ? 1 : 0;2134 else2135 enc_idx = radeon_crtc->crtc_id;2136 2137 goto assigned;2138 }2139 2140 /* on DCE3 - LVTMA can only be driven by DIGB */2141 list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {2142 struct radeon_encoder *radeon_test_encoder;2143 2144 if (encoder == test_encoder)2145 continue;2146 2147 if (!radeon_encoder_is_digital(test_encoder))2148 continue;2149 2150 radeon_test_encoder = to_radeon_encoder(test_encoder);2151 dig = radeon_test_encoder->enc_priv;2152 2153 if (dig->dig_encoder >= 0)2154 dig_enc_in_use |= (1 << dig->dig_encoder);2155 }2156 2157 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA) {2158 if (dig_enc_in_use & 0x2)2159 DRM_ERROR("LVDS required digital encoder 2 but it was in use - stealing\n");2160 return 1;2161 }2162 if (!(dig_enc_in_use & 1))2163 return 0;2164 return 1;2165 2166assigned:2167 if (enc_idx == -1) {2168 DRM_ERROR("Got encoder index incorrect - returning 0\n");2169 return 0;2170 }2171 if (rdev->mode_info.active_encoders & (1 << enc_idx))2172 DRM_ERROR("chosen encoder in use %d\n", enc_idx);2173 2174 rdev->mode_info.active_encoders |= (1 << enc_idx);2175 return enc_idx;2176}2177 2178/* This only needs to be called once at startup */2179void2180radeon_atom_encoder_init(struct radeon_device *rdev)2181{2182 struct drm_device *dev = rdev_to_drm(rdev);2183 struct drm_encoder *encoder;2184 2185 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {2186 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);2187 struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);2188 2189 switch (radeon_encoder->encoder_id) {2190 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:2191 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:2192 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:2193 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:2194 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:2195 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);2196 break;2197 default:2198 break;2199 }2200 2201 if (ext_encoder && (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)))2202 atombios_external_encoder_setup(encoder, ext_encoder,2203 EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT);2204 }2205}2206 2207static void2208radeon_atom_encoder_mode_set(struct drm_encoder *encoder,2209 struct drm_display_mode *mode,2210 struct drm_display_mode *adjusted_mode)2211{2212 struct drm_device *dev = encoder->dev;2213 struct radeon_device *rdev = dev->dev_private;2214 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);2215 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);2216 int encoder_mode;2217 2218 radeon_encoder->pixel_clock = adjusted_mode->clock;2219 2220 /* need to call this here rather than in prepare() since we need some crtc info */2221 radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);2222 2223 if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) {2224 if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))2225 atombios_yuv_setup(encoder, true);2226 else2227 atombios_yuv_setup(encoder, false);2228 }2229 2230 switch (radeon_encoder->encoder_id) {2231 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:2232 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:2233 case ENCODER_OBJECT_ID_INTERNAL_LVDS:2234 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:2235 atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE);2236 break;2237 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:2238 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:2239 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:2240 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:2241 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:2242 /* handled in dpms */2243 break;2244 case ENCODER_OBJECT_ID_INTERNAL_DDI:2245 case ENCODER_OBJECT_ID_INTERNAL_DVO1:2246 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:2247 atombios_dvo_setup(encoder, ATOM_ENABLE);2248 break;2249 case ENCODER_OBJECT_ID_INTERNAL_DAC1:2250 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:2251 case ENCODER_OBJECT_ID_INTERNAL_DAC2:2252 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:2253 atombios_dac_setup(encoder, ATOM_ENABLE);2254 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) {2255 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))2256 atombios_tv_setup(encoder, ATOM_ENABLE);2257 else2258 atombios_tv_setup(encoder, ATOM_DISABLE);2259 }2260 break;2261 }2262 2263 atombios_apply_encoder_quirks(encoder, adjusted_mode);2264 2265 encoder_mode = atombios_get_encoder_mode(encoder);2266 if (connector && (radeon_audio != 0) &&2267 ((encoder_mode == ATOM_ENCODER_MODE_HDMI) ||2268 ENCODER_MODE_IS_DP(encoder_mode)))2269 radeon_audio_mode_set(encoder, adjusted_mode);2270}2271 2272static bool2273atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *connector)2274{2275 struct drm_device *dev = encoder->dev;2276 struct radeon_device *rdev = dev->dev_private;2277 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);2278 struct radeon_connector *radeon_connector = to_radeon_connector(connector);2279 2280 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT |2281 ATOM_DEVICE_CV_SUPPORT |2282 ATOM_DEVICE_CRT_SUPPORT)) {2283 DAC_LOAD_DETECTION_PS_ALLOCATION args;2284 int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);2285 uint8_t frev, crev;2286 2287 memset(&args, 0, sizeof(args));2288 2289 if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))2290 return false;2291 2292 args.sDacload.ucMisc = 0;2293 2294 if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) ||2295 (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1))2296 args.sDacload.ucDacType = ATOM_DAC_A;2297 else2298 args.sDacload.ucDacType = ATOM_DAC_B;2299 2300 if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)2301 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT);2302 else if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)2303 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT);2304 else if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {2305 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT);2306 if (crev >= 3)2307 args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;2308 } else if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {2309 args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT);2310 if (crev >= 3)2311 args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;2312 }2313 2314 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));2315 2316 return true;2317 } else2318 return false;2319}2320 2321static enum drm_connector_status2322radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)2323{2324 struct drm_device *dev = encoder->dev;2325 struct radeon_device *rdev = dev->dev_private;2326 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);2327 struct radeon_connector *radeon_connector = to_radeon_connector(connector);2328 uint32_t bios_0_scratch;2329 2330 if (!atombios_dac_load_detect(encoder, connector)) {2331 DRM_DEBUG_KMS("detect returned false \n");2332 return connector_status_unknown;2333 }2334 2335 if (rdev->family >= CHIP_R600)2336 bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH);2337 else2338 bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);2339 2340 DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices);2341 if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) {2342 if (bios_0_scratch & ATOM_S0_CRT1_MASK)2343 return connector_status_connected;2344 }2345 if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) {2346 if (bios_0_scratch & ATOM_S0_CRT2_MASK)2347 return connector_status_connected;2348 }2349 if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {2350 if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))2351 return connector_status_connected;2352 }2353 if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {2354 if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))2355 return connector_status_connected; /* CTV */2356 else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))2357 return connector_status_connected; /* STV */2358 }2359 return connector_status_disconnected;2360}2361 2362static enum drm_connector_status2363radeon_atom_dig_detect(struct drm_encoder *encoder, struct drm_connector *connector)2364{2365 struct drm_device *dev = encoder->dev;2366 struct radeon_device *rdev = dev->dev_private;2367 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);2368 struct radeon_connector *radeon_connector = to_radeon_connector(connector);2369 struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);2370 u32 bios_0_scratch;2371 2372 if (!ASIC_IS_DCE4(rdev))2373 return connector_status_unknown;2374 2375 if (!ext_encoder)2376 return connector_status_unknown;2377 2378 if ((radeon_connector->devices & ATOM_DEVICE_CRT_SUPPORT) == 0)2379 return connector_status_unknown;2380 2381 /* load detect on the dp bridge */2382 atombios_external_encoder_setup(encoder, ext_encoder,2383 EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION);2384 2385 bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH);2386 2387 DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices);2388 if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) {2389 if (bios_0_scratch & ATOM_S0_CRT1_MASK)2390 return connector_status_connected;2391 }2392 if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) {2393 if (bios_0_scratch & ATOM_S0_CRT2_MASK)2394 return connector_status_connected;2395 }2396 if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {2397 if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))2398 return connector_status_connected;2399 }2400 if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {2401 if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))2402 return connector_status_connected; /* CTV */2403 else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))2404 return connector_status_connected; /* STV */2405 }2406 return connector_status_disconnected;2407}2408 2409void2410radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder)2411{2412 struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);2413 2414 if (ext_encoder)2415 /* ddc_setup on the dp bridge */2416 atombios_external_encoder_setup(encoder, ext_encoder,2417 EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP);2418 2419}2420 2421static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)2422{2423 struct radeon_device *rdev = encoder->dev->dev_private;2424 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);2425 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);2426 2427 if ((radeon_encoder->active_device &2428 (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) ||2429 (radeon_encoder_get_dp_bridge_encoder_id(encoder) !=2430 ENCODER_OBJECT_ID_NONE)) {2431 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;2432 if (dig) {2433 if (dig->dig_encoder >= 0)2434 radeon_atom_release_dig_encoder(rdev, dig->dig_encoder);2435 dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder, -1);2436 if (radeon_encoder->active_device & ATOM_DEVICE_DFP_SUPPORT) {2437 if (rdev->family >= CHIP_R600)2438 dig->afmt = rdev->mode_info.afmt[dig->dig_encoder];2439 else2440 /* RS600/690/740 have only 1 afmt block */2441 dig->afmt = rdev->mode_info.afmt[0];2442 }2443 }2444 }2445 2446 radeon_atom_output_lock(encoder, true);2447 2448 if (connector) {2449 struct radeon_connector *radeon_connector = to_radeon_connector(connector);2450 2451 /* select the clock/data port if it uses a router */2452 if (radeon_connector->router.cd_valid)2453 radeon_router_select_cd_port(radeon_connector);2454 2455 /* turn eDP panel on for mode set */2456 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)2457 atombios_set_edp_panel_power(connector,2458 ATOM_TRANSMITTER_ACTION_POWER_ON);2459 }2460 2461 /* this is needed for the pll/ss setup to work correctly in some cases */2462 atombios_set_encoder_crtc_source(encoder);2463 /* set up the FMT blocks */2464 if (ASIC_IS_DCE8(rdev))2465 dce8_program_fmt(encoder);2466 else if (ASIC_IS_DCE4(rdev))2467 dce4_program_fmt(encoder);2468 else if (ASIC_IS_DCE3(rdev))2469 dce3_program_fmt(encoder);2470 else if (ASIC_IS_AVIVO(rdev))2471 avivo_program_fmt(encoder);2472}2473 2474static void radeon_atom_encoder_commit(struct drm_encoder *encoder)2475{2476 /* need to call this here as we need the crtc set up */2477 radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON);2478 radeon_atom_output_lock(encoder, false);2479}2480 2481static void radeon_atom_encoder_disable(struct drm_encoder *encoder)2482{2483 struct drm_device *dev = encoder->dev;2484 struct radeon_device *rdev = dev->dev_private;2485 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);2486 struct radeon_encoder_atom_dig *dig;2487 2488 /* check for pre-DCE3 cards with shared encoders;2489 * can't really use the links individually, so don't disable2490 * the encoder if it's in use by another connector2491 */2492 if (!ASIC_IS_DCE3(rdev)) {2493 struct drm_encoder *other_encoder;2494 struct radeon_encoder *other_radeon_encoder;2495 2496 list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {2497 other_radeon_encoder = to_radeon_encoder(other_encoder);2498 if ((radeon_encoder->encoder_id == other_radeon_encoder->encoder_id) &&2499 drm_helper_encoder_in_use(other_encoder))2500 goto disable_done;2501 }2502 }2503 2504 radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);2505 2506 switch (radeon_encoder->encoder_id) {2507 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:2508 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:2509 case ENCODER_OBJECT_ID_INTERNAL_LVDS:2510 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:2511 atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_DISABLE);2512 break;2513 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:2514 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:2515 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:2516 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:2517 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:2518 /* handled in dpms */2519 break;2520 case ENCODER_OBJECT_ID_INTERNAL_DDI:2521 case ENCODER_OBJECT_ID_INTERNAL_DVO1:2522 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:2523 atombios_dvo_setup(encoder, ATOM_DISABLE);2524 break;2525 case ENCODER_OBJECT_ID_INTERNAL_DAC1:2526 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:2527 case ENCODER_OBJECT_ID_INTERNAL_DAC2:2528 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:2529 atombios_dac_setup(encoder, ATOM_DISABLE);2530 if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))2531 atombios_tv_setup(encoder, ATOM_DISABLE);2532 break;2533 }2534 2535disable_done:2536 if (radeon_encoder_is_digital(encoder)) {2537 if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {2538 if (rdev->asic->display.hdmi_enable)2539 radeon_hdmi_enable(rdev, encoder, false);2540 }2541 if (atombios_get_encoder_mode(encoder) != ATOM_ENCODER_MODE_DP_MST) {2542 dig = radeon_encoder->enc_priv;2543 radeon_atom_release_dig_encoder(rdev, dig->dig_encoder);2544 dig->dig_encoder = -1;2545 radeon_encoder->active_device = 0;2546 }2547 } else2548 radeon_encoder->active_device = 0;2549}2550 2551/* these are handled by the primary encoders */2552static void radeon_atom_ext_prepare(struct drm_encoder *encoder)2553{2554 2555}2556 2557static void radeon_atom_ext_commit(struct drm_encoder *encoder)2558{2559 2560}2561 2562static void2563radeon_atom_ext_mode_set(struct drm_encoder *encoder,2564 struct drm_display_mode *mode,2565 struct drm_display_mode *adjusted_mode)2566{2567 2568}2569 2570static void radeon_atom_ext_disable(struct drm_encoder *encoder)2571{2572 2573}2574 2575static void2576radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode)2577{2578 2579}2580 2581static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = {2582 .dpms = radeon_atom_ext_dpms,2583 .prepare = radeon_atom_ext_prepare,2584 .mode_set = radeon_atom_ext_mode_set,2585 .commit = radeon_atom_ext_commit,2586 .disable = radeon_atom_ext_disable,2587 /* no detect for TMDS/LVDS yet */2588};2589 2590static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = {2591 .dpms = radeon_atom_encoder_dpms,2592 .mode_fixup = radeon_atom_mode_fixup,2593 .prepare = radeon_atom_encoder_prepare,2594 .mode_set = radeon_atom_encoder_mode_set,2595 .commit = radeon_atom_encoder_commit,2596 .disable = radeon_atom_encoder_disable,2597 .detect = radeon_atom_dig_detect,2598};2599 2600static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = {2601 .dpms = radeon_atom_encoder_dpms,2602 .mode_fixup = radeon_atom_mode_fixup,2603 .prepare = radeon_atom_encoder_prepare,2604 .mode_set = radeon_atom_encoder_mode_set,2605 .commit = radeon_atom_encoder_commit,2606 .detect = radeon_atom_dac_detect,2607};2608 2609void radeon_enc_destroy(struct drm_encoder *encoder)2610{2611 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);2612 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))2613 radeon_atom_backlight_exit(radeon_encoder);2614 kfree(radeon_encoder->enc_priv);2615 drm_encoder_cleanup(encoder);2616 kfree(radeon_encoder);2617}2618 2619static const struct drm_encoder_funcs radeon_atom_enc_funcs = {2620 .destroy = radeon_enc_destroy,2621};2622 2623static struct radeon_encoder_atom_dac *2624radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder)2625{2626 struct drm_device *dev = radeon_encoder->base.dev;2627 struct radeon_device *rdev = dev->dev_private;2628 struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL);2629 2630 if (!dac)2631 return NULL;2632 2633 dac->tv_std = radeon_atombios_get_tv_info(rdev);2634 return dac;2635}2636 2637static struct radeon_encoder_atom_dig *2638radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)2639{2640 int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;2641 struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL);2642 2643 if (!dig)2644 return NULL;2645 2646 /* coherent mode by default */2647 dig->coherent_mode = true;2648 dig->dig_encoder = -1;2649 2650 if (encoder_enum == 2)2651 dig->linkb = true;2652 else2653 dig->linkb = false;2654 2655 return dig;2656}2657 2658void2659radeon_add_atom_encoder(struct drm_device *dev,2660 uint32_t encoder_enum,2661 uint32_t supported_device,2662 u16 caps)2663{2664 struct radeon_device *rdev = dev->dev_private;2665 struct drm_encoder *encoder;2666 struct radeon_encoder *radeon_encoder;2667 2668 /* see if we already added it */2669 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {2670 radeon_encoder = to_radeon_encoder(encoder);2671 if (radeon_encoder->encoder_enum == encoder_enum) {2672 radeon_encoder->devices |= supported_device;2673 return;2674 }2675 2676 }2677 2678 /* add a new one */2679 radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL);2680 if (!radeon_encoder)2681 return;2682 2683 encoder = &radeon_encoder->base;2684 switch (rdev->num_crtc) {2685 case 1:2686 encoder->possible_crtcs = 0x1;2687 break;2688 case 2:2689 default:2690 encoder->possible_crtcs = 0x3;2691 break;2692 case 4:2693 encoder->possible_crtcs = 0xf;2694 break;2695 case 6:2696 encoder->possible_crtcs = 0x3f;2697 break;2698 }2699 2700 radeon_encoder->enc_priv = NULL;2701 2702 radeon_encoder->encoder_enum = encoder_enum;2703 radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;2704 radeon_encoder->devices = supported_device;2705 radeon_encoder->rmx_type = RMX_OFF;2706 radeon_encoder->underscan_type = UNDERSCAN_OFF;2707 radeon_encoder->is_ext_encoder = false;2708 radeon_encoder->caps = caps;2709 2710 switch (radeon_encoder->encoder_id) {2711 case ENCODER_OBJECT_ID_INTERNAL_LVDS:2712 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:2713 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:2714 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:2715 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {2716 radeon_encoder->rmx_type = RMX_FULL;2717 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,2718 DRM_MODE_ENCODER_LVDS, NULL);2719 radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);2720 } else {2721 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,2722 DRM_MODE_ENCODER_TMDS, NULL);2723 radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);2724 }2725 drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);2726 break;2727 case ENCODER_OBJECT_ID_INTERNAL_DAC1:2728 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,2729 DRM_MODE_ENCODER_DAC, NULL);2730 radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);2731 drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);2732 break;2733 case ENCODER_OBJECT_ID_INTERNAL_DAC2:2734 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:2735 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:2736 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,2737 DRM_MODE_ENCODER_TVDAC, NULL);2738 radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);2739 drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);2740 break;2741 case ENCODER_OBJECT_ID_INTERNAL_DVO1:2742 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:2743 case ENCODER_OBJECT_ID_INTERNAL_DDI:2744 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:2745 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:2746 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:2747 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:2748 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:2749 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {2750 radeon_encoder->rmx_type = RMX_FULL;2751 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,2752 DRM_MODE_ENCODER_LVDS, NULL);2753 radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);2754 } else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) {2755 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,2756 DRM_MODE_ENCODER_DAC, NULL);2757 radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);2758 } else {2759 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,2760 DRM_MODE_ENCODER_TMDS, NULL);2761 radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);2762 }2763 drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);2764 break;2765 case ENCODER_OBJECT_ID_SI170B:2766 case ENCODER_OBJECT_ID_CH7303:2767 case ENCODER_OBJECT_ID_EXTERNAL_SDVOA:2768 case ENCODER_OBJECT_ID_EXTERNAL_SDVOB:2769 case ENCODER_OBJECT_ID_TITFP513:2770 case ENCODER_OBJECT_ID_VT1623:2771 case ENCODER_OBJECT_ID_HDMI_SI1930:2772 case ENCODER_OBJECT_ID_TRAVIS:2773 case ENCODER_OBJECT_ID_NUTMEG:2774 /* these are handled by the primary encoders */2775 radeon_encoder->is_ext_encoder = true;2776 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))2777 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,2778 DRM_MODE_ENCODER_LVDS, NULL);2779 else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT))2780 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,2781 DRM_MODE_ENCODER_DAC, NULL);2782 else2783 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs,2784 DRM_MODE_ENCODER_TMDS, NULL);2785 drm_encoder_helper_add(encoder, &radeon_atom_ext_helper_funcs);2786 break;2787 }2788}2789