atombios_output.c revision b7e1c893
1/* 2 * Copyright © 2007 Red Hat, Inc. 3 * Copyright 2007 Advanced Micro Devices, Inc. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 * Authors: 25 * Dave Airlie <airlied@redhat.com> 26 * Alex Deucher <alexdeucher@gmail.com> 27 * 28 */ 29 30/* 31 * avivo output handling functions. 32 */ 33#ifdef HAVE_CONFIG_H 34#include "config.h" 35#endif 36/* DPMS */ 37#define DPMS_SERVER 38#include <X11/extensions/dpms.h> 39#include <unistd.h> 40 41#include "radeon.h" 42#include "radeon_reg.h" 43#include "radeon_macros.h" 44#include "radeon_atombios.h" 45 46#include "ati_pciids_gen.h" 47 48const char *device_name[12] = { 49 "CRT1", 50 "LCD1", 51 "TV1", 52 "DFP1", 53 "CRT2", 54 "LCD2", 55 "TV2", 56 "DFP2", 57 "CV", 58 "DFP3", 59 "DFP4", 60 "DFP5", 61}; 62 63static int 64atombios_output_dac_setup(xf86OutputPtr output, int action) 65{ 66 RADEONOutputPrivatePtr radeon_output = output->driver_private; 67 RADEONInfoPtr info = RADEONPTR(output->scrn); 68 radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); 69 radeon_tvout_ptr tvout = &radeon_output->tvout; 70 DAC_ENCODER_CONTROL_PS_ALLOCATION disp_data; 71 AtomBiosArgRec data; 72 unsigned char *space; 73 int index = 0, num = 0; 74 int clock = radeon_output->pixel_clock; 75 76 if (radeon_encoder == NULL) 77 return ATOM_NOT_IMPLEMENTED; 78 79 memset(&disp_data,0, sizeof(disp_data)); 80 81 switch (radeon_encoder->encoder_id) { 82 case ENCODER_OBJECT_ID_INTERNAL_DAC1: 83 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: 84 index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); 85 num = 1; 86 break; 87 case ENCODER_OBJECT_ID_INTERNAL_DAC2: 88 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: 89 index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); 90 num = 2; 91 break; 92 } 93 94 disp_data.ucAction =action; 95 96 if (radeon_output->active_device & (ATOM_DEVICE_CRT_SUPPORT)) 97 disp_data.ucDacStandard = ATOM_DAC1_PS2; 98 else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) 99 disp_data.ucDacStandard = ATOM_DAC1_CV; 100 else { 101 switch (tvout->tvStd) { 102 case TV_STD_PAL: 103 case TV_STD_PAL_M: 104 case TV_STD_SCART_PAL: 105 case TV_STD_SECAM: 106 case TV_STD_PAL_CN: 107 disp_data.ucDacStandard = ATOM_DAC1_PAL; 108 break; 109 case TV_STD_NTSC: 110 case TV_STD_NTSC_J: 111 case TV_STD_PAL_60: 112 default: 113 disp_data.ucDacStandard = ATOM_DAC1_NTSC; 114 break; 115 } 116 } 117 disp_data.usPixelClock = cpu_to_le16(clock / 10); 118 119 data.exec.index = index; 120 data.exec.dataSpace = (void *)&space; 121 data.exec.pspace = &disp_data; 122 123 if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { 124 ErrorF("Output DAC%d setup success\n", num); 125 return ATOM_SUCCESS; 126 } 127 128 ErrorF("Output DAC%d setup failed\n", num); 129 return ATOM_NOT_IMPLEMENTED; 130 131} 132 133static int 134atombios_output_tv_setup(xf86OutputPtr output, int action) 135{ 136 RADEONOutputPrivatePtr radeon_output = output->driver_private; 137 radeon_tvout_ptr tvout = &radeon_output->tvout; 138 RADEONInfoPtr info = RADEONPTR(output->scrn); 139 TV_ENCODER_CONTROL_PS_ALLOCATION disp_data; 140 AtomBiosArgRec data; 141 unsigned char *space; 142 int clock = radeon_output->pixel_clock; 143 144 memset(&disp_data,0, sizeof(disp_data)); 145 146 disp_data.sTVEncoder.ucAction = action; 147 148 if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) 149 disp_data.sTVEncoder.ucTvStandard = ATOM_TV_CV; 150 else { 151 switch (tvout->tvStd) { 152 case TV_STD_NTSC: 153 disp_data.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; 154 break; 155 case TV_STD_PAL: 156 disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PAL; 157 break; 158 case TV_STD_PAL_M: 159 disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PALM; 160 break; 161 case TV_STD_PAL_60: 162 disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PAL60; 163 break; 164 case TV_STD_NTSC_J: 165 disp_data.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ; 166 break; 167 case TV_STD_SCART_PAL: 168 disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */ 169 break; 170 case TV_STD_SECAM: 171 disp_data.sTVEncoder.ucTvStandard = ATOM_TV_SECAM; 172 break; 173 case TV_STD_PAL_CN: 174 disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PALCN; 175 break; 176 default: 177 disp_data.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; 178 break; 179 } 180 } 181 182 disp_data.sTVEncoder.usPixelClock = cpu_to_le16(clock / 10); 183 data.exec.index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl); 184 data.exec.dataSpace = (void *)&space; 185 data.exec.pspace = &disp_data; 186 187 if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { 188 ErrorF("Output TV setup success\n"); 189 return ATOM_SUCCESS; 190 } 191 192 ErrorF("Output TV setup failed\n"); 193 return ATOM_NOT_IMPLEMENTED; 194 195} 196 197int 198atombios_external_tmds_setup(xf86OutputPtr output, int action) 199{ 200 RADEONOutputPrivatePtr radeon_output = output->driver_private; 201 ScrnInfoPtr pScrn = output->scrn; 202 RADEONInfoPtr info = RADEONPTR(pScrn); 203 ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION disp_data; 204 AtomBiosArgRec data; 205 unsigned char *space; 206 int clock = radeon_output->pixel_clock; 207 208 memset(&disp_data,0, sizeof(disp_data)); 209 210 disp_data.sXTmdsEncoder.ucEnable = action; 211 212 if (clock > 165000) 213 disp_data.sXTmdsEncoder.ucMisc = PANEL_ENCODER_MISC_DUAL; 214 215 if (pScrn->rgbBits == 8) 216 disp_data.sXTmdsEncoder.ucMisc |= (1 << 1); 217 218 data.exec.index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl); 219 data.exec.dataSpace = (void *)&space; 220 data.exec.pspace = &disp_data; 221 222 if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { 223 ErrorF("External TMDS setup success\n"); 224 return ATOM_SUCCESS; 225 } 226 227 ErrorF("External TMDS setup failed\n"); 228 return ATOM_NOT_IMPLEMENTED; 229} 230 231static int 232atombios_output_ddia_setup(xf86OutputPtr output, int action) 233{ 234 RADEONOutputPrivatePtr radeon_output = output->driver_private; 235 RADEONInfoPtr info = RADEONPTR(output->scrn); 236 DVO_ENCODER_CONTROL_PS_ALLOCATION disp_data; 237 AtomBiosArgRec data; 238 unsigned char *space; 239 int clock = radeon_output->pixel_clock; 240 241 memset(&disp_data,0, sizeof(disp_data)); 242 243 disp_data.sDVOEncoder.ucAction = action; 244 disp_data.sDVOEncoder.usPixelClock = cpu_to_le16(clock / 10); 245 246 if (clock > 165000) 247 disp_data.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL; 248 249 data.exec.index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl); 250 data.exec.dataSpace = (void *)&space; 251 data.exec.pspace = &disp_data; 252 253 if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { 254 ErrorF("DDIA setup success\n"); 255 return ATOM_SUCCESS; 256 } 257 258 ErrorF("DDIA setup failed\n"); 259 return ATOM_NOT_IMPLEMENTED; 260} 261 262static int 263atombios_output_digital_setup(xf86OutputPtr output, int action) 264{ 265 RADEONOutputPrivatePtr radeon_output = output->driver_private; 266 ScrnInfoPtr pScrn = output->scrn; 267 RADEONInfoPtr info = RADEONPTR(pScrn); 268 radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); 269 LVDS_ENCODER_CONTROL_PS_ALLOCATION disp_data; 270 LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 disp_data2; 271 AtomBiosArgRec data; 272 unsigned char *space; 273 int index = 0; 274 int major, minor; 275 int lvds_misc = 0; 276 int clock = radeon_output->pixel_clock; 277 278 if (radeon_encoder == NULL) 279 return ATOM_NOT_IMPLEMENTED; 280 281 if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { 282 radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv; 283 if (lvds == NULL) 284 return ATOM_NOT_IMPLEMENTED; 285 lvds_misc = lvds->lvds_misc; 286 } 287 288 memset(&disp_data,0, sizeof(disp_data)); 289 memset(&disp_data2,0, sizeof(disp_data2)); 290 291 switch (radeon_encoder->encoder_id) { 292 case ENCODER_OBJECT_ID_INTERNAL_LVDS: 293 index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); 294 break; 295 case ENCODER_OBJECT_ID_INTERNAL_TMDS1: 296 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: 297 index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl); 298 break; 299 case ENCODER_OBJECT_ID_INTERNAL_LVTM1: 300 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: 301 if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) 302 index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); 303 else 304 index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl); 305 break; 306 } 307 308 atombios_get_command_table_version(info->atomBIOS, index, &major, &minor); 309 310 /*ErrorF("table is %d %d\n", major, minor);*/ 311 switch (major) { 312 case 0: 313 case 1: 314 case 2: 315 switch (minor) { 316 case 1: 317 disp_data.ucMisc = 0; 318 disp_data.ucAction = action; 319 if ((radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_A) || 320 (radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_B)) 321 disp_data.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; 322 disp_data.usPixelClock = cpu_to_le16(clock / 10); 323 if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { 324 if (lvds_misc & (1 << 0)) 325 disp_data.ucMisc |= PANEL_ENCODER_MISC_DUAL; 326 if (lvds_misc & (1 << 1)) 327 disp_data.ucMisc |= (1 << 1); 328 } else { 329 if (radeon_output->linkb) 330 disp_data.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; 331 if (clock > 165000) 332 disp_data.ucMisc |= PANEL_ENCODER_MISC_DUAL; 333 if (pScrn->rgbBits == 8) 334 disp_data.ucMisc |= (1 << 1); 335 } 336 data.exec.pspace = &disp_data; 337 break; 338 case 2: 339 case 3: 340 disp_data2.ucMisc = 0; 341 disp_data2.ucAction = action; 342 if (minor == 3) { 343 if (radeon_output->coherent_mode) { 344 disp_data2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; 345 xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "Coherent Mode enabled\n"); 346 } 347 } 348 if ((radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_A) || 349 (radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_B)) 350 disp_data2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; 351 disp_data2.usPixelClock = cpu_to_le16(clock / 10); 352 disp_data2.ucTruncate = 0; 353 disp_data2.ucSpatial = 0; 354 disp_data2.ucTemporal = 0; 355 disp_data2.ucFRC = 0; 356 if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { 357 if (lvds_misc & (1 << 0)) 358 disp_data2.ucMisc |= PANEL_ENCODER_MISC_DUAL; 359 if (lvds_misc & (1 << 5)) { 360 disp_data2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; 361 if (lvds_misc & (1 << 1)) 362 disp_data2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; 363 } 364 if (lvds_misc & (1 << 6)) { 365 disp_data2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; 366 if (lvds_misc & (1 << 1)) 367 disp_data2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; 368 if (((lvds_misc >> 2) & 0x3) == 2) 369 disp_data2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; 370 } 371 } else { 372 if (radeon_output->linkb) 373 disp_data2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; 374 if (clock > 165000) 375 disp_data2.ucMisc |= PANEL_ENCODER_MISC_DUAL; 376 } 377 data.exec.pspace = &disp_data2; 378 break; 379 default: 380 ErrorF("Unknown table version\n"); 381 exit(-1); 382 } 383 break; 384 default: 385 ErrorF("Unknown table version\n"); 386 exit(-1); 387 } 388 389 data.exec.index = index; 390 data.exec.dataSpace = (void *)&space; 391 392 if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { 393 ErrorF("Output digital setup success\n"); 394 return ATOM_SUCCESS; 395 } 396 397 ErrorF("Output digital setup failed\n"); 398 return ATOM_NOT_IMPLEMENTED; 399} 400 401static int 402atombios_maybe_hdmi_mode(xf86OutputPtr output) 403{ 404#ifndef EDID_COMPLETE_RAWDATA 405 /* there's no getting this right unless we have complete EDID */ 406 return ATOM_ENCODER_MODE_HDMI; 407#else 408 if (output && xf86MonitorIsHDMI(output->MonInfo)) 409 return ATOM_ENCODER_MODE_HDMI; 410 411 return ATOM_ENCODER_MODE_DVI; 412#endif 413} 414 415int 416atombios_get_encoder_mode(xf86OutputPtr output) 417{ 418 RADEONOutputPrivatePtr radeon_output = output->driver_private; 419 420 /* DVI should really be atombios_maybe_hdmi_mode() as well */ 421 switch (radeon_output->ConnectorType) { 422 case CONNECTOR_DVI_I: 423 if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT)) 424 return ATOM_ENCODER_MODE_DVI; 425 else 426 return ATOM_ENCODER_MODE_CRT; 427 break; 428 case CONNECTOR_DVI_D: 429 default: 430 return ATOM_ENCODER_MODE_DVI; 431 break; 432 case CONNECTOR_HDMI_TYPE_A: 433 case CONNECTOR_HDMI_TYPE_B: 434 return atombios_maybe_hdmi_mode(output); 435 break; 436 case CONNECTOR_LVDS: 437 return ATOM_ENCODER_MODE_LVDS; 438 break; 439 case CONNECTOR_DISPLAY_PORT: 440 if (radeon_output->MonType == MT_DP) 441 return ATOM_ENCODER_MODE_DP; 442 else 443 return atombios_maybe_hdmi_mode(output); 444 break; 445 case CONNECTOR_DVI_A: 446 case CONNECTOR_VGA: 447 case CONNECTOR_STV: 448 case CONNECTOR_CTV: 449 case CONNECTOR_DIN: 450 if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) 451 return ATOM_ENCODER_MODE_TV; 452 else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) 453 return ATOM_ENCODER_MODE_CV; 454 else 455 return ATOM_ENCODER_MODE_CRT; 456 break; 457 } 458 459} 460 461static const int dp_clocks[] = { 462 16200, 463 27000, 464 32400, 465 54000, 466 0, 467 0, 468 64800, 469 108000, 470}; 471static const int num_dp_clocks = sizeof(dp_clocks) / sizeof(int); 472 473static int 474dp_lanes_for_mode_clock(int mode_clock) 475{ 476 int i; 477 478 for (i = 0; i < num_dp_clocks; i++) 479 if (dp_clocks[i] > (mode_clock / 10)) 480 return (i / 2) + 1; 481 482 return 0; 483} 484 485static int 486dp_link_clock_for_mode_clock(int mode_clock) 487{ 488 int i; 489 490 for (i = 0; i < num_dp_clocks; i++) 491 if (dp_clocks[i] > (mode_clock / 10)) 492 return (dp_clocks[i % 2]); 493 494 return 0; 495} 496 497static int 498atombios_output_dig_encoder_setup(xf86OutputPtr output, int action) 499{ 500 RADEONOutputPrivatePtr radeon_output = output->driver_private; 501 RADEONInfoPtr info = RADEONPTR(output->scrn); 502 radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); 503 DIG_ENCODER_CONTROL_PS_ALLOCATION disp_data; 504 AtomBiosArgRec data; 505 unsigned char *space; 506 int index = 0, major, minor, num = 0; 507 int clock = radeon_output->pixel_clock; 508 int dig_block = radeon_output->dig_block; 509 510 if (radeon_encoder == NULL) 511 return ATOM_NOT_IMPLEMENTED; 512 513 memset(&disp_data,0, sizeof(disp_data)); 514 515 if (IS_DCE32_VARIANT) { 516 if (dig_block) 517 index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); 518 else 519 index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); 520 num = dig_block + 1; 521 } else { 522 switch (radeon_encoder->encoder_id) { 523 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: 524 index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); 525 num = 1; 526 break; 527 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: 528 index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); 529 num = 2; 530 break; 531 } 532 } 533 534 atombios_get_command_table_version(info->atomBIOS, index, &major, &minor); 535 536 disp_data.ucAction = action; 537 disp_data.usPixelClock = cpu_to_le16(clock / 10); 538 539 if (IS_DCE32_VARIANT) { 540 switch (radeon_encoder->encoder_id) { 541 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: 542 disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; 543 break; 544 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: 545 disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; 546 break; 547 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: 548 disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; 549 break; 550 } 551 } else { 552 switch (radeon_encoder->encoder_id) { 553 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: 554 disp_data.ucConfig = ATOM_ENCODER_CONFIG_UNIPHY; 555 break; 556 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: 557 disp_data.ucConfig = ATOM_ENCODER_CONFIG_LVTMA; 558 break; 559 } 560 } 561 562 disp_data.ucEncoderMode = atombios_get_encoder_mode(output); 563 564 if (disp_data.ucEncoderMode == ATOM_ENCODER_MODE_DP) { 565 if (radeon_output->linkb) 566 disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; 567 else 568 disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; 569 570 if (dp_link_clock_for_mode_clock(clock) == 27000) 571 disp_data.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; 572 573 disp_data.ucLaneNum = dp_lanes_for_mode_clock(clock); 574 } else if (clock > 165000) { 575 disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B; 576 disp_data.ucLaneNum = 8; 577 } else { 578 if (radeon_output->linkb) 579 disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; 580 else 581 disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; 582 583 disp_data.ucLaneNum = 4; 584 } 585 586 data.exec.index = index; 587 data.exec.dataSpace = (void *)&space; 588 data.exec.pspace = &disp_data; 589 590 if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { 591 ErrorF("Output DIG%d encoder setup success\n", num); 592 return ATOM_SUCCESS; 593 } 594 595 ErrorF("Output DIG%d setup failed\n", num); 596 return ATOM_NOT_IMPLEMENTED; 597 598} 599 600union dig_transmitter_control { 601 DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; 602 DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; 603}; 604 605static int 606atombios_output_dig_transmitter_setup(xf86OutputPtr output, int action) 607{ 608 RADEONOutputPrivatePtr radeon_output = output->driver_private; 609 RADEONInfoPtr info = RADEONPTR(output->scrn); 610 radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); 611 union dig_transmitter_control disp_data; 612 AtomBiosArgRec data; 613 unsigned char *space; 614 int index = 0, num = 0; 615 int major, minor; 616 int clock = radeon_output->pixel_clock; 617 int dig_block = radeon_output->dig_block; 618 619 if (radeon_encoder == NULL) 620 return ATOM_NOT_IMPLEMENTED; 621 622 memset(&disp_data,0, sizeof(disp_data)); 623 624 if (IS_DCE32_VARIANT) 625 index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); 626 else { 627 switch (radeon_encoder->encoder_id) { 628 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: 629 index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl); 630 break; 631 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: 632 index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl); 633 break; 634 } 635 } 636 637 atombios_get_command_table_version(info->atomBIOS, index, &major, &minor); 638 639 disp_data.v1.ucAction = action; 640 641 if (IS_DCE32_VARIANT) { 642 if (radeon_output->MonType == MT_DP) { 643 disp_data.v2.usPixelClock = 644 cpu_to_le16(dp_link_clock_for_mode_clock(clock)); 645 disp_data.v2.acConfig.fDPConnector = 1; 646 } else if (clock > 165000) { 647 disp_data.v2.usPixelClock = cpu_to_le16((clock * 10 * 2) / 100); 648 disp_data.v2.acConfig.fDualLinkConnector = 1; 649 } else { 650 disp_data.v2.usPixelClock = cpu_to_le16((clock * 10 * 4) / 100); 651 } 652 if (dig_block) 653 disp_data.v2.acConfig.ucEncoderSel = 1; 654 655 switch (radeon_encoder->encoder_id) { 656 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: 657 disp_data.v2.acConfig.ucTransmitterSel = 0; 658 num = 0; 659 break; 660 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: 661 disp_data.v2.acConfig.ucTransmitterSel = 1; 662 num = 1; 663 break; 664 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: 665 disp_data.v2.acConfig.ucTransmitterSel = 2; 666 num = 2; 667 break; 668 } 669 670 if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT)) { 671 if (radeon_output->coherent_mode) { 672 disp_data.v2.acConfig.fCoherentMode = 1; 673 xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "UNIPHY%d transmitter: Coherent Mode enabled\n",disp_data.v2.acConfig.ucTransmitterSel); 674 } else 675 xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "UNIPHY%d transmitter: Coherent Mode disabled\n",disp_data.v2.acConfig.ucTransmitterSel); 676 } 677 } else { 678 disp_data.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; 679 680 if (radeon_output->MonType == MT_DP) 681 disp_data.v1.usPixelClock = 682 cpu_to_le16(dp_link_clock_for_mode_clock(clock)); 683 else 684 disp_data.v1.usPixelClock = cpu_to_le16((clock) / 10); 685 686 switch (radeon_encoder->encoder_id) { 687 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: 688 disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; 689 if (info->IsIGP) { 690 if (clock > 165000) { 691 disp_data.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | 692 ATOM_TRANSMITTER_CONFIG_LINKA_B); 693 694 if (radeon_output->igp_lane_info & 0x3) 695 disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; 696 else if (radeon_output->igp_lane_info & 0xc) 697 disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; 698 } else { 699 disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; 700 if (radeon_output->igp_lane_info & 0x1) 701 disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; 702 else if (radeon_output->igp_lane_info & 0x2) 703 disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; 704 else if (radeon_output->igp_lane_info & 0x4) 705 disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; 706 else if (radeon_output->igp_lane_info & 0x8) 707 disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; 708 } 709 } else { 710 if (clock > 165000) 711 disp_data.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | 712 ATOM_TRANSMITTER_CONFIG_LINKA_B | 713 ATOM_TRANSMITTER_CONFIG_LANE_0_7); 714 else { 715 /* XXX */ 716 if (radeon_output->linkb) 717 disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3; 718 else 719 disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; 720 } 721 } 722 break; 723 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: 724 disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; 725 if (clock > 165000) 726 disp_data.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK | 727 ATOM_TRANSMITTER_CONFIG_LINKA_B | 728 ATOM_TRANSMITTER_CONFIG_LANE_0_7); 729 else { 730 /* XXX */ 731 if (radeon_output->linkb) 732 disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3; 733 else 734 disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3; 735 } 736 break; 737 } 738 739 if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT)) { 740 if (radeon_output->coherent_mode && 741 radeon_output->MonType != MT_DP) { 742 disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; 743 xf86DrvMsg(output->scrn->scrnIndex, X_INFO, 744 "DIG%d transmitter: Coherent Mode enabled\n", num); 745 } else { 746 xf86DrvMsg(output->scrn->scrnIndex, X_INFO, 747 "DIG%d transmitter: Coherent Mode disabled\n", num); 748 } 749 } 750 } 751 752 data.exec.index = index; 753 data.exec.dataSpace = (void *)&space; 754 data.exec.pspace = &disp_data; 755 756 if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { 757 if (IS_DCE32_VARIANT) 758 ErrorF("Output UNIPHY%d transmitter setup success\n", num); 759 else 760 ErrorF("Output DIG%d transmitter setup success\n", num); 761 return ATOM_SUCCESS; 762 } 763 764 ErrorF("Output DIG%d transmitter setup failed\n", num); 765 return ATOM_NOT_IMPLEMENTED; 766 767} 768 769static void atom_rv515_force_tv_scaler(ScrnInfoPtr pScrn) 770{ 771 RADEONInfoPtr info = RADEONPTR(pScrn); 772 unsigned char *RADEONMMIO = info->MMIO; 773 774 OUTREG(0x659C,0x0); 775 OUTREG(0x6594,0x705); 776 OUTREG(0x65A4,0x10001); 777 OUTREG(0x65D8,0x0); 778 OUTREG(0x65B0,0x0); 779 OUTREG(0x65C0,0x0); 780 OUTREG(0x65D4,0x0); 781 OUTREG(0x6578,0x0); 782 OUTREG(0x657C,0x841880A8); 783 OUTREG(0x6578,0x1); 784 OUTREG(0x657C,0x84208680); 785 OUTREG(0x6578,0x2); 786 OUTREG(0x657C,0xBFF880B0); 787 OUTREG(0x6578,0x100); 788 OUTREG(0x657C,0x83D88088); 789 OUTREG(0x6578,0x101); 790 OUTREG(0x657C,0x84608680); 791 OUTREG(0x6578,0x102); 792 OUTREG(0x657C,0xBFF080D0); 793 OUTREG(0x6578,0x200); 794 OUTREG(0x657C,0x83988068); 795 OUTREG(0x6578,0x201); 796 OUTREG(0x657C,0x84A08680); 797 OUTREG(0x6578,0x202); 798 OUTREG(0x657C,0xBFF080F8); 799 OUTREG(0x6578,0x300); 800 OUTREG(0x657C,0x83588058); 801 OUTREG(0x6578,0x301); 802 OUTREG(0x657C,0x84E08660); 803 OUTREG(0x6578,0x302); 804 OUTREG(0x657C,0xBFF88120); 805 OUTREG(0x6578,0x400); 806 OUTREG(0x657C,0x83188040); 807 OUTREG(0x6578,0x401); 808 OUTREG(0x657C,0x85008660); 809 OUTREG(0x6578,0x402); 810 OUTREG(0x657C,0xBFF88150); 811 OUTREG(0x6578,0x500); 812 OUTREG(0x657C,0x82D88030); 813 OUTREG(0x6578,0x501); 814 OUTREG(0x657C,0x85408640); 815 OUTREG(0x6578,0x502); 816 OUTREG(0x657C,0xBFF88180); 817 OUTREG(0x6578,0x600); 818 OUTREG(0x657C,0x82A08018); 819 OUTREG(0x6578,0x601); 820 OUTREG(0x657C,0x85808620); 821 OUTREG(0x6578,0x602); 822 OUTREG(0x657C,0xBFF081B8); 823 OUTREG(0x6578,0x700); 824 OUTREG(0x657C,0x82608010); 825 OUTREG(0x6578,0x701); 826 OUTREG(0x657C,0x85A08600); 827 OUTREG(0x6578,0x702); 828 OUTREG(0x657C,0x800081F0); 829 OUTREG(0x6578,0x800); 830 OUTREG(0x657C,0x8228BFF8); 831 OUTREG(0x6578,0x801); 832 OUTREG(0x657C,0x85E085E0); 833 OUTREG(0x6578,0x802); 834 OUTREG(0x657C,0xBFF88228); 835 OUTREG(0x6578,0x10000); 836 OUTREG(0x657C,0x82A8BF00); 837 OUTREG(0x6578,0x10001); 838 OUTREG(0x657C,0x82A08CC0); 839 OUTREG(0x6578,0x10002); 840 OUTREG(0x657C,0x8008BEF8); 841 OUTREG(0x6578,0x10100); 842 OUTREG(0x657C,0x81F0BF28); 843 OUTREG(0x6578,0x10101); 844 OUTREG(0x657C,0x83608CA0); 845 OUTREG(0x6578,0x10102); 846 OUTREG(0x657C,0x8018BED0); 847 OUTREG(0x6578,0x10200); 848 OUTREG(0x657C,0x8148BF38); 849 OUTREG(0x6578,0x10201); 850 OUTREG(0x657C,0x84408C80); 851 OUTREG(0x6578,0x10202); 852 OUTREG(0x657C,0x8008BEB8); 853 OUTREG(0x6578,0x10300); 854 OUTREG(0x657C,0x80B0BF78); 855 OUTREG(0x6578,0x10301); 856 OUTREG(0x657C,0x85008C20); 857 OUTREG(0x6578,0x10302); 858 OUTREG(0x657C,0x8020BEA0); 859 OUTREG(0x6578,0x10400); 860 OUTREG(0x657C,0x8028BF90); 861 OUTREG(0x6578,0x10401); 862 OUTREG(0x657C,0x85E08BC0); 863 OUTREG(0x6578,0x10402); 864 OUTREG(0x657C,0x8018BE90); 865 OUTREG(0x6578,0x10500); 866 OUTREG(0x657C,0xBFB8BFB0); 867 OUTREG(0x6578,0x10501); 868 OUTREG(0x657C,0x86C08B40); 869 OUTREG(0x6578,0x10502); 870 OUTREG(0x657C,0x8010BE90); 871 OUTREG(0x6578,0x10600); 872 OUTREG(0x657C,0xBF58BFC8); 873 OUTREG(0x6578,0x10601); 874 OUTREG(0x657C,0x87A08AA0); 875 OUTREG(0x6578,0x10602); 876 OUTREG(0x657C,0x8010BE98); 877 OUTREG(0x6578,0x10700); 878 OUTREG(0x657C,0xBF10BFF0); 879 OUTREG(0x6578,0x10701); 880 OUTREG(0x657C,0x886089E0); 881 OUTREG(0x6578,0x10702); 882 OUTREG(0x657C,0x8018BEB0); 883 OUTREG(0x6578,0x10800); 884 OUTREG(0x657C,0xBED8BFE8); 885 OUTREG(0x6578,0x10801); 886 OUTREG(0x657C,0x89408940); 887 OUTREG(0x6578,0x10802); 888 OUTREG(0x657C,0xBFE8BED8); 889 OUTREG(0x6578,0x20000); 890 OUTREG(0x657C,0x80008000); 891 OUTREG(0x6578,0x20001); 892 OUTREG(0x657C,0x90008000); 893 OUTREG(0x6578,0x20002); 894 OUTREG(0x657C,0x80008000); 895 OUTREG(0x6578,0x20003); 896 OUTREG(0x657C,0x80008000); 897 OUTREG(0x6578,0x20100); 898 OUTREG(0x657C,0x80108000); 899 OUTREG(0x6578,0x20101); 900 OUTREG(0x657C,0x8FE0BF70); 901 OUTREG(0x6578,0x20102); 902 OUTREG(0x657C,0xBFE880C0); 903 OUTREG(0x6578,0x20103); 904 OUTREG(0x657C,0x80008000); 905 OUTREG(0x6578,0x20200); 906 OUTREG(0x657C,0x8018BFF8); 907 OUTREG(0x6578,0x20201); 908 OUTREG(0x657C,0x8F80BF08); 909 OUTREG(0x6578,0x20202); 910 OUTREG(0x657C,0xBFD081A0); 911 OUTREG(0x6578,0x20203); 912 OUTREG(0x657C,0xBFF88000); 913 OUTREG(0x6578,0x20300); 914 OUTREG(0x657C,0x80188000); 915 OUTREG(0x6578,0x20301); 916 OUTREG(0x657C,0x8EE0BEC0); 917 OUTREG(0x6578,0x20302); 918 OUTREG(0x657C,0xBFB082A0); 919 OUTREG(0x6578,0x20303); 920 OUTREG(0x657C,0x80008000); 921 OUTREG(0x6578,0x20400); 922 OUTREG(0x657C,0x80188000); 923 OUTREG(0x6578,0x20401); 924 OUTREG(0x657C,0x8E00BEA0); 925 OUTREG(0x6578,0x20402); 926 OUTREG(0x657C,0xBF8883C0); 927 OUTREG(0x6578,0x20403); 928 OUTREG(0x657C,0x80008000); 929 OUTREG(0x6578,0x20500); 930 OUTREG(0x657C,0x80188000); 931 OUTREG(0x6578,0x20501); 932 OUTREG(0x657C,0x8D00BE90); 933 OUTREG(0x6578,0x20502); 934 OUTREG(0x657C,0xBF588500); 935 OUTREG(0x6578,0x20503); 936 OUTREG(0x657C,0x80008008); 937 OUTREG(0x6578,0x20600); 938 OUTREG(0x657C,0x80188000); 939 OUTREG(0x6578,0x20601); 940 OUTREG(0x657C,0x8BC0BE98); 941 OUTREG(0x6578,0x20602); 942 OUTREG(0x657C,0xBF308660); 943 OUTREG(0x6578,0x20603); 944 OUTREG(0x657C,0x80008008); 945 OUTREG(0x6578,0x20700); 946 OUTREG(0x657C,0x80108000); 947 OUTREG(0x6578,0x20701); 948 OUTREG(0x657C,0x8A80BEB0); 949 OUTREG(0x6578,0x20702); 950 OUTREG(0x657C,0xBF0087C0); 951 OUTREG(0x6578,0x20703); 952 OUTREG(0x657C,0x80008008); 953 OUTREG(0x6578,0x20800); 954 OUTREG(0x657C,0x80108000); 955 OUTREG(0x6578,0x20801); 956 OUTREG(0x657C,0x8920BED0); 957 OUTREG(0x6578,0x20802); 958 OUTREG(0x657C,0xBED08920); 959 OUTREG(0x6578,0x20803); 960 OUTREG(0x657C,0x80008010); 961 OUTREG(0x6578,0x30000); 962 OUTREG(0x657C,0x90008000); 963 OUTREG(0x6578,0x30001); 964 OUTREG(0x657C,0x80008000); 965 OUTREG(0x6578,0x30100); 966 OUTREG(0x657C,0x8FE0BF90); 967 OUTREG(0x6578,0x30101); 968 OUTREG(0x657C,0xBFF880A0); 969 OUTREG(0x6578,0x30200); 970 OUTREG(0x657C,0x8F60BF40); 971 OUTREG(0x6578,0x30201); 972 OUTREG(0x657C,0xBFE88180); 973 OUTREG(0x6578,0x30300); 974 OUTREG(0x657C,0x8EC0BF00); 975 OUTREG(0x6578,0x30301); 976 OUTREG(0x657C,0xBFC88280); 977 OUTREG(0x6578,0x30400); 978 OUTREG(0x657C,0x8DE0BEE0); 979 OUTREG(0x6578,0x30401); 980 OUTREG(0x657C,0xBFA083A0); 981 OUTREG(0x6578,0x30500); 982 OUTREG(0x657C,0x8CE0BED0); 983 OUTREG(0x6578,0x30501); 984 OUTREG(0x657C,0xBF7884E0); 985 OUTREG(0x6578,0x30600); 986 OUTREG(0x657C,0x8BA0BED8); 987 OUTREG(0x6578,0x30601); 988 OUTREG(0x657C,0xBF508640); 989 OUTREG(0x6578,0x30700); 990 OUTREG(0x657C,0x8A60BEE8); 991 OUTREG(0x6578,0x30701); 992 OUTREG(0x657C,0xBF2087A0); 993 OUTREG(0x6578,0x30800); 994 OUTREG(0x657C,0x8900BF00); 995 OUTREG(0x6578,0x30801); 996 OUTREG(0x657C,0xBF008900); 997} 998 999static int 1000atombios_output_yuv_setup(xf86OutputPtr output, Bool enable) 1001{ 1002 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1003 RADEONInfoPtr info = RADEONPTR(output->scrn); 1004 RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private; 1005 ENABLE_YUV_PS_ALLOCATION disp_data; 1006 AtomBiosArgRec data; 1007 unsigned char *space; 1008 unsigned char *RADEONMMIO = info->MMIO; 1009 uint32_t temp, reg; 1010 1011 if (info->ChipFamily >= CHIP_FAMILY_R600) 1012 reg = R600_BIOS_3_SCRATCH; 1013 else 1014 reg = RADEON_BIOS_3_SCRATCH; 1015 1016 //fix up scratch reg handling 1017 temp = INREG(reg); 1018 if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) 1019 OUTREG(reg, (ATOM_S3_TV1_ACTIVE | 1020 (radeon_crtc->crtc_id << 18))); 1021 else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) 1022 OUTREG(reg, (ATOM_S3_CV_ACTIVE | 1023 (radeon_crtc->crtc_id << 24))); 1024 else 1025 OUTREG(reg, 0); 1026 1027 memset(&disp_data, 0, sizeof(disp_data)); 1028 1029 if (enable) 1030 disp_data.ucEnable = ATOM_ENABLE; 1031 disp_data.ucCRTC = radeon_crtc->crtc_id; 1032 1033 data.exec.index = GetIndexIntoMasterTable(COMMAND, EnableYUV); 1034 data.exec.dataSpace = (void *)&space; 1035 data.exec.pspace = &disp_data; 1036 1037 if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { 1038 1039 OUTREG(reg, temp); 1040 1041 ErrorF("crtc %d YUV %s setup success\n", radeon_crtc->crtc_id, enable ? "enable" : "disable"); 1042 return ATOM_SUCCESS; 1043 } 1044 1045 OUTREG(reg, temp); 1046 1047 ErrorF("crtc %d YUV %s setup failed\n", radeon_crtc->crtc_id, enable ? "enable" : "disable"); 1048 return ATOM_NOT_IMPLEMENTED; 1049 1050} 1051 1052static int 1053atombios_output_overscan_setup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode) 1054{ 1055 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1056 RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private; 1057 RADEONInfoPtr info = RADEONPTR(output->scrn); 1058 SET_CRTC_OVERSCAN_PS_ALLOCATION overscan_param; 1059 AtomBiosArgRec data; 1060 unsigned char *space; 1061 memset(&overscan_param, 0, sizeof(overscan_param)); 1062 1063 overscan_param.usOverscanRight = 0; 1064 overscan_param.usOverscanLeft = 0; 1065 overscan_param.usOverscanBottom = 0; 1066 overscan_param.usOverscanTop = 0; 1067 overscan_param.ucCRTC = radeon_crtc->crtc_id; 1068 1069 if (radeon_output->Flags & RADEON_USE_RMX) { 1070 if (radeon_output->rmx_type == RMX_FULL) { 1071 overscan_param.usOverscanRight = 0; 1072 overscan_param.usOverscanLeft = 0; 1073 overscan_param.usOverscanBottom = 0; 1074 overscan_param.usOverscanTop = 0; 1075 } else if (radeon_output->rmx_type == RMX_CENTER) { 1076 overscan_param.usOverscanTop = (adjusted_mode->CrtcVDisplay - mode->CrtcVDisplay) / 2; 1077 overscan_param.usOverscanBottom = (adjusted_mode->CrtcVDisplay - mode->CrtcVDisplay) / 2; 1078 overscan_param.usOverscanLeft = (adjusted_mode->CrtcHDisplay - mode->CrtcHDisplay) / 2; 1079 overscan_param.usOverscanRight = (adjusted_mode->CrtcHDisplay - mode->CrtcHDisplay) / 2; 1080 } else if (radeon_output->rmx_type == RMX_ASPECT) { 1081 int a1 = mode->CrtcVDisplay * adjusted_mode->CrtcHDisplay; 1082 int a2 = adjusted_mode->CrtcVDisplay * mode->CrtcHDisplay; 1083 1084 if (a1 > a2) { 1085 overscan_param.usOverscanLeft = (adjusted_mode->CrtcHDisplay - (a2 / mode->CrtcVDisplay)) / 2; 1086 overscan_param.usOverscanRight = (adjusted_mode->CrtcHDisplay - (a2 / mode->CrtcVDisplay)) / 2; 1087 } else if (a2 > a1) { 1088 overscan_param.usOverscanLeft = (adjusted_mode->CrtcVDisplay - (a1 / mode->CrtcHDisplay)) / 2; 1089 overscan_param.usOverscanRight = (adjusted_mode->CrtcVDisplay - (a1 / mode->CrtcHDisplay)) / 2; 1090 } 1091 } 1092 } 1093 1094 data.exec.index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan); 1095 data.exec.dataSpace = (void *)&space; 1096 data.exec.pspace = &overscan_param; 1097 1098 if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { 1099 ErrorF("Set CRTC %d Overscan success\n", radeon_crtc->crtc_id); 1100 return ATOM_SUCCESS ; 1101 } 1102 1103 ErrorF("Set CRTC %d Overscan failed\n", radeon_crtc->crtc_id); 1104 return ATOM_NOT_IMPLEMENTED; 1105} 1106 1107static int 1108atombios_output_scaler_setup(xf86OutputPtr output) 1109{ 1110 RADEONInfoPtr info = RADEONPTR(output->scrn); 1111 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1112 radeon_tvout_ptr tvout = &radeon_output->tvout; 1113 RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private; 1114 ENABLE_SCALER_PS_ALLOCATION disp_data; 1115 AtomBiosArgRec data; 1116 unsigned char *space; 1117 1118 if (!IS_AVIVO_VARIANT && radeon_crtc->crtc_id) 1119 return ATOM_SUCCESS; 1120 1121 memset(&disp_data, 0, sizeof(disp_data)); 1122 1123 disp_data.ucScaler = radeon_crtc->crtc_id; 1124 1125 if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { 1126 switch (tvout->tvStd) { 1127 case TV_STD_NTSC: 1128 disp_data.ucTVStandard = ATOM_TV_NTSC; 1129 break; 1130 case TV_STD_PAL: 1131 disp_data.ucTVStandard = ATOM_TV_PAL; 1132 break; 1133 case TV_STD_PAL_M: 1134 disp_data.ucTVStandard = ATOM_TV_PALM; 1135 break; 1136 case TV_STD_PAL_60: 1137 disp_data.ucTVStandard = ATOM_TV_PAL60; 1138 break; 1139 case TV_STD_NTSC_J: 1140 disp_data.ucTVStandard = ATOM_TV_NTSCJ; 1141 break; 1142 case TV_STD_SCART_PAL: 1143 disp_data.ucTVStandard = ATOM_TV_PAL; /* ??? */ 1144 break; 1145 case TV_STD_SECAM: 1146 disp_data.ucTVStandard = ATOM_TV_SECAM; 1147 break; 1148 case TV_STD_PAL_CN: 1149 disp_data.ucTVStandard = ATOM_TV_PALCN; 1150 break; 1151 default: 1152 disp_data.ucTVStandard = ATOM_TV_NTSC; 1153 break; 1154 } 1155 disp_data.ucEnable = SCALER_ENABLE_MULTITAP_MODE; 1156 ErrorF("Using TV scaler %x %x\n", disp_data.ucTVStandard, disp_data.ucEnable); 1157 } else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) { 1158 disp_data.ucTVStandard = ATOM_TV_CV; 1159 disp_data.ucEnable = SCALER_ENABLE_MULTITAP_MODE; 1160 ErrorF("Using CV scaler %x %x\n", disp_data.ucTVStandard, disp_data.ucEnable); 1161 } else if (radeon_output->Flags & RADEON_USE_RMX) { 1162 ErrorF("Using RMX\n"); 1163 if (radeon_output->rmx_type == RMX_FULL) 1164 disp_data.ucEnable = ATOM_SCALER_EXPANSION; 1165 else if (radeon_output->rmx_type == RMX_CENTER) 1166 disp_data.ucEnable = ATOM_SCALER_CENTER; 1167 else if (radeon_output->rmx_type == RMX_ASPECT) 1168 disp_data.ucEnable = ATOM_SCALER_EXPANSION; 1169 } else { 1170 ErrorF("Not using RMX\n"); 1171 if (IS_AVIVO_VARIANT) 1172 disp_data.ucEnable = ATOM_SCALER_DISABLE; 1173 else 1174 disp_data.ucEnable = ATOM_SCALER_CENTER; 1175 } 1176 1177 data.exec.index = GetIndexIntoMasterTable(COMMAND, EnableScaler); 1178 data.exec.dataSpace = (void *)&space; 1179 data.exec.pspace = &disp_data; 1180 1181 if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { 1182 if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT) 1183 && info->ChipFamily >= CHIP_FAMILY_RV515 && info->ChipFamily <= CHIP_FAMILY_RV570) { 1184 ErrorF("forcing TV scaler\n"); 1185 atom_rv515_force_tv_scaler(output->scrn); 1186 } 1187 ErrorF("scaler %d setup success\n", radeon_crtc->crtc_id); 1188 return ATOM_SUCCESS; 1189 } 1190 1191 ErrorF("scaler %d setup failed\n", radeon_crtc->crtc_id); 1192 return ATOM_NOT_IMPLEMENTED; 1193 1194} 1195 1196void 1197atombios_output_dpms(xf86OutputPtr output, int mode) 1198{ 1199 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1200 radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); 1201 RADEONInfoPtr info = RADEONPTR(output->scrn); 1202 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION disp_data; 1203 AtomBiosArgRec data; 1204 unsigned char *space; 1205 int index = 0; 1206 Bool is_dig = FALSE; 1207 1208 if (radeon_encoder == NULL) 1209 return; 1210 1211 switch (radeon_encoder->encoder_id) { 1212 case ENCODER_OBJECT_ID_INTERNAL_TMDS1: 1213 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: 1214 index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl); 1215 break; 1216 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: 1217 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: 1218 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: 1219 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: 1220 is_dig = TRUE; 1221 break; 1222 case ENCODER_OBJECT_ID_INTERNAL_DVO1: 1223 case ENCODER_OBJECT_ID_INTERNAL_DDI: 1224 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: 1225 index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); 1226 break; 1227 case ENCODER_OBJECT_ID_INTERNAL_LVDS: 1228 index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); 1229 break; 1230 case ENCODER_OBJECT_ID_INTERNAL_LVTM1: 1231 if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) 1232 index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); 1233 else 1234 index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl); 1235 break; 1236 case ENCODER_OBJECT_ID_INTERNAL_DAC1: 1237 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: 1238 if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) 1239 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); 1240 else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) 1241 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); 1242 else 1243 index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); 1244 break; 1245 case ENCODER_OBJECT_ID_INTERNAL_DAC2: 1246 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: 1247 if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) 1248 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); 1249 else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) 1250 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); 1251 else 1252 index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); 1253 break; 1254 } 1255 1256 switch (mode) { 1257 case DPMSModeOn: 1258 radeon_encoder->devices |= radeon_output->active_device; 1259 if (is_dig) 1260 atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT); 1261 else { 1262 disp_data.ucAction = ATOM_ENABLE; 1263 data.exec.index = index; 1264 data.exec.dataSpace = (void *)&space; 1265 data.exec.pspace = &disp_data; 1266 1267 if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) 1268 ErrorF("Output %s enable success\n", 1269 device_name[radeon_get_device_index(radeon_output->active_device)]); 1270 else 1271 ErrorF("Output %s enable failed\n", 1272 device_name[radeon_get_device_index(radeon_output->active_device)]); 1273 } 1274 break; 1275 case DPMSModeStandby: 1276 case DPMSModeSuspend: 1277 case DPMSModeOff: 1278 radeon_encoder->devices &= ~(radeon_output->active_device); 1279 if (!radeon_encoder->devices) { 1280 if (is_dig) 1281 atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT); 1282 else { 1283 disp_data.ucAction = ATOM_DISABLE; 1284 data.exec.index = index; 1285 data.exec.dataSpace = (void *)&space; 1286 data.exec.pspace = &disp_data; 1287 1288 if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) 1289 == ATOM_SUCCESS) 1290 ErrorF("Output %s disable success\n", 1291 device_name[radeon_get_device_index(radeon_output->active_device)]); 1292 else 1293 ErrorF("Output %s disable failed\n", 1294 device_name[radeon_get_device_index(radeon_output->active_device)]); 1295 } 1296 } 1297 break; 1298 } 1299} 1300 1301static void 1302atombios_set_output_crtc_source(xf86OutputPtr output) 1303{ 1304 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1305 RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private; 1306 RADEONInfoPtr info = RADEONPTR(output->scrn); 1307 radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); 1308 AtomBiosArgRec data; 1309 unsigned char *space; 1310 SELECT_CRTC_SOURCE_PS_ALLOCATION crtc_src_param; 1311 SELECT_CRTC_SOURCE_PARAMETERS_V2 crtc_src_param2; 1312 int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); 1313 int major, minor; 1314 1315 if (radeon_encoder == NULL) 1316 return; 1317 1318 memset(&crtc_src_param, 0, sizeof(crtc_src_param)); 1319 memset(&crtc_src_param2, 0, sizeof(crtc_src_param2)); 1320 atombios_get_command_table_version(info->atomBIOS, index, &major, &minor); 1321 1322 /*ErrorF("select crtc source table is %d %d\n", major, minor);*/ 1323 1324 switch(major) { 1325 case 1: 1326 switch(minor) { 1327 case 0: 1328 case 1: 1329 default: 1330 if (IS_AVIVO_VARIANT) 1331 crtc_src_param.ucCRTC = radeon_crtc->crtc_id; 1332 else { 1333 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) 1334 crtc_src_param.ucCRTC = radeon_crtc->crtc_id; 1335 else 1336 crtc_src_param.ucCRTC = radeon_crtc->crtc_id << 2; 1337 } 1338 switch (radeon_encoder->encoder_id) { 1339 case ENCODER_OBJECT_ID_INTERNAL_TMDS1: 1340 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: 1341 crtc_src_param.ucDevice = ATOM_DEVICE_DFP1_INDEX; 1342 break; 1343 case ENCODER_OBJECT_ID_INTERNAL_LVDS: 1344 case ENCODER_OBJECT_ID_INTERNAL_LVTM1: 1345 if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) 1346 crtc_src_param.ucDevice = ATOM_DEVICE_LCD1_INDEX; 1347 else 1348 crtc_src_param.ucDevice = ATOM_DEVICE_DFP3_INDEX; 1349 break; 1350 case ENCODER_OBJECT_ID_INTERNAL_DVO1: 1351 case ENCODER_OBJECT_ID_INTERNAL_DDI: 1352 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: 1353 crtc_src_param.ucDevice = ATOM_DEVICE_DFP2_INDEX; 1354 break; 1355 case ENCODER_OBJECT_ID_INTERNAL_DAC1: 1356 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: 1357 if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) 1358 crtc_src_param.ucDevice = ATOM_DEVICE_TV1_INDEX; 1359 else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) 1360 crtc_src_param.ucDevice = ATOM_DEVICE_CV_INDEX; 1361 else 1362 crtc_src_param.ucDevice = ATOM_DEVICE_CRT1_INDEX; 1363 break; 1364 case ENCODER_OBJECT_ID_INTERNAL_DAC2: 1365 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: 1366 if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) 1367 crtc_src_param.ucDevice = ATOM_DEVICE_TV1_INDEX; 1368 else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) 1369 crtc_src_param.ucDevice = ATOM_DEVICE_CV_INDEX; 1370 else 1371 crtc_src_param.ucDevice = ATOM_DEVICE_CRT2_INDEX; 1372 break; 1373 } 1374 data.exec.pspace = &crtc_src_param; 1375 /*ErrorF("device sourced: 0x%x\n", crtc_src_param.ucDevice);*/ 1376 break; 1377 case 2: 1378 crtc_src_param2.ucCRTC = radeon_crtc->crtc_id; 1379 crtc_src_param2.ucEncodeMode = atombios_get_encoder_mode(output); 1380 switch (radeon_encoder->encoder_id) { 1381 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: 1382 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: 1383 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: 1384 if (IS_DCE32_VARIANT) { 1385 if (radeon_crtc->crtc_id) 1386 crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; 1387 else 1388 crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; 1389 } else 1390 crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; 1391 break; 1392 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: 1393 crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; 1394 break; 1395 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: 1396 if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) 1397 crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; 1398 else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) 1399 crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; 1400 else 1401 crtc_src_param2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID; 1402 break; 1403 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: 1404 if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) 1405 crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; 1406 else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) 1407 crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; 1408 else 1409 crtc_src_param2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID; 1410 break; 1411 } 1412 data.exec.pspace = &crtc_src_param2; 1413 /*ErrorF("device sourced: 0x%x\n", crtc_src_param2.ucEncoderID);*/ 1414 break; 1415 } 1416 break; 1417 default: 1418 ErrorF("Unknown table version\n"); 1419 exit(-1); 1420 } 1421 1422 data.exec.index = index; 1423 data.exec.dataSpace = (void *)&space; 1424 1425 if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { 1426 ErrorF("Set CRTC %d Source success\n", radeon_crtc->crtc_id); 1427 return; 1428 } 1429 1430 ErrorF("Set CRTC Source failed\n"); 1431 return; 1432} 1433 1434static void 1435atombios_apply_output_quirks(xf86OutputPtr output, DisplayModePtr mode) 1436{ 1437 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1438 RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private; 1439 RADEONInfoPtr info = RADEONPTR(output->scrn); 1440 unsigned char *RADEONMMIO = info->MMIO; 1441 1442 /* Funky macbooks */ 1443 if ((info->Chipset == PCI_CHIP_RV530_71C5) && 1444 (PCI_SUB_VENDOR_ID(info->PciInfo) == 0x106b) && 1445 (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x0080)) { 1446 if (radeon_output->MonType == MT_LCD) { 1447 if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) { 1448 uint32_t lvtma_bit_depth_control = INREG(AVIVO_LVTMA_BIT_DEPTH_CONTROL); 1449 1450 lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN; 1451 lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN; 1452 1453 OUTREG(AVIVO_LVTMA_BIT_DEPTH_CONTROL, lvtma_bit_depth_control); 1454 } 1455 } 1456 } 1457 1458 /* set scaler clears this on some chips */ 1459 if (IS_AVIVO_VARIANT && (mode->Flags & V_INTERLACE)) 1460 OUTREG(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, AVIVO_D1MODE_INTERLEAVE_EN); 1461} 1462 1463void 1464atombios_output_mode_set(xf86OutputPtr output, 1465 DisplayModePtr mode, 1466 DisplayModePtr adjusted_mode) 1467{ 1468 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1469 RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private; 1470 radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output); 1471 RADEONInfoPtr info = RADEONPTR(output->scrn); 1472 if (radeon_encoder == NULL) 1473 return; 1474 1475 radeon_output->pixel_clock = adjusted_mode->Clock; 1476 radeon_output->dig_block = radeon_crtc->crtc_id; 1477 atombios_output_overscan_setup(output, mode, adjusted_mode); 1478 atombios_output_scaler_setup(output); 1479 atombios_set_output_crtc_source(output); 1480 1481 if (IS_AVIVO_VARIANT) { 1482 if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) 1483 atombios_output_yuv_setup(output, TRUE); 1484 else 1485 atombios_output_yuv_setup(output, FALSE); 1486 } 1487 1488 switch (radeon_encoder->encoder_id) { 1489 case ENCODER_OBJECT_ID_INTERNAL_TMDS1: 1490 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: 1491 case ENCODER_OBJECT_ID_INTERNAL_LVDS: 1492 case ENCODER_OBJECT_ID_INTERNAL_LVTM1: 1493 atombios_output_digital_setup(output, PANEL_ENCODER_ACTION_ENABLE); 1494 break; 1495 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: 1496 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: 1497 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: 1498 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: 1499 /* disable encoder and transmitter */ 1500 atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_DISABLE); 1501 atombios_output_dig_encoder_setup(output, ATOM_DISABLE); 1502 1503 /* setup and enable the encoder and transmitter */ 1504 atombios_output_dig_encoder_setup(output, ATOM_ENABLE); 1505 atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_SETUP); 1506 atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_ENABLE); 1507 break; 1508 case ENCODER_OBJECT_ID_INTERNAL_DDI: 1509 atombios_output_ddia_setup(output, ATOM_ENABLE); 1510 break; 1511 case ENCODER_OBJECT_ID_INTERNAL_DVO1: 1512 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: 1513 atombios_external_tmds_setup(output, ATOM_ENABLE); 1514 break; 1515 case ENCODER_OBJECT_ID_INTERNAL_DAC1: 1516 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: 1517 case ENCODER_OBJECT_ID_INTERNAL_DAC2: 1518 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: 1519 atombios_output_dac_setup(output, ATOM_ENABLE); 1520 if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) 1521 atombios_output_tv_setup(output, ATOM_ENABLE); 1522 break; 1523 } 1524 atombios_apply_output_quirks(output, adjusted_mode); 1525} 1526 1527static AtomBiosResult 1528atom_bios_dac_load_detect(atomBiosHandlePtr atomBIOS, xf86OutputPtr output) 1529{ 1530 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1531 RADEONInfoPtr info = RADEONPTR(output->scrn); 1532 DAC_LOAD_DETECTION_PS_ALLOCATION dac_data; 1533 AtomBiosArgRec data; 1534 unsigned char *space; 1535 int major, minor; 1536 int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection); 1537 1538 atombios_get_command_table_version(info->atomBIOS, index, &major, &minor); 1539 1540 dac_data.sDacload.ucMisc = 0; 1541 1542 if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) { 1543 dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT); 1544 if (info->encoders[ATOM_DEVICE_CRT1_INDEX] && 1545 ((info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) || 1546 (info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1))) 1547 dac_data.sDacload.ucDacType = ATOM_DAC_A; 1548 else 1549 dac_data.sDacload.ucDacType = ATOM_DAC_B; 1550 } else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) { 1551 dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT); 1552 if (info->encoders[ATOM_DEVICE_CRT2_INDEX] && 1553 ((info->encoders[ATOM_DEVICE_CRT2_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) || 1554 (info->encoders[ATOM_DEVICE_CRT2_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1))) 1555 dac_data.sDacload.ucDacType = ATOM_DAC_A; 1556 else 1557 dac_data.sDacload.ucDacType = ATOM_DAC_B; 1558 } else if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) { 1559 dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT); 1560 if (info->encoders[ATOM_DEVICE_CV_INDEX] && 1561 ((info->encoders[ATOM_DEVICE_CV_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) || 1562 (info->encoders[ATOM_DEVICE_CV_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1))) 1563 dac_data.sDacload.ucDacType = ATOM_DAC_A; 1564 else 1565 dac_data.sDacload.ucDacType = ATOM_DAC_B; 1566 if (minor >= 3) 1567 dac_data.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; 1568 } else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) { 1569 dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT); 1570 if (info->encoders[ATOM_DEVICE_TV1_INDEX] && 1571 ((info->encoders[ATOM_DEVICE_TV1_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) || 1572 (info->encoders[ATOM_DEVICE_TV1_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1))) 1573 dac_data.sDacload.ucDacType = ATOM_DAC_A; 1574 else 1575 dac_data.sDacload.ucDacType = ATOM_DAC_B; 1576 if (minor >= 3) 1577 dac_data.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; 1578 } else 1579 return ATOM_NOT_IMPLEMENTED; 1580 1581 data.exec.index = index; 1582 data.exec.dataSpace = (void *)&space; 1583 data.exec.pspace = &dac_data; 1584 1585 if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { 1586 ErrorF("Dac detection success\n"); 1587 return ATOM_SUCCESS ; 1588 } 1589 1590 ErrorF("DAC detection failed\n"); 1591 return ATOM_NOT_IMPLEMENTED; 1592} 1593 1594RADEONMonitorType 1595atombios_dac_detect(xf86OutputPtr output) 1596{ 1597 ScrnInfoPtr pScrn = output->scrn; 1598 RADEONInfoPtr info = RADEONPTR(pScrn); 1599 unsigned char *RADEONMMIO = info->MMIO; 1600 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1601 RADEONMonitorType MonType = MT_NONE; 1602 AtomBiosResult ret; 1603 uint32_t bios_0_scratch; 1604 1605 if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) { 1606 if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) { 1607 if (radeon_output->ConnectorType == CONNECTOR_STV) 1608 return MT_STV; 1609 else 1610 return MT_CTV; 1611 } 1612 } 1613 1614 ret = atom_bios_dac_load_detect(info->atomBIOS, output); 1615 if (ret == ATOM_SUCCESS) { 1616 if (info->ChipFamily >= CHIP_FAMILY_R600) 1617 bios_0_scratch = INREG(R600_BIOS_0_SCRATCH); 1618 else 1619 bios_0_scratch = INREG(RADEON_BIOS_0_SCRATCH); 1620 /*ErrorF("DAC connect %08X\n", (unsigned int)bios_0_scratch);*/ 1621 1622 if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) { 1623 if (bios_0_scratch & ATOM_S0_CRT1_MASK) 1624 MonType = MT_CRT; 1625 } else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) { 1626 if (bios_0_scratch & ATOM_S0_CRT2_MASK) 1627 MonType = MT_CRT; 1628 } else if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) { 1629 if (bios_0_scratch & (ATOM_S0_CV_MASK | ATOM_S0_CV_MASK_A)) 1630 MonType = MT_CV; 1631 } else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) { 1632 if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) 1633 MonType = MT_CTV; 1634 else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) 1635 MonType = MT_STV; 1636 } 1637 } 1638 1639 return MonType; 1640} 1641 1642