1209ff23fSmrg/* 2209ff23fSmrg * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and 3209ff23fSmrg * VA Linux Systems Inc., Fremont, California. 4209ff23fSmrg * 5209ff23fSmrg * All Rights Reserved. 6209ff23fSmrg * 7209ff23fSmrg * Permission is hereby granted, free of charge, to any person obtaining 8209ff23fSmrg * a copy of this software and associated documentation files (the 9209ff23fSmrg * "Software"), to deal in the Software without restriction, including 10209ff23fSmrg * without limitation on the rights to use, copy, modify, merge, 11209ff23fSmrg * publish, distribute, sublicense, and/or sell copies of the Software, 12209ff23fSmrg * and to permit persons to whom the Software is furnished to do so, 13209ff23fSmrg * subject to the following conditions: 14209ff23fSmrg * 15209ff23fSmrg * The above copyright notice and this permission notice (including the 16209ff23fSmrg * next paragraph) shall be included in all copies or substantial 17209ff23fSmrg * portions of the Software. 18209ff23fSmrg * 19209ff23fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20209ff23fSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21209ff23fSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22209ff23fSmrg * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR 23209ff23fSmrg * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24209ff23fSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25209ff23fSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26209ff23fSmrg * DEALINGS IN THE SOFTWARE. 27209ff23fSmrg */ 28209ff23fSmrg 29209ff23fSmrg#ifdef HAVE_CONFIG_H 30209ff23fSmrg#include "config.h" 31209ff23fSmrg#endif 32209ff23fSmrg 33209ff23fSmrg#include <string.h> 34209ff23fSmrg#include <stdio.h> 35ad43ddacSmrg#include <fcntl.h> 36ba58b518Smacallan#ifdef __NetBSD__ 37ba58b518Smacallan#include <sys/ioctl.h> 38ba58b518Smacallan#include <dev/ofw/openfirmio.h> 39ba58b518Smacallan#endif 40209ff23fSmrg/* X and server generic header files */ 41209ff23fSmrg#include "xf86.h" 42209ff23fSmrg#include "xf86_OSproc.h" 43209ff23fSmrg#include "vgaHW.h" 44209ff23fSmrg#include "xf86Modes.h" 45209ff23fSmrg 46209ff23fSmrg/* Driver data structures */ 47209ff23fSmrg#include "radeon.h" 48209ff23fSmrg#include "radeon_reg.h" 49209ff23fSmrg#include "radeon_macros.h" 50209ff23fSmrg#include "radeon_probe.h" 51209ff23fSmrg#include "radeon_version.h" 52209ff23fSmrg#include "radeon_tv.h" 53209ff23fSmrg#include "radeon_atombios.h" 54209ff23fSmrg 55b7e1c893Smrgconst char *encoder_name[34] = { 56b7e1c893Smrg "NONE", 57b7e1c893Smrg "INTERNAL_LVDS", 58b7e1c893Smrg "INTERNAL_TMDS1", 59b7e1c893Smrg "INTERNAL_TMDS2", 60b7e1c893Smrg "INTERNAL_DAC1", 61b7e1c893Smrg "INTERNAL_DAC2", 62b7e1c893Smrg "INTERNAL_SDVOA", 63b7e1c893Smrg "INTERNAL_SDVOB", 64b7e1c893Smrg "SI170B", 65b7e1c893Smrg "CH7303", 66b7e1c893Smrg "CH7301", 67b7e1c893Smrg "INTERNAL_DVO1", 68b7e1c893Smrg "EXTERNAL_SDVOA", 69b7e1c893Smrg "EXTERNAL_SDVOB", 70b7e1c893Smrg "TITFP513", 71b7e1c893Smrg "INTERNAL_LVTM1", 72b7e1c893Smrg "VT1623", 73b7e1c893Smrg "HDMI_SI1930", 74b7e1c893Smrg "HDMI_INTERNAL", 75b7e1c893Smrg "INTERNAL_KLDSCP_TMDS1", 76b7e1c893Smrg "INTERNAL_KLDSCP_DVO1", 77b7e1c893Smrg "INTERNAL_KLDSCP_DAC1", 78b7e1c893Smrg "INTERNAL_KLDSCP_DAC2", 79b7e1c893Smrg "SI178", 80b7e1c893Smrg "MVPU_FPGA", 81b7e1c893Smrg "INTERNAL_DDI", 82b7e1c893Smrg "VT1625", 83b7e1c893Smrg "HDMI_SI1932", 84b7e1c893Smrg "DP_AN9801", 85b7e1c893Smrg "DP_DP501", 86b7e1c893Smrg "INTERNAL_UNIPHY", 87b7e1c893Smrg "INTERNAL_KLDSCP_LVTMA", 88b7e1c893Smrg "INTERNAL_UNIPHY1", 89b7e1c893Smrg "INTERNAL_UNIPHY2", 90209ff23fSmrg}; 91209ff23fSmrg 92ad43ddacSmrgconst char *ConnectorTypeName[18] = { 93209ff23fSmrg "None", 94209ff23fSmrg "VGA", 95209ff23fSmrg "DVI-I", 96209ff23fSmrg "DVI-D", 97209ff23fSmrg "DVI-A", 98b7e1c893Smrg "S-video", 99b7e1c893Smrg "Composite", 100209ff23fSmrg "LVDS", 101209ff23fSmrg "Digital", 102209ff23fSmrg "SCART", 103209ff23fSmrg "HDMI-A", 104209ff23fSmrg "HDMI-B", 105209ff23fSmrg "Unsupported", 106209ff23fSmrg "Unsupported", 107209ff23fSmrg "DIN", 108209ff23fSmrg "DisplayPort", 109ad43ddacSmrg "eDP", 110209ff23fSmrg "Unsupported" 111209ff23fSmrg}; 112209ff23fSmrg 113209ff23fSmrgextern void atombios_output_mode_set(xf86OutputPtr output, 114209ff23fSmrg DisplayModePtr mode, 115209ff23fSmrg DisplayModePtr adjusted_mode); 116209ff23fSmrgextern void atombios_output_dpms(xf86OutputPtr output, int mode); 117b7e1c893Smrgextern RADEONMonitorType atombios_dac_detect(xf86OutputPtr output); 118b7e1c893Smrgextern AtomBiosResult 119b7e1c893Smrgatombios_lock_crtc(atomBiosHandlePtr atomBIOS, int crtc, int lock); 120209ff23fSmrgstatic void 121209ff23fSmrgradeon_bios_output_dpms(xf86OutputPtr output, int mode); 122209ff23fSmrgstatic void 123209ff23fSmrgradeon_bios_output_crtc(xf86OutputPtr output); 124209ff23fSmrgstatic void 125209ff23fSmrgradeon_bios_output_lock(xf86OutputPtr output, Bool lock); 126b13dfe66Smrgextern void 127b13dfe66Smrgatombios_pick_dig_encoder(xf86OutputPtr output); 128209ff23fSmrg 129209ff23fSmrgvoid RADEONPrintPortMap(ScrnInfoPtr pScrn) 130209ff23fSmrg{ 131b7e1c893Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 132209ff23fSmrg xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 133209ff23fSmrg RADEONOutputPrivatePtr radeon_output; 134209ff23fSmrg xf86OutputPtr output; 135209ff23fSmrg int o; 136209ff23fSmrg 137209ff23fSmrg for (o = 0; o < xf86_config->num_output; o++) { 138209ff23fSmrg output = xf86_config->output[o]; 139209ff23fSmrg radeon_output = output->driver_private; 140209ff23fSmrg 141b7e1c893Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d:\n", o); 142b7e1c893Smrg ErrorF(" XRANDR name: %s\n", output->name); 143b7e1c893Smrg ErrorF(" Connector: %s\n", ConnectorTypeName[radeon_output->ConnectorType]); 144b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) 145b7e1c893Smrg ErrorF(" CRT1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id]); 146b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) 147b7e1c893Smrg ErrorF(" CRT2: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT2_INDEX]->encoder_id]); 148b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) 149b7e1c893Smrg ErrorF(" LCD1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_LCD1_INDEX]->encoder_id]); 150b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) 151b7e1c893Smrg ErrorF(" DFP1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP1_INDEX]->encoder_id]); 152b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) 153b7e1c893Smrg ErrorF(" DFP2: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP2_INDEX]->encoder_id]); 154b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) 155b7e1c893Smrg ErrorF(" DFP3: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP3_INDEX]->encoder_id]); 156b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT) 157b7e1c893Smrg ErrorF(" DFP4: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP4_INDEX]->encoder_id]); 158b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT) 159b7e1c893Smrg ErrorF(" DFP5: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP5_INDEX]->encoder_id]); 160b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) 161b7e1c893Smrg ErrorF(" TV1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_TV1_INDEX]->encoder_id]); 162b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) 163ad43ddacSmrg ErrorF(" CV: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CV_INDEX]->encoder_id]); 164b7e1c893Smrg ErrorF(" DDC reg: 0x%x\n",(unsigned int)radeon_output->ddc_i2c.mask_clk_reg); 165209ff23fSmrg } 166209ff23fSmrg 167209ff23fSmrg} 168209ff23fSmrg 169b7e1c893Smrgstatic void 170b7e1c893Smrgradeon_set_active_device(xf86OutputPtr output) 171209ff23fSmrg{ 172209ff23fSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 173209ff23fSmrg 174b7e1c893Smrg radeon_output->active_device = 0; 175b7e1c893Smrg 176b7e1c893Smrg switch (radeon_output->MonType) { 177b7e1c893Smrg case MT_DP: 178b7e1c893Smrg case MT_DFP: 179b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) 180b7e1c893Smrg radeon_output->active_device = ATOM_DEVICE_DFP1_SUPPORT; 181b7e1c893Smrg else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) 182b7e1c893Smrg radeon_output->active_device = ATOM_DEVICE_DFP2_SUPPORT; 183b7e1c893Smrg else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) 184b7e1c893Smrg radeon_output->active_device = ATOM_DEVICE_DFP3_SUPPORT; 185b7e1c893Smrg else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT) 186b7e1c893Smrg radeon_output->active_device = ATOM_DEVICE_DFP4_SUPPORT; 187b7e1c893Smrg else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT) 188b7e1c893Smrg radeon_output->active_device = ATOM_DEVICE_DFP5_SUPPORT; 189ad43ddacSmrg else if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) 190ad43ddacSmrg radeon_output->active_device = ATOM_DEVICE_LCD1_SUPPORT; 191ad43ddacSmrg else if (radeon_output->devices & ATOM_DEVICE_LCD2_SUPPORT) 192ad43ddacSmrg radeon_output->active_device = ATOM_DEVICE_LCD2_SUPPORT; 193b7e1c893Smrg break; 194b7e1c893Smrg case MT_CRT: 195b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) 196b7e1c893Smrg radeon_output->active_device = ATOM_DEVICE_CRT1_SUPPORT; 197b7e1c893Smrg else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) 198b7e1c893Smrg radeon_output->active_device = ATOM_DEVICE_CRT2_SUPPORT; 199b7e1c893Smrg break; 200b7e1c893Smrg case MT_LCD: 201b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) 202b7e1c893Smrg radeon_output->active_device = ATOM_DEVICE_LCD1_SUPPORT; 203b7e1c893Smrg else if (radeon_output->devices & ATOM_DEVICE_LCD2_SUPPORT) 204b7e1c893Smrg radeon_output->active_device = ATOM_DEVICE_LCD2_SUPPORT; 205b7e1c893Smrg break; 206b7e1c893Smrg case MT_STV: 207b7e1c893Smrg case MT_CTV: 208b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) 209b7e1c893Smrg radeon_output->active_device = ATOM_DEVICE_TV1_SUPPORT; 210b7e1c893Smrg else if (radeon_output->devices & ATOM_DEVICE_TV2_SUPPORT) 211b7e1c893Smrg radeon_output->active_device = ATOM_DEVICE_TV2_SUPPORT; 212b7e1c893Smrg break; 213b7e1c893Smrg case MT_CV: 214b7e1c893Smrg if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) 215b7e1c893Smrg radeon_output->active_device = ATOM_DEVICE_CV_SUPPORT; 216b7e1c893Smrg break; 217b7e1c893Smrg default: 218b7e1c893Smrg ErrorF("Unhandled monitor type %d\n", radeon_output->MonType); 219b7e1c893Smrg radeon_output->active_device = 0; 220209ff23fSmrg } 221209ff23fSmrg} 222209ff23fSmrg 223ad43ddacSmrgstatic Bool 224ad43ddacSmrgmonitor_is_digital(xf86MonPtr MonInfo) 225ad43ddacSmrg{ 226ad43ddacSmrg return (MonInfo->rawData[0x14] & 0x80) != 0; 227ad43ddacSmrg} 228ad43ddacSmrg 229ad43ddacSmrgstatic void 230ad43ddacSmrgRADEONGetHardCodedEDIDFromFile(xf86OutputPtr output) 231ad43ddacSmrg{ 232ad43ddacSmrg ScrnInfoPtr pScrn = output->scrn; 233ad43ddacSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 234ad43ddacSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 235ad43ddacSmrg char *EDIDlist = (char *)xf86GetOptValString(info->Options, OPTION_CUSTOM_EDID); 236ad43ddacSmrg 237ad43ddacSmrg radeon_output->custom_edid = FALSE; 238ad43ddacSmrg radeon_output->custom_mon = NULL; 239ad43ddacSmrg 240ad43ddacSmrg if (EDIDlist != NULL) { 241ad43ddacSmrg unsigned char* edid = xnfcalloc(128, 1); 242ad43ddacSmrg char *name = output->name; 243ad43ddacSmrg char *outputEDID = strstr(EDIDlist, name); 244ad43ddacSmrg 245ad43ddacSmrg if (outputEDID != NULL) { 246ad43ddacSmrg char *end; 247ad43ddacSmrg char *colon; 248ad43ddacSmrg char *command = NULL; 249ad43ddacSmrg int fd; 250ad43ddacSmrg 251ad43ddacSmrg outputEDID += strlen(name) + 1; 252ad43ddacSmrg end = strstr(outputEDID, ";"); 253ad43ddacSmrg if (end != NULL) 254ad43ddacSmrg *end = 0; 255ad43ddacSmrg 256ad43ddacSmrg colon = strstr(outputEDID, ":"); 257ad43ddacSmrg if (colon != NULL) { 258ad43ddacSmrg *colon = 0; 259ad43ddacSmrg command = colon + 1; 260ad43ddacSmrg } 261ad43ddacSmrg 262ad43ddacSmrg fd = open (outputEDID, O_RDONLY); 263ad43ddacSmrg if (fd >= 0) { 264ad43ddacSmrg read(fd, edid, 128); 265ad43ddacSmrg close(fd); 266ad43ddacSmrg if (edid[1] == 0xff) { 267ad43ddacSmrg radeon_output->custom_mon = xf86InterpretEDID(output->scrn->scrnIndex, edid); 268ad43ddacSmrg radeon_output->custom_edid = TRUE; 269ad43ddacSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 270ad43ddacSmrg "Successfully read Custom EDID data for output %s from %s.\n", 271ad43ddacSmrg name, outputEDID); 272ad43ddacSmrg if (command != NULL) { 273ad43ddacSmrg if (!strcmp(command, "digital")) { 274ad43ddacSmrg radeon_output->custom_mon->rawData[0x14] |= 0x80; 275ad43ddacSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 276ad43ddacSmrg "Forcing digital output for output %s.\n", name); 277ad43ddacSmrg } else if (!strcmp(command, "analog")) { 278ad43ddacSmrg radeon_output->custom_mon->rawData[0x14] &= ~0x80; 279ad43ddacSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 280ad43ddacSmrg "Forcing analog output for output %s.\n", name); 281ad43ddacSmrg } else { 282ad43ddacSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 283ad43ddacSmrg "Unknown custom EDID command: '%s'.\n", 284ad43ddacSmrg command); 285ad43ddacSmrg } 286ad43ddacSmrg } 287ad43ddacSmrg } else { 288ad43ddacSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 289ad43ddacSmrg "Custom EDID data for %s read from %s was invalid.\n", 290ad43ddacSmrg name, outputEDID); 291ad43ddacSmrg } 292ad43ddacSmrg } else { 293ad43ddacSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 294ad43ddacSmrg "Could not read custom EDID for output %s from file %s.\n", 295ad43ddacSmrg name, outputEDID); 296ad43ddacSmrg } 297ad43ddacSmrg } else { 298ad43ddacSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 299ad43ddacSmrg "Could not find EDID file name for output %s; using auto detection.\n", 300ad43ddacSmrg name); 301ad43ddacSmrg } 302ad43ddacSmrg } 303ad43ddacSmrg} 304ad43ddacSmrg 305ad43ddacSmrg 306209ff23fSmrgstatic RADEONMonitorType 307209ff23fSmrgradeon_ddc_connected(xf86OutputPtr output) 308209ff23fSmrg{ 309209ff23fSmrg ScrnInfoPtr pScrn = output->scrn; 310209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 311209ff23fSmrg RADEONMonitorType MonType = MT_NONE; 312209ff23fSmrg xf86MonPtr MonInfo = NULL; 313209ff23fSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 314ad43ddacSmrg int ret; 315ad43ddacSmrg 316ad43ddacSmrg if (radeon_output->custom_edid) { 317ad43ddacSmrg MonInfo = xnfcalloc(sizeof(xf86Monitor), 1); 318ad43ddacSmrg *MonInfo = *radeon_output->custom_mon; 319ad43ddacSmrg } else if ((radeon_output->ConnectorType == CONNECTOR_DISPLAY_PORT) || 320ad43ddacSmrg (radeon_output->ConnectorType == CONNECTOR_EDP)) { 321ad43ddacSmrg ret = RADEON_DP_GetSinkType(output); 322ad43ddacSmrg if (ret == CONNECTOR_OBJECT_ID_DISPLAYPORT || 323ad43ddacSmrg ret == CONNECTOR_OBJECT_ID_eDP) { 324ad43ddacSmrg MonInfo = xf86OutputGetEDID(output, radeon_output->dp_pI2CBus); 325ad43ddacSmrg } 326ad43ddacSmrg if (MonInfo == NULL) { 327ad43ddacSmrg if (radeon_output->pI2CBus) { 328ad43ddacSmrg RADEONI2CDoLock(output, radeon_output->pI2CBus, TRUE); 329ad43ddacSmrg MonInfo = xf86OutputGetEDID(output, radeon_output->pI2CBus); 330ad43ddacSmrg RADEONI2CDoLock(output, radeon_output->pI2CBus, FALSE); 331ad43ddacSmrg } 332ad43ddacSmrg } 333ad43ddacSmrg } else if (radeon_output->pI2CBus) { 334c503f109Smrg if (info->get_hardcoded_edid_from_bios) 335b7e1c893Smrg MonInfo = RADEONGetHardCodedEDIDFromBIOS(output); 336c503f109Smrg if (MonInfo == NULL) { 337c503f109Smrg RADEONI2CDoLock(output, radeon_output->pI2CBus, TRUE); 338b7e1c893Smrg MonInfo = xf86OutputGetEDID(output, radeon_output->pI2CBus); 339c503f109Smrg RADEONI2CDoLock(output, radeon_output->pI2CBus, FALSE); 340b7e1c893Smrg } 341b7e1c893Smrg } 342209ff23fSmrg if (MonInfo) { 343b7e1c893Smrg switch (radeon_output->ConnectorType) { 344b7e1c893Smrg case CONNECTOR_LVDS: 345209ff23fSmrg MonType = MT_LCD; 346b7e1c893Smrg break; 347b7e1c893Smrg case CONNECTOR_DVI_D: 348b7e1c893Smrg case CONNECTOR_HDMI_TYPE_A: 349b7e1c893Smrg if (radeon_output->shared_ddc) { 350ad43ddacSmrg xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (output->scrn); 351ad43ddacSmrg int i; 352ad43ddacSmrg 353ad43ddacSmrg if (monitor_is_digital(MonInfo)) 354b7e1c893Smrg MonType = MT_DFP; 355b7e1c893Smrg else 356b7e1c893Smrg MonType = MT_NONE; 357ad43ddacSmrg 358ad43ddacSmrg for (i = 0; i < config->num_output; i++) { 359ad43ddacSmrg if (output != config->output[i]) { 360ad43ddacSmrg RADEONOutputPrivatePtr other_radeon_output = 361ad43ddacSmrg config->output[i]->driver_private; 362ad43ddacSmrg if (radeon_output->devices & other_radeon_output->devices) { 363ad43ddacSmrg#ifndef EDID_COMPLETE_RAWDATA 364ad43ddacSmrg if (radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_A) { 365ad43ddacSmrg MonType = MT_NONE; 366ad43ddacSmrg break; 367ad43ddacSmrg } 368ad43ddacSmrg#else 369ad43ddacSmrg if (xf86MonitorIsHDMI(MonInfo)) { 370ad43ddacSmrg if (radeon_output->ConnectorType == CONNECTOR_DVI_D) { 371ad43ddacSmrg MonType = MT_NONE; 372ad43ddacSmrg break; 373ad43ddacSmrg } 374ad43ddacSmrg } else { 375ad43ddacSmrg if (radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_A) { 376ad43ddacSmrg MonType = MT_NONE; 377ad43ddacSmrg break; 378ad43ddacSmrg } 379ad43ddacSmrg } 380ad43ddacSmrg#endif 381ad43ddacSmrg } 382ad43ddacSmrg } 383ad43ddacSmrg } 384b7e1c893Smrg } else 385b7e1c893Smrg MonType = MT_DFP; 386b7e1c893Smrg break; 387b7e1c893Smrg case CONNECTOR_DISPLAY_PORT: 388ad43ddacSmrg case CONNECTOR_EDP: 389b7e1c893Smrg /* 390b7e1c893Smrg * XXX wrong. need to infer based on whether we got DDC from I2C 391b7e1c893Smrg * or AUXCH. 392b7e1c893Smrg */ 393ad43ddacSmrg ret = RADEON_DP_GetSinkType(output); 394ad43ddacSmrg 395ad43ddacSmrg if ((ret == CONNECTOR_OBJECT_ID_DISPLAYPORT) || 396ad43ddacSmrg (ret == CONNECTOR_OBJECT_ID_eDP)) { 397ad43ddacSmrg MonType = MT_DP; 398ad43ddacSmrg RADEON_DP_GetDPCD(output); 399ad43ddacSmrg } else 400ad43ddacSmrg MonType = MT_DFP; 401ad43ddacSmrg break; 402ad43ddacSmrg case CONNECTOR_HDMI_TYPE_B: 403b7e1c893Smrg case CONNECTOR_DVI_I: 404ad43ddacSmrg if (monitor_is_digital(MonInfo)) 405b7e1c893Smrg MonType = MT_DFP; 406b7e1c893Smrg else 407b7e1c893Smrg MonType = MT_CRT; 408b7e1c893Smrg break; 409b7e1c893Smrg case CONNECTOR_VGA: 410b7e1c893Smrg case CONNECTOR_DVI_A: 411b7e1c893Smrg default: 412b7e1c893Smrg if (radeon_output->shared_ddc) { 413ad43ddacSmrg if (monitor_is_digital(MonInfo)) 414b7e1c893Smrg MonType = MT_NONE; 415b7e1c893Smrg else 416b7e1c893Smrg MonType = MT_CRT; 417b7e1c893Smrg } else 418b7e1c893Smrg MonType = MT_CRT; 419b7e1c893Smrg break; 420b7e1c893Smrg } 421b7e1c893Smrg 422ad43ddacSmrg if (MonType != MT_NONE) { 423b7e1c893Smrg if (!xf86ReturnOptValBool(info->Options, OPTION_IGNORE_EDID, FALSE)) 424b7e1c893Smrg xf86OutputSetEDID(output, MonInfo); 425ad43ddacSmrg } else 4262f39173dSmrg free(MonInfo); 427209ff23fSmrg } else 428209ff23fSmrg MonType = MT_NONE; 429b7e1c893Smrg 430209ff23fSmrg return MonType; 431209ff23fSmrg} 432209ff23fSmrg 433209ff23fSmrg#ifndef __powerpc__ 434209ff23fSmrg 435209ff23fSmrgstatic RADEONMonitorType 436209ff23fSmrgRADEONDetectLidStatus(ScrnInfoPtr pScrn) 437209ff23fSmrg{ 438209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 439209ff23fSmrg RADEONMonitorType MonType = MT_NONE; 440209ff23fSmrg#ifdef __linux__ 441209ff23fSmrg char lidline[50]; /* 50 should be sufficient for our purposes */ 442209ff23fSmrg FILE *f = fopen ("/proc/acpi/button/lid/LID/state", "r"); 443209ff23fSmrg 444209ff23fSmrg if (f != NULL) { 445209ff23fSmrg while (fgets(lidline, sizeof lidline, f)) { 446209ff23fSmrg if (!strncmp(lidline, "state:", strlen ("state:"))) { 447209ff23fSmrg if (strstr(lidline, "open")) { 448209ff23fSmrg fclose(f); 449209ff23fSmrg ErrorF("proc lid open\n"); 450209ff23fSmrg return MT_LCD; 451209ff23fSmrg } 452209ff23fSmrg else if (strstr(lidline, "closed")) { 453209ff23fSmrg fclose(f); 454209ff23fSmrg ErrorF("proc lid closed\n"); 455209ff23fSmrg return MT_NONE; 456209ff23fSmrg } 457209ff23fSmrg } 458209ff23fSmrg } 459209ff23fSmrg fclose(f); 460209ff23fSmrg } 461209ff23fSmrg#endif 462209ff23fSmrg 463209ff23fSmrg if (!info->IsAtomBios) { 464209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 465209ff23fSmrg 466209ff23fSmrg /* see if the lid is closed -- only works at boot */ 467209ff23fSmrg if (INREG(RADEON_BIOS_6_SCRATCH) & 0x10) 468209ff23fSmrg MonType = MT_NONE; 469209ff23fSmrg else 470209ff23fSmrg MonType = MT_LCD; 471209ff23fSmrg } else 472209ff23fSmrg MonType = MT_LCD; 473209ff23fSmrg 474209ff23fSmrg return MonType; 475209ff23fSmrg} 476209ff23fSmrg 477209ff23fSmrg#endif /* __powerpc__ */ 478209ff23fSmrg 479209ff23fSmrgstatic void 480209ff23fSmrgradeon_dpms(xf86OutputPtr output, int mode) 481209ff23fSmrg{ 482209ff23fSmrg RADEONInfoPtr info = RADEONPTR(output->scrn); 483209ff23fSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 484209ff23fSmrg 485209ff23fSmrg if ((mode == DPMSModeOn) && radeon_output->enabled) 486209ff23fSmrg return; 487209ff23fSmrg 488ad43ddacSmrg if ((mode != DPMSModeOn) && radeon_output->shared_ddc) { 489ad43ddacSmrg xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (output->scrn); 490ad43ddacSmrg int i; 491ad43ddacSmrg 492ad43ddacSmrg for (i = 0; i < config->num_output; i++) { 493ad43ddacSmrg if (output != config->output[i]) { 494ad43ddacSmrg RADEONOutputPrivatePtr other_radeon_output = 495ad43ddacSmrg config->output[i]->driver_private; 496ad43ddacSmrg if (radeon_output->devices & other_radeon_output->devices) { 497ad43ddacSmrg if (output->status == XF86OutputStatusDisconnected) 498ad43ddacSmrg return; 499ad43ddacSmrg } 500ad43ddacSmrg } 501ad43ddacSmrg } 502ad43ddacSmrg } 503ad43ddacSmrg 504b7e1c893Smrg if (IS_AVIVO_VARIANT || info->r4xx_atom) { 505209ff23fSmrg atombios_output_dpms(output, mode); 506209ff23fSmrg } else { 507209ff23fSmrg legacy_output_dpms(output, mode); 508209ff23fSmrg } 509209ff23fSmrg radeon_bios_output_dpms(output, mode); 510209ff23fSmrg 511209ff23fSmrg if (mode == DPMSModeOn) 512209ff23fSmrg radeon_output->enabled = TRUE; 513209ff23fSmrg else 514209ff23fSmrg radeon_output->enabled = FALSE; 515209ff23fSmrg 516209ff23fSmrg} 517209ff23fSmrg 518209ff23fSmrgstatic void 519209ff23fSmrgradeon_save(xf86OutputPtr output) 520209ff23fSmrg{ 521209ff23fSmrg 522209ff23fSmrg} 523209ff23fSmrg 524209ff23fSmrgstatic void 525209ff23fSmrgradeon_restore(xf86OutputPtr restore) 526209ff23fSmrg{ 527209ff23fSmrg 528209ff23fSmrg} 529209ff23fSmrg 530209ff23fSmrgstatic int 531209ff23fSmrgradeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) 532209ff23fSmrg{ 533209ff23fSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 534b7e1c893Smrg radeon_native_mode_ptr native_mode = &radeon_output->native_mode; 535209ff23fSmrg ScrnInfoPtr pScrn = output->scrn; 536209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 537209ff23fSmrg RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 538209ff23fSmrg 539209ff23fSmrg /* 540209ff23fSmrg * RN50 has effective maximum mode bandwidth of about 300MiB/s. 541209ff23fSmrg * XXX should really do this for all chips by properly computing 542209ff23fSmrg * memory bandwidth and an overhead factor. 543209ff23fSmrg */ 544209ff23fSmrg if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) { 545209ff23fSmrg if (xf86ModeBandwidth(pMode, pScrn->bitsPerPixel) > 300) 546209ff23fSmrg return MODE_BANDWIDTH; 547209ff23fSmrg } 548209ff23fSmrg 549b7e1c893Smrg if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { 550b7e1c893Smrg if (IS_AVIVO_VARIANT) 551b7e1c893Smrg return MODE_OK; 552b7e1c893Smrg else { 553b7e1c893Smrg /* FIXME: Update when more modes are added */ 554209ff23fSmrg if (pMode->HDisplay == 800 && pMode->VDisplay == 600) 555209ff23fSmrg return MODE_OK; 556209ff23fSmrg else 557209ff23fSmrg return MODE_CLOCK_RANGE; 558209ff23fSmrg } 559209ff23fSmrg } 560209ff23fSmrg 561ad43ddacSmrg /* clocks over 135 MHz have heat issues with DVI on RV100 */ 562ad43ddacSmrg if ((radeon_output->MonType == MT_DFP) && 563ad43ddacSmrg (info->ChipFamily == CHIP_FAMILY_RV100) && 564ad43ddacSmrg (pMode->Clock > 135000)) 565ad43ddacSmrg return MODE_CLOCK_HIGH; 566ad43ddacSmrg 567b7e1c893Smrg /* single link DVI check */ 568b7e1c893Smrg if (pMode->Clock > 165000 && radeon_output->MonType == MT_DFP) { 569b7e1c893Smrg /* DP->DVI converter */ 570b7e1c893Smrg if (radeon_output->ConnectorType == CONNECTOR_DISPLAY_PORT) 571b7e1c893Smrg return MODE_CLOCK_HIGH; 572b7e1c893Smrg 573ad43ddacSmrg if (radeon_output->ConnectorType == CONNECTOR_EDP) 574ad43ddacSmrg return MODE_CLOCK_HIGH; 575ad43ddacSmrg 576b7e1c893Smrg /* XXX some HDMI can do better than 165MHz on a link */ 577b7e1c893Smrg if (radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_A) 578b7e1c893Smrg return MODE_CLOCK_HIGH; 579b7e1c893Smrg 580b7e1c893Smrg /* XXX some R300 and R400 can actually do this */ 581b7e1c893Smrg if (!IS_AVIVO_VARIANT) 582b7e1c893Smrg return MODE_CLOCK_HIGH; 583b7e1c893Smrg 584b7e1c893Smrg /* XXX and some AVIVO can't */ 585b7e1c893Smrg } 586b7e1c893Smrg 587b7e1c893Smrg if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { 588209ff23fSmrg if (radeon_output->rmx_type == RMX_OFF) { 589b7e1c893Smrg if (pMode->HDisplay != native_mode->PanelXRes || 590b7e1c893Smrg pMode->VDisplay != native_mode->PanelYRes) 591209ff23fSmrg return MODE_PANEL; 592209ff23fSmrg } 593b7e1c893Smrg if (pMode->HDisplay > native_mode->PanelXRes || 594b7e1c893Smrg pMode->VDisplay > native_mode->PanelYRes) 595209ff23fSmrg return MODE_PANEL; 596209ff23fSmrg } 597209ff23fSmrg 598209ff23fSmrg return MODE_OK; 599209ff23fSmrg} 600209ff23fSmrg 601209ff23fSmrgstatic Bool 602209ff23fSmrgradeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, 603209ff23fSmrg DisplayModePtr adjusted_mode) 604209ff23fSmrg{ 605209ff23fSmrg RADEONInfoPtr info = RADEONPTR(output->scrn); 606209ff23fSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 607b7e1c893Smrg radeon_native_mode_ptr native_mode = &radeon_output->native_mode; 608ad43ddacSmrg xf86CrtcPtr crtc = output->crtc; 609ad43ddacSmrg RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; 610209ff23fSmrg 611209ff23fSmrg radeon_output->Flags &= ~RADEON_USE_RMX; 612ad43ddacSmrg radeon_crtc->scaler_enabled = FALSE; 613209ff23fSmrg 614b7e1c893Smrg /* 615b7e1c893Smrg * Refresh the Crtc values without INTERLACE_HALVE_V 616b7e1c893Smrg * Should we use output->scrn->adjustFlags like xf86RandRModeConvert() does? 617b7e1c893Smrg */ 618b7e1c893Smrg xf86SetModeCrtc(adjusted_mode, 0); 619b7e1c893Smrg 620209ff23fSmrg /* decide if we are using RMX */ 621b7e1c893Smrg if ((radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) 622209ff23fSmrg && radeon_output->rmx_type != RMX_OFF) { 623209ff23fSmrg 624209ff23fSmrg if (IS_AVIVO_VARIANT || radeon_crtc->crtc_id == 0) { 625b7e1c893Smrg if (mode->HDisplay < native_mode->PanelXRes || 626b7e1c893Smrg mode->VDisplay < native_mode->PanelYRes) { 627209ff23fSmrg radeon_output->Flags |= RADEON_USE_RMX; 628ad43ddacSmrg radeon_crtc->scaler_enabled = TRUE; 629209ff23fSmrg if (IS_AVIVO_VARIANT) { 630ad43ddacSmrg radeon_crtc->hsc = (float)mode->HDisplay / (float)native_mode->PanelXRes; 631ad43ddacSmrg radeon_crtc->vsc = (float)mode->VDisplay / (float)native_mode->PanelYRes; 632209ff23fSmrg /* set to the panel's native mode */ 633b7e1c893Smrg adjusted_mode->HDisplay = native_mode->PanelXRes; 634b7e1c893Smrg adjusted_mode->VDisplay = native_mode->PanelYRes; 635b7e1c893Smrg adjusted_mode->HTotal = native_mode->PanelXRes + native_mode->HBlank; 636b7e1c893Smrg adjusted_mode->HSyncStart = native_mode->PanelXRes + native_mode->HOverPlus; 637b7e1c893Smrg adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + native_mode->HSyncWidth; 638b7e1c893Smrg adjusted_mode->VTotal = native_mode->PanelYRes + native_mode->VBlank; 639b7e1c893Smrg adjusted_mode->VSyncStart = native_mode->PanelYRes + native_mode->VOverPlus; 640b7e1c893Smrg adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + native_mode->VSyncWidth; 641209ff23fSmrg /* update crtc values */ 642209ff23fSmrg xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); 643209ff23fSmrg /* adjust crtc values */ 644b7e1c893Smrg adjusted_mode->CrtcHDisplay = native_mode->PanelXRes; 645b7e1c893Smrg adjusted_mode->CrtcVDisplay = native_mode->PanelYRes; 646b7e1c893Smrg adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + native_mode->HBlank; 647b7e1c893Smrg adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + native_mode->HOverPlus; 648b7e1c893Smrg adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + native_mode->HSyncWidth; 649b7e1c893Smrg adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + native_mode->VBlank; 650b7e1c893Smrg adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + native_mode->VOverPlus; 651b7e1c893Smrg adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + native_mode->VSyncWidth; 652209ff23fSmrg } else { 653209ff23fSmrg /* set to the panel's native mode */ 654b7e1c893Smrg adjusted_mode->HTotal = native_mode->PanelXRes + native_mode->HBlank; 655b7e1c893Smrg adjusted_mode->HSyncStart = native_mode->PanelXRes + native_mode->HOverPlus; 656b7e1c893Smrg adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + native_mode->HSyncWidth; 657b7e1c893Smrg adjusted_mode->VTotal = native_mode->PanelYRes + native_mode->VBlank; 658b7e1c893Smrg adjusted_mode->VSyncStart = native_mode->PanelYRes + native_mode->VOverPlus; 659b7e1c893Smrg adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + native_mode->VSyncWidth; 660b7e1c893Smrg adjusted_mode->Clock = native_mode->DotClock; 661209ff23fSmrg /* update crtc values */ 662209ff23fSmrg xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); 663209ff23fSmrg /* adjust crtc values */ 664b7e1c893Smrg adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + native_mode->HBlank; 665b7e1c893Smrg adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + native_mode->HOverPlus; 666b7e1c893Smrg adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + native_mode->HSyncWidth; 667b7e1c893Smrg adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + native_mode->VBlank; 668b7e1c893Smrg adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + native_mode->VOverPlus; 669b7e1c893Smrg adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + native_mode->VSyncWidth; 670209ff23fSmrg } 671b7e1c893Smrg adjusted_mode->Clock = native_mode->DotClock; 672b7e1c893Smrg adjusted_mode->Flags = native_mode->Flags; 673209ff23fSmrg } 674209ff23fSmrg } 675209ff23fSmrg } 676209ff23fSmrg 677ad43ddacSmrg /* FIXME: vsc/hsc */ 678ad43ddacSmrg if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) { 679ad43ddacSmrg radeon_crtc->scaler_enabled = TRUE; 680ad43ddacSmrg radeon_crtc->hsc = (float)mode->HDisplay / (float)640; 681ad43ddacSmrg radeon_crtc->vsc = (float)mode->VDisplay / (float)480; 682ad43ddacSmrg } 683ad43ddacSmrg 684b7e1c893Smrg if (IS_AVIVO_VARIANT) { 685b7e1c893Smrg /* hw bug */ 686b7e1c893Smrg if ((mode->Flags & V_INTERLACE) 687b7e1c893Smrg && (adjusted_mode->CrtcVSyncStart < (adjusted_mode->CrtcVDisplay + 2))) 688b7e1c893Smrg adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + 2; 689b7e1c893Smrg } 690b7e1c893Smrg 691ad43ddacSmrg if (IS_AVIVO_VARIANT || info->r4xx_atom) { 692ad43ddacSmrg if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) { 693ad43ddacSmrg radeon_tvout_ptr tvout = &radeon_output->tvout; 694ad43ddacSmrg ScrnInfoPtr pScrn = output->scrn; 695ad43ddacSmrg 696ad43ddacSmrg if (tvout->tvStd == TV_STD_NTSC || 697ad43ddacSmrg tvout->tvStd == TV_STD_NTSC_J || 698ad43ddacSmrg tvout->tvStd == TV_STD_PAL_M) 699ad43ddacSmrg RADEONATOMGetTVTimings(pScrn, 0, adjusted_mode); 700ad43ddacSmrg else 701ad43ddacSmrg RADEONATOMGetTVTimings(pScrn, 1, adjusted_mode); 702ad43ddacSmrg } 703ad43ddacSmrg } 704ad43ddacSmrg 705ad43ddacSmrg if (((radeon_output->ConnectorType == CONNECTOR_DISPLAY_PORT) || 706ad43ddacSmrg (radeon_output->ConnectorType == CONNECTOR_EDP)) && 707ad43ddacSmrg (radeon_output->MonType == MT_DP)) { 708ad43ddacSmrg radeon_dp_mode_fixup(output, mode, adjusted_mode); 709ad43ddacSmrg } 710209ff23fSmrg return TRUE; 711209ff23fSmrg} 712209ff23fSmrg 713209ff23fSmrgstatic void 714209ff23fSmrgradeon_mode_prepare(xf86OutputPtr output) 715209ff23fSmrg{ 716c503f109Smrg RADEONInfoPtr info = RADEONPTR(output->scrn); 717c503f109Smrg xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (output->scrn); 718c503f109Smrg int o; 719c503f109Smrg 720c503f109Smrg for (o = 0; o < config->num_output; o++) { 721c503f109Smrg xf86OutputPtr loop_output = config->output[o]; 722c503f109Smrg if (loop_output == output) 723c503f109Smrg continue; 724c503f109Smrg else if (loop_output->crtc) { 725c503f109Smrg xf86CrtcPtr other_crtc = loop_output->crtc; 726c503f109Smrg RADEONCrtcPrivatePtr other_radeon_crtc = other_crtc->driver_private; 727c503f109Smrg if (other_crtc->enabled) { 728c503f109Smrg if (other_radeon_crtc->initialized) { 729c503f109Smrg radeon_crtc_dpms(other_crtc, DPMSModeOff); 730c503f109Smrg if (IS_AVIVO_VARIANT || info->r4xx_atom) 731c503f109Smrg atombios_lock_crtc(info->atomBIOS, other_radeon_crtc->crtc_id, 1); 732c503f109Smrg radeon_dpms(loop_output, DPMSModeOff); 733c503f109Smrg } 734c503f109Smrg } 735c503f109Smrg } 736c503f109Smrg } 737c503f109Smrg 738209ff23fSmrg radeon_bios_output_lock(output, TRUE); 739b13dfe66Smrg if (IS_AVIVO_VARIANT) 740b13dfe66Smrg atombios_pick_dig_encoder(output); 741209ff23fSmrg radeon_dpms(output, DPMSModeOff); 742c503f109Smrg radeon_crtc_dpms(output->crtc, DPMSModeOff); 743c503f109Smrg 7440974d292Smrg if (IS_AVIVO_VARIANT || info->r4xx_atom) 7450974d292Smrg atombios_set_output_crtc_source(output); 7460974d292Smrg 747209ff23fSmrg} 748209ff23fSmrg 749209ff23fSmrgstatic void 750209ff23fSmrgradeon_mode_set(xf86OutputPtr output, DisplayModePtr mode, 751209ff23fSmrg DisplayModePtr adjusted_mode) 752209ff23fSmrg{ 753209ff23fSmrg RADEONInfoPtr info = RADEONPTR(output->scrn); 754209ff23fSmrg 755b7e1c893Smrg if (IS_AVIVO_VARIANT || info->r4xx_atom) 756209ff23fSmrg atombios_output_mode_set(output, mode, adjusted_mode); 757209ff23fSmrg else 758209ff23fSmrg legacy_output_mode_set(output, mode, adjusted_mode); 759209ff23fSmrg radeon_bios_output_crtc(output); 760209ff23fSmrg 761209ff23fSmrg} 762209ff23fSmrg 763209ff23fSmrgstatic void 764209ff23fSmrgradeon_mode_commit(xf86OutputPtr output) 765209ff23fSmrg{ 766c503f109Smrg RADEONInfoPtr info = RADEONPTR(output->scrn); 767c503f109Smrg xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (output->scrn); 768c503f109Smrg int o; 769c503f109Smrg 770c503f109Smrg for (o = 0; o < config->num_output; o++) { 771c503f109Smrg xf86OutputPtr loop_output = config->output[o]; 772c503f109Smrg if (loop_output == output) 773c503f109Smrg continue; 774c503f109Smrg else if (loop_output->crtc) { 775c503f109Smrg xf86CrtcPtr other_crtc = loop_output->crtc; 776c503f109Smrg RADEONCrtcPrivatePtr other_radeon_crtc = other_crtc->driver_private; 777c503f109Smrg if (other_crtc->enabled) { 778c503f109Smrg if (other_radeon_crtc->initialized) { 779c503f109Smrg radeon_crtc_dpms(other_crtc, DPMSModeOn); 780c503f109Smrg if (IS_AVIVO_VARIANT || info->r4xx_atom) 781c503f109Smrg atombios_lock_crtc(info->atomBIOS, other_radeon_crtc->crtc_id, 0); 782c503f109Smrg radeon_dpms(loop_output, DPMSModeOn); 783c503f109Smrg } 784c503f109Smrg } 785c503f109Smrg } 786c503f109Smrg } 787c503f109Smrg 788209ff23fSmrg radeon_dpms(output, DPMSModeOn); 789c503f109Smrg radeon_crtc_dpms(output->crtc, DPMSModeOn); 790209ff23fSmrg radeon_bios_output_lock(output, FALSE); 791209ff23fSmrg} 792209ff23fSmrg 793209ff23fSmrgstatic void 794209ff23fSmrgradeon_bios_output_lock(xf86OutputPtr output, Bool lock) 795209ff23fSmrg{ 796209ff23fSmrg ScrnInfoPtr pScrn = output->scrn; 797209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 798209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 799209ff23fSmrg RADEONSavePtr save = info->ModeReg; 800209ff23fSmrg 801209ff23fSmrg if (info->IsAtomBios) { 802209ff23fSmrg if (lock) { 803209ff23fSmrg save->bios_6_scratch |= ATOM_S6_CRITICAL_STATE; 804209ff23fSmrg } else { 805209ff23fSmrg save->bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE; 806209ff23fSmrg } 807209ff23fSmrg } else { 808209ff23fSmrg if (lock) { 809209ff23fSmrg save->bios_6_scratch |= RADEON_DRIVER_CRITICAL; 810209ff23fSmrg } else { 811209ff23fSmrg save->bios_6_scratch &= ~RADEON_DRIVER_CRITICAL; 812209ff23fSmrg } 813209ff23fSmrg } 814209ff23fSmrg if (info->ChipFamily >= CHIP_FAMILY_R600) 815209ff23fSmrg OUTREG(R600_BIOS_6_SCRATCH, save->bios_6_scratch); 816209ff23fSmrg else 817209ff23fSmrg OUTREG(RADEON_BIOS_6_SCRATCH, save->bios_6_scratch); 818209ff23fSmrg} 819209ff23fSmrg 820209ff23fSmrgstatic void 821209ff23fSmrgradeon_bios_output_dpms(xf86OutputPtr output, int mode) 822209ff23fSmrg{ 823209ff23fSmrg ScrnInfoPtr pScrn = output->scrn; 824209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 825209ff23fSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 826209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 827209ff23fSmrg RADEONSavePtr save = info->ModeReg; 828209ff23fSmrg 829209ff23fSmrg if (info->IsAtomBios) { 830b7e1c893Smrg if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) { 831b7e1c893Smrg if (mode == DPMSModeOn) 832b7e1c893Smrg save->bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE; 833b7e1c893Smrg else 834b7e1c893Smrg save->bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE; 835b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_CV_SUPPORT) { 836b7e1c893Smrg if (mode == DPMSModeOn) 837b7e1c893Smrg save->bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE; 838b7e1c893Smrg else 839b7e1c893Smrg save->bios_2_scratch |= ATOM_S2_CV_DPMS_STATE; 840b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) { 841b7e1c893Smrg if (mode == DPMSModeOn) 842b7e1c893Smrg save->bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE; 843b7e1c893Smrg else 844b7e1c893Smrg save->bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE; 845b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) { 846b7e1c893Smrg if (mode == DPMSModeOn) 847b7e1c893Smrg save->bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE; 848b7e1c893Smrg else 849b7e1c893Smrg save->bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE; 850b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) { 851b7e1c893Smrg if (mode == DPMSModeOn) 852b7e1c893Smrg save->bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE; 853b7e1c893Smrg else 854b7e1c893Smrg save->bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE; 855b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) { 856b7e1c893Smrg if (mode == DPMSModeOn) 857b7e1c893Smrg save->bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE; 858b7e1c893Smrg else 859b7e1c893Smrg save->bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE; 860b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) { 861b7e1c893Smrg if (mode == DPMSModeOn) 862b7e1c893Smrg save->bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE; 863b7e1c893Smrg else 864b7e1c893Smrg save->bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE; 865b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_DFP3_SUPPORT) { 866b7e1c893Smrg if (mode == DPMSModeOn) 867b7e1c893Smrg save->bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE; 868b7e1c893Smrg else 869b7e1c893Smrg save->bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE; 870b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_DFP4_SUPPORT) { 871b7e1c893Smrg if (mode == DPMSModeOn) 872b7e1c893Smrg save->bios_2_scratch &= ~ATOM_S2_DFP4_DPMS_STATE; 873b7e1c893Smrg else 874b7e1c893Smrg save->bios_2_scratch |= ATOM_S2_DFP4_DPMS_STATE; 875b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_DFP5_SUPPORT) { 876b7e1c893Smrg if (mode == DPMSModeOn) 877b7e1c893Smrg save->bios_2_scratch &= ~ATOM_S2_DFP5_DPMS_STATE; 878b7e1c893Smrg else 879b7e1c893Smrg save->bios_2_scratch |= ATOM_S2_DFP5_DPMS_STATE; 880209ff23fSmrg } 881b7e1c893Smrg if (info->ChipFamily >= CHIP_FAMILY_R600) 882209ff23fSmrg OUTREG(R600_BIOS_2_SCRATCH, save->bios_2_scratch); 883b7e1c893Smrg else 884209ff23fSmrg OUTREG(RADEON_BIOS_2_SCRATCH, save->bios_2_scratch); 885209ff23fSmrg } else { 886209ff23fSmrg if (mode == DPMSModeOn) { 887209ff23fSmrg save->bios_6_scratch &= ~(RADEON_DPMS_MASK | RADEON_SCREEN_BLANKING); 888209ff23fSmrg save->bios_6_scratch |= RADEON_DPMS_ON; 889209ff23fSmrg } else { 890209ff23fSmrg save->bios_6_scratch &= ~RADEON_DPMS_MASK; 891209ff23fSmrg save->bios_6_scratch |= (RADEON_DPMS_OFF | RADEON_SCREEN_BLANKING); 892b7e1c893Smrg } 893b7e1c893Smrg if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) { 894b7e1c893Smrg if (mode == DPMSModeOn) 895b7e1c893Smrg save->bios_6_scratch |= RADEON_TV_DPMS_ON; 896b7e1c893Smrg else 897209ff23fSmrg save->bios_6_scratch &= ~RADEON_TV_DPMS_ON; 898b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) { 899b7e1c893Smrg if (mode == DPMSModeOn) 900b7e1c893Smrg save->bios_6_scratch |= RADEON_CRT_DPMS_ON; 901b7e1c893Smrg else 902209ff23fSmrg save->bios_6_scratch &= ~RADEON_CRT_DPMS_ON; 903b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) { 904b7e1c893Smrg if (mode == DPMSModeOn) 905b7e1c893Smrg save->bios_6_scratch |= RADEON_CRT_DPMS_ON; 906b7e1c893Smrg else 907b7e1c893Smrg save->bios_6_scratch &= ~RADEON_CRT_DPMS_ON; 908b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) { 909b7e1c893Smrg if (mode == DPMSModeOn) 910b7e1c893Smrg save->bios_6_scratch |= RADEON_LCD_DPMS_ON; 911b7e1c893Smrg else 912209ff23fSmrg save->bios_6_scratch &= ~RADEON_LCD_DPMS_ON; 913b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) { 914b7e1c893Smrg if (mode == DPMSModeOn) 915b7e1c893Smrg save->bios_6_scratch |= RADEON_DFP_DPMS_ON; 916b7e1c893Smrg else 917b7e1c893Smrg save->bios_6_scratch &= ~RADEON_DFP_DPMS_ON; 918b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) { 919b7e1c893Smrg if (mode == DPMSModeOn) 920b7e1c893Smrg save->bios_6_scratch |= RADEON_DFP_DPMS_ON; 921b7e1c893Smrg else 922209ff23fSmrg save->bios_6_scratch &= ~RADEON_DFP_DPMS_ON; 923209ff23fSmrg } 924209ff23fSmrg OUTREG(RADEON_BIOS_6_SCRATCH, save->bios_6_scratch); 925209ff23fSmrg } 926209ff23fSmrg} 927209ff23fSmrg 928209ff23fSmrgstatic void 929209ff23fSmrgradeon_bios_output_crtc(xf86OutputPtr output) 930209ff23fSmrg{ 931209ff23fSmrg ScrnInfoPtr pScrn = output->scrn; 932209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 933209ff23fSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 934209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 935209ff23fSmrg RADEONSavePtr save = info->ModeReg; 936209ff23fSmrg xf86CrtcPtr crtc = output->crtc; 937209ff23fSmrg RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; 938209ff23fSmrg 939ad43ddacSmrg /* no need to update crtc routing scratch regs on DCE4 */ 940ad43ddacSmrg if (IS_DCE4_VARIANT) 941ad43ddacSmrg return; 942ad43ddacSmrg 943209ff23fSmrg if (info->IsAtomBios) { 944b7e1c893Smrg if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) { 945b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE; 946b7e1c893Smrg save->bios_3_scratch |= (radeon_crtc->crtc_id << 18); 947b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_CV_SUPPORT) { 948b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE; 949b7e1c893Smrg save->bios_3_scratch |= (radeon_crtc->crtc_id << 24); 950b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) { 951b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE; 952b7e1c893Smrg save->bios_3_scratch |= (radeon_crtc->crtc_id << 16); 953b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) { 954b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE; 955b7e1c893Smrg save->bios_3_scratch |= (radeon_crtc->crtc_id << 20); 956b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) { 957b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE; 958b7e1c893Smrg save->bios_3_scratch |= (radeon_crtc->crtc_id << 17); 959b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) { 960b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE; 961b7e1c893Smrg save->bios_3_scratch |= (radeon_crtc->crtc_id << 19); 962b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) { 963b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE; 964b7e1c893Smrg save->bios_3_scratch |= (radeon_crtc->crtc_id << 23); 965b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_DFP3_SUPPORT) { 966b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE; 967b7e1c893Smrg save->bios_3_scratch |= (radeon_crtc->crtc_id << 25); 968209ff23fSmrg } 969209ff23fSmrg if (info->ChipFamily >= CHIP_FAMILY_R600) 970209ff23fSmrg OUTREG(R600_BIOS_3_SCRATCH, save->bios_3_scratch); 971209ff23fSmrg else 972209ff23fSmrg OUTREG(RADEON_BIOS_3_SCRATCH, save->bios_3_scratch); 973209ff23fSmrg } else { 974b7e1c893Smrg if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) { 975209ff23fSmrg save->bios_5_scratch &= ~RADEON_TV1_CRTC_MASK; 976209ff23fSmrg save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_TV1_CRTC_SHIFT); 977b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) { 978b7e1c893Smrg save->bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK; 979b7e1c893Smrg save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT1_CRTC_SHIFT); 980b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) { 981b7e1c893Smrg save->bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK; 982b7e1c893Smrg save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT2_CRTC_SHIFT); 983b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) { 984209ff23fSmrg save->bios_5_scratch &= ~RADEON_LCD1_CRTC_MASK; 985209ff23fSmrg save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_LCD1_CRTC_SHIFT); 986b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) { 987b7e1c893Smrg save->bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK; 988b7e1c893Smrg save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP1_CRTC_SHIFT); 989b7e1c893Smrg } else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) { 990b7e1c893Smrg save->bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK; 991b7e1c893Smrg save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP2_CRTC_SHIFT); 992209ff23fSmrg } 993209ff23fSmrg OUTREG(RADEON_BIOS_5_SCRATCH, save->bios_5_scratch); 994209ff23fSmrg } 995209ff23fSmrg} 996209ff23fSmrg 997209ff23fSmrgstatic void 998209ff23fSmrgradeon_bios_output_connected(xf86OutputPtr output, Bool connected) 999209ff23fSmrg{ 1000209ff23fSmrg ScrnInfoPtr pScrn = output->scrn; 1001209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 1002209ff23fSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 1003209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 1004209ff23fSmrg RADEONSavePtr save = info->ModeReg; 1005209ff23fSmrg 1006209ff23fSmrg if (info->IsAtomBios) { 1007b7e1c893Smrg switch (radeon_output->active_device) { 1008b7e1c893Smrg case ATOM_DEVICE_TV1_SUPPORT: 1009b7e1c893Smrg if (connected) 1010b7e1c893Smrg save->bios_3_scratch |= ATOM_S3_TV1_ACTIVE; 1011b7e1c893Smrg else { 1012b7e1c893Smrg save->bios_0_scratch &= ~ATOM_S0_TV1_MASK; 1013b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE; 1014209ff23fSmrg } 1015b7e1c893Smrg break; 1016b7e1c893Smrg case ATOM_DEVICE_CV_SUPPORT: 1017b7e1c893Smrg if (connected) 1018b7e1c893Smrg save->bios_3_scratch |= ATOM_S3_CV_ACTIVE; 1019b7e1c893Smrg else { 1020b7e1c893Smrg save->bios_0_scratch &= ~ATOM_S0_CV_MASK; 1021b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_CV_ACTIVE; 1022b7e1c893Smrg } 1023b7e1c893Smrg break; 1024b7e1c893Smrg case ATOM_DEVICE_LCD1_SUPPORT: 1025b7e1c893Smrg if (connected) { 1026b7e1c893Smrg save->bios_0_scratch |= ATOM_S0_LCD1; 1027b7e1c893Smrg save->bios_3_scratch |= ATOM_S3_LCD1_ACTIVE; 1028b7e1c893Smrg } else { 1029b7e1c893Smrg save->bios_0_scratch &= ~ATOM_S0_LCD1; 1030b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE; 1031b7e1c893Smrg } 1032b7e1c893Smrg break; 1033b7e1c893Smrg case ATOM_DEVICE_CRT1_SUPPORT: 1034b7e1c893Smrg if (connected) { 1035b7e1c893Smrg save->bios_0_scratch |= ATOM_S0_CRT1_COLOR; 1036b7e1c893Smrg save->bios_3_scratch |= ATOM_S3_CRT1_ACTIVE; 1037b7e1c893Smrg } else { 1038b7e1c893Smrg save->bios_0_scratch &= ~ATOM_S0_CRT1_MASK; 1039b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE; 1040b7e1c893Smrg } 1041b7e1c893Smrg break; 1042b7e1c893Smrg case ATOM_DEVICE_CRT2_SUPPORT: 1043b7e1c893Smrg if (connected) { 1044b7e1c893Smrg save->bios_0_scratch |= ATOM_S0_CRT2_COLOR; 1045b7e1c893Smrg save->bios_3_scratch |= ATOM_S3_CRT2_ACTIVE; 1046b7e1c893Smrg } else { 1047b7e1c893Smrg save->bios_0_scratch &= ~ATOM_S0_CRT2_MASK; 1048b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE; 1049b7e1c893Smrg } 1050b7e1c893Smrg break; 1051b7e1c893Smrg case ATOM_DEVICE_DFP1_SUPPORT: 1052b7e1c893Smrg if (connected) { 1053b7e1c893Smrg save->bios_0_scratch |= ATOM_S0_DFP1; 1054b7e1c893Smrg save->bios_3_scratch |= ATOM_S3_DFP1_ACTIVE; 1055b7e1c893Smrg } else { 1056b7e1c893Smrg save->bios_0_scratch &= ~ATOM_S0_DFP1; 1057b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE; 1058209ff23fSmrg } 1059b7e1c893Smrg break; 1060b7e1c893Smrg case ATOM_DEVICE_DFP2_SUPPORT: 1061b7e1c893Smrg if (connected) { 1062b7e1c893Smrg save->bios_0_scratch |= ATOM_S0_DFP2; 1063b7e1c893Smrg save->bios_3_scratch |= ATOM_S3_DFP2_ACTIVE; 1064b7e1c893Smrg } else { 1065b7e1c893Smrg save->bios_0_scratch &= ~ATOM_S0_DFP2; 1066b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE; 1067209ff23fSmrg } 1068b7e1c893Smrg break; 1069b7e1c893Smrg case ATOM_DEVICE_DFP3_SUPPORT: 1070b7e1c893Smrg if (connected) { 1071b7e1c893Smrg save->bios_0_scratch |= ATOM_S0_DFP3; 1072b7e1c893Smrg save->bios_3_scratch |= ATOM_S3_DFP3_ACTIVE; 1073b7e1c893Smrg } else { 1074b7e1c893Smrg save->bios_0_scratch &= ~ATOM_S0_DFP3; 1075b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE; 1076209ff23fSmrg } 1077b7e1c893Smrg break; 1078b7e1c893Smrg case ATOM_DEVICE_DFP4_SUPPORT: 1079b7e1c893Smrg if (connected) { 1080b7e1c893Smrg save->bios_0_scratch |= ATOM_S0_DFP4; 1081b7e1c893Smrg save->bios_3_scratch |= ATOM_S3_DFP4_ACTIVE; 1082b7e1c893Smrg } else { 1083b7e1c893Smrg save->bios_0_scratch &= ~ATOM_S0_DFP4; 1084b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE; 1085209ff23fSmrg } 1086b7e1c893Smrg break; 1087b7e1c893Smrg case ATOM_DEVICE_DFP5_SUPPORT: 1088b7e1c893Smrg if (connected) { 1089b7e1c893Smrg save->bios_0_scratch |= ATOM_S0_DFP5; 1090b7e1c893Smrg save->bios_3_scratch |= ATOM_S3_DFP5_ACTIVE; 1091b7e1c893Smrg } else { 1092b7e1c893Smrg save->bios_0_scratch &= ~ATOM_S0_DFP5; 1093b7e1c893Smrg save->bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE; 1094209ff23fSmrg } 1095b7e1c893Smrg break; 1096209ff23fSmrg } 1097b7e1c893Smrg if (info->ChipFamily >= CHIP_FAMILY_R600) { 1098209ff23fSmrg OUTREG(R600_BIOS_0_SCRATCH, save->bios_0_scratch); 1099b7e1c893Smrg OUTREG(R600_BIOS_3_SCRATCH, save->bios_3_scratch); 1100b7e1c893Smrg } else { 1101209ff23fSmrg OUTREG(RADEON_BIOS_0_SCRATCH, save->bios_0_scratch); 1102b7e1c893Smrg OUTREG(RADEON_BIOS_3_SCRATCH, save->bios_3_scratch); 1103b7e1c893Smrg } 1104209ff23fSmrg } else { 1105b7e1c893Smrg switch (radeon_output->active_device) { 1106b7e1c893Smrg case ATOM_DEVICE_TV1_SUPPORT: 1107b7e1c893Smrg if (connected) { 1108b7e1c893Smrg if (radeon_output->MonType == MT_STV) 1109b7e1c893Smrg save->bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO; 1110b7e1c893Smrg else if (radeon_output->MonType == MT_CTV) 1111b7e1c893Smrg save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP; 1112b7e1c893Smrg save->bios_5_scratch |= RADEON_TV1_ON; 1113b7e1c893Smrg } else { 1114b7e1c893Smrg save->bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK; 1115b7e1c893Smrg save->bios_5_scratch &= ~RADEON_TV1_ON; 1116b7e1c893Smrg } 1117b7e1c893Smrg break; 1118b7e1c893Smrg case ATOM_DEVICE_LCD1_SUPPORT: 1119b7e1c893Smrg if (connected) { 1120209ff23fSmrg save->bios_4_scratch |= RADEON_LCD1_ATTACHED; 1121b7e1c893Smrg save->bios_5_scratch |= RADEON_LCD1_ON; 1122b7e1c893Smrg } else { 1123b7e1c893Smrg save->bios_4_scratch &= ~RADEON_LCD1_ATTACHED; 1124b7e1c893Smrg save->bios_5_scratch &= ~RADEON_LCD1_ON; 1125209ff23fSmrg } 1126b7e1c893Smrg break; 1127b7e1c893Smrg case ATOM_DEVICE_CRT1_SUPPORT: 1128b7e1c893Smrg if (connected) { 1129b7e1c893Smrg save->bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR; 1130b7e1c893Smrg save->bios_5_scratch |= RADEON_CRT1_ON; 1131b7e1c893Smrg } else { 1132209ff23fSmrg save->bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK; 1133b7e1c893Smrg save->bios_5_scratch &= ~RADEON_CRT1_ON; 1134b7e1c893Smrg } 1135b7e1c893Smrg break; 1136b7e1c893Smrg case ATOM_DEVICE_CRT2_SUPPORT: 1137b7e1c893Smrg if (connected) { 1138b7e1c893Smrg save->bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR; 1139b7e1c893Smrg save->bios_5_scratch |= RADEON_CRT2_ON; 1140b7e1c893Smrg } else { 1141b7e1c893Smrg save->bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK; 1142b7e1c893Smrg save->bios_5_scratch &= ~RADEON_CRT2_ON; 1143b7e1c893Smrg } 1144b7e1c893Smrg break; 1145b7e1c893Smrg case ATOM_DEVICE_DFP1_SUPPORT: 1146b7e1c893Smrg if (connected) { 1147b7e1c893Smrg save->bios_4_scratch |= RADEON_DFP1_ATTACHED; 1148b7e1c893Smrg save->bios_5_scratch |= RADEON_DFP1_ON; 1149b7e1c893Smrg } else { 1150209ff23fSmrg save->bios_4_scratch &= ~RADEON_DFP1_ATTACHED; 1151b7e1c893Smrg save->bios_5_scratch &= ~RADEON_DFP1_ON; 1152b7e1c893Smrg } 1153b7e1c893Smrg break; 1154b7e1c893Smrg case ATOM_DEVICE_DFP2_SUPPORT: 1155b7e1c893Smrg if (connected) { 1156b7e1c893Smrg save->bios_4_scratch |= RADEON_DFP2_ATTACHED; 1157b7e1c893Smrg save->bios_5_scratch |= RADEON_DFP2_ON; 1158b7e1c893Smrg } else { 1159209ff23fSmrg save->bios_4_scratch &= ~RADEON_DFP2_ATTACHED; 1160b7e1c893Smrg save->bios_5_scratch &= ~RADEON_DFP2_ON; 1161b7e1c893Smrg } 1162b7e1c893Smrg break; 1163209ff23fSmrg } 1164209ff23fSmrg OUTREG(RADEON_BIOS_4_SCRATCH, save->bios_4_scratch); 1165b7e1c893Smrg OUTREG(RADEON_BIOS_5_SCRATCH, save->bios_5_scratch); 1166209ff23fSmrg } 1167209ff23fSmrg 1168209ff23fSmrg} 1169209ff23fSmrg 1170209ff23fSmrgstatic xf86OutputStatus 1171209ff23fSmrgradeon_detect(xf86OutputPtr output) 1172209ff23fSmrg{ 1173209ff23fSmrg ScrnInfoPtr pScrn = output->scrn; 1174209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 1175209ff23fSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 1176209ff23fSmrg Bool connected = TRUE; 1177209ff23fSmrg 1178209ff23fSmrg radeon_output->MonType = MT_UNKNOWN; 1179209ff23fSmrg radeon_bios_output_connected(output, FALSE); 1180b7e1c893Smrg radeon_output->MonType = radeon_ddc_connected(output); 1181b7e1c893Smrg if (!radeon_output->MonType) { 1182b7e1c893Smrg if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) { 1183b7e1c893Smrg if (xf86ReturnOptValBool(info->Options, OPTION_IGNORE_LID_STATUS, TRUE)) 1184b7e1c893Smrg radeon_output->MonType = MT_LCD; 1185b7e1c893Smrg else 1186b7e1c893Smrg#if defined(__powerpc__) 1187b7e1c893Smrg radeon_output->MonType = MT_LCD; 1188b7e1c893Smrg#else 1189b7e1c893Smrg radeon_output->MonType = RADEONDetectLidStatus(pScrn); 1190b7e1c893Smrg#endif 1191b7e1c893Smrg } else { 1192b7e1c893Smrg if (info->IsAtomBios) 1193b7e1c893Smrg radeon_output->MonType = atombios_dac_detect(output); 1194b7e1c893Smrg else 1195b7e1c893Smrg radeon_output->MonType = legacy_dac_detect(output); 1196b7e1c893Smrg } 1197b7e1c893Smrg } 1198b7e1c893Smrg 1199b7e1c893Smrg // if size is zero panel probably broken or not connected 1200b7e1c893Smrg if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) { 1201b7e1c893Smrg radeon_encoder_ptr radeon_encoder = info->encoders[ATOM_DEVICE_LCD1_INDEX]; 1202b7e1c893Smrg if (radeon_encoder) { 1203b7e1c893Smrg radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv; 1204b7e1c893Smrg if (lvds) { 1205b7e1c893Smrg if ((lvds->native_mode.PanelXRes == 0) || (lvds->native_mode.PanelYRes == 0)) 1206b7e1c893Smrg radeon_output->MonType = MT_NONE; 1207b7e1c893Smrg } 1208b7e1c893Smrg } 1209b7e1c893Smrg } 1210b7e1c893Smrg 1211b7e1c893Smrg 1212c503f109Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1213c503f109Smrg "Output: %s, Detected Monitor Type: %d\n", output->name, radeon_output->MonType); 1214b7e1c893Smrg if (output->MonInfo) { 1215b7e1c893Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on output: %s ----------------------\n", 1216b7e1c893Smrg output->name); 1217b7e1c893Smrg xf86PrintEDID( output->MonInfo ); 1218b7e1c893Smrg } 1219209ff23fSmrg 1220209ff23fSmrg /* nothing connected, light up some defaults so the server comes up */ 1221209ff23fSmrg if (radeon_output->MonType == MT_NONE && 1222209ff23fSmrg info->first_load_no_devices) { 1223209ff23fSmrg if (info->IsMobility) { 1224b7e1c893Smrg if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) { 1225209ff23fSmrg radeon_output->MonType = MT_LCD; 1226209ff23fSmrg info->first_load_no_devices = FALSE; 1227b7e1c893Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using LCD default\n"); 1228209ff23fSmrg } 1229209ff23fSmrg } else { 1230b7e1c893Smrg if (radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT)) { 1231209ff23fSmrg radeon_output->MonType = MT_CRT; 1232209ff23fSmrg info->first_load_no_devices = FALSE; 1233b7e1c893Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using CRT default\n"); 1234b7e1c893Smrg } else if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT)) { 1235209ff23fSmrg radeon_output->MonType = MT_DFP; 1236209ff23fSmrg info->first_load_no_devices = FALSE; 1237b7e1c893Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using DFP default\n"); 1238209ff23fSmrg } 1239209ff23fSmrg } 1240209ff23fSmrg } 1241209ff23fSmrg 1242209ff23fSmrg radeon_bios_output_connected(output, TRUE); 1243209ff23fSmrg 1244209ff23fSmrg /* set montype so users can force outputs on even if detection fails */ 1245209ff23fSmrg if (radeon_output->MonType == MT_NONE) { 1246209ff23fSmrg connected = FALSE; 1247b7e1c893Smrg switch (radeon_output->ConnectorType) { 1248b7e1c893Smrg case CONNECTOR_LVDS: 1249209ff23fSmrg radeon_output->MonType = MT_LCD; 1250b7e1c893Smrg break; 1251b7e1c893Smrg case CONNECTOR_DVI_D: 1252b7e1c893Smrg case CONNECTOR_HDMI_TYPE_A: 1253b7e1c893Smrg case CONNECTOR_HDMI_TYPE_B: 1254209ff23fSmrg radeon_output->MonType = MT_DFP; 1255b7e1c893Smrg break; 1256b7e1c893Smrg case CONNECTOR_VGA: 1257b7e1c893Smrg case CONNECTOR_DVI_A: 1258b7e1c893Smrg default: 1259209ff23fSmrg radeon_output->MonType = MT_CRT; 1260b7e1c893Smrg break; 1261b7e1c893Smrg case CONNECTOR_DVI_I: 1262209ff23fSmrg if (radeon_output->DVIType == DVI_ANALOG) 1263209ff23fSmrg radeon_output->MonType = MT_CRT; 1264209ff23fSmrg else if (radeon_output->DVIType == DVI_DIGITAL) 1265209ff23fSmrg radeon_output->MonType = MT_DFP; 1266b7e1c893Smrg break; 1267b7e1c893Smrg case CONNECTOR_STV: 1268b7e1c893Smrg radeon_output->MonType = MT_STV; 1269b7e1c893Smrg break; 1270b7e1c893Smrg case CONNECTOR_CTV: 1271b7e1c893Smrg radeon_output->MonType = MT_CTV; 1272b7e1c893Smrg break; 1273b7e1c893Smrg case CONNECTOR_DIN: 1274b7e1c893Smrg radeon_output->MonType = MT_CV; 1275b7e1c893Smrg break; 1276b7e1c893Smrg case CONNECTOR_DISPLAY_PORT: 1277ad43ddacSmrg case CONNECTOR_EDP: 1278b7e1c893Smrg radeon_output->MonType = MT_DP; 1279b7e1c893Smrg break; 1280209ff23fSmrg } 1281209ff23fSmrg } 1282209ff23fSmrg 1283b7e1c893Smrg radeon_set_active_device(output); 1284209ff23fSmrg 1285b7e1c893Smrg if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) 1286b7e1c893Smrg output->subpixel_order = SubPixelHorizontalRGB; 1287b7e1c893Smrg else 1288b7e1c893Smrg output->subpixel_order = SubPixelNone; 1289209ff23fSmrg 1290b7e1c893Smrg if (connected) 1291b7e1c893Smrg return XF86OutputStatusConnected; 1292b7e1c893Smrg else 1293b7e1c893Smrg return XF86OutputStatusDisconnected; 1294209ff23fSmrg} 1295209ff23fSmrg 1296209ff23fSmrgstatic DisplayModePtr 1297209ff23fSmrgradeon_get_modes(xf86OutputPtr output) 1298209ff23fSmrg{ 1299209ff23fSmrg DisplayModePtr modes; 1300209ff23fSmrg modes = RADEONProbeOutputModes(output); 1301209ff23fSmrg return modes; 1302209ff23fSmrg} 1303209ff23fSmrg 1304209ff23fSmrgstatic void 1305209ff23fSmrgradeon_destroy (xf86OutputPtr output) 1306209ff23fSmrg{ 1307209ff23fSmrg if (output->driver_private) 13082f39173dSmrg free(output->driver_private); 1309209ff23fSmrg} 1310209ff23fSmrg 1311209ff23fSmrgstatic void 1312209ff23fSmrgradeon_set_backlight_level(xf86OutputPtr output, int level) 1313209ff23fSmrg{ 1314209ff23fSmrg#if 0 1315209ff23fSmrg ScrnInfoPtr pScrn = output->scrn; 1316209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 1317209ff23fSmrg unsigned char * RADEONMMIO = info->MMIO; 1318209ff23fSmrg uint32_t lvds_gen_cntl; 1319209ff23fSmrg 1320209ff23fSmrg lvds_gen_cntl = INREG(RADEON_LVDS_GEN_CNTL); 1321209ff23fSmrg lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN; 1322209ff23fSmrg lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_LEVEL_MASK; 1323209ff23fSmrg lvds_gen_cntl |= (level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & RADEON_LVDS_BL_MOD_LEVEL_MASK; 1324209ff23fSmrg //usleep (radeon_output->PanelPwrDly * 1000); 1325209ff23fSmrg OUTREG(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); 1326209ff23fSmrg lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_EN; 1327209ff23fSmrg //usleep (radeon_output->PanelPwrDly * 1000); 1328209ff23fSmrg OUTREG(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); 1329209ff23fSmrg#endif 1330209ff23fSmrg} 1331209ff23fSmrg 1332209ff23fSmrgstatic Atom backlight_atom; 1333209ff23fSmrgstatic Atom tmds_pll_atom; 1334209ff23fSmrgstatic Atom rmx_atom; 1335209ff23fSmrgstatic Atom monitor_type_atom; 1336209ff23fSmrgstatic Atom load_detection_atom; 1337209ff23fSmrgstatic Atom coherent_mode_atom; 1338209ff23fSmrgstatic Atom tv_hsize_atom; 1339209ff23fSmrgstatic Atom tv_hpos_atom; 1340209ff23fSmrgstatic Atom tv_vpos_atom; 1341209ff23fSmrgstatic Atom tv_std_atom; 1342209ff23fSmrg#define RADEON_MAX_BACKLIGHT_LEVEL 255 1343209ff23fSmrg 1344209ff23fSmrgstatic void 1345209ff23fSmrgradeon_create_resources(xf86OutputPtr output) 1346209ff23fSmrg{ 1347209ff23fSmrg ScrnInfoPtr pScrn = output->scrn; 1348209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 1349209ff23fSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 1350209ff23fSmrg INT32 range[2]; 1351209ff23fSmrg int data, err; 1352209ff23fSmrg const char *s; 1353209ff23fSmrg 1354b7e1c893Smrg#if 0 1355209ff23fSmrg /* backlight control */ 1356209ff23fSmrg if (radeon_output->type == OUTPUT_LVDS) { 1357209ff23fSmrg backlight_atom = MAKE_ATOM("backlight"); 1358209ff23fSmrg 1359209ff23fSmrg range[0] = 0; 1360209ff23fSmrg range[1] = RADEON_MAX_BACKLIGHT_LEVEL; 1361209ff23fSmrg err = RRConfigureOutputProperty(output->randr_output, backlight_atom, 1362209ff23fSmrg FALSE, TRUE, FALSE, 2, range); 1363209ff23fSmrg if (err != 0) { 1364209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1365209ff23fSmrg "RRConfigureOutputProperty error, %d\n", err); 1366209ff23fSmrg } 1367209ff23fSmrg /* Set the current value of the backlight property */ 1368209ff23fSmrg //data = (info->SavedReg->lvds_gen_cntl & RADEON_LVDS_BL_MOD_LEVEL_MASK) >> RADEON_LVDS_BL_MOD_LEVEL_SHIFT; 1369209ff23fSmrg data = RADEON_MAX_BACKLIGHT_LEVEL; 1370209ff23fSmrg err = RRChangeOutputProperty(output->randr_output, backlight_atom, 1371209ff23fSmrg XA_INTEGER, 32, PropModeReplace, 1, &data, 1372209ff23fSmrg FALSE, TRUE); 1373209ff23fSmrg if (err != 0) { 1374209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1375209ff23fSmrg "RRChangeOutputProperty error, %d\n", err); 1376209ff23fSmrg } 1377209ff23fSmrg } 1378b7e1c893Smrg#endif 1379209ff23fSmrg 1380b7e1c893Smrg if (radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT | ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) { 1381209ff23fSmrg load_detection_atom = MAKE_ATOM("load_detection"); 1382209ff23fSmrg 1383209ff23fSmrg range[0] = 0; /* off */ 1384209ff23fSmrg range[1] = 1; /* on */ 1385209ff23fSmrg err = RRConfigureOutputProperty(output->randr_output, load_detection_atom, 1386209ff23fSmrg FALSE, TRUE, FALSE, 2, range); 1387209ff23fSmrg if (err != 0) { 1388209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1389209ff23fSmrg "RRConfigureOutputProperty error, %d\n", err); 1390209ff23fSmrg } 1391209ff23fSmrg 1392209ff23fSmrg if (radeon_output->load_detection) 1393b7e1c893Smrg data = 1; 1394209ff23fSmrg else 1395b7e1c893Smrg data = 0; 1396209ff23fSmrg 1397209ff23fSmrg err = RRChangeOutputProperty(output->randr_output, load_detection_atom, 1398209ff23fSmrg XA_INTEGER, 32, PropModeReplace, 1, &data, 1399209ff23fSmrg FALSE, TRUE); 1400209ff23fSmrg if (err != 0) { 1401209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1402209ff23fSmrg "RRChangeOutputProperty error, %d\n", err); 1403209ff23fSmrg } 1404209ff23fSmrg } 1405209ff23fSmrg 1406b7e1c893Smrg if (IS_AVIVO_VARIANT && (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT))) { 1407209ff23fSmrg coherent_mode_atom = MAKE_ATOM("coherent_mode"); 1408209ff23fSmrg 1409209ff23fSmrg range[0] = 0; /* off */ 1410209ff23fSmrg range[1] = 1; /* on */ 1411209ff23fSmrg err = RRConfigureOutputProperty(output->randr_output, coherent_mode_atom, 1412209ff23fSmrg FALSE, TRUE, FALSE, 2, range); 1413209ff23fSmrg if (err != 0) { 1414209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1415209ff23fSmrg "RRConfigureOutputProperty error, %d\n", err); 1416209ff23fSmrg } 1417209ff23fSmrg 1418b7e1c893Smrg data = 1; /* coherent mode on by default */ 1419209ff23fSmrg 1420209ff23fSmrg err = RRChangeOutputProperty(output->randr_output, coherent_mode_atom, 1421209ff23fSmrg XA_INTEGER, 32, PropModeReplace, 1, &data, 1422209ff23fSmrg FALSE, TRUE); 1423209ff23fSmrg if (err != 0) { 1424209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1425209ff23fSmrg "RRChangeOutputProperty error, %d\n", err); 1426209ff23fSmrg } 1427209ff23fSmrg } 1428209ff23fSmrg 1429c503f109Smrg if ((!IS_AVIVO_VARIANT) && (radeon_output->devices & (ATOM_DEVICE_DFP1_SUPPORT))) { 1430209ff23fSmrg tmds_pll_atom = MAKE_ATOM("tmds_pll"); 1431209ff23fSmrg 1432209ff23fSmrg err = RRConfigureOutputProperty(output->randr_output, tmds_pll_atom, 1433209ff23fSmrg FALSE, FALSE, FALSE, 0, NULL); 1434209ff23fSmrg if (err != 0) { 1435209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1436209ff23fSmrg "RRConfigureOutputProperty error, %d\n", err); 1437209ff23fSmrg } 1438209ff23fSmrg /* Set the current value of the property */ 1439209ff23fSmrg#if defined(__powerpc__) 1440209ff23fSmrg s = "driver"; 1441209ff23fSmrg#else 1442209ff23fSmrg s = "bios"; 1443209ff23fSmrg#endif 1444209ff23fSmrg if (xf86ReturnOptValBool(info->Options, OPTION_DEFAULT_TMDS_PLL, FALSE)) { 1445209ff23fSmrg s = "driver"; 1446209ff23fSmrg } 1447209ff23fSmrg 1448209ff23fSmrg err = RRChangeOutputProperty(output->randr_output, tmds_pll_atom, 1449209ff23fSmrg XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s, 1450209ff23fSmrg FALSE, FALSE); 1451209ff23fSmrg if (err != 0) { 1452209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1453209ff23fSmrg "RRChangeOutputProperty error, %d\n", err); 1454209ff23fSmrg } 1455209ff23fSmrg 1456209ff23fSmrg } 1457209ff23fSmrg 1458209ff23fSmrg /* RMX control - fullscreen, centered, keep ratio, off */ 1459209ff23fSmrg /* actually more of a crtc property as only crtc1 has rmx */ 1460b7e1c893Smrg if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { 1461209ff23fSmrg rmx_atom = MAKE_ATOM("scaler"); 1462209ff23fSmrg 1463209ff23fSmrg err = RRConfigureOutputProperty(output->randr_output, rmx_atom, 1464209ff23fSmrg FALSE, FALSE, FALSE, 0, NULL); 1465209ff23fSmrg if (err != 0) { 1466209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1467209ff23fSmrg "RRConfigureOutputProperty error, %d\n", err); 1468209ff23fSmrg } 1469209ff23fSmrg /* Set the current value of the property */ 1470b7e1c893Smrg switch (radeon_output->rmx_type) { 1471b7e1c893Smrg case RMX_OFF: 1472b7e1c893Smrg default: 1473209ff23fSmrg s = "off"; 1474b7e1c893Smrg break; 1475b7e1c893Smrg case RMX_FULL: 1476b7e1c893Smrg s = "full"; 1477b7e1c893Smrg break; 1478b7e1c893Smrg case RMX_CENTER: 1479b7e1c893Smrg s = "center"; 1480b7e1c893Smrg break; 1481b7e1c893Smrg case RMX_ASPECT: 1482b7e1c893Smrg s = "aspect"; 1483b7e1c893Smrg break; 1484b7e1c893Smrg } 1485209ff23fSmrg err = RRChangeOutputProperty(output->randr_output, rmx_atom, 1486209ff23fSmrg XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s, 1487209ff23fSmrg FALSE, FALSE); 1488209ff23fSmrg if (err != 0) { 1489209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1490209ff23fSmrg "RRChangeOutputProperty error, %d\n", err); 1491209ff23fSmrg } 1492209ff23fSmrg } 1493209ff23fSmrg 1494209ff23fSmrg /* force auto/analog/digital for DVI-I ports */ 1495b7e1c893Smrg if ((radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT)) && 1496b7e1c893Smrg (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT))){ 1497209ff23fSmrg monitor_type_atom = MAKE_ATOM("dvi_monitor_type"); 1498209ff23fSmrg 1499209ff23fSmrg err = RRConfigureOutputProperty(output->randr_output, monitor_type_atom, 1500209ff23fSmrg FALSE, FALSE, FALSE, 0, NULL); 1501209ff23fSmrg if (err != 0) { 1502209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1503209ff23fSmrg "RRConfigureOutputProperty error, %d\n", err); 1504209ff23fSmrg } 1505209ff23fSmrg /* Set the current value of the backlight property */ 1506209ff23fSmrg s = "auto"; 1507209ff23fSmrg err = RRChangeOutputProperty(output->randr_output, monitor_type_atom, 1508209ff23fSmrg XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s, 1509209ff23fSmrg FALSE, FALSE); 1510209ff23fSmrg if (err != 0) { 1511209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1512209ff23fSmrg "RRChangeOutputProperty error, %d\n", err); 1513209ff23fSmrg } 1514209ff23fSmrg } 1515209ff23fSmrg 1516b7e1c893Smrg if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) { 1517b7e1c893Smrg radeon_tvout_ptr tvout = &radeon_output->tvout; 1518209ff23fSmrg if (!IS_AVIVO_VARIANT) { 1519209ff23fSmrg tv_hsize_atom = MAKE_ATOM("tv_horizontal_size"); 1520209ff23fSmrg 1521209ff23fSmrg range[0] = -MAX_H_SIZE; 1522209ff23fSmrg range[1] = MAX_H_SIZE; 1523209ff23fSmrg err = RRConfigureOutputProperty(output->randr_output, tv_hsize_atom, 1524209ff23fSmrg FALSE, TRUE, FALSE, 2, range); 1525209ff23fSmrg if (err != 0) { 1526209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1527209ff23fSmrg "RRConfigureOutputProperty error, %d\n", err); 1528209ff23fSmrg } 1529209ff23fSmrg data = 0; 1530209ff23fSmrg err = RRChangeOutputProperty(output->randr_output, tv_hsize_atom, 1531209ff23fSmrg XA_INTEGER, 32, PropModeReplace, 1, &data, 1532209ff23fSmrg FALSE, TRUE); 1533209ff23fSmrg if (err != 0) { 1534209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1535209ff23fSmrg "RRChangeOutputProperty error, %d\n", err); 1536209ff23fSmrg } 1537209ff23fSmrg 1538209ff23fSmrg tv_hpos_atom = MAKE_ATOM("tv_horizontal_position"); 1539209ff23fSmrg 1540209ff23fSmrg range[0] = -MAX_H_POSITION; 1541209ff23fSmrg range[1] = MAX_H_POSITION; 1542209ff23fSmrg err = RRConfigureOutputProperty(output->randr_output, tv_hpos_atom, 1543209ff23fSmrg FALSE, TRUE, FALSE, 2, range); 1544209ff23fSmrg if (err != 0) { 1545209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1546209ff23fSmrg "RRConfigureOutputProperty error, %d\n", err); 1547209ff23fSmrg } 1548209ff23fSmrg data = 0; 1549209ff23fSmrg err = RRChangeOutputProperty(output->randr_output, tv_hpos_atom, 1550209ff23fSmrg XA_INTEGER, 32, PropModeReplace, 1, &data, 1551209ff23fSmrg FALSE, TRUE); 1552209ff23fSmrg if (err != 0) { 1553209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1554209ff23fSmrg "RRChangeOutputProperty error, %d\n", err); 1555209ff23fSmrg } 1556209ff23fSmrg 1557209ff23fSmrg tv_vpos_atom = MAKE_ATOM("tv_vertical_position"); 1558209ff23fSmrg 1559209ff23fSmrg range[0] = -MAX_V_POSITION; 1560209ff23fSmrg range[1] = MAX_V_POSITION; 1561209ff23fSmrg err = RRConfigureOutputProperty(output->randr_output, tv_vpos_atom, 1562209ff23fSmrg FALSE, TRUE, FALSE, 2, range); 1563209ff23fSmrg if (err != 0) { 1564209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1565209ff23fSmrg "RRConfigureOutputProperty error, %d\n", err); 1566209ff23fSmrg } 1567209ff23fSmrg data = 0; 1568209ff23fSmrg err = RRChangeOutputProperty(output->randr_output, tv_vpos_atom, 1569209ff23fSmrg XA_INTEGER, 32, PropModeReplace, 1, &data, 1570209ff23fSmrg FALSE, TRUE); 1571209ff23fSmrg if (err != 0) { 1572209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1573209ff23fSmrg "RRChangeOutputProperty error, %d\n", err); 1574209ff23fSmrg } 1575209ff23fSmrg } 1576209ff23fSmrg 1577209ff23fSmrg tv_std_atom = MAKE_ATOM("tv_standard"); 1578209ff23fSmrg 1579209ff23fSmrg err = RRConfigureOutputProperty(output->randr_output, tv_std_atom, 1580209ff23fSmrg FALSE, FALSE, FALSE, 0, NULL); 1581209ff23fSmrg if (err != 0) { 1582209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1583209ff23fSmrg "RRConfigureOutputProperty error, %d\n", err); 1584209ff23fSmrg } 1585209ff23fSmrg 1586209ff23fSmrg /* Set the current value of the property */ 1587b7e1c893Smrg switch (tvout->tvStd) { 1588209ff23fSmrg case TV_STD_PAL: 1589209ff23fSmrg s = "pal"; 1590209ff23fSmrg break; 1591209ff23fSmrg case TV_STD_PAL_M: 1592209ff23fSmrg s = "pal-m"; 1593209ff23fSmrg break; 1594209ff23fSmrg case TV_STD_PAL_60: 1595209ff23fSmrg s = "pal-60"; 1596209ff23fSmrg break; 1597209ff23fSmrg case TV_STD_NTSC_J: 1598209ff23fSmrg s = "ntsc-j"; 1599209ff23fSmrg break; 1600209ff23fSmrg case TV_STD_SCART_PAL: 1601209ff23fSmrg s = "scart-pal"; 1602209ff23fSmrg break; 1603209ff23fSmrg case TV_STD_NTSC: 1604209ff23fSmrg default: 1605209ff23fSmrg s = "ntsc"; 1606209ff23fSmrg break; 1607209ff23fSmrg } 1608209ff23fSmrg 1609209ff23fSmrg err = RRChangeOutputProperty(output->randr_output, tv_std_atom, 1610209ff23fSmrg XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s, 1611209ff23fSmrg FALSE, FALSE); 1612209ff23fSmrg if (err != 0) { 1613209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1614209ff23fSmrg "RRChangeOutputProperty error, %d\n", err); 1615209ff23fSmrg } 1616209ff23fSmrg } 1617209ff23fSmrg} 1618209ff23fSmrg 1619209ff23fSmrgstatic Bool 1620209ff23fSmrgradeon_set_mode_for_property(xf86OutputPtr output) 1621209ff23fSmrg{ 1622209ff23fSmrg ScrnInfoPtr pScrn = output->scrn; 1623209ff23fSmrg 1624209ff23fSmrg if (output->crtc) { 1625209ff23fSmrg xf86CrtcPtr crtc = output->crtc; 1626209ff23fSmrg 1627209ff23fSmrg if (crtc->enabled) { 1628b13dfe66Smrg#ifdef RANDR_14_INTERFACE 1629921a55d8Smrg xf86CrtcSetRec crtc_set_rec; 1630921a55d8Smrg 1631921a55d8Smrg crtc_set_rec.flags = (XF86CrtcSetMode | 1632921a55d8Smrg XF86CrtcSetOutput | 1633921a55d8Smrg XF86CrtcSetOrigin | 1634921a55d8Smrg XF86CrtcSetRotation); 1635921a55d8Smrg crtc_set_rec.mode = &crtc->desiredMode; 1636921a55d8Smrg crtc_set_rec.rotation = crtc->desiredRotation; 1637921a55d8Smrg crtc_set_rec.transform = NULL; 1638921a55d8Smrg crtc_set_rec.x = crtc->desiredX; 1639921a55d8Smrg crtc_set_rec.y = crtc->desiredY; 1640921a55d8Smrg if (!xf86CrtcSet(crtc, &crtc_set_rec)) { 1641921a55d8Smrg#else 1642209ff23fSmrg if (!xf86CrtcSetMode(crtc, &crtc->desiredMode, crtc->desiredRotation, 1643209ff23fSmrg crtc->desiredX, crtc->desiredY)) { 1644921a55d8Smrg#endif 1645209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1646b13dfe66Smrg "Failed to set mode after property change!\n"); 1647209ff23fSmrg return FALSE; 1648209ff23fSmrg } 1649209ff23fSmrg } 1650209ff23fSmrg } 1651209ff23fSmrg return TRUE; 1652209ff23fSmrg} 1653209ff23fSmrg 1654209ff23fSmrgstatic Bool 1655209ff23fSmrgradeon_set_property(xf86OutputPtr output, Atom property, 1656209ff23fSmrg RRPropertyValuePtr value) 1657209ff23fSmrg{ 1658209ff23fSmrg RADEONInfoPtr info = RADEONPTR(output->scrn); 1659209ff23fSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 1660209ff23fSmrg INT32 val; 1661209ff23fSmrg 1662209ff23fSmrg 1663209ff23fSmrg if (property == backlight_atom) { 1664209ff23fSmrg if (value->type != XA_INTEGER || 1665209ff23fSmrg value->format != 32 || 1666209ff23fSmrg value->size != 1) { 1667209ff23fSmrg return FALSE; 1668209ff23fSmrg } 1669209ff23fSmrg 1670209ff23fSmrg val = *(INT32 *)value->data; 1671209ff23fSmrg if (val < 0 || val > RADEON_MAX_BACKLIGHT_LEVEL) 1672209ff23fSmrg return FALSE; 1673209ff23fSmrg 1674209ff23fSmrg#if defined(__powerpc__) 1675209ff23fSmrg val = RADEON_MAX_BACKLIGHT_LEVEL - val; 1676209ff23fSmrg#endif 1677209ff23fSmrg 1678209ff23fSmrg radeon_set_backlight_level(output, val); 1679209ff23fSmrg 1680209ff23fSmrg } else if (property == load_detection_atom) { 1681209ff23fSmrg if (value->type != XA_INTEGER || 1682209ff23fSmrg value->format != 32 || 1683209ff23fSmrg value->size != 1) { 1684209ff23fSmrg return FALSE; 1685209ff23fSmrg } 1686209ff23fSmrg 1687209ff23fSmrg val = *(INT32 *)value->data; 1688209ff23fSmrg if (val < 0 || val > 1) 1689209ff23fSmrg return FALSE; 1690209ff23fSmrg 1691209ff23fSmrg radeon_output->load_detection = val; 1692209ff23fSmrg 1693209ff23fSmrg } else if (property == coherent_mode_atom) { 1694209ff23fSmrg Bool coherent_mode = radeon_output->coherent_mode; 1695209ff23fSmrg 1696209ff23fSmrg if (value->type != XA_INTEGER || 1697209ff23fSmrg value->format != 32 || 1698209ff23fSmrg value->size != 1) { 1699209ff23fSmrg return FALSE; 1700209ff23fSmrg } 1701209ff23fSmrg 1702209ff23fSmrg val = *(INT32 *)value->data; 1703209ff23fSmrg if (val < 0 || val > 1) 1704209ff23fSmrg return FALSE; 1705209ff23fSmrg 1706209ff23fSmrg radeon_output->coherent_mode = val; 1707209ff23fSmrg if (!radeon_set_mode_for_property(output)) { 1708209ff23fSmrg radeon_output->coherent_mode = coherent_mode; 1709209ff23fSmrg (void)radeon_set_mode_for_property(output); 1710209ff23fSmrg return FALSE; 1711209ff23fSmrg } 1712209ff23fSmrg 1713209ff23fSmrg } else if (property == rmx_atom) { 1714209ff23fSmrg const char *s; 1715209ff23fSmrg RADEONRMXType rmx = radeon_output->rmx_type; 1716209ff23fSmrg 1717209ff23fSmrg if (value->type != XA_STRING || value->format != 8) 1718209ff23fSmrg return FALSE; 1719209ff23fSmrg s = (char*)value->data; 1720209ff23fSmrg if (value->size == strlen("full") && !strncmp("full", s, strlen("full"))) { 1721209ff23fSmrg radeon_output->rmx_type = RMX_FULL; 1722209ff23fSmrg } else if (value->size == strlen("center") && !strncmp("center", s, strlen("center"))) { 1723209ff23fSmrg radeon_output->rmx_type = RMX_CENTER; 1724b7e1c893Smrg } else if (value->size == strlen("aspect") && !strncmp("aspect", s, strlen("aspect"))) { 1725b7e1c893Smrg if (IS_AVIVO_VARIANT) 1726b7e1c893Smrg radeon_output->rmx_type = RMX_ASPECT; 1727b7e1c893Smrg else 1728b7e1c893Smrg return FALSE; 1729209ff23fSmrg } else if (value->size == strlen("off") && !strncmp("off", s, strlen("off"))) { 1730209ff23fSmrg radeon_output->rmx_type = RMX_OFF; 1731209ff23fSmrg } else 1732209ff23fSmrg return FALSE; 1733209ff23fSmrg 1734209ff23fSmrg if (!radeon_set_mode_for_property(output)) { 1735209ff23fSmrg radeon_output->rmx_type = rmx; 1736209ff23fSmrg (void)radeon_set_mode_for_property(output); 1737209ff23fSmrg return FALSE; 1738209ff23fSmrg } 1739209ff23fSmrg } else if (property == tmds_pll_atom) { 1740b7e1c893Smrg radeon_tmds_ptr tmds = NULL; 1741209ff23fSmrg const char *s; 1742b7e1c893Smrg 1743b7e1c893Smrg if (info->encoders[ATOM_DEVICE_DFP1_INDEX] && info->encoders[ATOM_DEVICE_DFP1_INDEX]->dev_priv) 1744b7e1c893Smrg tmds = (radeon_tmds_ptr)info->encoders[ATOM_DEVICE_DFP1_INDEX]->dev_priv; 1745b7e1c893Smrg else 1746b7e1c893Smrg return FALSE; 1747b7e1c893Smrg 1748209ff23fSmrg if (value->type != XA_STRING || value->format != 8) 1749209ff23fSmrg return FALSE; 1750209ff23fSmrg s = (char*)value->data; 1751209ff23fSmrg if (value->size == strlen("bios") && !strncmp("bios", s, strlen("bios"))) { 1752b7e1c893Smrg if (!RADEONGetTMDSInfoFromBIOS(output->scrn, tmds)) 1753b7e1c893Smrg RADEONGetTMDSInfoFromTable(output->scrn, tmds); 1754b7e1c893Smrg } else if (value->size == strlen("driver") && !strncmp("driver", s, strlen("driver"))) 1755b7e1c893Smrg RADEONGetTMDSInfoFromTable(output->scrn, tmds); 1756b7e1c893Smrg else 1757209ff23fSmrg return FALSE; 1758209ff23fSmrg 1759209ff23fSmrg return radeon_set_mode_for_property(output); 1760209ff23fSmrg } else if (property == monitor_type_atom) { 1761209ff23fSmrg const char *s; 1762209ff23fSmrg if (value->type != XA_STRING || value->format != 8) 1763209ff23fSmrg return FALSE; 1764209ff23fSmrg s = (char*)value->data; 1765209ff23fSmrg if (value->size == strlen("auto") && !strncmp("auto", s, strlen("auto"))) { 1766209ff23fSmrg radeon_output->DVIType = DVI_AUTO; 1767209ff23fSmrg return TRUE; 1768209ff23fSmrg } else if (value->size == strlen("analog") && !strncmp("analog", s, strlen("analog"))) { 1769209ff23fSmrg radeon_output->DVIType = DVI_ANALOG; 1770209ff23fSmrg return TRUE; 1771209ff23fSmrg } else if (value->size == strlen("digital") && !strncmp("digital", s, strlen("digital"))) { 1772209ff23fSmrg radeon_output->DVIType = DVI_DIGITAL; 1773209ff23fSmrg return TRUE; 1774209ff23fSmrg } else 1775209ff23fSmrg return FALSE; 1776209ff23fSmrg } else if (property == tv_hsize_atom) { 1777b7e1c893Smrg radeon_tvout_ptr tvout = &radeon_output->tvout; 1778209ff23fSmrg if (value->type != XA_INTEGER || 1779209ff23fSmrg value->format != 32 || 1780209ff23fSmrg value->size != 1) { 1781209ff23fSmrg return FALSE; 1782209ff23fSmrg } 1783209ff23fSmrg 1784209ff23fSmrg val = *(INT32 *)value->data; 1785209ff23fSmrg if (val < -MAX_H_SIZE || val > MAX_H_SIZE) 1786209ff23fSmrg return FALSE; 1787209ff23fSmrg 1788b7e1c893Smrg tvout->hSize = val; 1789b7e1c893Smrg if (tvout->tv_on && !IS_AVIVO_VARIANT) 1790209ff23fSmrg RADEONUpdateHVPosition(output, &output->crtc->mode); 1791209ff23fSmrg 1792209ff23fSmrg } else if (property == tv_hpos_atom) { 1793b7e1c893Smrg radeon_tvout_ptr tvout = &radeon_output->tvout; 1794209ff23fSmrg if (value->type != XA_INTEGER || 1795209ff23fSmrg value->format != 32 || 1796209ff23fSmrg value->size != 1) { 1797209ff23fSmrg return FALSE; 1798209ff23fSmrg } 1799209ff23fSmrg 1800209ff23fSmrg val = *(INT32 *)value->data; 1801209ff23fSmrg if (val < -MAX_H_POSITION || val > MAX_H_POSITION) 1802209ff23fSmrg return FALSE; 1803209ff23fSmrg 1804b7e1c893Smrg tvout->hPos = val; 1805b7e1c893Smrg if (tvout->tv_on && !IS_AVIVO_VARIANT) 1806209ff23fSmrg RADEONUpdateHVPosition(output, &output->crtc->mode); 1807209ff23fSmrg 1808209ff23fSmrg } else if (property == tv_vpos_atom) { 1809b7e1c893Smrg radeon_tvout_ptr tvout = &radeon_output->tvout; 1810209ff23fSmrg if (value->type != XA_INTEGER || 1811209ff23fSmrg value->format != 32 || 1812209ff23fSmrg value->size != 1) { 1813209ff23fSmrg return FALSE; 1814209ff23fSmrg } 1815209ff23fSmrg 1816209ff23fSmrg val = *(INT32 *)value->data; 1817209ff23fSmrg if (val < -MAX_H_POSITION || val > MAX_H_POSITION) 1818209ff23fSmrg return FALSE; 1819209ff23fSmrg 1820b7e1c893Smrg tvout->vPos = val; 1821b7e1c893Smrg if (tvout->tv_on && !IS_AVIVO_VARIANT) 1822209ff23fSmrg RADEONUpdateHVPosition(output, &output->crtc->mode); 1823209ff23fSmrg 1824209ff23fSmrg } else if (property == tv_std_atom) { 1825209ff23fSmrg const char *s; 1826b7e1c893Smrg radeon_tvout_ptr tvout = &radeon_output->tvout; 1827b7e1c893Smrg TVStd std = tvout->tvStd; 1828209ff23fSmrg 1829209ff23fSmrg if (value->type != XA_STRING || value->format != 8) 1830209ff23fSmrg return FALSE; 1831209ff23fSmrg s = (char*)value->data; 1832209ff23fSmrg if (value->size == strlen("ntsc") && !strncmp("ntsc", s, strlen("ntsc"))) { 1833b7e1c893Smrg tvout->tvStd = TV_STD_NTSC; 1834209ff23fSmrg } else if (value->size == strlen("pal") && !strncmp("pal", s, strlen("pal"))) { 1835b7e1c893Smrg tvout->tvStd = TV_STD_PAL; 1836209ff23fSmrg } else if (value->size == strlen("pal-m") && !strncmp("pal-m", s, strlen("pal-m"))) { 1837b7e1c893Smrg tvout->tvStd = TV_STD_PAL_M; 1838209ff23fSmrg } else if (value->size == strlen("pal-60") && !strncmp("pal-60", s, strlen("pal-60"))) { 1839b7e1c893Smrg tvout->tvStd = TV_STD_PAL_60; 1840209ff23fSmrg } else if (value->size == strlen("ntsc-j") && !strncmp("ntsc-j", s, strlen("ntsc-j"))) { 1841b7e1c893Smrg tvout->tvStd = TV_STD_NTSC_J; 1842209ff23fSmrg } else if (value->size == strlen("scart-pal") && !strncmp("scart-pal", s, strlen("scart-pal"))) { 1843b7e1c893Smrg tvout->tvStd = TV_STD_SCART_PAL; 1844209ff23fSmrg } else if (value->size == strlen("pal-cn") && !strncmp("pal-cn", s, strlen("pal-cn"))) { 1845b7e1c893Smrg tvout->tvStd = TV_STD_PAL_CN; 1846209ff23fSmrg } else if (value->size == strlen("secam") && !strncmp("secam", s, strlen("secam"))) { 1847b7e1c893Smrg tvout->tvStd = TV_STD_SECAM; 1848209ff23fSmrg } else 1849209ff23fSmrg return FALSE; 1850209ff23fSmrg 1851209ff23fSmrg if (!radeon_set_mode_for_property(output)) { 1852b7e1c893Smrg tvout->tvStd = std; 1853209ff23fSmrg (void)radeon_set_mode_for_property(output); 1854209ff23fSmrg return FALSE; 1855209ff23fSmrg } 1856209ff23fSmrg } 1857209ff23fSmrg 1858209ff23fSmrg return TRUE; 1859209ff23fSmrg} 1860209ff23fSmrg 1861209ff23fSmrgstatic const xf86OutputFuncsRec radeon_output_funcs = { 1862209ff23fSmrg .create_resources = radeon_create_resources, 1863209ff23fSmrg .dpms = radeon_dpms, 1864209ff23fSmrg .save = radeon_save, 1865209ff23fSmrg .restore = radeon_restore, 1866209ff23fSmrg .mode_valid = radeon_mode_valid, 1867209ff23fSmrg .mode_fixup = radeon_mode_fixup, 1868209ff23fSmrg .prepare = radeon_mode_prepare, 1869209ff23fSmrg .mode_set = radeon_mode_set, 1870209ff23fSmrg .commit = radeon_mode_commit, 1871209ff23fSmrg .detect = radeon_detect, 1872209ff23fSmrg .get_modes = radeon_get_modes, 1873209ff23fSmrg .set_property = radeon_set_property, 1874209ff23fSmrg .destroy = radeon_destroy 1875209ff23fSmrg}; 1876209ff23fSmrg 1877b7e1c893SmrgBool 1878c503f109SmrgRADEONI2CDoLock(xf86OutputPtr output, I2CBusPtr b, int lock_state) 1879209ff23fSmrg{ 1880209ff23fSmrg ScrnInfoPtr pScrn = output->scrn; 1881209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 1882c503f109Smrg RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr; 1883209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 1884209ff23fSmrg uint32_t temp; 1885209ff23fSmrg 1886b7e1c893Smrg if (lock_state) { 1887c503f109Smrg /* RV410 appears to have a bug where the hw i2c in reset 1888c503f109Smrg * holds the i2c port in a bad state - switch hw i2c away before 1889c503f109Smrg * doing DDC - do this for all r200s/r300s for safety sakes */ 1890c503f109Smrg if ((info->ChipFamily >= CHIP_FAMILY_R200) && (!IS_AVIVO_VARIANT)) { 1891c503f109Smrg if (pRADEONI2CBus->mask_clk_reg == RADEON_GPIO_MONID) 1892c503f109Smrg OUTREG(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | 1893c503f109Smrg R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); 1894c503f109Smrg else 1895c503f109Smrg OUTREG(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | 1896c503f109Smrg R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); 1897c503f109Smrg } 1898c503f109Smrg 18990974d292Smrg /* set the pad in ddc mode */ 1900921a55d8Smrg if (IS_DCE3_VARIANT && 1901921a55d8Smrg pRADEONI2CBus->hw_capable) { 19020974d292Smrg temp = INREG(pRADEONI2CBus->mask_clk_reg); 19030974d292Smrg temp &= ~(1 << 16); 19040974d292Smrg OUTREG(pRADEONI2CBus->mask_clk_reg, temp); 19050974d292Smrg } 19060974d292Smrg 1907b7e1c893Smrg temp = INREG(pRADEONI2CBus->a_clk_reg); 1908b7e1c893Smrg temp &= ~(pRADEONI2CBus->a_clk_mask); 1909b7e1c893Smrg OUTREG(pRADEONI2CBus->a_clk_reg, temp); 1910b7e1c893Smrg 1911b7e1c893Smrg temp = INREG(pRADEONI2CBus->a_data_reg); 1912b7e1c893Smrg temp &= ~(pRADEONI2CBus->a_data_mask); 1913b7e1c893Smrg OUTREG(pRADEONI2CBus->a_data_reg, temp); 1914b7e1c893Smrg } 1915b7e1c893Smrg 1916209ff23fSmrg temp = INREG(pRADEONI2CBus->mask_clk_reg); 1917b7e1c893Smrg if (lock_state) 1918b7e1c893Smrg temp |= (pRADEONI2CBus->mask_clk_mask); 1919209ff23fSmrg else 1920b7e1c893Smrg temp &= ~(pRADEONI2CBus->mask_clk_mask); 1921209ff23fSmrg OUTREG(pRADEONI2CBus->mask_clk_reg, temp); 1922209ff23fSmrg temp = INREG(pRADEONI2CBus->mask_clk_reg); 1923209ff23fSmrg 1924209ff23fSmrg temp = INREG(pRADEONI2CBus->mask_data_reg); 1925b7e1c893Smrg if (lock_state) 1926b7e1c893Smrg temp |= (pRADEONI2CBus->mask_data_mask); 1927209ff23fSmrg else 1928b7e1c893Smrg temp &= ~(pRADEONI2CBus->mask_data_mask); 1929209ff23fSmrg OUTREG(pRADEONI2CBus->mask_data_reg, temp); 1930209ff23fSmrg temp = INREG(pRADEONI2CBus->mask_data_reg); 1931209ff23fSmrg 1932209ff23fSmrg return TRUE; 1933209ff23fSmrg} 1934209ff23fSmrg 1935209ff23fSmrgstatic void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data) 1936209ff23fSmrg{ 1937209ff23fSmrg ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; 1938209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 1939209ff23fSmrg unsigned long val; 1940209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 1941209ff23fSmrg RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr; 1942209ff23fSmrg 1943209ff23fSmrg /* Get the result */ 1944209ff23fSmrg val = INREG(pRADEONI2CBus->get_clk_reg); 1945209ff23fSmrg *Clock = (val & pRADEONI2CBus->get_clk_mask) != 0; 1946209ff23fSmrg val = INREG(pRADEONI2CBus->get_data_reg); 1947209ff23fSmrg *data = (val & pRADEONI2CBus->get_data_mask) != 0; 1948209ff23fSmrg 1949209ff23fSmrg} 1950209ff23fSmrg 1951209ff23fSmrgstatic void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data) 1952209ff23fSmrg{ 1953209ff23fSmrg ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; 1954209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 1955209ff23fSmrg unsigned long val; 1956209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO; 1957209ff23fSmrg RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr; 1958209ff23fSmrg 1959209ff23fSmrg val = INREG(pRADEONI2CBus->put_clk_reg) & (uint32_t)~(pRADEONI2CBus->put_clk_mask); 1960209ff23fSmrg val |= (Clock ? 0:pRADEONI2CBus->put_clk_mask); 1961209ff23fSmrg OUTREG(pRADEONI2CBus->put_clk_reg, val); 1962209ff23fSmrg /* read back to improve reliability on some cards. */ 1963209ff23fSmrg val = INREG(pRADEONI2CBus->put_clk_reg); 1964209ff23fSmrg 1965209ff23fSmrg val = INREG(pRADEONI2CBus->put_data_reg) & (uint32_t)~(pRADEONI2CBus->put_data_mask); 1966209ff23fSmrg val |= (data ? 0:pRADEONI2CBus->put_data_mask); 1967209ff23fSmrg OUTREG(pRADEONI2CBus->put_data_reg, val); 1968209ff23fSmrg /* read back to improve reliability on some cards. */ 1969209ff23fSmrg val = INREG(pRADEONI2CBus->put_data_reg); 1970209ff23fSmrg 1971209ff23fSmrg} 1972209ff23fSmrg 1973b7e1c893SmrgBool 1974b7e1c893SmrgRADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, char *name, RADEONI2CBusPtr pRADEONI2CBus) 1975209ff23fSmrg{ 1976209ff23fSmrg I2CBusPtr pI2CBus; 1977209ff23fSmrg 1978209ff23fSmrg pI2CBus = xf86CreateI2CBusRec(); 1979209ff23fSmrg if (!pI2CBus) return FALSE; 1980209ff23fSmrg 1981209ff23fSmrg pI2CBus->BusName = name; 1982209ff23fSmrg pI2CBus->scrnIndex = pScrn->scrnIndex; 1983209ff23fSmrg pI2CBus->I2CPutBits = RADEONI2CPutBits; 1984209ff23fSmrg pI2CBus->I2CGetBits = RADEONI2CGetBits; 1985b7e1c893Smrg pI2CBus->AcknTimeout = 5; 1986209ff23fSmrg 1987b7e1c893Smrg pI2CBus->DriverPrivate.ptr = (pointer)pRADEONI2CBus; 1988209ff23fSmrg 1989b7e1c893Smrg if (!xf86I2CBusInit(pI2CBus)) 1990b7e1c893Smrg return FALSE; 1991209ff23fSmrg 1992b7e1c893Smrg *bus_ptr = pI2CBus; 1993209ff23fSmrg return TRUE; 1994209ff23fSmrg} 1995209ff23fSmrg 1996b7e1c893SmrgRADEONI2CBusRec 1997b7e1c893Smrglegacy_setup_i2c_bus(int ddc_line) 1998209ff23fSmrg{ 1999b7e1c893Smrg RADEONI2CBusRec i2c; 2000209ff23fSmrg 2001b7e1c893Smrg i2c.hw_line = 0; 2002b7e1c893Smrg i2c.hw_capable = FALSE; 2003b7e1c893Smrg i2c.mask_clk_mask = RADEON_GPIO_EN_1; 2004b7e1c893Smrg i2c.mask_data_mask = RADEON_GPIO_EN_0; 2005b7e1c893Smrg i2c.a_clk_mask = RADEON_GPIO_A_1; 2006b7e1c893Smrg i2c.a_data_mask = RADEON_GPIO_A_0; 2007b7e1c893Smrg i2c.put_clk_mask = RADEON_GPIO_EN_1; 2008b7e1c893Smrg i2c.put_data_mask = RADEON_GPIO_EN_0; 2009b7e1c893Smrg i2c.get_clk_mask = RADEON_GPIO_Y_1; 2010b7e1c893Smrg i2c.get_data_mask = RADEON_GPIO_Y_0; 2011b7e1c893Smrg if ((ddc_line == RADEON_LCD_GPIO_MASK) || 2012b7e1c893Smrg (ddc_line == RADEON_MDGPIO_EN_REG)) { 2013b7e1c893Smrg i2c.mask_clk_reg = ddc_line; 2014b7e1c893Smrg i2c.mask_data_reg = ddc_line; 2015b7e1c893Smrg i2c.a_clk_reg = ddc_line; 2016b7e1c893Smrg i2c.a_data_reg = ddc_line; 2017b7e1c893Smrg i2c.put_clk_reg = ddc_line; 2018b7e1c893Smrg i2c.put_data_reg = ddc_line; 2019b7e1c893Smrg i2c.get_clk_reg = ddc_line + 4; 2020b7e1c893Smrg i2c.get_data_reg = ddc_line + 4; 2021b7e1c893Smrg } else { 2022b7e1c893Smrg i2c.mask_clk_reg = ddc_line; 2023b7e1c893Smrg i2c.mask_data_reg = ddc_line; 2024b7e1c893Smrg i2c.a_clk_reg = ddc_line; 2025b7e1c893Smrg i2c.a_data_reg = ddc_line; 2026b7e1c893Smrg i2c.put_clk_reg = ddc_line; 2027b7e1c893Smrg i2c.put_data_reg = ddc_line; 2028b7e1c893Smrg i2c.get_clk_reg = ddc_line; 2029b7e1c893Smrg i2c.get_data_reg = ddc_line; 2030209ff23fSmrg } 2031b7e1c893Smrg 2032b7e1c893Smrg if (ddc_line) 2033b7e1c893Smrg i2c.valid = TRUE; 2034b7e1c893Smrg else 2035b7e1c893Smrg i2c.valid = FALSE; 2036b7e1c893Smrg 2037b7e1c893Smrg return i2c; 2038209ff23fSmrg} 2039209ff23fSmrg 2040b7e1c893SmrgRADEONI2CBusRec 2041b7e1c893Smrgatom_setup_i2c_bus(int ddc_line) 2042209ff23fSmrg{ 2043b7e1c893Smrg RADEONI2CBusRec i2c; 2044209ff23fSmrg 2045b7e1c893Smrg i2c.hw_line = 0; 2046b7e1c893Smrg i2c.hw_capable = FALSE; 2047b7e1c893Smrg if (ddc_line == AVIVO_GPIO_0) { 2048b7e1c893Smrg i2c.put_clk_mask = (1 << 19); 2049b7e1c893Smrg i2c.put_data_mask = (1 << 18); 2050b7e1c893Smrg i2c.get_clk_mask = (1 << 19); 2051b7e1c893Smrg i2c.get_data_mask = (1 << 18); 2052b7e1c893Smrg i2c.mask_clk_mask = (1 << 19); 2053b7e1c893Smrg i2c.mask_data_mask = (1 << 18); 2054b7e1c893Smrg i2c.a_clk_mask = (1 << 19); 2055b7e1c893Smrg i2c.a_data_mask = (1 << 18); 2056b7e1c893Smrg } else { 2057b7e1c893Smrg i2c.put_clk_mask = (1 << 0); 2058b7e1c893Smrg i2c.put_data_mask = (1 << 8); 2059b7e1c893Smrg i2c.get_clk_mask = (1 << 0); 2060b7e1c893Smrg i2c.get_data_mask = (1 << 8); 2061b7e1c893Smrg i2c.mask_clk_mask = (1 << 0); 2062b7e1c893Smrg i2c.mask_data_mask = (1 << 8); 2063b7e1c893Smrg i2c.a_clk_mask = (1 << 0); 2064b7e1c893Smrg i2c.a_data_mask = (1 << 8); 2065209ff23fSmrg } 2066b7e1c893Smrg i2c.mask_clk_reg = ddc_line; 2067b7e1c893Smrg i2c.mask_data_reg = ddc_line; 2068b7e1c893Smrg i2c.a_clk_reg = ddc_line + 0x4; 2069b7e1c893Smrg i2c.a_data_reg = ddc_line + 0x4; 2070b7e1c893Smrg i2c.put_clk_reg = ddc_line + 0x8; 2071b7e1c893Smrg i2c.put_data_reg = ddc_line + 0x8; 2072b7e1c893Smrg i2c.get_clk_reg = ddc_line + 0xc; 2073b7e1c893Smrg i2c.get_data_reg = ddc_line + 0xc; 2074b7e1c893Smrg if (ddc_line) 2075b7e1c893Smrg i2c.valid = TRUE; 2076b7e1c893Smrg else 2077b7e1c893Smrg i2c.valid = FALSE; 2078209ff23fSmrg 2079b7e1c893Smrg return i2c; 2080209ff23fSmrg} 2081209ff23fSmrg 2082209ff23fSmrgstatic void 2083209ff23fSmrgRADEONGetTVInfo(xf86OutputPtr output) 2084209ff23fSmrg{ 2085209ff23fSmrg ScrnInfoPtr pScrn = output->scrn; 2086209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 2087209ff23fSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 2088b7e1c893Smrg radeon_tvout_ptr tvout = &radeon_output->tvout; 2089209ff23fSmrg char *optstr; 2090209ff23fSmrg 2091b7e1c893Smrg tvout->hPos = 0; 2092b7e1c893Smrg tvout->vPos = 0; 2093b7e1c893Smrg tvout->hSize = 0; 2094b7e1c893Smrg tvout->tv_on = FALSE; 2095209ff23fSmrg 2096209ff23fSmrg if (!RADEONGetTVInfoFromBIOS(output)) { 2097209ff23fSmrg /* set some reasonable defaults */ 2098b7e1c893Smrg tvout->default_tvStd = TV_STD_NTSC; 2099b7e1c893Smrg tvout->tvStd = TV_STD_NTSC; 2100b7e1c893Smrg tvout->TVRefClk = 27.000000000; 2101b7e1c893Smrg tvout->SupportedTVStds = TV_STD_NTSC | TV_STD_PAL; 2102209ff23fSmrg } 2103209ff23fSmrg 2104209ff23fSmrg optstr = (char *)xf86GetOptValString(info->Options, OPTION_TVSTD); 2105209ff23fSmrg if (optstr) { 2106209ff23fSmrg if (!strncmp("ntsc", optstr, strlen("ntsc"))) 2107b7e1c893Smrg tvout->tvStd = TV_STD_NTSC; 2108209ff23fSmrg else if (!strncmp("pal", optstr, strlen("pal"))) 2109b7e1c893Smrg tvout->tvStd = TV_STD_PAL; 2110209ff23fSmrg else if (!strncmp("pal-m", optstr, strlen("pal-m"))) 2111b7e1c893Smrg tvout->tvStd = TV_STD_PAL_M; 2112209ff23fSmrg else if (!strncmp("pal-60", optstr, strlen("pal-60"))) 2113b7e1c893Smrg tvout->tvStd = TV_STD_PAL_60; 2114209ff23fSmrg else if (!strncmp("ntsc-j", optstr, strlen("ntsc-j"))) 2115b7e1c893Smrg tvout->tvStd = TV_STD_NTSC_J; 2116209ff23fSmrg else if (!strncmp("scart-pal", optstr, strlen("scart-pal"))) 2117b7e1c893Smrg tvout->tvStd = TV_STD_SCART_PAL; 2118209ff23fSmrg else { 2119209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid TV Standard: %s\n", optstr); 2120209ff23fSmrg } 2121209ff23fSmrg } 2122209ff23fSmrg 2123209ff23fSmrg} 2124209ff23fSmrg 2125209ff23fSmrgvoid RADEONInitConnector(xf86OutputPtr output) 2126209ff23fSmrg{ 2127209ff23fSmrg ScrnInfoPtr pScrn = output->scrn; 2128209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 2129209ff23fSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 2130209ff23fSmrg 2131b7e1c893Smrg if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) 2132b7e1c893Smrg radeon_output->rmx_type = RMX_FULL; 2133209ff23fSmrg else 2134b7e1c893Smrg radeon_output->rmx_type = RMX_OFF; 2135209ff23fSmrg 2136b7e1c893Smrg if (!IS_AVIVO_VARIANT) { 2137b7e1c893Smrg if (radeon_output->devices & (ATOM_DEVICE_CRT2_SUPPORT)) { 2138b7e1c893Smrg if (xf86ReturnOptValBool(info->Options, OPTION_TVDAC_LOAD_DETECT, FALSE)) 2139b7e1c893Smrg radeon_output->load_detection = 1; 2140b7e1c893Smrg } 2141209ff23fSmrg } 2142209ff23fSmrg 2143b7e1c893Smrg if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) 2144209ff23fSmrg RADEONGetTVInfo(output); 2145209ff23fSmrg 2146b7e1c893Smrg if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT)) 2147209ff23fSmrg radeon_output->coherent_mode = TRUE; 2148209ff23fSmrg 2149ad43ddacSmrg if (radeon_output->ConnectorType == CONNECTOR_DISPLAY_PORT) { 2150ad43ddacSmrg strcpy(radeon_output->dp_bus_name, output->name); 2151ad43ddacSmrg strcat(radeon_output->dp_bus_name, "-DP"); 2152ad43ddacSmrg RADEON_DP_I2CInit(pScrn, &radeon_output->dp_pI2CBus, radeon_output->dp_bus_name, output); 2153ad43ddacSmrg RADEON_DP_GetSinkType(output); 2154ad43ddacSmrg } 2155ad43ddacSmrg 2156ad43ddacSmrg if (radeon_output->ConnectorType == CONNECTOR_EDP) { 2157ad43ddacSmrg strcpy(radeon_output->dp_bus_name, output->name); 2158ad43ddacSmrg strcat(radeon_output->dp_bus_name, "-eDP"); 2159ad43ddacSmrg RADEON_DP_I2CInit(pScrn, &radeon_output->dp_pI2CBus, radeon_output->dp_bus_name, output); 2160ad43ddacSmrg RADEON_DP_GetSinkType(output); 2161ad43ddacSmrg } 2162ad43ddacSmrg 2163209ff23fSmrg if (radeon_output->ddc_i2c.valid) 2164b7e1c893Smrg RADEONI2CInit(pScrn, &radeon_output->pI2CBus, output->name, &radeon_output->ddc_i2c); 2165209ff23fSmrg 2166209ff23fSmrg} 2167209ff23fSmrg 2168209ff23fSmrg#if defined(__powerpc__) 2169209ff23fSmrgstatic Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn) 2170209ff23fSmrg{ 2171209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 2172209ff23fSmrg 2173209ff23fSmrg 2174209ff23fSmrg switch (info->MacModel) { 2175209ff23fSmrg case RADEON_MAC_IBOOK: 2176209ff23fSmrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 2177209ff23fSmrg info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; 2178209ff23fSmrg info->BiosConnector[0].valid = TRUE; 2179b7e1c893Smrg info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; 2180b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2181b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2182b7e1c893Smrg ATOM_DEVICE_LCD1_SUPPORT, 2183b7e1c893Smrg 0), 2184b7e1c893Smrg ATOM_DEVICE_LCD1_SUPPORT)) 2185b7e1c893Smrg return FALSE; 2186209ff23fSmrg 2187209ff23fSmrg info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2188b7e1c893Smrg info->BiosConnector[1].load_detection = FALSE; 2189209ff23fSmrg info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; 2190209ff23fSmrg info->BiosConnector[1].valid = TRUE; 2191b7e1c893Smrg info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT; 2192b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2193b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2194b7e1c893Smrg ATOM_DEVICE_CRT2_SUPPORT, 2195b7e1c893Smrg 2), 2196b7e1c893Smrg ATOM_DEVICE_CRT2_SUPPORT)) 2197b7e1c893Smrg return FALSE; 2198209ff23fSmrg 2199209ff23fSmrg info->BiosConnector[2].ConnectorType = CONNECTOR_STV; 2200b7e1c893Smrg info->BiosConnector[2].load_detection = FALSE; 2201209ff23fSmrg info->BiosConnector[2].ddc_i2c.valid = FALSE; 2202209ff23fSmrg info->BiosConnector[2].valid = TRUE; 2203b7e1c893Smrg info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; 2204b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2205b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2206b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT, 2207b7e1c893Smrg 2), 2208b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT)) 2209b7e1c893Smrg return FALSE; 2210209ff23fSmrg return TRUE; 2211209ff23fSmrg case RADEON_MAC_POWERBOOK_EXTERNAL: 2212209ff23fSmrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 2213209ff23fSmrg info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; 2214209ff23fSmrg info->BiosConnector[0].valid = TRUE; 2215b7e1c893Smrg info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; 2216b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2217b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2218b7e1c893Smrg ATOM_DEVICE_LCD1_SUPPORT, 2219b7e1c893Smrg 0), 2220b7e1c893Smrg ATOM_DEVICE_LCD1_SUPPORT)) 2221b7e1c893Smrg return FALSE; 2222209ff23fSmrg 2223209ff23fSmrg info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2224209ff23fSmrg info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I; 2225209ff23fSmrg info->BiosConnector[1].valid = TRUE; 2226b7e1c893Smrg info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT; 2227b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2228b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2229b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT, 2230b7e1c893Smrg 1), 2231b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT)) 2232b7e1c893Smrg return FALSE; 2233b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2234b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2235b7e1c893Smrg ATOM_DEVICE_DFP2_SUPPORT, 2236b7e1c893Smrg 0), 2237b7e1c893Smrg ATOM_DEVICE_DFP2_SUPPORT)) 2238b7e1c893Smrg return FALSE; 2239209ff23fSmrg 2240209ff23fSmrg info->BiosConnector[2].ConnectorType = CONNECTOR_STV; 2241b7e1c893Smrg info->BiosConnector[2].load_detection = FALSE; 2242209ff23fSmrg info->BiosConnector[2].ddc_i2c.valid = FALSE; 2243209ff23fSmrg info->BiosConnector[2].valid = TRUE; 2244b7e1c893Smrg info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; 2245b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2246b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2247b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT, 2248b7e1c893Smrg 2), 2249b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT)) 2250b7e1c893Smrg return FALSE; 2251209ff23fSmrg return TRUE; 2252209ff23fSmrg case RADEON_MAC_POWERBOOK_INTERNAL: 2253209ff23fSmrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 2254209ff23fSmrg info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; 2255209ff23fSmrg info->BiosConnector[0].valid = TRUE; 2256b7e1c893Smrg info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; 2257b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2258b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2259b7e1c893Smrg ATOM_DEVICE_LCD1_SUPPORT, 2260b7e1c893Smrg 0), 2261b7e1c893Smrg ATOM_DEVICE_LCD1_SUPPORT)) 2262b7e1c893Smrg return FALSE; 2263209ff23fSmrg 2264209ff23fSmrg info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2265209ff23fSmrg info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I; 2266209ff23fSmrg info->BiosConnector[1].valid = TRUE; 2267b7e1c893Smrg info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT; 2268b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2269b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2270b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT, 2271b7e1c893Smrg 1), 2272b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT)) 2273b7e1c893Smrg return FALSE; 2274b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2275b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2276b7e1c893Smrg ATOM_DEVICE_DFP1_SUPPORT, 2277b7e1c893Smrg 0), 2278b7e1c893Smrg ATOM_DEVICE_DFP1_SUPPORT)) 2279b7e1c893Smrg return FALSE; 2280209ff23fSmrg 2281209ff23fSmrg info->BiosConnector[2].ConnectorType = CONNECTOR_STV; 2282b7e1c893Smrg info->BiosConnector[2].load_detection = FALSE; 2283209ff23fSmrg info->BiosConnector[2].ddc_i2c.valid = FALSE; 2284209ff23fSmrg info->BiosConnector[2].valid = TRUE; 2285b7e1c893Smrg info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; 2286b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2287b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2288b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT, 2289b7e1c893Smrg 2), 2290b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT)) 2291b7e1c893Smrg return FALSE; 2292209ff23fSmrg return TRUE; 2293209ff23fSmrg case RADEON_MAC_POWERBOOK_VGA: 2294209ff23fSmrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 2295b7e1c893Smrg info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; 2296209ff23fSmrg info->BiosConnector[0].valid = TRUE; 2297b7e1c893Smrg info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; 2298b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2299b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2300b7e1c893Smrg ATOM_DEVICE_LCD1_SUPPORT, 2301b7e1c893Smrg 0), 2302b7e1c893Smrg ATOM_DEVICE_LCD1_SUPPORT)) 2303b7e1c893Smrg return FALSE; 2304209ff23fSmrg 2305209ff23fSmrg info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2306b7e1c893Smrg info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; 2307209ff23fSmrg info->BiosConnector[1].valid = TRUE; 2308b7e1c893Smrg info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT; 2309b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2310b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2311b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT, 2312b7e1c893Smrg 1), 2313b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT)) 2314b7e1c893Smrg return FALSE; 2315209ff23fSmrg 2316209ff23fSmrg info->BiosConnector[2].ConnectorType = CONNECTOR_STV; 2317b7e1c893Smrg info->BiosConnector[2].load_detection = FALSE; 2318209ff23fSmrg info->BiosConnector[2].ddc_i2c.valid = FALSE; 2319209ff23fSmrg info->BiosConnector[2].valid = TRUE; 2320b7e1c893Smrg info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; 2321b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2322b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2323b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT, 2324b7e1c893Smrg 2), 2325b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT)) 2326b7e1c893Smrg return FALSE; 2327209ff23fSmrg return TRUE; 2328209ff23fSmrg case RADEON_MAC_MINI_EXTERNAL: 2329209ff23fSmrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); 2330b7e1c893Smrg info->BiosConnector[0].load_detection = FALSE; 2331209ff23fSmrg info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I; 2332209ff23fSmrg info->BiosConnector[0].valid = TRUE; 2333b7e1c893Smrg info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT; 2334b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2335b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2336b7e1c893Smrg ATOM_DEVICE_CRT2_SUPPORT, 2337b7e1c893Smrg 2), 2338b7e1c893Smrg ATOM_DEVICE_CRT2_SUPPORT)) 2339b7e1c893Smrg return FALSE; 2340b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2341b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2342b7e1c893Smrg ATOM_DEVICE_DFP2_SUPPORT, 2343b7e1c893Smrg 0), 2344b7e1c893Smrg ATOM_DEVICE_DFP2_SUPPORT)) 2345b7e1c893Smrg return FALSE; 2346209ff23fSmrg 2347209ff23fSmrg info->BiosConnector[1].ConnectorType = CONNECTOR_STV; 2348b7e1c893Smrg info->BiosConnector[1].load_detection = FALSE; 2349209ff23fSmrg info->BiosConnector[1].ddc_i2c.valid = FALSE; 2350209ff23fSmrg info->BiosConnector[1].valid = TRUE; 2351b7e1c893Smrg info->BiosConnector[1].devices = ATOM_DEVICE_TV1_SUPPORT; 2352b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2353b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2354b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT, 2355b7e1c893Smrg 2), 2356b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT)) 2357b7e1c893Smrg return FALSE; 2358209ff23fSmrg return TRUE; 2359209ff23fSmrg case RADEON_MAC_MINI_INTERNAL: 2360209ff23fSmrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); 2361b7e1c893Smrg info->BiosConnector[0].load_detection = FALSE; 2362209ff23fSmrg info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I; 2363209ff23fSmrg info->BiosConnector[0].valid = TRUE; 2364b7e1c893Smrg info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT; 2365b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2366b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2367b7e1c893Smrg ATOM_DEVICE_CRT2_SUPPORT, 2368b7e1c893Smrg 2), 2369b7e1c893Smrg ATOM_DEVICE_CRT2_SUPPORT)) 2370b7e1c893Smrg return FALSE; 2371b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2372b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2373b7e1c893Smrg ATOM_DEVICE_DFP1_SUPPORT, 2374b7e1c893Smrg 0), 2375b7e1c893Smrg ATOM_DEVICE_DFP1_SUPPORT)) 2376b7e1c893Smrg return FALSE; 2377209ff23fSmrg 2378209ff23fSmrg info->BiosConnector[1].ConnectorType = CONNECTOR_STV; 2379b7e1c893Smrg info->BiosConnector[1].load_detection = FALSE; 2380209ff23fSmrg info->BiosConnector[1].ddc_i2c.valid = FALSE; 2381209ff23fSmrg info->BiosConnector[1].valid = TRUE; 2382b7e1c893Smrg info->BiosConnector[1].devices = ATOM_DEVICE_TV1_SUPPORT; 2383b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2384b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2385b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT, 2386b7e1c893Smrg 2), 2387b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT)) 2388b7e1c893Smrg return FALSE; 2389209ff23fSmrg return TRUE; 2390209ff23fSmrg case RADEON_MAC_IMAC_G5_ISIGHT: 2391209ff23fSmrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); 2392209ff23fSmrg info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_D; 2393209ff23fSmrg info->BiosConnector[0].valid = TRUE; 2394b7e1c893Smrg info->BiosConnector[0].devices = ATOM_DEVICE_DFP1_SUPPORT; 2395b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2396b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2397b7e1c893Smrg ATOM_DEVICE_DFP1_SUPPORT, 2398b7e1c893Smrg 0), 2399b7e1c893Smrg ATOM_DEVICE_DFP1_SUPPORT)) 2400b7e1c893Smrg return FALSE; 2401209ff23fSmrg 2402209ff23fSmrg info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 2403b7e1c893Smrg info->BiosConnector[1].load_detection = FALSE; 2404b7e1c893Smrg info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; 2405b7e1c893Smrg info->BiosConnector[1].valid = TRUE; 2406b7e1c893Smrg info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT; 2407b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2408b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2409b7e1c893Smrg ATOM_DEVICE_CRT2_SUPPORT, 2410b7e1c893Smrg 2), 2411b7e1c893Smrg ATOM_DEVICE_CRT2_SUPPORT)) 2412b7e1c893Smrg return FALSE; 2413b7e1c893Smrg 2414b7e1c893Smrg info->BiosConnector[2].ConnectorType = CONNECTOR_STV; 2415b7e1c893Smrg info->BiosConnector[2].load_detection = FALSE; 2416b7e1c893Smrg info->BiosConnector[2].ddc_i2c.valid = FALSE; 2417b7e1c893Smrg info->BiosConnector[2].valid = TRUE; 2418b7e1c893Smrg info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; 2419b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2420b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2421b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT, 2422b7e1c893Smrg 2), 2423b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT)) 2424b7e1c893Smrg return FALSE; 2425b7e1c893Smrg return TRUE; 2426b7e1c893Smrg case RADEON_MAC_EMAC: 2427b7e1c893Smrg /* eMac G4 800/1.0 with radeon 7500, no EDID on internal monitor 2428b7e1c893Smrg * later eMac's (G4 1.25/1.42) with radeon 9200 and 9600 may have 2429b7e1c893Smrg * different ddc setups. need to verify 2430b7e1c893Smrg */ 2431b7e1c893Smrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2432b7e1c893Smrg info->BiosConnector[0].ConnectorType = CONNECTOR_VGA; 2433b7e1c893Smrg info->BiosConnector[0].valid = TRUE; 2434b7e1c893Smrg info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT; 2435b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2436b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2437b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT, 2438b7e1c893Smrg 1), 2439b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT)) 2440b7e1c893Smrg return FALSE; 2441b7e1c893Smrg 2442b7e1c893Smrg info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); 2443b7e1c893Smrg info->BiosConnector[1].load_detection = FALSE; 2444209ff23fSmrg info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; 2445209ff23fSmrg info->BiosConnector[1].valid = TRUE; 2446b7e1c893Smrg info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT; 2447b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2448b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2449b7e1c893Smrg ATOM_DEVICE_CRT2_SUPPORT, 2450b7e1c893Smrg 2), 2451b7e1c893Smrg ATOM_DEVICE_CRT2_SUPPORT)) 2452b7e1c893Smrg return FALSE; 2453209ff23fSmrg 2454209ff23fSmrg info->BiosConnector[2].ConnectorType = CONNECTOR_STV; 2455b7e1c893Smrg info->BiosConnector[2].load_detection = FALSE; 2456209ff23fSmrg info->BiosConnector[2].ddc_i2c.valid = FALSE; 2457209ff23fSmrg info->BiosConnector[2].valid = TRUE; 2458b7e1c893Smrg info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; 2459b7e1c893Smrg if (!radeon_add_encoder(pScrn, 2460b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2461b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT, 2462b7e1c893Smrg 2), 2463b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT)) 2464b7e1c893Smrg return FALSE; 2465209ff23fSmrg return TRUE; 246668105dcbSveego case RADEON_MAC_SAM440EP: 246768105dcbSveego /* LVDS header */ 246868105dcbSveego info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(0); 246968105dcbSveego info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; 247068105dcbSveego info->BiosConnector[0].valid = TRUE; 247168105dcbSveego info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; 247268105dcbSveego if (!radeon_add_encoder(pScrn, 247368105dcbSveego radeon_get_encoder_id_from_supported_device(pScrn, 247468105dcbSveego ATOM_DEVICE_LCD1_SUPPORT, 247568105dcbSveego 0), 247668105dcbSveego ATOM_DEVICE_LCD1_SUPPORT)) 247768105dcbSveego return FALSE; 247868105dcbSveego 247968105dcbSveego /* DVI-I port */ 248068105dcbSveego info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 248168105dcbSveego info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I; 248268105dcbSveego info->BiosConnector[1].valid = TRUE; 248368105dcbSveego info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT; 248468105dcbSveego if (!radeon_add_encoder(pScrn, 248568105dcbSveego radeon_get_encoder_id_from_supported_device(pScrn, 248668105dcbSveego ATOM_DEVICE_CRT2_SUPPORT, 248768105dcbSveego 2), 248868105dcbSveego ATOM_DEVICE_CRT2_SUPPORT)) 248968105dcbSveego return FALSE; 249068105dcbSveego if (!radeon_add_encoder(pScrn, 249168105dcbSveego radeon_get_encoder_id_from_supported_device(pScrn, 249268105dcbSveego ATOM_DEVICE_DFP1_SUPPORT, 249368105dcbSveego 0), 249468105dcbSveego ATOM_DEVICE_DFP1_SUPPORT)) 249568105dcbSveego return FALSE; 249668105dcbSveego 249768105dcbSveego /* VGA header */ 249868105dcbSveego info->BiosConnector[2].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 249968105dcbSveego info->BiosConnector[2].ConnectorType = CONNECTOR_VGA; 250068105dcbSveego info->BiosConnector[2].valid = TRUE; 250168105dcbSveego info->BiosConnector[2].devices = ATOM_DEVICE_CRT1_SUPPORT; 250268105dcbSveego if (!radeon_add_encoder(pScrn, 250368105dcbSveego radeon_get_encoder_id_from_supported_device(pScrn, 250468105dcbSveego ATOM_DEVICE_CRT1_SUPPORT, 250568105dcbSveego 1), 250668105dcbSveego ATOM_DEVICE_CRT1_SUPPORT)) 250768105dcbSveego return FALSE; 250868105dcbSveego 250968105dcbSveego /* s-video */ 251068105dcbSveego info->BiosConnector[3].ConnectorType = CONNECTOR_STV; 251168105dcbSveego info->BiosConnector[3].load_detection = FALSE; 251268105dcbSveego info->BiosConnector[3].ddc_i2c.valid = FALSE; 251368105dcbSveego info->BiosConnector[3].valid = TRUE; 251468105dcbSveego info->BiosConnector[3].devices = ATOM_DEVICE_TV1_SUPPORT; 251568105dcbSveego if (!radeon_add_encoder(pScrn, 251668105dcbSveego radeon_get_encoder_id_from_supported_device(pScrn, 251768105dcbSveego ATOM_DEVICE_TV1_SUPPORT, 251868105dcbSveego 2), 251968105dcbSveego ATOM_DEVICE_TV1_SUPPORT)) 252068105dcbSveego return FALSE; 252168105dcbSveego return TRUE; 2522209ff23fSmrg default: 2523209ff23fSmrg return FALSE; 2524209ff23fSmrg } 2525209ff23fSmrg 2526209ff23fSmrg return FALSE; 2527209ff23fSmrg} 2528209ff23fSmrg#endif 2529209ff23fSmrg 2530209ff23fSmrgstatic void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn) 2531209ff23fSmrg{ 2532209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 2533209ff23fSmrg RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 2534209ff23fSmrg 2535b7e1c893Smrg if (IS_AVIVO_VARIANT) 2536b7e1c893Smrg return; 2537b7e1c893Smrg 2538209ff23fSmrg if (!pRADEONEnt->HasCRTC2) { 2539209ff23fSmrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2540209ff23fSmrg info->BiosConnector[0].ConnectorType = CONNECTOR_VGA; 2541209ff23fSmrg info->BiosConnector[0].valid = TRUE; 2542b7e1c893Smrg info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT; 2543b7e1c893Smrg radeon_add_encoder(pScrn, 2544b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2545b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT, 2546b7e1c893Smrg 1), 2547b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT); 2548209ff23fSmrg return; 2549209ff23fSmrg } 2550209ff23fSmrg 2551b7e1c893Smrg if (info->IsMobility) { 2552b7e1c893Smrg /* Below is the most common setting, but may not be true */ 2553b7e1c893Smrg if (info->IsIGP) { 2554b7e1c893Smrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK); 2555209ff23fSmrg info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; 2556209ff23fSmrg info->BiosConnector[0].valid = TRUE; 2557b7e1c893Smrg info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; 2558b7e1c893Smrg radeon_add_encoder(pScrn, 2559b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2560b7e1c893Smrg ATOM_DEVICE_LCD1_SUPPORT, 2561b7e1c893Smrg 0), 2562b7e1c893Smrg ATOM_DEVICE_LCD1_SUPPORT); 2563b7e1c893Smrg 2564b7e1c893Smrg /* IGP only has TVDAC */ 2565b7e1c893Smrg if ((info->ChipFamily == CHIP_FAMILY_RS400) || 2566b7e1c893Smrg (info->ChipFamily == CHIP_FAMILY_RS480)) 2567b7e1c893Smrg info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); 2568b7e1c893Smrg else 2569b7e1c893Smrg info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2570b7e1c893Smrg info->BiosConnector[1].load_detection = FALSE; 2571209ff23fSmrg info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; 2572209ff23fSmrg info->BiosConnector[1].valid = TRUE; 2573b7e1c893Smrg info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT; 2574b7e1c893Smrg radeon_add_encoder(pScrn, 2575b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2576b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT, 2577b7e1c893Smrg 2), 2578b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT); 2579209ff23fSmrg } else { 2580b7e1c893Smrg#if defined(__powerpc__) 2581b7e1c893Smrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 2582b7e1c893Smrg#else 2583b7e1c893Smrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK); 2584b7e1c893Smrg#endif 2585b7e1c893Smrg info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; 2586209ff23fSmrg info->BiosConnector[0].valid = TRUE; 2587b7e1c893Smrg info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; 2588b7e1c893Smrg radeon_add_encoder(pScrn, 2589b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2590b7e1c893Smrg ATOM_DEVICE_LCD1_SUPPORT, 2591b7e1c893Smrg 0), 2592b7e1c893Smrg ATOM_DEVICE_LCD1_SUPPORT); 2593209ff23fSmrg 2594b7e1c893Smrg info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2595209ff23fSmrg info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; 2596209ff23fSmrg info->BiosConnector[1].valid = TRUE; 2597b7e1c893Smrg info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT; 2598b7e1c893Smrg radeon_add_encoder(pScrn, 2599b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2600b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT, 2601b7e1c893Smrg 1), 2602b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT); 2603209ff23fSmrg } 2604209ff23fSmrg } else { 2605b7e1c893Smrg /* Below is the most common setting, but may not be true */ 2606b7e1c893Smrg if (info->IsIGP) { 2607b7e1c893Smrg if ((info->ChipFamily == CHIP_FAMILY_RS400) || 2608b7e1c893Smrg (info->ChipFamily == CHIP_FAMILY_RS480)) 2609b7e1c893Smrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); 2610b7e1c893Smrg else 2611b7e1c893Smrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2612b7e1c893Smrg info->BiosConnector[0].load_detection = FALSE; 2613b7e1c893Smrg info->BiosConnector[0].ConnectorType = CONNECTOR_VGA; 2614b7e1c893Smrg info->BiosConnector[0].valid = TRUE; 2615b7e1c893Smrg info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT; 2616b7e1c893Smrg radeon_add_encoder(pScrn, 2617b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2618b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT, 2619b7e1c893Smrg 1), 2620b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT); 2621b7e1c893Smrg 2622b7e1c893Smrg /* not sure what a good default DDCType for DVI on 2623b7e1c893Smrg * IGP desktop chips is 2624b7e1c893Smrg */ 2625b7e1c893Smrg info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); /* DDC_DVI? */ 2626b7e1c893Smrg info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_D; 2627b7e1c893Smrg info->BiosConnector[1].valid = TRUE; 2628b7e1c893Smrg info->BiosConnector[1].devices = ATOM_DEVICE_DFP1_SUPPORT; 2629b7e1c893Smrg radeon_add_encoder(pScrn, 2630b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2631b7e1c893Smrg ATOM_DEVICE_DFP1_SUPPORT, 2632b7e1c893Smrg 0), 2633b7e1c893Smrg ATOM_DEVICE_DFP1_SUPPORT); 2634209ff23fSmrg } else { 2635b7e1c893Smrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 2636b7e1c893Smrg info->BiosConnector[0].load_detection = FALSE; 2637b7e1c893Smrg info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I; 2638b7e1c893Smrg info->BiosConnector[0].valid = TRUE; 2639b7e1c893Smrg info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT; 2640b7e1c893Smrg radeon_add_encoder(pScrn, 2641b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2642b7e1c893Smrg ATOM_DEVICE_CRT2_SUPPORT, 2643b7e1c893Smrg 2), 2644b7e1c893Smrg ATOM_DEVICE_CRT2_SUPPORT); 2645b7e1c893Smrg radeon_add_encoder(pScrn, 2646b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2647b7e1c893Smrg ATOM_DEVICE_DFP1_SUPPORT, 2648b7e1c893Smrg 0), 2649b7e1c893Smrg ATOM_DEVICE_DFP1_SUPPORT); 2650209ff23fSmrg 2651209ff23fSmrg#if defined(__powerpc__) 2652b7e1c893Smrg info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2653b7e1c893Smrg info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I; 2654b7e1c893Smrg info->BiosConnector[1].valid = TRUE; 2655b7e1c893Smrg info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT; 2656b7e1c893Smrg radeon_add_encoder(pScrn, 2657b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2658b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT, 2659b7e1c893Smrg 1), 2660b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT); 2661b7e1c893Smrg radeon_add_encoder(pScrn, 2662b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2663b7e1c893Smrg ATOM_DEVICE_DFP2_SUPPORT, 2664b7e1c893Smrg 0), 2665b7e1c893Smrg ATOM_DEVICE_DFP2_SUPPORT); 2666209ff23fSmrg#else 2667b7e1c893Smrg info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2668b7e1c893Smrg info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; 2669b7e1c893Smrg info->BiosConnector[1].valid = TRUE; 2670b7e1c893Smrg info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT; 2671b7e1c893Smrg radeon_add_encoder(pScrn, 2672b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2673b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT, 2674b7e1c893Smrg 1), 2675b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT); 2676209ff23fSmrg#endif 2677209ff23fSmrg } 2678b7e1c893Smrg } 2679209ff23fSmrg 2680b7e1c893Smrg if (info->InternalTVOut) { 2681b7e1c893Smrg info->BiosConnector[2].ConnectorType = CONNECTOR_STV; 2682b7e1c893Smrg info->BiosConnector[2].load_detection = FALSE; 2683b7e1c893Smrg info->BiosConnector[2].ddc_i2c.valid = FALSE; 2684b7e1c893Smrg info->BiosConnector[2].valid = TRUE; 2685b7e1c893Smrg info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; 2686b7e1c893Smrg radeon_add_encoder(pScrn, 2687b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 2688b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT, 2689b7e1c893Smrg 2), 2690b7e1c893Smrg ATOM_DEVICE_TV1_SUPPORT); 2691b7e1c893Smrg } 2692209ff23fSmrg 2693b7e1c893Smrg /* Some cards have the DDC lines swapped and we have no way to 2694b7e1c893Smrg * detect it yet (Mac cards) 2695b7e1c893Smrg */ 2696b7e1c893Smrg if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) { 2697b7e1c893Smrg info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2698b7e1c893Smrg info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 2699209ff23fSmrg } 2700209ff23fSmrg} 2701209ff23fSmrg 2702209ff23fSmrg#if defined(__powerpc__) 2703209ff23fSmrg 2704ad43ddacSmrg#ifdef __OpenBSD__ 2705ad43ddacSmrg#include <sys/param.h> 2706ad43ddacSmrg#include <sys/sysctl.h> 2707ad43ddacSmrg#endif 2708ad43ddacSmrg 2709209ff23fSmrg/* 2710209ff23fSmrg * Returns RADEONMacModel or 0 based on lines 'detected as' and 'machine' 2711209ff23fSmrg * in /proc/cpuinfo (on Linux) */ 2712209ff23fSmrgstatic RADEONMacModel RADEONDetectMacModel(ScrnInfoPtr pScrn) 2713209ff23fSmrg{ 2714209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 2715209ff23fSmrg RADEONMacModel ret = 0; 2716209ff23fSmrg#ifdef __linux__ 2717209ff23fSmrg char cpuline[50]; /* 50 should be sufficient for our purposes */ 2718209ff23fSmrg FILE *f = fopen ("/proc/cpuinfo", "r"); 2719209ff23fSmrg 2720209ff23fSmrg /* Some macs (minis and powerbooks) use internal tmds, others use external tmds 2721209ff23fSmrg * and not just for dual-link TMDS, it shows up with single-link as well. 2722209ff23fSmrg * Unforunately, there doesn't seem to be any good way to figure it out. 2723209ff23fSmrg */ 2724209ff23fSmrg 2725b7e1c893Smrg /* 2726209ff23fSmrg * PowerBook5,[1-5]: external tmds, single-link 2727209ff23fSmrg * PowerBook5,[789]: external tmds, dual-link 2728209ff23fSmrg * PowerBook5,6: external tmds, single-link or dual-link 2729209ff23fSmrg * need to add another option to specify the external tmds chip 2730209ff23fSmrg * or find out what's used and add it. 2731209ff23fSmrg */ 2732209ff23fSmrg 2733209ff23fSmrg 2734209ff23fSmrg if (f != NULL) { 2735209ff23fSmrg while (fgets(cpuline, sizeof cpuline, f)) { 2736209ff23fSmrg if (!strncmp(cpuline, "machine", strlen ("machine"))) { 2737ba58b518Smacallan#elif defined(__NetBSD__) 2738ba58b518Smacallan char cpuline[50]; 2739ba58b518Smacallan int of; 2740ba58b518Smacallan struct ofiocdesc ofio; 2741ba58b518Smacallan 2742ba58b518Smacallan of = open("/dev/openfirm", O_RDONLY); 2743ba58b518Smacallan if (of > 0) { 2744ba58b518Smacallan ofio.of_nodeid = 0; 2745ba58b518Smacallan ofio.of_name = "/"; 2746ba58b518Smacallan ofio.of_namelen = 1; 2747ba58b518Smacallan if (ioctl(of, OFIOCFINDDEVICE, &ofio) != -1) { 2748ba58b518Smacallan ofio.of_name = "model"; 2749ba58b518Smacallan ofio.of_namelen = 5; 2750ba58b518Smacallan ofio.of_buf = cpuline; 2751ba58b518Smacallan ofio.of_buflen = sizeof(cpuline); 2752ba58b518Smacallan while (ioctl(of, OFIOCGET, &ofio) != -1) { 2753ba58b518Smacallan cpuline[49] = 0; 2754ba58b518Smacallan xf86Msg(X_ERROR, "model %s\n", cpuline); 2755ba58b518Smacallan#endif 2756209ff23fSmrg if (strstr(cpuline, "PowerBook5,1") || 2757209ff23fSmrg strstr(cpuline, "PowerBook5,2") || 2758209ff23fSmrg strstr(cpuline, "PowerBook5,3") || 2759209ff23fSmrg strstr(cpuline, "PowerBook5,4") || 2760209ff23fSmrg strstr(cpuline, "PowerBook5,5")) { 2761209ff23fSmrg ret = RADEON_MAC_POWERBOOK_EXTERNAL; /* single link */ 2762209ff23fSmrg info->ext_tmds_chip = RADEON_SIL_164; /* works on 5,2 */ 2763209ff23fSmrg break; 2764209ff23fSmrg } 2765209ff23fSmrg 2766209ff23fSmrg if (strstr(cpuline, "PowerBook5,6")) { 2767209ff23fSmrg ret = RADEON_MAC_POWERBOOK_EXTERNAL; /* dual or single link */ 2768209ff23fSmrg break; 2769209ff23fSmrg } 2770209ff23fSmrg 2771209ff23fSmrg if (strstr(cpuline, "PowerBook5,7") || 2772209ff23fSmrg strstr(cpuline, "PowerBook5,8") || 2773209ff23fSmrg strstr(cpuline, "PowerBook5,9")) { 2774209ff23fSmrg ret = RADEON_MAC_POWERBOOK_EXTERNAL; /* dual link */ 2775209ff23fSmrg info->ext_tmds_chip = RADEON_SIL_1178; /* guess */ 2776209ff23fSmrg break; 2777209ff23fSmrg } 2778209ff23fSmrg 2779209ff23fSmrg if (strstr(cpuline, "PowerBook3,3")) { 2780209ff23fSmrg ret = RADEON_MAC_POWERBOOK_VGA; /* vga rather than dvi */ 2781209ff23fSmrg break; 2782209ff23fSmrg } 2783209ff23fSmrg 2784209ff23fSmrg if (strstr(cpuline, "PowerMac10,1")) { 2785209ff23fSmrg ret = RADEON_MAC_MINI_INTERNAL; /* internal tmds */ 2786209ff23fSmrg break; 2787209ff23fSmrg } 2788209ff23fSmrg if (strstr(cpuline, "PowerMac10,2")) { 2789209ff23fSmrg ret = RADEON_MAC_MINI_EXTERNAL; /* external tmds */ 2790209ff23fSmrg break; 2791209ff23fSmrg } 2792ba58b518Smacallan#ifdef __linux__ 2793209ff23fSmrg } else if (!strncmp(cpuline, "detected as", strlen("detected as"))) { 2794209ff23fSmrg if (strstr(cpuline, "iBook")) { 2795209ff23fSmrg ret = RADEON_MAC_IBOOK; 2796209ff23fSmrg break; 2797209ff23fSmrg } else if (strstr(cpuline, "PowerBook")) { 2798209ff23fSmrg ret = RADEON_MAC_POWERBOOK_INTERNAL; /* internal tmds */ 2799209ff23fSmrg break; 2800209ff23fSmrg } else if (strstr(cpuline, "iMac G5 (iSight)")) { 2801209ff23fSmrg ret = RADEON_MAC_IMAC_G5_ISIGHT; 2802209ff23fSmrg break; 2803b7e1c893Smrg } else if (strstr(cpuline, "eMac")) { 2804b7e1c893Smrg ret = RADEON_MAC_EMAC; 2805b7e1c893Smrg break; 2806209ff23fSmrg } 2807ba58b518Smacallan#endif 2808209ff23fSmrg /* No known PowerMac model detected */ 2809209ff23fSmrg break; 2810209ff23fSmrg } 2811209ff23fSmrg } 2812209ff23fSmrg 2813ba58b518Smacallan#ifdef __linux__ 2814209ff23fSmrg fclose (f); 2815209ff23fSmrg } else 2816209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2817209ff23fSmrg "Cannot detect PowerMac model because /proc/cpuinfo not " 2818209ff23fSmrg "readable.\n"); 2819ba58b518Smacallan#elif defined(__NetBSD__) 2820ba58b518Smacallan close(of); 2821ba58b518Smacallan } else 2822ba58b518Smacallan xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2823ba58b518Smacallan "Cannot detect PowerMac model because /dev/openfirm not " 2824ba58b518Smacallan "readable.\n"); 2825ba58b518Smacallan#endif 2826209ff23fSmrg 2827ad43ddacSmrg#ifdef __OpenBSD__ 2828ad43ddacSmrg char model[32]; 2829ad43ddacSmrg int mib[2]; 2830ad43ddacSmrg size_t len; 2831ad43ddacSmrg 2832ad43ddacSmrg mib[0] = CTL_HW; 2833ad43ddacSmrg mib[1] = HW_PRODUCT; 2834ad43ddacSmrg len = sizeof(model); 2835ad43ddacSmrg if (sysctl(mib, 2, model, &len, NULL, 0) >= 0) { 2836ad43ddacSmrg if (strcmp(model, "PowerBook5,1") == 0 || 2837ad43ddacSmrg strcmp(model, "PowerBook5,2") == 0 || 2838ad43ddacSmrg strcmp(model, "PowerBook5,3") == 0 || 2839ad43ddacSmrg strcmp(model, "PowerBook5,4") == 0 || 2840ad43ddacSmrg strcmp(model, "PowerBook5,5") == 0) { 2841ad43ddacSmrg ret = RADEON_MAC_POWERBOOK_EXTERNAL; /* single link */ 2842ad43ddacSmrg info->ext_tmds_chip = RADEON_SIL_164; /* works on 5,2 */ 2843ad43ddacSmrg } 2844ad43ddacSmrg 2845ad43ddacSmrg if (strcmp(model, "PowerBook5,6") == 0) { 2846ad43ddacSmrg ret = RADEON_MAC_POWERBOOK_EXTERNAL; /* dual or single link */ 2847ad43ddacSmrg } 2848ad43ddacSmrg 2849ad43ddacSmrg if (strcmp(model, "PowerBook5,7") || 2850ad43ddacSmrg strcmp(model, "PowerBook5,8") == 0 || 2851ad43ddacSmrg strcmp(model, "PowerBook5,9") == 0) { 2852ad43ddacSmrg ret = RADEON_MAC_POWERBOOK_EXTERNAL; /* dual link */ 2853ad43ddacSmrg info->ext_tmds_chip = RADEON_SIL_1178; /* guess */ 2854ad43ddacSmrg } 2855ad43ddacSmrg 2856ad43ddacSmrg if (strcmp(model, "PowerBook3,3") == 0) { 2857ad43ddacSmrg ret = RADEON_MAC_POWERBOOK_VGA; /* vga rather than dvi */ 2858ad43ddacSmrg } 2859ad43ddacSmrg 2860ad43ddacSmrg if (strcmp(model, "PowerMac10,1") == 0) { 2861ad43ddacSmrg ret = RADEON_MAC_MINI_INTERNAL; /* internal tmds */ 2862ad43ddacSmrg } 2863ad43ddacSmrg 2864ad43ddacSmrg if (strcmp(model, "PowerMac10,2") == 0) { 2865ad43ddacSmrg ret = RADEON_MAC_MINI_EXTERNAL; /* external tmds */ 2866ad43ddacSmrg } 2867ad43ddacSmrg 2868ad43ddacSmrg if (strcmp(model, "PowerBook2,1") == 0 || 2869ad43ddacSmrg strcmp(model, "PowerBook2,2") == 0 || 2870ad43ddacSmrg strcmp(model, "PowerBook4,1") == 0 || 2871ad43ddacSmrg strcmp(model, "PowerBook4,2") == 0 || 2872ad43ddacSmrg strcmp(model, "PowerBook4,3") == 0 || 2873ad43ddacSmrg strcmp(model, "PowerBook6,3") == 0 || 2874ad43ddacSmrg strcmp(model, "PowerBook6,5") == 0 || 2875ad43ddacSmrg strcmp(model, "PowerBook6,7") == 0) { 2876ad43ddacSmrg ret = RADEON_MAC_IBOOK; 2877ad43ddacSmrg } 2878ad43ddacSmrg 2879ad43ddacSmrg if (strcmp(model, "PowerBook1,1") == 0 || 2880ad43ddacSmrg strcmp(model, "PowerBook3,1") == 0 || 2881ad43ddacSmrg strcmp(model, "PowerBook3,2") == 0 || 2882ad43ddacSmrg strcmp(model, "PowerBook3,4") == 0 || 2883ad43ddacSmrg strcmp(model, "PowerBook3,5") == 0) { 2884ad43ddacSmrg ret = RADEON_MAC_POWERBOOK_INTERNAL; 2885ad43ddacSmrg } 2886ad43ddacSmrg 2887ad43ddacSmrg if (strcmp(model, "PowerMac12,1") == 0) { 2888ad43ddacSmrg ret = RADEON_MAC_IMAC_G5_ISIGHT; 2889ad43ddacSmrg } 2890ad43ddacSmrg } 2891ad43ddacSmrg#endif /* __OpenBSD__ */ 2892ad43ddacSmrg 2893209ff23fSmrg if (ret) { 2894209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Detected %s.\n", 2895209ff23fSmrg ret == RADEON_MAC_POWERBOOK_EXTERNAL ? "PowerBook with external DVI" : 2896209ff23fSmrg ret == RADEON_MAC_POWERBOOK_INTERNAL ? "PowerBook with integrated DVI" : 2897209ff23fSmrg ret == RADEON_MAC_POWERBOOK_VGA ? "PowerBook with VGA" : 2898209ff23fSmrg ret == RADEON_MAC_IBOOK ? "iBook" : 2899209ff23fSmrg ret == RADEON_MAC_MINI_EXTERNAL ? "Mac Mini with external DVI" : 2900209ff23fSmrg ret == RADEON_MAC_MINI_INTERNAL ? "Mac Mini with integrated DVI" : 2901209ff23fSmrg "iMac G5 iSight"); 2902209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2903209ff23fSmrg "If this is not correct, try Option \"MacModel\" and " 2904209ff23fSmrg "consider reporting to the\n"); 2905209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2906209ff23fSmrg "xorg-driver-ati@lists.x.org mailing list" 2907209ff23fSmrg#ifdef __linux__ 2908209ff23fSmrg " with the contents of /proc/cpuinfo" 2909209ff23fSmrg#endif 2910209ff23fSmrg ".\n"); 2911209ff23fSmrg } 2912209ff23fSmrg 2913209ff23fSmrg return ret; 2914209ff23fSmrg} 2915209ff23fSmrg 2916209ff23fSmrg#endif /* __powerpc__ */ 2917209ff23fSmrg 2918209ff23fSmrgstatic int 2919209ff23fSmrgradeon_output_clones (ScrnInfoPtr pScrn, xf86OutputPtr output) 2920209ff23fSmrg{ 2921b7e1c893Smrg RADEONInfoPtr info = RADEONPTR(pScrn); 2922209ff23fSmrg RADEONOutputPrivatePtr radeon_output = output->driver_private; 2923209ff23fSmrg xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); 2924209ff23fSmrg int o; 2925209ff23fSmrg int index_mask = 0; 2926209ff23fSmrg 2927ad43ddacSmrg /* no cloning with zaphod */ 2928ad43ddacSmrg if (info->IsPrimary || info->IsSecondary) 2929ad43ddacSmrg return index_mask; 2930ad43ddacSmrg 2931b7e1c893Smrg /* DIG routing gets problematic */ 2932ad43ddacSmrg if (info->ChipFamily >= CHIP_FAMILY_R600) 2933209ff23fSmrg return index_mask; 2934209ff23fSmrg 2935209ff23fSmrg /* LVDS is too wacky */ 2936b7e1c893Smrg if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) 2937b7e1c893Smrg return index_mask; 2938b7e1c893Smrg 2939ad43ddacSmrg /* TV requires very specific timing */ 2940b7e1c893Smrg if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) 2941209ff23fSmrg return index_mask; 2942209ff23fSmrg 2943ad43ddacSmrg /* DVO requires 2x ppll clocks depending on the tmds chip */ 2944ad43ddacSmrg if (radeon_output->devices & (ATOM_DEVICE_DFP2_SUPPORT)) 2945ad43ddacSmrg return index_mask; 2946ad43ddacSmrg 2947209ff23fSmrg for (o = 0; o < config->num_output; o++) { 2948209ff23fSmrg xf86OutputPtr clone = config->output[o]; 2949209ff23fSmrg RADEONOutputPrivatePtr radeon_clone = clone->driver_private; 2950b7e1c893Smrg 2951209ff23fSmrg if (output == clone) /* don't clone yourself */ 2952209ff23fSmrg continue; 2953b7e1c893Smrg else if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT)) /* LVDS */ 2954209ff23fSmrg continue; 2955b7e1c893Smrg else if (radeon_clone->devices & (ATOM_DEVICE_TV_SUPPORT)) /* TV */ 2956209ff23fSmrg continue; 2957209ff23fSmrg else 2958209ff23fSmrg index_mask |= (1 << o); 2959209ff23fSmrg } 2960209ff23fSmrg 2961209ff23fSmrg return index_mask; 2962209ff23fSmrg} 2963209ff23fSmrg 2964b7e1c893Smrgstatic xf86OutputPtr 2965b7e1c893SmrgRADEONOutputCreate(ScrnInfoPtr pScrn, const char *name, int i) 2966b7e1c893Smrg{ 2967b7e1c893Smrg char buf[32]; 2968b7e1c893Smrg sprintf(buf, name, i); 2969b7e1c893Smrg return xf86OutputCreate(pScrn, &radeon_output_funcs, buf); 2970b7e1c893Smrg} 2971b7e1c893Smrg 2972209ff23fSmrg/* 2973209ff23fSmrg * initialise the static data sos we don't have to re-do at randr change */ 2974209ff23fSmrgBool RADEONSetupConnectors(ScrnInfoPtr pScrn) 2975209ff23fSmrg{ 2976209ff23fSmrg xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2977209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 2978209ff23fSmrg xf86OutputPtr output; 2979209ff23fSmrg char *optstr; 2980b7e1c893Smrg int i; 2981209ff23fSmrg int num_vga = 0; 2982209ff23fSmrg int num_dvi = 0; 2983209ff23fSmrg int num_hdmi = 0; 2984b7e1c893Smrg int num_dp = 0; 2985ad43ddacSmrg int num_edp = 0; 2986209ff23fSmrg 2987209ff23fSmrg /* We first get the information about all connectors from BIOS. 2988209ff23fSmrg * This is how the card is phyiscally wired up. 2989209ff23fSmrg * The information should be correct even on a OEM card. 2990209ff23fSmrg */ 2991209ff23fSmrg for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) { 2992b7e1c893Smrg info->encoders[i] = NULL; 2993209ff23fSmrg info->BiosConnector[i].valid = FALSE; 2994b7e1c893Smrg info->BiosConnector[i].load_detection = TRUE; 2995b7e1c893Smrg info->BiosConnector[i].shared_ddc = FALSE; 2996209ff23fSmrg info->BiosConnector[i].ddc_i2c.valid = FALSE; 2997209ff23fSmrg info->BiosConnector[i].ConnectorType = CONNECTOR_NONE; 2998b7e1c893Smrg info->BiosConnector[i].devices = 0; 2999209ff23fSmrg } 3000209ff23fSmrg 3001209ff23fSmrg#if defined(__powerpc__) 3002209ff23fSmrg info->MacModel = 0; 3003209ff23fSmrg optstr = (char *)xf86GetOptValString(info->Options, OPTION_MAC_MODEL); 3004209ff23fSmrg if (optstr) { 3005209ff23fSmrg if (!strncmp("ibook", optstr, strlen("ibook"))) 3006209ff23fSmrg info->MacModel = RADEON_MAC_IBOOK; 3007209ff23fSmrg else if (!strncmp("powerbook-duallink", optstr, strlen("powerbook-duallink"))) /* alias */ 3008209ff23fSmrg info->MacModel = RADEON_MAC_POWERBOOK_EXTERNAL; 3009209ff23fSmrg else if (!strncmp("powerbook-external", optstr, strlen("powerbook-external"))) 3010209ff23fSmrg info->MacModel = RADEON_MAC_POWERBOOK_EXTERNAL; 3011209ff23fSmrg else if (!strncmp("powerbook-internal", optstr, strlen("powerbook-internal"))) 3012209ff23fSmrg info->MacModel = RADEON_MAC_POWERBOOK_INTERNAL; 3013209ff23fSmrg else if (!strncmp("powerbook-vga", optstr, strlen("powerbook-vga"))) 3014209ff23fSmrg info->MacModel = RADEON_MAC_POWERBOOK_VGA; 3015209ff23fSmrg else if (!strncmp("powerbook", optstr, strlen("powerbook"))) /* alias */ 3016209ff23fSmrg info->MacModel = RADEON_MAC_POWERBOOK_INTERNAL; 3017209ff23fSmrg else if (!strncmp("mini-internal", optstr, strlen("mini-internal"))) 3018209ff23fSmrg info->MacModel = RADEON_MAC_MINI_INTERNAL; 3019209ff23fSmrg else if (!strncmp("mini-external", optstr, strlen("mini-external"))) 3020209ff23fSmrg info->MacModel = RADEON_MAC_MINI_EXTERNAL; 3021209ff23fSmrg else if (!strncmp("mini", optstr, strlen("mini"))) /* alias */ 3022209ff23fSmrg info->MacModel = RADEON_MAC_MINI_EXTERNAL; 3023209ff23fSmrg else if (!strncmp("imac-g5-isight", optstr, strlen("imac-g5-isight"))) 3024209ff23fSmrg info->MacModel = RADEON_MAC_IMAC_G5_ISIGHT; 3025b7e1c893Smrg else if (!strncmp("emac", optstr, strlen("emac"))) 3026b7e1c893Smrg info->MacModel = RADEON_MAC_EMAC; 302768105dcbSveego else if (!strncmp("sam440ep", optstr, strlen("sam440ep"))) 302868105dcbSveego info->MacModel = RADEON_MAC_SAM440EP; 3029209ff23fSmrg else { 3030209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid Mac Model: %s\n", optstr); 3031209ff23fSmrg } 3032209ff23fSmrg } 3033209ff23fSmrg 3034209ff23fSmrg if (!info->MacModel) { 3035209ff23fSmrg info->MacModel = RADEONDetectMacModel(pScrn); 3036209ff23fSmrg } 3037209ff23fSmrg 3038209ff23fSmrg if (info->MacModel){ 3039209ff23fSmrg if (!RADEONSetupAppleConnectors(pScrn)) 3040209ff23fSmrg RADEONSetupGenericConnectors(pScrn); 3041209ff23fSmrg } else 3042209ff23fSmrg#endif 3043209ff23fSmrg if (xf86ReturnOptValBool(info->Options, OPTION_DEFAULT_CONNECTOR_TABLE, FALSE)) { 3044209ff23fSmrg RADEONSetupGenericConnectors(pScrn); 3045209ff23fSmrg } else { 3046209ff23fSmrg if (!RADEONGetConnectorInfoFromBIOS(pScrn)) 3047209ff23fSmrg RADEONSetupGenericConnectors(pScrn); 3048209ff23fSmrg } 3049209ff23fSmrg 3050209ff23fSmrg /* parse connector table option */ 3051209ff23fSmrg optstr = (char *)xf86GetOptValString(info->Options, OPTION_CONNECTORTABLE); 3052209ff23fSmrg 3053209ff23fSmrg if (optstr) { 3054209ff23fSmrg unsigned int ddc_line[2]; 3055b7e1c893Smrg int DACType[2], TMDSType[2]; 3056209ff23fSmrg 3057209ff23fSmrg for (i = 2; i < RADEON_MAX_BIOS_CONNECTOR; i++) { 3058209ff23fSmrg info->BiosConnector[i].valid = FALSE; 3059209ff23fSmrg } 3060b7e1c893Smrg 3061209ff23fSmrg if (sscanf(optstr, "%u,%u,%u,%u,%u,%u,%u,%u", 3062209ff23fSmrg &ddc_line[0], 3063b7e1c893Smrg &DACType[0], 3064b7e1c893Smrg &TMDSType[0], 3065209ff23fSmrg &info->BiosConnector[0].ConnectorType, 3066209ff23fSmrg &ddc_line[1], 3067b7e1c893Smrg &DACType[1], 3068b7e1c893Smrg &TMDSType[1], 3069209ff23fSmrg &info->BiosConnector[1].ConnectorType) != 8) { 3070209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid ConnectorTable option: %s\n", optstr); 3071209ff23fSmrg return FALSE; 3072209ff23fSmrg } 3073209ff23fSmrg 3074b7e1c893Smrg for (i = 0; i < 2; i++) { 3075b7e1c893Smrg info->BiosConnector[i].valid = TRUE; 3076b7e1c893Smrg info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(ddc_line[i]); 3077b7e1c893Smrg switch (DACType[i]) { 3078b7e1c893Smrg case 1: 3079b7e1c893Smrg info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT; 3080b7e1c893Smrg if (!radeon_add_encoder(pScrn, 3081b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 3082b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT, 3083b7e1c893Smrg 1), 3084b7e1c893Smrg ATOM_DEVICE_CRT1_SUPPORT)) 3085b7e1c893Smrg return FALSE; 3086b7e1c893Smrg info->BiosConnector[i].load_detection = TRUE; 3087b7e1c893Smrg break; 3088b7e1c893Smrg case 2: 3089b7e1c893Smrg info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT; 3090b7e1c893Smrg if (!radeon_add_encoder(pScrn, 3091b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 309240732134Srjs ATOM_DEVICE_CRT2_SUPPORT, 3093b7e1c893Smrg 2), 309440732134Srjs ATOM_DEVICE_CRT2_SUPPORT)) 3095b7e1c893Smrg return FALSE; 3096b7e1c893Smrg info->BiosConnector[i].load_detection = FALSE; 3097b7e1c893Smrg break; 3098b7e1c893Smrg } 3099b7e1c893Smrg switch (TMDSType[i]) { 3100b7e1c893Smrg case 1: 3101b7e1c893Smrg info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT; 3102b7e1c893Smrg if (!radeon_add_encoder(pScrn, 3103b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 3104b7e1c893Smrg ATOM_DEVICE_DFP1_SUPPORT, 3105b7e1c893Smrg 0), 3106b7e1c893Smrg ATOM_DEVICE_DFP1_SUPPORT)) 3107b7e1c893Smrg return FALSE; 3108b7e1c893Smrg break; 3109b7e1c893Smrg case 2: 3110b7e1c893Smrg info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT; 3111b7e1c893Smrg if (!radeon_add_encoder(pScrn, 3112b7e1c893Smrg radeon_get_encoder_id_from_supported_device(pScrn, 3113b7e1c893Smrg ATOM_DEVICE_DFP2_SUPPORT, 3114b7e1c893Smrg 0), 3115b7e1c893Smrg ATOM_DEVICE_DFP2_SUPPORT)) 3116b7e1c893Smrg return FALSE; 3117b7e1c893Smrg break; 3118b7e1c893Smrg } 3119b7e1c893Smrg } 3120209ff23fSmrg } 3121209ff23fSmrg 3122209ff23fSmrg for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) { 3123209ff23fSmrg if (info->BiosConnector[i].valid) { 3124b7e1c893Smrg RADEONConnectorType conntype = info->BiosConnector[i].ConnectorType; 3125b7e1c893Smrg if ((conntype == CONNECTOR_DVI_D) || 3126b7e1c893Smrg (conntype == CONNECTOR_DVI_I) || 3127ad43ddacSmrg (conntype == CONNECTOR_DVI_A) || 3128ad43ddacSmrg (conntype == CONNECTOR_HDMI_TYPE_B)) { 3129209ff23fSmrg num_dvi++; 3130b7e1c893Smrg } else if (conntype == CONNECTOR_VGA) { 3131209ff23fSmrg num_vga++; 3132ad43ddacSmrg } else if (conntype == CONNECTOR_HDMI_TYPE_A) { 3133209ff23fSmrg num_hdmi++; 3134b7e1c893Smrg } else if (conntype == CONNECTOR_DISPLAY_PORT) { 3135b7e1c893Smrg num_dp++; 3136ad43ddacSmrg } else if (conntype == CONNECTOR_EDP) { 3137ad43ddacSmrg num_edp++; 3138209ff23fSmrg } 3139209ff23fSmrg } 3140209ff23fSmrg } 3141209ff23fSmrg 3142209ff23fSmrg for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) { 3143209ff23fSmrg if (info->BiosConnector[i].valid) { 3144209ff23fSmrg RADEONOutputPrivatePtr radeon_output; 3145b7e1c893Smrg RADEONConnectorType conntype = info->BiosConnector[i].ConnectorType; 3146209ff23fSmrg 3147b7e1c893Smrg if (conntype == CONNECTOR_NONE) 3148209ff23fSmrg continue; 3149209ff23fSmrg 3150209ff23fSmrg radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1); 3151209ff23fSmrg if (!radeon_output) { 3152209ff23fSmrg return FALSE; 3153209ff23fSmrg } 3154209ff23fSmrg radeon_output->MonType = MT_UNKNOWN; 3155b7e1c893Smrg radeon_output->ConnectorType = conntype; 3156209ff23fSmrg radeon_output->devices = info->BiosConnector[i].devices; 3157209ff23fSmrg radeon_output->ddc_i2c = info->BiosConnector[i].ddc_i2c; 3158209ff23fSmrg radeon_output->igp_lane_info = info->BiosConnector[i].igp_lane_info; 3159b7e1c893Smrg radeon_output->shared_ddc = info->BiosConnector[i].shared_ddc; 3160b7e1c893Smrg radeon_output->load_detection = info->BiosConnector[i].load_detection; 3161b7e1c893Smrg radeon_output->linkb = info->BiosConnector[i].linkb; 3162ad43ddacSmrg radeon_output->dig_encoder = -1; 3163b7e1c893Smrg radeon_output->connector_id = info->BiosConnector[i].connector_object; 3164ad43ddacSmrg radeon_output->connector_object_id = info->BiosConnector[i].connector_object_id; 3165ad43ddacSmrg radeon_output->ucI2cId = info->BiosConnector[i].ucI2cId; 3166ad43ddacSmrg radeon_output->hpd_id = info->BiosConnector[i].hpd_id; 3167b7e1c893Smrg 3168ad43ddacSmrg /* Technically HDMI-B is a glorfied DL DVI so the bios is correct, 3169ad43ddacSmrg * but this can be confusing to users when it comes to output names, 3170ad43ddacSmrg * so call it DVI 3171ad43ddacSmrg */ 3172b7e1c893Smrg if ((conntype == CONNECTOR_DVI_D) || 3173b7e1c893Smrg (conntype == CONNECTOR_DVI_I) || 3174ad43ddacSmrg (conntype == CONNECTOR_DVI_A) || 3175ad43ddacSmrg (conntype == CONNECTOR_HDMI_TYPE_B)) { 3176b7e1c893Smrg output = RADEONOutputCreate(pScrn, "DVI-%d", --num_dvi); 3177b7e1c893Smrg } else if (conntype == CONNECTOR_VGA) { 3178b7e1c893Smrg output = RADEONOutputCreate(pScrn, "VGA-%d", --num_vga); 3179ad43ddacSmrg } else if (conntype == CONNECTOR_HDMI_TYPE_A) { 3180b7e1c893Smrg output = RADEONOutputCreate(pScrn, "HDMI-%d", --num_hdmi); 3181b7e1c893Smrg } else if (conntype == CONNECTOR_DISPLAY_PORT) { 3182b7e1c893Smrg output = RADEONOutputCreate(pScrn, "DisplayPort-%d", --num_dp); 3183ad43ddacSmrg } else if (conntype == CONNECTOR_EDP) { 3184ad43ddacSmrg output = RADEONOutputCreate(pScrn, "eDP-%d", --num_edp); 3185b7e1c893Smrg } else { 3186b7e1c893Smrg output = RADEONOutputCreate(pScrn, 3187b7e1c893Smrg ConnectorTypeName[conntype], 0); 3188b7e1c893Smrg } 3189209ff23fSmrg 3190209ff23fSmrg if (!output) { 3191209ff23fSmrg return FALSE; 3192209ff23fSmrg } 31930974d292Smrg output->interlaceAllowed = TRUE; 31940974d292Smrg output->doubleScanAllowed = TRUE; 3195209ff23fSmrg output->driver_private = radeon_output; 3196ad43ddacSmrg if (IS_DCE4_VARIANT) { 3197ad43ddacSmrg output->possible_crtcs = 0x3f; 3198ad43ddacSmrg } else { 3199ad43ddacSmrg output->possible_crtcs = 1; 3200ad43ddacSmrg /* crtc2 can drive LVDS, it just doesn't have RMX */ 3201ad43ddacSmrg if (!(radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT))) 3202ad43ddacSmrg output->possible_crtcs |= 2; 3203ad43ddacSmrg } 3204209ff23fSmrg 3205b7e1c893Smrg /* we can clone the DACs, and probably TV-out, 3206209ff23fSmrg but I'm not sure it's worth the trouble */ 3207209ff23fSmrg output->possible_clones = 0; 3208209ff23fSmrg 3209209ff23fSmrg RADEONInitConnector(output); 3210209ff23fSmrg } 3211209ff23fSmrg } 3212209ff23fSmrg 3213209ff23fSmrg for (i = 0; i < xf86_config->num_output; i++) { 3214209ff23fSmrg xf86OutputPtr output = xf86_config->output[i]; 3215209ff23fSmrg 3216209ff23fSmrg output->possible_clones = radeon_output_clones(pScrn, output); 3217ad43ddacSmrg RADEONGetHardCodedEDIDFromFile(output); 3218209ff23fSmrg } 3219209ff23fSmrg 3220209ff23fSmrg return TRUE; 3221209ff23fSmrg} 3222209ff23fSmrg 3223