1254885Sdumbbell/* 2254885Sdumbbell * Copyright 2004 ATI Technologies Inc., Markham, Ontario 3254885Sdumbbell * Copyright 2007-8 Advanced Micro Devices, Inc. 4254885Sdumbbell * Copyright 2008 Red Hat Inc. 5254885Sdumbbell * 6254885Sdumbbell * Permission is hereby granted, free of charge, to any person obtaining a 7254885Sdumbbell * copy of this software and associated documentation files (the "Software"), 8254885Sdumbbell * to deal in the Software without restriction, including without limitation 9254885Sdumbbell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10254885Sdumbbell * and/or sell copies of the Software, and to permit persons to whom the 11254885Sdumbbell * Software is furnished to do so, subject to the following conditions: 12254885Sdumbbell * 13254885Sdumbbell * The above copyright notice and this permission notice shall be included in 14254885Sdumbbell * all copies or substantial portions of the Software. 15254885Sdumbbell * 16254885Sdumbbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17254885Sdumbbell * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18254885Sdumbbell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19254885Sdumbbell * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20254885Sdumbbell * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21254885Sdumbbell * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22254885Sdumbbell * OTHER DEALINGS IN THE SOFTWARE. 23254885Sdumbbell * 24254885Sdumbbell * Authors: Dave Airlie 25254885Sdumbbell * Alex Deucher 26254885Sdumbbell */ 27254885Sdumbbell 28254885Sdumbbell#include <sys/cdefs.h> 29254885Sdumbbell__FBSDID("$FreeBSD: releng/11.0/sys/dev/drm2/radeon/radeon_combios.c 280183 2015-03-17 18:50:33Z dumbbell $"); 30254885Sdumbbell 31254885Sdumbbell#include <dev/drm2/drmP.h> 32254885Sdumbbell#include <dev/drm2/radeon/radeon_drm.h> 33254885Sdumbbell#include "radeon.h" 34254885Sdumbbell#include "atom.h" 35254885Sdumbbell 36254885Sdumbbell#ifdef CONFIG_PPC_PMAC 37254885Sdumbbell/* not sure which of these are needed */ 38254885Sdumbbell#include <asm/machdep.h> 39254885Sdumbbell#include <asm/pmac_feature.h> 40254885Sdumbbell#include <asm/prom.h> 41254885Sdumbbell#include <asm/pci-bridge.h> 42254885Sdumbbell#endif /* CONFIG_PPC_PMAC */ 43254885Sdumbbell 44280183Sdumbbell#ifdef FREEBSD_WIP /* FreeBSD: to please GCC 4.2. */ 45280183Sdumbbell/* from radeon_encoder.c */ 46280183Sdumbbellextern uint32_t 47280183Sdumbbellradeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, 48280183Sdumbbell uint8_t dac); 49280183Sdumbbellextern void radeon_link_encoder_connector(struct drm_device *dev); 50280183Sdumbbell 51280183Sdumbbell/* from radeon_connector.c */ 52280183Sdumbbellextern void 53280183Sdumbbellradeon_add_legacy_connector(struct drm_device *dev, 54280183Sdumbbell uint32_t connector_id, 55280183Sdumbbell uint32_t supported_device, 56280183Sdumbbell int connector_type, 57280183Sdumbbell struct radeon_i2c_bus_rec *i2c_bus, 58280183Sdumbbell uint16_t connector_object_id, 59280183Sdumbbell struct radeon_hpd *hpd); 60280183Sdumbbell 61280183Sdumbbell/* from radeon_legacy_encoder.c */ 62280183Sdumbbellextern void 63280183Sdumbbellradeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, 64280183Sdumbbell uint32_t supported_device); 65280183Sdumbbell#endif 66280183Sdumbbell 67254885Sdumbbell/* old legacy ATI BIOS routines */ 68254885Sdumbbell 69254885Sdumbbell/* COMBIOS table offsets */ 70254885Sdumbbellenum radeon_combios_table_offset { 71254885Sdumbbell /* absolute offset tables */ 72254885Sdumbbell COMBIOS_ASIC_INIT_1_TABLE, 73254885Sdumbbell COMBIOS_BIOS_SUPPORT_TABLE, 74254885Sdumbbell COMBIOS_DAC_PROGRAMMING_TABLE, 75254885Sdumbbell COMBIOS_MAX_COLOR_DEPTH_TABLE, 76254885Sdumbbell COMBIOS_CRTC_INFO_TABLE, 77254885Sdumbbell COMBIOS_PLL_INFO_TABLE, 78254885Sdumbbell COMBIOS_TV_INFO_TABLE, 79254885Sdumbbell COMBIOS_DFP_INFO_TABLE, 80254885Sdumbbell COMBIOS_HW_CONFIG_INFO_TABLE, 81254885Sdumbbell COMBIOS_MULTIMEDIA_INFO_TABLE, 82254885Sdumbbell COMBIOS_TV_STD_PATCH_TABLE, 83254885Sdumbbell COMBIOS_LCD_INFO_TABLE, 84254885Sdumbbell COMBIOS_MOBILE_INFO_TABLE, 85254885Sdumbbell COMBIOS_PLL_INIT_TABLE, 86254885Sdumbbell COMBIOS_MEM_CONFIG_TABLE, 87254885Sdumbbell COMBIOS_SAVE_MASK_TABLE, 88254885Sdumbbell COMBIOS_HARDCODED_EDID_TABLE, 89254885Sdumbbell COMBIOS_ASIC_INIT_2_TABLE, 90254885Sdumbbell COMBIOS_CONNECTOR_INFO_TABLE, 91254885Sdumbbell COMBIOS_DYN_CLK_1_TABLE, 92254885Sdumbbell COMBIOS_RESERVED_MEM_TABLE, 93254885Sdumbbell COMBIOS_EXT_TMDS_INFO_TABLE, 94254885Sdumbbell COMBIOS_MEM_CLK_INFO_TABLE, 95254885Sdumbbell COMBIOS_EXT_DAC_INFO_TABLE, 96254885Sdumbbell COMBIOS_MISC_INFO_TABLE, 97254885Sdumbbell COMBIOS_CRT_INFO_TABLE, 98254885Sdumbbell COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE, 99254885Sdumbbell COMBIOS_COMPONENT_VIDEO_INFO_TABLE, 100254885Sdumbbell COMBIOS_FAN_SPEED_INFO_TABLE, 101254885Sdumbbell COMBIOS_OVERDRIVE_INFO_TABLE, 102254885Sdumbbell COMBIOS_OEM_INFO_TABLE, 103254885Sdumbbell COMBIOS_DYN_CLK_2_TABLE, 104254885Sdumbbell COMBIOS_POWER_CONNECTOR_INFO_TABLE, 105254885Sdumbbell COMBIOS_I2C_INFO_TABLE, 106254885Sdumbbell /* relative offset tables */ 107254885Sdumbbell COMBIOS_ASIC_INIT_3_TABLE, /* offset from misc info */ 108254885Sdumbbell COMBIOS_ASIC_INIT_4_TABLE, /* offset from misc info */ 109254885Sdumbbell COMBIOS_DETECTED_MEM_TABLE, /* offset from misc info */ 110254885Sdumbbell COMBIOS_ASIC_INIT_5_TABLE, /* offset from misc info */ 111254885Sdumbbell COMBIOS_RAM_RESET_TABLE, /* offset from mem config */ 112254885Sdumbbell COMBIOS_POWERPLAY_INFO_TABLE, /* offset from mobile info */ 113254885Sdumbbell COMBIOS_GPIO_INFO_TABLE, /* offset from mobile info */ 114254885Sdumbbell COMBIOS_LCD_DDC_INFO_TABLE, /* offset from mobile info */ 115254885Sdumbbell COMBIOS_TMDS_POWER_TABLE, /* offset from mobile info */ 116254885Sdumbbell COMBIOS_TMDS_POWER_ON_TABLE, /* offset from tmds power */ 117254885Sdumbbell COMBIOS_TMDS_POWER_OFF_TABLE, /* offset from tmds power */ 118254885Sdumbbell}; 119254885Sdumbbell 120254885Sdumbbellenum radeon_combios_ddc { 121254885Sdumbbell DDC_NONE_DETECTED, 122254885Sdumbbell DDC_MONID, 123254885Sdumbbell DDC_DVI, 124254885Sdumbbell DDC_VGA, 125254885Sdumbbell DDC_CRT2, 126254885Sdumbbell DDC_LCD, 127254885Sdumbbell DDC_GPIO, 128254885Sdumbbell}; 129254885Sdumbbell 130254885Sdumbbellenum radeon_combios_connector { 131254885Sdumbbell CONNECTOR_NONE_LEGACY, 132254885Sdumbbell CONNECTOR_PROPRIETARY_LEGACY, 133254885Sdumbbell CONNECTOR_CRT_LEGACY, 134254885Sdumbbell CONNECTOR_DVI_I_LEGACY, 135254885Sdumbbell CONNECTOR_DVI_D_LEGACY, 136254885Sdumbbell CONNECTOR_CTV_LEGACY, 137254885Sdumbbell CONNECTOR_STV_LEGACY, 138254885Sdumbbell CONNECTOR_UNSUPPORTED_LEGACY 139254885Sdumbbell}; 140254885Sdumbbell 141254885Sdumbbellconst int legacy_connector_convert[] = { 142254885Sdumbbell DRM_MODE_CONNECTOR_Unknown, 143254885Sdumbbell DRM_MODE_CONNECTOR_DVID, 144254885Sdumbbell DRM_MODE_CONNECTOR_VGA, 145254885Sdumbbell DRM_MODE_CONNECTOR_DVII, 146254885Sdumbbell DRM_MODE_CONNECTOR_DVID, 147254885Sdumbbell DRM_MODE_CONNECTOR_Composite, 148254885Sdumbbell DRM_MODE_CONNECTOR_SVIDEO, 149254885Sdumbbell DRM_MODE_CONNECTOR_Unknown, 150254885Sdumbbell}; 151254885Sdumbbell 152254885Sdumbbellstatic uint16_t combios_get_table_offset(struct drm_device *dev, 153254885Sdumbbell enum radeon_combios_table_offset table) 154254885Sdumbbell{ 155254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 156254885Sdumbbell int rev; 157254885Sdumbbell uint16_t offset = 0, check_offset; 158254885Sdumbbell 159254885Sdumbbell if (!rdev->bios) 160254885Sdumbbell return 0; 161254885Sdumbbell 162254885Sdumbbell switch (table) { 163254885Sdumbbell /* absolute offset tables */ 164254885Sdumbbell case COMBIOS_ASIC_INIT_1_TABLE: 165254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0xc); 166254885Sdumbbell if (check_offset) 167254885Sdumbbell offset = check_offset; 168254885Sdumbbell break; 169254885Sdumbbell case COMBIOS_BIOS_SUPPORT_TABLE: 170254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x14); 171254885Sdumbbell if (check_offset) 172254885Sdumbbell offset = check_offset; 173254885Sdumbbell break; 174254885Sdumbbell case COMBIOS_DAC_PROGRAMMING_TABLE: 175254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x2a); 176254885Sdumbbell if (check_offset) 177254885Sdumbbell offset = check_offset; 178254885Sdumbbell break; 179254885Sdumbbell case COMBIOS_MAX_COLOR_DEPTH_TABLE: 180254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x2c); 181254885Sdumbbell if (check_offset) 182254885Sdumbbell offset = check_offset; 183254885Sdumbbell break; 184254885Sdumbbell case COMBIOS_CRTC_INFO_TABLE: 185254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x2e); 186254885Sdumbbell if (check_offset) 187254885Sdumbbell offset = check_offset; 188254885Sdumbbell break; 189254885Sdumbbell case COMBIOS_PLL_INFO_TABLE: 190254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x30); 191254885Sdumbbell if (check_offset) 192254885Sdumbbell offset = check_offset; 193254885Sdumbbell break; 194254885Sdumbbell case COMBIOS_TV_INFO_TABLE: 195254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x32); 196254885Sdumbbell if (check_offset) 197254885Sdumbbell offset = check_offset; 198254885Sdumbbell break; 199254885Sdumbbell case COMBIOS_DFP_INFO_TABLE: 200254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x34); 201254885Sdumbbell if (check_offset) 202254885Sdumbbell offset = check_offset; 203254885Sdumbbell break; 204254885Sdumbbell case COMBIOS_HW_CONFIG_INFO_TABLE: 205254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x36); 206254885Sdumbbell if (check_offset) 207254885Sdumbbell offset = check_offset; 208254885Sdumbbell break; 209254885Sdumbbell case COMBIOS_MULTIMEDIA_INFO_TABLE: 210254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x38); 211254885Sdumbbell if (check_offset) 212254885Sdumbbell offset = check_offset; 213254885Sdumbbell break; 214254885Sdumbbell case COMBIOS_TV_STD_PATCH_TABLE: 215254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x3e); 216254885Sdumbbell if (check_offset) 217254885Sdumbbell offset = check_offset; 218254885Sdumbbell break; 219254885Sdumbbell case COMBIOS_LCD_INFO_TABLE: 220254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x40); 221254885Sdumbbell if (check_offset) 222254885Sdumbbell offset = check_offset; 223254885Sdumbbell break; 224254885Sdumbbell case COMBIOS_MOBILE_INFO_TABLE: 225254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x42); 226254885Sdumbbell if (check_offset) 227254885Sdumbbell offset = check_offset; 228254885Sdumbbell break; 229254885Sdumbbell case COMBIOS_PLL_INIT_TABLE: 230254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x46); 231254885Sdumbbell if (check_offset) 232254885Sdumbbell offset = check_offset; 233254885Sdumbbell break; 234254885Sdumbbell case COMBIOS_MEM_CONFIG_TABLE: 235254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x48); 236254885Sdumbbell if (check_offset) 237254885Sdumbbell offset = check_offset; 238254885Sdumbbell break; 239254885Sdumbbell case COMBIOS_SAVE_MASK_TABLE: 240254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x4a); 241254885Sdumbbell if (check_offset) 242254885Sdumbbell offset = check_offset; 243254885Sdumbbell break; 244254885Sdumbbell case COMBIOS_HARDCODED_EDID_TABLE: 245254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x4c); 246254885Sdumbbell if (check_offset) 247254885Sdumbbell offset = check_offset; 248254885Sdumbbell break; 249254885Sdumbbell case COMBIOS_ASIC_INIT_2_TABLE: 250254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x4e); 251254885Sdumbbell if (check_offset) 252254885Sdumbbell offset = check_offset; 253254885Sdumbbell break; 254254885Sdumbbell case COMBIOS_CONNECTOR_INFO_TABLE: 255254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x50); 256254885Sdumbbell if (check_offset) 257254885Sdumbbell offset = check_offset; 258254885Sdumbbell break; 259254885Sdumbbell case COMBIOS_DYN_CLK_1_TABLE: 260254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x52); 261254885Sdumbbell if (check_offset) 262254885Sdumbbell offset = check_offset; 263254885Sdumbbell break; 264254885Sdumbbell case COMBIOS_RESERVED_MEM_TABLE: 265254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x54); 266254885Sdumbbell if (check_offset) 267254885Sdumbbell offset = check_offset; 268254885Sdumbbell break; 269254885Sdumbbell case COMBIOS_EXT_TMDS_INFO_TABLE: 270254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x58); 271254885Sdumbbell if (check_offset) 272254885Sdumbbell offset = check_offset; 273254885Sdumbbell break; 274254885Sdumbbell case COMBIOS_MEM_CLK_INFO_TABLE: 275254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x5a); 276254885Sdumbbell if (check_offset) 277254885Sdumbbell offset = check_offset; 278254885Sdumbbell break; 279254885Sdumbbell case COMBIOS_EXT_DAC_INFO_TABLE: 280254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x5c); 281254885Sdumbbell if (check_offset) 282254885Sdumbbell offset = check_offset; 283254885Sdumbbell break; 284254885Sdumbbell case COMBIOS_MISC_INFO_TABLE: 285254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x5e); 286254885Sdumbbell if (check_offset) 287254885Sdumbbell offset = check_offset; 288254885Sdumbbell break; 289254885Sdumbbell case COMBIOS_CRT_INFO_TABLE: 290254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x60); 291254885Sdumbbell if (check_offset) 292254885Sdumbbell offset = check_offset; 293254885Sdumbbell break; 294254885Sdumbbell case COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE: 295254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x62); 296254885Sdumbbell if (check_offset) 297254885Sdumbbell offset = check_offset; 298254885Sdumbbell break; 299254885Sdumbbell case COMBIOS_COMPONENT_VIDEO_INFO_TABLE: 300254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x64); 301254885Sdumbbell if (check_offset) 302254885Sdumbbell offset = check_offset; 303254885Sdumbbell break; 304254885Sdumbbell case COMBIOS_FAN_SPEED_INFO_TABLE: 305254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x66); 306254885Sdumbbell if (check_offset) 307254885Sdumbbell offset = check_offset; 308254885Sdumbbell break; 309254885Sdumbbell case COMBIOS_OVERDRIVE_INFO_TABLE: 310254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x68); 311254885Sdumbbell if (check_offset) 312254885Sdumbbell offset = check_offset; 313254885Sdumbbell break; 314254885Sdumbbell case COMBIOS_OEM_INFO_TABLE: 315254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x6a); 316254885Sdumbbell if (check_offset) 317254885Sdumbbell offset = check_offset; 318254885Sdumbbell break; 319254885Sdumbbell case COMBIOS_DYN_CLK_2_TABLE: 320254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x6c); 321254885Sdumbbell if (check_offset) 322254885Sdumbbell offset = check_offset; 323254885Sdumbbell break; 324254885Sdumbbell case COMBIOS_POWER_CONNECTOR_INFO_TABLE: 325254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x6e); 326254885Sdumbbell if (check_offset) 327254885Sdumbbell offset = check_offset; 328254885Sdumbbell break; 329254885Sdumbbell case COMBIOS_I2C_INFO_TABLE: 330254885Sdumbbell check_offset = RBIOS16(rdev->bios_header_start + 0x70); 331254885Sdumbbell if (check_offset) 332254885Sdumbbell offset = check_offset; 333254885Sdumbbell break; 334254885Sdumbbell /* relative offset tables */ 335254885Sdumbbell case COMBIOS_ASIC_INIT_3_TABLE: /* offset from misc info */ 336254885Sdumbbell check_offset = 337254885Sdumbbell combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE); 338254885Sdumbbell if (check_offset) { 339254885Sdumbbell rev = RBIOS8(check_offset); 340254885Sdumbbell if (rev > 0) { 341254885Sdumbbell check_offset = RBIOS16(check_offset + 0x3); 342254885Sdumbbell if (check_offset) 343254885Sdumbbell offset = check_offset; 344254885Sdumbbell } 345254885Sdumbbell } 346254885Sdumbbell break; 347254885Sdumbbell case COMBIOS_ASIC_INIT_4_TABLE: /* offset from misc info */ 348254885Sdumbbell check_offset = 349254885Sdumbbell combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE); 350254885Sdumbbell if (check_offset) { 351254885Sdumbbell rev = RBIOS8(check_offset); 352254885Sdumbbell if (rev > 0) { 353254885Sdumbbell check_offset = RBIOS16(check_offset + 0x5); 354254885Sdumbbell if (check_offset) 355254885Sdumbbell offset = check_offset; 356254885Sdumbbell } 357254885Sdumbbell } 358254885Sdumbbell break; 359254885Sdumbbell case COMBIOS_DETECTED_MEM_TABLE: /* offset from misc info */ 360254885Sdumbbell check_offset = 361254885Sdumbbell combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE); 362254885Sdumbbell if (check_offset) { 363254885Sdumbbell rev = RBIOS8(check_offset); 364254885Sdumbbell if (rev > 0) { 365254885Sdumbbell check_offset = RBIOS16(check_offset + 0x7); 366254885Sdumbbell if (check_offset) 367254885Sdumbbell offset = check_offset; 368254885Sdumbbell } 369254885Sdumbbell } 370254885Sdumbbell break; 371254885Sdumbbell case COMBIOS_ASIC_INIT_5_TABLE: /* offset from misc info */ 372254885Sdumbbell check_offset = 373254885Sdumbbell combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE); 374254885Sdumbbell if (check_offset) { 375254885Sdumbbell rev = RBIOS8(check_offset); 376254885Sdumbbell if (rev == 2) { 377254885Sdumbbell check_offset = RBIOS16(check_offset + 0x9); 378254885Sdumbbell if (check_offset) 379254885Sdumbbell offset = check_offset; 380254885Sdumbbell } 381254885Sdumbbell } 382254885Sdumbbell break; 383254885Sdumbbell case COMBIOS_RAM_RESET_TABLE: /* offset from mem config */ 384254885Sdumbbell check_offset = 385254885Sdumbbell combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE); 386254885Sdumbbell if (check_offset) { 387254885Sdumbbell while (RBIOS8(check_offset++)); 388254885Sdumbbell check_offset += 2; 389254885Sdumbbell if (check_offset) 390254885Sdumbbell offset = check_offset; 391254885Sdumbbell } 392254885Sdumbbell break; 393254885Sdumbbell case COMBIOS_POWERPLAY_INFO_TABLE: /* offset from mobile info */ 394254885Sdumbbell check_offset = 395254885Sdumbbell combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE); 396254885Sdumbbell if (check_offset) { 397254885Sdumbbell check_offset = RBIOS16(check_offset + 0x11); 398254885Sdumbbell if (check_offset) 399254885Sdumbbell offset = check_offset; 400254885Sdumbbell } 401254885Sdumbbell break; 402254885Sdumbbell case COMBIOS_GPIO_INFO_TABLE: /* offset from mobile info */ 403254885Sdumbbell check_offset = 404254885Sdumbbell combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE); 405254885Sdumbbell if (check_offset) { 406254885Sdumbbell check_offset = RBIOS16(check_offset + 0x13); 407254885Sdumbbell if (check_offset) 408254885Sdumbbell offset = check_offset; 409254885Sdumbbell } 410254885Sdumbbell break; 411254885Sdumbbell case COMBIOS_LCD_DDC_INFO_TABLE: /* offset from mobile info */ 412254885Sdumbbell check_offset = 413254885Sdumbbell combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE); 414254885Sdumbbell if (check_offset) { 415254885Sdumbbell check_offset = RBIOS16(check_offset + 0x15); 416254885Sdumbbell if (check_offset) 417254885Sdumbbell offset = check_offset; 418254885Sdumbbell } 419254885Sdumbbell break; 420254885Sdumbbell case COMBIOS_TMDS_POWER_TABLE: /* offset from mobile info */ 421254885Sdumbbell check_offset = 422254885Sdumbbell combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE); 423254885Sdumbbell if (check_offset) { 424254885Sdumbbell check_offset = RBIOS16(check_offset + 0x17); 425254885Sdumbbell if (check_offset) 426254885Sdumbbell offset = check_offset; 427254885Sdumbbell } 428254885Sdumbbell break; 429254885Sdumbbell case COMBIOS_TMDS_POWER_ON_TABLE: /* offset from tmds power */ 430254885Sdumbbell check_offset = 431254885Sdumbbell combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE); 432254885Sdumbbell if (check_offset) { 433254885Sdumbbell check_offset = RBIOS16(check_offset + 0x2); 434254885Sdumbbell if (check_offset) 435254885Sdumbbell offset = check_offset; 436254885Sdumbbell } 437254885Sdumbbell break; 438254885Sdumbbell case COMBIOS_TMDS_POWER_OFF_TABLE: /* offset from tmds power */ 439254885Sdumbbell check_offset = 440254885Sdumbbell combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE); 441254885Sdumbbell if (check_offset) { 442254885Sdumbbell check_offset = RBIOS16(check_offset + 0x4); 443254885Sdumbbell if (check_offset) 444254885Sdumbbell offset = check_offset; 445254885Sdumbbell } 446254885Sdumbbell break; 447254885Sdumbbell default: 448254885Sdumbbell break; 449254885Sdumbbell } 450254885Sdumbbell 451254885Sdumbbell return offset; 452254885Sdumbbell 453254885Sdumbbell} 454254885Sdumbbell 455254885Sdumbbellbool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) 456254885Sdumbbell{ 457254885Sdumbbell int edid_info, size; 458254885Sdumbbell struct edid *edid; 459254885Sdumbbell unsigned char *raw; 460254885Sdumbbell edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE); 461254885Sdumbbell if (!edid_info) 462254885Sdumbbell return false; 463254885Sdumbbell 464254885Sdumbbell raw = rdev->bios + edid_info; 465254885Sdumbbell size = EDID_LENGTH * (raw[0x7e] + 1); 466280183Sdumbbell edid = malloc(size, DRM_MEM_KMS, M_NOWAIT); 467254885Sdumbbell if (edid == NULL) 468254885Sdumbbell return false; 469254885Sdumbbell 470254885Sdumbbell memcpy((unsigned char *)edid, raw, size); 471254885Sdumbbell 472254885Sdumbbell if (!drm_edid_is_valid(edid)) { 473254885Sdumbbell free(edid, DRM_MEM_KMS); 474254885Sdumbbell return false; 475254885Sdumbbell } 476254885Sdumbbell 477254885Sdumbbell rdev->mode_info.bios_hardcoded_edid = edid; 478254885Sdumbbell rdev->mode_info.bios_hardcoded_edid_size = size; 479254885Sdumbbell return true; 480254885Sdumbbell} 481254885Sdumbbell 482254885Sdumbbell/* this is used for atom LCDs as well */ 483254885Sdumbbellstruct edid * 484254885Sdumbbellradeon_bios_get_hardcoded_edid(struct radeon_device *rdev) 485254885Sdumbbell{ 486254885Sdumbbell struct edid *edid; 487254885Sdumbbell 488254885Sdumbbell if (rdev->mode_info.bios_hardcoded_edid) { 489254885Sdumbbell edid = malloc(rdev->mode_info.bios_hardcoded_edid_size, 490280183Sdumbbell DRM_MEM_KMS, M_NOWAIT); 491254885Sdumbbell if (edid) { 492254885Sdumbbell memcpy((unsigned char *)edid, 493254885Sdumbbell (unsigned char *)rdev->mode_info.bios_hardcoded_edid, 494254885Sdumbbell rdev->mode_info.bios_hardcoded_edid_size); 495254885Sdumbbell return edid; 496254885Sdumbbell } 497254885Sdumbbell } 498254885Sdumbbell return NULL; 499254885Sdumbbell} 500254885Sdumbbell 501254885Sdumbbellstatic struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev, 502254885Sdumbbell enum radeon_combios_ddc ddc, 503254885Sdumbbell u32 clk_mask, 504254885Sdumbbell u32 data_mask) 505254885Sdumbbell{ 506254885Sdumbbell struct radeon_i2c_bus_rec i2c; 507254885Sdumbbell int ddc_line = 0; 508254885Sdumbbell 509254885Sdumbbell /* ddc id = mask reg 510254885Sdumbbell * DDC_NONE_DETECTED = none 511254885Sdumbbell * DDC_DVI = RADEON_GPIO_DVI_DDC 512254885Sdumbbell * DDC_VGA = RADEON_GPIO_VGA_DDC 513254885Sdumbbell * DDC_LCD = RADEON_GPIOPAD_MASK 514254885Sdumbbell * DDC_GPIO = RADEON_MDGPIO_MASK 515254885Sdumbbell * r1xx 516254885Sdumbbell * DDC_MONID = RADEON_GPIO_MONID 517254885Sdumbbell * DDC_CRT2 = RADEON_GPIO_CRT2_DDC 518254885Sdumbbell * r200 519254885Sdumbbell * DDC_MONID = RADEON_GPIO_MONID 520254885Sdumbbell * DDC_CRT2 = RADEON_GPIO_DVI_DDC 521254885Sdumbbell * r300/r350 522254885Sdumbbell * DDC_MONID = RADEON_GPIO_DVI_DDC 523254885Sdumbbell * DDC_CRT2 = RADEON_GPIO_DVI_DDC 524254885Sdumbbell * rv2xx/rv3xx 525254885Sdumbbell * DDC_MONID = RADEON_GPIO_MONID 526254885Sdumbbell * DDC_CRT2 = RADEON_GPIO_MONID 527254885Sdumbbell * rs3xx/rs4xx 528254885Sdumbbell * DDC_MONID = RADEON_GPIOPAD_MASK 529254885Sdumbbell * DDC_CRT2 = RADEON_GPIO_MONID 530254885Sdumbbell */ 531254885Sdumbbell switch (ddc) { 532254885Sdumbbell case DDC_NONE_DETECTED: 533254885Sdumbbell default: 534254885Sdumbbell ddc_line = 0; 535254885Sdumbbell break; 536254885Sdumbbell case DDC_DVI: 537254885Sdumbbell ddc_line = RADEON_GPIO_DVI_DDC; 538254885Sdumbbell break; 539254885Sdumbbell case DDC_VGA: 540254885Sdumbbell ddc_line = RADEON_GPIO_VGA_DDC; 541254885Sdumbbell break; 542254885Sdumbbell case DDC_LCD: 543254885Sdumbbell ddc_line = RADEON_GPIOPAD_MASK; 544254885Sdumbbell break; 545254885Sdumbbell case DDC_GPIO: 546254885Sdumbbell ddc_line = RADEON_MDGPIO_MASK; 547254885Sdumbbell break; 548254885Sdumbbell case DDC_MONID: 549254885Sdumbbell if (rdev->family == CHIP_RS300 || 550254885Sdumbbell rdev->family == CHIP_RS400 || 551254885Sdumbbell rdev->family == CHIP_RS480) 552254885Sdumbbell ddc_line = RADEON_GPIOPAD_MASK; 553254885Sdumbbell else if (rdev->family == CHIP_R300 || 554254885Sdumbbell rdev->family == CHIP_R350) { 555254885Sdumbbell ddc_line = RADEON_GPIO_DVI_DDC; 556254885Sdumbbell ddc = DDC_DVI; 557254885Sdumbbell } else 558254885Sdumbbell ddc_line = RADEON_GPIO_MONID; 559254885Sdumbbell break; 560254885Sdumbbell case DDC_CRT2: 561254885Sdumbbell if (rdev->family == CHIP_R200 || 562254885Sdumbbell rdev->family == CHIP_R300 || 563254885Sdumbbell rdev->family == CHIP_R350) { 564254885Sdumbbell ddc_line = RADEON_GPIO_DVI_DDC; 565254885Sdumbbell ddc = DDC_DVI; 566254885Sdumbbell } else if (rdev->family == CHIP_RS300 || 567254885Sdumbbell rdev->family == CHIP_RS400 || 568254885Sdumbbell rdev->family == CHIP_RS480) 569254885Sdumbbell ddc_line = RADEON_GPIO_MONID; 570254885Sdumbbell else if (rdev->family >= CHIP_RV350) { 571254885Sdumbbell ddc_line = RADEON_GPIO_MONID; 572254885Sdumbbell ddc = DDC_MONID; 573254885Sdumbbell } else 574254885Sdumbbell ddc_line = RADEON_GPIO_CRT2_DDC; 575254885Sdumbbell break; 576254885Sdumbbell } 577254885Sdumbbell 578254885Sdumbbell if (ddc_line == RADEON_GPIOPAD_MASK) { 579254885Sdumbbell i2c.mask_clk_reg = RADEON_GPIOPAD_MASK; 580254885Sdumbbell i2c.mask_data_reg = RADEON_GPIOPAD_MASK; 581254885Sdumbbell i2c.a_clk_reg = RADEON_GPIOPAD_A; 582254885Sdumbbell i2c.a_data_reg = RADEON_GPIOPAD_A; 583254885Sdumbbell i2c.en_clk_reg = RADEON_GPIOPAD_EN; 584254885Sdumbbell i2c.en_data_reg = RADEON_GPIOPAD_EN; 585254885Sdumbbell i2c.y_clk_reg = RADEON_GPIOPAD_Y; 586254885Sdumbbell i2c.y_data_reg = RADEON_GPIOPAD_Y; 587254885Sdumbbell } else if (ddc_line == RADEON_MDGPIO_MASK) { 588254885Sdumbbell i2c.mask_clk_reg = RADEON_MDGPIO_MASK; 589254885Sdumbbell i2c.mask_data_reg = RADEON_MDGPIO_MASK; 590254885Sdumbbell i2c.a_clk_reg = RADEON_MDGPIO_A; 591254885Sdumbbell i2c.a_data_reg = RADEON_MDGPIO_A; 592254885Sdumbbell i2c.en_clk_reg = RADEON_MDGPIO_EN; 593254885Sdumbbell i2c.en_data_reg = RADEON_MDGPIO_EN; 594254885Sdumbbell i2c.y_clk_reg = RADEON_MDGPIO_Y; 595254885Sdumbbell i2c.y_data_reg = RADEON_MDGPIO_Y; 596254885Sdumbbell } else { 597254885Sdumbbell i2c.mask_clk_reg = ddc_line; 598254885Sdumbbell i2c.mask_data_reg = ddc_line; 599254885Sdumbbell i2c.a_clk_reg = ddc_line; 600254885Sdumbbell i2c.a_data_reg = ddc_line; 601254885Sdumbbell i2c.en_clk_reg = ddc_line; 602254885Sdumbbell i2c.en_data_reg = ddc_line; 603254885Sdumbbell i2c.y_clk_reg = ddc_line; 604254885Sdumbbell i2c.y_data_reg = ddc_line; 605254885Sdumbbell } 606254885Sdumbbell 607254885Sdumbbell if (clk_mask && data_mask) { 608254885Sdumbbell /* system specific masks */ 609254885Sdumbbell i2c.mask_clk_mask = clk_mask; 610254885Sdumbbell i2c.mask_data_mask = data_mask; 611254885Sdumbbell i2c.a_clk_mask = clk_mask; 612254885Sdumbbell i2c.a_data_mask = data_mask; 613254885Sdumbbell i2c.en_clk_mask = clk_mask; 614254885Sdumbbell i2c.en_data_mask = data_mask; 615254885Sdumbbell i2c.y_clk_mask = clk_mask; 616254885Sdumbbell i2c.y_data_mask = data_mask; 617254885Sdumbbell } else if ((ddc_line == RADEON_GPIOPAD_MASK) || 618254885Sdumbbell (ddc_line == RADEON_MDGPIO_MASK)) { 619254885Sdumbbell /* default gpiopad masks */ 620254885Sdumbbell i2c.mask_clk_mask = (0x20 << 8); 621254885Sdumbbell i2c.mask_data_mask = 0x80; 622254885Sdumbbell i2c.a_clk_mask = (0x20 << 8); 623254885Sdumbbell i2c.a_data_mask = 0x80; 624254885Sdumbbell i2c.en_clk_mask = (0x20 << 8); 625254885Sdumbbell i2c.en_data_mask = 0x80; 626254885Sdumbbell i2c.y_clk_mask = (0x20 << 8); 627254885Sdumbbell i2c.y_data_mask = 0x80; 628254885Sdumbbell } else { 629254885Sdumbbell /* default masks for ddc pads */ 630254885Sdumbbell i2c.mask_clk_mask = RADEON_GPIO_MASK_1; 631254885Sdumbbell i2c.mask_data_mask = RADEON_GPIO_MASK_0; 632254885Sdumbbell i2c.a_clk_mask = RADEON_GPIO_A_1; 633254885Sdumbbell i2c.a_data_mask = RADEON_GPIO_A_0; 634254885Sdumbbell i2c.en_clk_mask = RADEON_GPIO_EN_1; 635254885Sdumbbell i2c.en_data_mask = RADEON_GPIO_EN_0; 636254885Sdumbbell i2c.y_clk_mask = RADEON_GPIO_Y_1; 637254885Sdumbbell i2c.y_data_mask = RADEON_GPIO_Y_0; 638254885Sdumbbell } 639254885Sdumbbell 640254885Sdumbbell switch (rdev->family) { 641254885Sdumbbell case CHIP_R100: 642254885Sdumbbell case CHIP_RV100: 643254885Sdumbbell case CHIP_RS100: 644254885Sdumbbell case CHIP_RV200: 645254885Sdumbbell case CHIP_RS200: 646254885Sdumbbell case CHIP_RS300: 647254885Sdumbbell switch (ddc_line) { 648254885Sdumbbell case RADEON_GPIO_DVI_DDC: 649254885Sdumbbell i2c.hw_capable = true; 650254885Sdumbbell break; 651254885Sdumbbell default: 652254885Sdumbbell i2c.hw_capable = false; 653254885Sdumbbell break; 654254885Sdumbbell } 655254885Sdumbbell break; 656254885Sdumbbell case CHIP_R200: 657254885Sdumbbell switch (ddc_line) { 658254885Sdumbbell case RADEON_GPIO_DVI_DDC: 659254885Sdumbbell case RADEON_GPIO_MONID: 660254885Sdumbbell i2c.hw_capable = true; 661254885Sdumbbell break; 662254885Sdumbbell default: 663254885Sdumbbell i2c.hw_capable = false; 664254885Sdumbbell break; 665254885Sdumbbell } 666254885Sdumbbell break; 667254885Sdumbbell case CHIP_RV250: 668254885Sdumbbell case CHIP_RV280: 669254885Sdumbbell switch (ddc_line) { 670254885Sdumbbell case RADEON_GPIO_VGA_DDC: 671254885Sdumbbell case RADEON_GPIO_DVI_DDC: 672254885Sdumbbell case RADEON_GPIO_CRT2_DDC: 673254885Sdumbbell i2c.hw_capable = true; 674254885Sdumbbell break; 675254885Sdumbbell default: 676254885Sdumbbell i2c.hw_capable = false; 677254885Sdumbbell break; 678254885Sdumbbell } 679254885Sdumbbell break; 680254885Sdumbbell case CHIP_R300: 681254885Sdumbbell case CHIP_R350: 682254885Sdumbbell switch (ddc_line) { 683254885Sdumbbell case RADEON_GPIO_VGA_DDC: 684254885Sdumbbell case RADEON_GPIO_DVI_DDC: 685254885Sdumbbell i2c.hw_capable = true; 686254885Sdumbbell break; 687254885Sdumbbell default: 688254885Sdumbbell i2c.hw_capable = false; 689254885Sdumbbell break; 690254885Sdumbbell } 691254885Sdumbbell break; 692254885Sdumbbell case CHIP_RV350: 693254885Sdumbbell case CHIP_RV380: 694254885Sdumbbell case CHIP_RS400: 695254885Sdumbbell case CHIP_RS480: 696254885Sdumbbell switch (ddc_line) { 697254885Sdumbbell case RADEON_GPIO_VGA_DDC: 698254885Sdumbbell case RADEON_GPIO_DVI_DDC: 699254885Sdumbbell i2c.hw_capable = true; 700254885Sdumbbell break; 701254885Sdumbbell case RADEON_GPIO_MONID: 702254885Sdumbbell /* hw i2c on RADEON_GPIO_MONID doesn't seem to work 703254885Sdumbbell * reliably on some pre-r4xx hardware; not sure why. 704254885Sdumbbell */ 705254885Sdumbbell i2c.hw_capable = false; 706254885Sdumbbell break; 707254885Sdumbbell default: 708254885Sdumbbell i2c.hw_capable = false; 709254885Sdumbbell break; 710254885Sdumbbell } 711254885Sdumbbell break; 712254885Sdumbbell default: 713254885Sdumbbell i2c.hw_capable = false; 714254885Sdumbbell break; 715254885Sdumbbell } 716254885Sdumbbell i2c.mm_i2c = false; 717254885Sdumbbell 718254885Sdumbbell i2c.i2c_id = ddc; 719254885Sdumbbell i2c.hpd = RADEON_HPD_NONE; 720254885Sdumbbell 721254885Sdumbbell if (ddc_line) 722254885Sdumbbell i2c.valid = true; 723254885Sdumbbell else 724254885Sdumbbell i2c.valid = false; 725254885Sdumbbell 726254885Sdumbbell return i2c; 727254885Sdumbbell} 728254885Sdumbbell 729254885Sdumbbellstatic struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev) 730254885Sdumbbell{ 731254885Sdumbbell struct drm_device *dev = rdev->ddev; 732254885Sdumbbell struct radeon_i2c_bus_rec i2c; 733254885Sdumbbell u16 offset; 734254885Sdumbbell u8 id, blocks, clk, data; 735254885Sdumbbell int i; 736254885Sdumbbell 737254885Sdumbbell i2c.valid = false; 738254885Sdumbbell 739254885Sdumbbell offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); 740254885Sdumbbell if (offset) { 741254885Sdumbbell blocks = RBIOS8(offset + 2); 742254885Sdumbbell for (i = 0; i < blocks; i++) { 743254885Sdumbbell id = RBIOS8(offset + 3 + (i * 5) + 0); 744254885Sdumbbell if (id == 136) { 745254885Sdumbbell clk = RBIOS8(offset + 3 + (i * 5) + 3); 746254885Sdumbbell data = RBIOS8(offset + 3 + (i * 5) + 4); 747254885Sdumbbell /* gpiopad */ 748254885Sdumbbell i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 749254885Sdumbbell (1 << clk), (1 << data)); 750254885Sdumbbell break; 751254885Sdumbbell } 752254885Sdumbbell } 753254885Sdumbbell } 754254885Sdumbbell return i2c; 755254885Sdumbbell} 756254885Sdumbbell 757254885Sdumbbellvoid radeon_combios_i2c_init(struct radeon_device *rdev) 758254885Sdumbbell{ 759254885Sdumbbell struct drm_device *dev = rdev->ddev; 760254885Sdumbbell struct radeon_i2c_bus_rec i2c; 761254885Sdumbbell 762254885Sdumbbell /* actual hw pads 763254885Sdumbbell * r1xx/rs2xx/rs3xx 764254885Sdumbbell * 0x60, 0x64, 0x68, 0x6c, gpiopads, mm 765254885Sdumbbell * r200 766254885Sdumbbell * 0x60, 0x64, 0x68, mm 767254885Sdumbbell * r300/r350 768254885Sdumbbell * 0x60, 0x64, mm 769254885Sdumbbell * rv2xx/rv3xx/rs4xx 770254885Sdumbbell * 0x60, 0x64, 0x68, gpiopads, mm 771254885Sdumbbell */ 772254885Sdumbbell 773254885Sdumbbell /* 0x60 */ 774254885Sdumbbell i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); 775254885Sdumbbell rdev->i2c_bus[0] = radeon_i2c_create(dev, &i2c, "DVI_DDC"); 776254885Sdumbbell /* 0x64 */ 777254885Sdumbbell i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); 778254885Sdumbbell rdev->i2c_bus[1] = radeon_i2c_create(dev, &i2c, "VGA_DDC"); 779254885Sdumbbell 780254885Sdumbbell /* mm i2c */ 781254885Sdumbbell i2c.valid = true; 782254885Sdumbbell i2c.hw_capable = true; 783254885Sdumbbell i2c.mm_i2c = true; 784254885Sdumbbell i2c.i2c_id = 0xa0; 785254885Sdumbbell rdev->i2c_bus[2] = radeon_i2c_create(dev, &i2c, "MM_I2C"); 786254885Sdumbbell 787254885Sdumbbell if (rdev->family == CHIP_R300 || 788254885Sdumbbell rdev->family == CHIP_R350) { 789254885Sdumbbell /* only 2 sw i2c pads */ 790254885Sdumbbell } else if (rdev->family == CHIP_RS300 || 791254885Sdumbbell rdev->family == CHIP_RS400 || 792254885Sdumbbell rdev->family == CHIP_RS480) { 793254885Sdumbbell /* 0x68 */ 794254885Sdumbbell i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); 795254885Sdumbbell rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); 796254885Sdumbbell 797254885Sdumbbell /* gpiopad */ 798254885Sdumbbell i2c = radeon_combios_get_i2c_info_from_table(rdev); 799254885Sdumbbell if (i2c.valid) 800254885Sdumbbell rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); 801254885Sdumbbell } else if ((rdev->family == CHIP_R200) || 802254885Sdumbbell (rdev->family >= CHIP_R300)) { 803254885Sdumbbell /* 0x68 */ 804254885Sdumbbell i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); 805254885Sdumbbell rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); 806254885Sdumbbell } else { 807254885Sdumbbell /* 0x68 */ 808254885Sdumbbell i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); 809254885Sdumbbell rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); 810254885Sdumbbell /* 0x6c */ 811254885Sdumbbell i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); 812254885Sdumbbell rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "CRT2_DDC"); 813254885Sdumbbell } 814254885Sdumbbell} 815254885Sdumbbell 816254885Sdumbbellbool radeon_combios_get_clock_info(struct drm_device *dev) 817254885Sdumbbell{ 818254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 819254885Sdumbbell uint16_t pll_info; 820254885Sdumbbell struct radeon_pll *p1pll = &rdev->clock.p1pll; 821254885Sdumbbell struct radeon_pll *p2pll = &rdev->clock.p2pll; 822254885Sdumbbell struct radeon_pll *spll = &rdev->clock.spll; 823254885Sdumbbell struct radeon_pll *mpll = &rdev->clock.mpll; 824254885Sdumbbell int8_t rev; 825254885Sdumbbell uint16_t sclk, mclk; 826254885Sdumbbell 827254885Sdumbbell pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE); 828254885Sdumbbell if (pll_info) { 829254885Sdumbbell rev = RBIOS8(pll_info); 830254885Sdumbbell 831254885Sdumbbell /* pixel clocks */ 832254885Sdumbbell p1pll->reference_freq = RBIOS16(pll_info + 0xe); 833254885Sdumbbell p1pll->reference_div = RBIOS16(pll_info + 0x10); 834254885Sdumbbell p1pll->pll_out_min = RBIOS32(pll_info + 0x12); 835254885Sdumbbell p1pll->pll_out_max = RBIOS32(pll_info + 0x16); 836254885Sdumbbell p1pll->lcd_pll_out_min = p1pll->pll_out_min; 837254885Sdumbbell p1pll->lcd_pll_out_max = p1pll->pll_out_max; 838254885Sdumbbell 839254885Sdumbbell if (rev > 9) { 840254885Sdumbbell p1pll->pll_in_min = RBIOS32(pll_info + 0x36); 841254885Sdumbbell p1pll->pll_in_max = RBIOS32(pll_info + 0x3a); 842254885Sdumbbell } else { 843254885Sdumbbell p1pll->pll_in_min = 40; 844254885Sdumbbell p1pll->pll_in_max = 500; 845254885Sdumbbell } 846254885Sdumbbell *p2pll = *p1pll; 847254885Sdumbbell 848254885Sdumbbell /* system clock */ 849254885Sdumbbell spll->reference_freq = RBIOS16(pll_info + 0x1a); 850254885Sdumbbell spll->reference_div = RBIOS16(pll_info + 0x1c); 851254885Sdumbbell spll->pll_out_min = RBIOS32(pll_info + 0x1e); 852254885Sdumbbell spll->pll_out_max = RBIOS32(pll_info + 0x22); 853254885Sdumbbell 854254885Sdumbbell if (rev > 10) { 855254885Sdumbbell spll->pll_in_min = RBIOS32(pll_info + 0x48); 856254885Sdumbbell spll->pll_in_max = RBIOS32(pll_info + 0x4c); 857254885Sdumbbell } else { 858254885Sdumbbell /* ??? */ 859254885Sdumbbell spll->pll_in_min = 40; 860254885Sdumbbell spll->pll_in_max = 500; 861254885Sdumbbell } 862254885Sdumbbell 863254885Sdumbbell /* memory clock */ 864254885Sdumbbell mpll->reference_freq = RBIOS16(pll_info + 0x26); 865254885Sdumbbell mpll->reference_div = RBIOS16(pll_info + 0x28); 866254885Sdumbbell mpll->pll_out_min = RBIOS32(pll_info + 0x2a); 867254885Sdumbbell mpll->pll_out_max = RBIOS32(pll_info + 0x2e); 868254885Sdumbbell 869254885Sdumbbell if (rev > 10) { 870254885Sdumbbell mpll->pll_in_min = RBIOS32(pll_info + 0x5a); 871254885Sdumbbell mpll->pll_in_max = RBIOS32(pll_info + 0x5e); 872254885Sdumbbell } else { 873254885Sdumbbell /* ??? */ 874254885Sdumbbell mpll->pll_in_min = 40; 875254885Sdumbbell mpll->pll_in_max = 500; 876254885Sdumbbell } 877254885Sdumbbell 878254885Sdumbbell /* default sclk/mclk */ 879254885Sdumbbell sclk = RBIOS16(pll_info + 0xa); 880254885Sdumbbell mclk = RBIOS16(pll_info + 0x8); 881254885Sdumbbell if (sclk == 0) 882254885Sdumbbell sclk = 200 * 100; 883254885Sdumbbell if (mclk == 0) 884254885Sdumbbell mclk = 200 * 100; 885254885Sdumbbell 886254885Sdumbbell rdev->clock.default_sclk = sclk; 887254885Sdumbbell rdev->clock.default_mclk = mclk; 888254885Sdumbbell 889254885Sdumbbell if (RBIOS32(pll_info + 0x16)) 890254885Sdumbbell rdev->clock.max_pixel_clock = RBIOS32(pll_info + 0x16); 891254885Sdumbbell else 892254885Sdumbbell rdev->clock.max_pixel_clock = 35000; /* might need something asic specific */ 893254885Sdumbbell 894254885Sdumbbell return true; 895254885Sdumbbell } 896254885Sdumbbell return false; 897254885Sdumbbell} 898254885Sdumbbell 899254885Sdumbbellbool radeon_combios_sideport_present(struct radeon_device *rdev) 900254885Sdumbbell{ 901254885Sdumbbell struct drm_device *dev = rdev->ddev; 902254885Sdumbbell u16 igp_info; 903254885Sdumbbell 904254885Sdumbbell /* sideport is AMD only */ 905254885Sdumbbell if (rdev->family == CHIP_RS400) 906254885Sdumbbell return false; 907254885Sdumbbell 908254885Sdumbbell igp_info = combios_get_table_offset(dev, COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE); 909254885Sdumbbell 910254885Sdumbbell if (igp_info) { 911254885Sdumbbell if (RBIOS16(igp_info + 0x4)) 912254885Sdumbbell return true; 913254885Sdumbbell } 914254885Sdumbbell return false; 915254885Sdumbbell} 916254885Sdumbbell 917254885Sdumbbellstatic const uint32_t default_primarydac_adj[CHIP_LAST] = { 918254885Sdumbbell 0x00000808, /* r100 */ 919254885Sdumbbell 0x00000808, /* rv100 */ 920254885Sdumbbell 0x00000808, /* rs100 */ 921254885Sdumbbell 0x00000808, /* rv200 */ 922254885Sdumbbell 0x00000808, /* rs200 */ 923254885Sdumbbell 0x00000808, /* r200 */ 924254885Sdumbbell 0x00000808, /* rv250 */ 925254885Sdumbbell 0x00000000, /* rs300 */ 926254885Sdumbbell 0x00000808, /* rv280 */ 927254885Sdumbbell 0x00000808, /* r300 */ 928254885Sdumbbell 0x00000808, /* r350 */ 929254885Sdumbbell 0x00000808, /* rv350 */ 930254885Sdumbbell 0x00000808, /* rv380 */ 931254885Sdumbbell 0x00000808, /* r420 */ 932254885Sdumbbell 0x00000808, /* r423 */ 933254885Sdumbbell 0x00000808, /* rv410 */ 934254885Sdumbbell 0x00000000, /* rs400 */ 935254885Sdumbbell 0x00000000, /* rs480 */ 936254885Sdumbbell}; 937254885Sdumbbell 938254885Sdumbbellstatic void radeon_legacy_get_primary_dac_info_from_table(struct radeon_device *rdev, 939254885Sdumbbell struct radeon_encoder_primary_dac *p_dac) 940254885Sdumbbell{ 941254885Sdumbbell p_dac->ps2_pdac_adj = default_primarydac_adj[rdev->family]; 942254885Sdumbbell return; 943254885Sdumbbell} 944254885Sdumbbell 945254885Sdumbbellstruct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct 946254885Sdumbbell radeon_encoder 947254885Sdumbbell *encoder) 948254885Sdumbbell{ 949254885Sdumbbell struct drm_device *dev = encoder->base.dev; 950254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 951254885Sdumbbell uint16_t dac_info; 952254885Sdumbbell uint8_t rev, bg, dac; 953254885Sdumbbell struct radeon_encoder_primary_dac *p_dac = NULL; 954254885Sdumbbell int found = 0; 955254885Sdumbbell 956254885Sdumbbell p_dac = malloc(sizeof(struct radeon_encoder_primary_dac), 957280183Sdumbbell DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 958254885Sdumbbell 959254885Sdumbbell if (!p_dac) 960254885Sdumbbell return NULL; 961254885Sdumbbell 962254885Sdumbbell /* check CRT table */ 963254885Sdumbbell dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); 964254885Sdumbbell if (dac_info) { 965254885Sdumbbell rev = RBIOS8(dac_info) & 0x3; 966254885Sdumbbell if (rev < 2) { 967254885Sdumbbell bg = RBIOS8(dac_info + 0x2) & 0xf; 968254885Sdumbbell dac = (RBIOS8(dac_info + 0x2) >> 4) & 0xf; 969254885Sdumbbell p_dac->ps2_pdac_adj = (bg << 8) | (dac); 970254885Sdumbbell } else { 971254885Sdumbbell bg = RBIOS8(dac_info + 0x2) & 0xf; 972254885Sdumbbell dac = RBIOS8(dac_info + 0x3) & 0xf; 973254885Sdumbbell p_dac->ps2_pdac_adj = (bg << 8) | (dac); 974254885Sdumbbell } 975254885Sdumbbell /* if the values are all zeros, use the table */ 976254885Sdumbbell if (p_dac->ps2_pdac_adj) 977254885Sdumbbell found = 1; 978254885Sdumbbell } 979254885Sdumbbell 980280183Sdumbbell /* quirks */ 981280183Sdumbbell /* Radeon 9100 (R200) */ 982280183Sdumbbell if ((dev->pci_device == 0x514D) && 983280183Sdumbbell (dev->pci_subvendor == 0x174B) && 984280183Sdumbbell (dev->pci_subdevice == 0x7149)) { 985280183Sdumbbell /* vbios value is bad, use the default */ 986280183Sdumbbell found = 0; 987280183Sdumbbell } 988280183Sdumbbell 989254885Sdumbbell if (!found) /* fallback to defaults */ 990254885Sdumbbell radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac); 991254885Sdumbbell 992254885Sdumbbell return p_dac; 993254885Sdumbbell} 994254885Sdumbbell 995254885Sdumbbellenum radeon_tv_std 996254885Sdumbbellradeon_combios_get_tv_info(struct radeon_device *rdev) 997254885Sdumbbell{ 998254885Sdumbbell struct drm_device *dev = rdev->ddev; 999254885Sdumbbell uint16_t tv_info; 1000254885Sdumbbell enum radeon_tv_std tv_std = TV_STD_NTSC; 1001254885Sdumbbell 1002254885Sdumbbell tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); 1003254885Sdumbbell if (tv_info) { 1004254885Sdumbbell if (RBIOS8(tv_info + 6) == 'T') { 1005254885Sdumbbell switch (RBIOS8(tv_info + 7) & 0xf) { 1006254885Sdumbbell case 1: 1007254885Sdumbbell tv_std = TV_STD_NTSC; 1008254885Sdumbbell DRM_DEBUG_KMS("Default TV standard: NTSC\n"); 1009254885Sdumbbell break; 1010254885Sdumbbell case 2: 1011254885Sdumbbell tv_std = TV_STD_PAL; 1012254885Sdumbbell DRM_DEBUG_KMS("Default TV standard: PAL\n"); 1013254885Sdumbbell break; 1014254885Sdumbbell case 3: 1015254885Sdumbbell tv_std = TV_STD_PAL_M; 1016254885Sdumbbell DRM_DEBUG_KMS("Default TV standard: PAL-M\n"); 1017254885Sdumbbell break; 1018254885Sdumbbell case 4: 1019254885Sdumbbell tv_std = TV_STD_PAL_60; 1020254885Sdumbbell DRM_DEBUG_KMS("Default TV standard: PAL-60\n"); 1021254885Sdumbbell break; 1022254885Sdumbbell case 5: 1023254885Sdumbbell tv_std = TV_STD_NTSC_J; 1024254885Sdumbbell DRM_DEBUG_KMS("Default TV standard: NTSC-J\n"); 1025254885Sdumbbell break; 1026254885Sdumbbell case 6: 1027254885Sdumbbell tv_std = TV_STD_SCART_PAL; 1028254885Sdumbbell DRM_DEBUG_KMS("Default TV standard: SCART-PAL\n"); 1029254885Sdumbbell break; 1030254885Sdumbbell default: 1031254885Sdumbbell tv_std = TV_STD_NTSC; 1032254885Sdumbbell DRM_DEBUG_KMS 1033254885Sdumbbell ("Unknown TV standard; defaulting to NTSC\n"); 1034254885Sdumbbell break; 1035254885Sdumbbell } 1036254885Sdumbbell 1037254885Sdumbbell switch ((RBIOS8(tv_info + 9) >> 2) & 0x3) { 1038254885Sdumbbell case 0: 1039254885Sdumbbell DRM_DEBUG_KMS("29.498928713 MHz TV ref clk\n"); 1040254885Sdumbbell break; 1041254885Sdumbbell case 1: 1042254885Sdumbbell DRM_DEBUG_KMS("28.636360000 MHz TV ref clk\n"); 1043254885Sdumbbell break; 1044254885Sdumbbell case 2: 1045254885Sdumbbell DRM_DEBUG_KMS("14.318180000 MHz TV ref clk\n"); 1046254885Sdumbbell break; 1047254885Sdumbbell case 3: 1048254885Sdumbbell DRM_DEBUG_KMS("27.000000000 MHz TV ref clk\n"); 1049254885Sdumbbell break; 1050254885Sdumbbell default: 1051254885Sdumbbell break; 1052254885Sdumbbell } 1053254885Sdumbbell } 1054254885Sdumbbell } 1055254885Sdumbbell return tv_std; 1056254885Sdumbbell} 1057254885Sdumbbell 1058254885Sdumbbellstatic const uint32_t default_tvdac_adj[CHIP_LAST] = { 1059254885Sdumbbell 0x00000000, /* r100 */ 1060254885Sdumbbell 0x00280000, /* rv100 */ 1061254885Sdumbbell 0x00000000, /* rs100 */ 1062254885Sdumbbell 0x00880000, /* rv200 */ 1063254885Sdumbbell 0x00000000, /* rs200 */ 1064254885Sdumbbell 0x00000000, /* r200 */ 1065254885Sdumbbell 0x00770000, /* rv250 */ 1066254885Sdumbbell 0x00290000, /* rs300 */ 1067254885Sdumbbell 0x00560000, /* rv280 */ 1068254885Sdumbbell 0x00780000, /* r300 */ 1069254885Sdumbbell 0x00770000, /* r350 */ 1070254885Sdumbbell 0x00780000, /* rv350 */ 1071254885Sdumbbell 0x00780000, /* rv380 */ 1072254885Sdumbbell 0x01080000, /* r420 */ 1073254885Sdumbbell 0x01080000, /* r423 */ 1074254885Sdumbbell 0x01080000, /* rv410 */ 1075254885Sdumbbell 0x00780000, /* rs400 */ 1076254885Sdumbbell 0x00780000, /* rs480 */ 1077254885Sdumbbell}; 1078254885Sdumbbell 1079254885Sdumbbellstatic void radeon_legacy_get_tv_dac_info_from_table(struct radeon_device *rdev, 1080254885Sdumbbell struct radeon_encoder_tv_dac *tv_dac) 1081254885Sdumbbell{ 1082254885Sdumbbell tv_dac->ps2_tvdac_adj = default_tvdac_adj[rdev->family]; 1083254885Sdumbbell if ((rdev->flags & RADEON_IS_MOBILITY) && (rdev->family == CHIP_RV250)) 1084254885Sdumbbell tv_dac->ps2_tvdac_adj = 0x00880000; 1085254885Sdumbbell tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; 1086254885Sdumbbell tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; 1087254885Sdumbbell return; 1088254885Sdumbbell} 1089254885Sdumbbell 1090254885Sdumbbellstruct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct 1091254885Sdumbbell radeon_encoder 1092254885Sdumbbell *encoder) 1093254885Sdumbbell{ 1094254885Sdumbbell struct drm_device *dev = encoder->base.dev; 1095254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 1096254885Sdumbbell uint16_t dac_info; 1097254885Sdumbbell uint8_t rev, bg, dac; 1098254885Sdumbbell struct radeon_encoder_tv_dac *tv_dac = NULL; 1099254885Sdumbbell int found = 0; 1100254885Sdumbbell 1101254885Sdumbbell tv_dac = malloc(sizeof(struct radeon_encoder_tv_dac), 1102280183Sdumbbell DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 1103254885Sdumbbell if (!tv_dac) 1104254885Sdumbbell return NULL; 1105254885Sdumbbell 1106254885Sdumbbell /* first check TV table */ 1107254885Sdumbbell dac_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); 1108254885Sdumbbell if (dac_info) { 1109254885Sdumbbell rev = RBIOS8(dac_info + 0x3); 1110254885Sdumbbell if (rev > 4) { 1111254885Sdumbbell bg = RBIOS8(dac_info + 0xc) & 0xf; 1112254885Sdumbbell dac = RBIOS8(dac_info + 0xd) & 0xf; 1113254885Sdumbbell tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20); 1114254885Sdumbbell 1115254885Sdumbbell bg = RBIOS8(dac_info + 0xe) & 0xf; 1116254885Sdumbbell dac = RBIOS8(dac_info + 0xf) & 0xf; 1117254885Sdumbbell tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20); 1118254885Sdumbbell 1119254885Sdumbbell bg = RBIOS8(dac_info + 0x10) & 0xf; 1120254885Sdumbbell dac = RBIOS8(dac_info + 0x11) & 0xf; 1121254885Sdumbbell tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); 1122254885Sdumbbell /* if the values are all zeros, use the table */ 1123254885Sdumbbell if (tv_dac->ps2_tvdac_adj) 1124254885Sdumbbell found = 1; 1125254885Sdumbbell } else if (rev > 1) { 1126254885Sdumbbell bg = RBIOS8(dac_info + 0xc) & 0xf; 1127254885Sdumbbell dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf; 1128254885Sdumbbell tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20); 1129254885Sdumbbell 1130254885Sdumbbell bg = RBIOS8(dac_info + 0xd) & 0xf; 1131254885Sdumbbell dac = (RBIOS8(dac_info + 0xd) >> 4) & 0xf; 1132254885Sdumbbell tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20); 1133254885Sdumbbell 1134254885Sdumbbell bg = RBIOS8(dac_info + 0xe) & 0xf; 1135254885Sdumbbell dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf; 1136254885Sdumbbell tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); 1137254885Sdumbbell /* if the values are all zeros, use the table */ 1138254885Sdumbbell if (tv_dac->ps2_tvdac_adj) 1139254885Sdumbbell found = 1; 1140254885Sdumbbell } 1141254885Sdumbbell tv_dac->tv_std = radeon_combios_get_tv_info(rdev); 1142254885Sdumbbell } 1143254885Sdumbbell if (!found) { 1144254885Sdumbbell /* then check CRT table */ 1145254885Sdumbbell dac_info = 1146254885Sdumbbell combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); 1147254885Sdumbbell if (dac_info) { 1148254885Sdumbbell rev = RBIOS8(dac_info) & 0x3; 1149254885Sdumbbell if (rev < 2) { 1150254885Sdumbbell bg = RBIOS8(dac_info + 0x3) & 0xf; 1151254885Sdumbbell dac = (RBIOS8(dac_info + 0x3) >> 4) & 0xf; 1152254885Sdumbbell tv_dac->ps2_tvdac_adj = 1153254885Sdumbbell (bg << 16) | (dac << 20); 1154254885Sdumbbell tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; 1155254885Sdumbbell tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; 1156254885Sdumbbell /* if the values are all zeros, use the table */ 1157254885Sdumbbell if (tv_dac->ps2_tvdac_adj) 1158254885Sdumbbell found = 1; 1159254885Sdumbbell } else { 1160254885Sdumbbell bg = RBIOS8(dac_info + 0x4) & 0xf; 1161254885Sdumbbell dac = RBIOS8(dac_info + 0x5) & 0xf; 1162254885Sdumbbell tv_dac->ps2_tvdac_adj = 1163254885Sdumbbell (bg << 16) | (dac << 20); 1164254885Sdumbbell tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; 1165254885Sdumbbell tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; 1166254885Sdumbbell /* if the values are all zeros, use the table */ 1167254885Sdumbbell if (tv_dac->ps2_tvdac_adj) 1168254885Sdumbbell found = 1; 1169254885Sdumbbell } 1170254885Sdumbbell } else { 1171254885Sdumbbell DRM_INFO("No TV DAC info found in BIOS\n"); 1172254885Sdumbbell } 1173254885Sdumbbell } 1174254885Sdumbbell 1175254885Sdumbbell if (!found) /* fallback to defaults */ 1176254885Sdumbbell radeon_legacy_get_tv_dac_info_from_table(rdev, tv_dac); 1177254885Sdumbbell 1178254885Sdumbbell return tv_dac; 1179254885Sdumbbell} 1180254885Sdumbbell 1181254885Sdumbbellstatic struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct 1182254885Sdumbbell radeon_device 1183254885Sdumbbell *rdev) 1184254885Sdumbbell{ 1185254885Sdumbbell struct radeon_encoder_lvds *lvds = NULL; 1186254885Sdumbbell uint32_t fp_vert_stretch, fp_horz_stretch; 1187254885Sdumbbell uint32_t ppll_div_sel, ppll_val; 1188254885Sdumbbell uint32_t lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL); 1189254885Sdumbbell 1190254885Sdumbbell lvds = malloc(sizeof(struct radeon_encoder_lvds), 1191280183Sdumbbell DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 1192254885Sdumbbell 1193254885Sdumbbell if (!lvds) 1194254885Sdumbbell return NULL; 1195254885Sdumbbell 1196254885Sdumbbell fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH); 1197254885Sdumbbell fp_horz_stretch = RREG32(RADEON_FP_HORZ_STRETCH); 1198254885Sdumbbell 1199254885Sdumbbell /* These should be fail-safe defaults, fingers crossed */ 1200254885Sdumbbell lvds->panel_pwr_delay = 200; 1201254885Sdumbbell lvds->panel_vcc_delay = 2000; 1202254885Sdumbbell 1203254885Sdumbbell lvds->lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); 1204254885Sdumbbell lvds->panel_digon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) & 0xf; 1205254885Sdumbbell lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf; 1206254885Sdumbbell 1207254885Sdumbbell if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) 1208254885Sdumbbell lvds->native_mode.vdisplay = 1209254885Sdumbbell ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >> 1210254885Sdumbbell RADEON_VERT_PANEL_SHIFT) + 1; 1211254885Sdumbbell else 1212254885Sdumbbell lvds->native_mode.vdisplay = 1213254885Sdumbbell (RREG32(RADEON_CRTC_V_TOTAL_DISP) >> 16) + 1; 1214254885Sdumbbell 1215254885Sdumbbell if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) 1216254885Sdumbbell lvds->native_mode.hdisplay = 1217254885Sdumbbell (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >> 1218254885Sdumbbell RADEON_HORZ_PANEL_SHIFT) + 1) * 8; 1219254885Sdumbbell else 1220254885Sdumbbell lvds->native_mode.hdisplay = 1221254885Sdumbbell ((RREG32(RADEON_CRTC_H_TOTAL_DISP) >> 16) + 1) * 8; 1222254885Sdumbbell 1223254885Sdumbbell if ((lvds->native_mode.hdisplay < 640) || 1224254885Sdumbbell (lvds->native_mode.vdisplay < 480)) { 1225254885Sdumbbell lvds->native_mode.hdisplay = 640; 1226254885Sdumbbell lvds->native_mode.vdisplay = 480; 1227254885Sdumbbell } 1228254885Sdumbbell 1229254885Sdumbbell ppll_div_sel = RREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3; 1230254885Sdumbbell ppll_val = RREG32_PLL(RADEON_PPLL_DIV_0 + ppll_div_sel); 1231254885Sdumbbell if ((ppll_val & 0x000707ff) == 0x1bb) 1232254885Sdumbbell lvds->use_bios_dividers = false; 1233254885Sdumbbell else { 1234254885Sdumbbell lvds->panel_ref_divider = 1235254885Sdumbbell RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff; 1236254885Sdumbbell lvds->panel_post_divider = (ppll_val >> 16) & 0x7; 1237254885Sdumbbell lvds->panel_fb_divider = ppll_val & 0x7ff; 1238254885Sdumbbell 1239254885Sdumbbell if ((lvds->panel_ref_divider != 0) && 1240254885Sdumbbell (lvds->panel_fb_divider > 3)) 1241254885Sdumbbell lvds->use_bios_dividers = true; 1242254885Sdumbbell } 1243254885Sdumbbell lvds->panel_vcc_delay = 200; 1244254885Sdumbbell 1245254885Sdumbbell DRM_INFO("Panel info derived from registers\n"); 1246254885Sdumbbell DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay, 1247254885Sdumbbell lvds->native_mode.vdisplay); 1248254885Sdumbbell 1249254885Sdumbbell return lvds; 1250254885Sdumbbell} 1251254885Sdumbbell 1252254885Sdumbbellstruct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder 1253254885Sdumbbell *encoder) 1254254885Sdumbbell{ 1255254885Sdumbbell struct drm_device *dev = encoder->base.dev; 1256254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 1257254885Sdumbbell uint16_t lcd_info; 1258254885Sdumbbell uint32_t panel_setup; 1259254885Sdumbbell char stmp[30]; 1260254885Sdumbbell int tmp, i; 1261254885Sdumbbell struct radeon_encoder_lvds *lvds = NULL; 1262254885Sdumbbell 1263254885Sdumbbell lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE); 1264254885Sdumbbell 1265254885Sdumbbell if (lcd_info) { 1266254885Sdumbbell lvds = malloc(sizeof(struct radeon_encoder_lvds), 1267280183Sdumbbell DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 1268254885Sdumbbell 1269254885Sdumbbell if (!lvds) 1270254885Sdumbbell return NULL; 1271254885Sdumbbell 1272254885Sdumbbell for (i = 0; i < 24; i++) 1273254885Sdumbbell stmp[i] = RBIOS8(lcd_info + i + 1); 1274254885Sdumbbell stmp[24] = 0; 1275254885Sdumbbell 1276254885Sdumbbell DRM_INFO("Panel ID String: %s\n", stmp); 1277254885Sdumbbell 1278254885Sdumbbell lvds->native_mode.hdisplay = RBIOS16(lcd_info + 0x19); 1279254885Sdumbbell lvds->native_mode.vdisplay = RBIOS16(lcd_info + 0x1b); 1280254885Sdumbbell 1281254885Sdumbbell DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay, 1282254885Sdumbbell lvds->native_mode.vdisplay); 1283254885Sdumbbell 1284254885Sdumbbell lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c); 1285254885Sdumbbell lvds->panel_vcc_delay = min_t(u16, lvds->panel_vcc_delay, 2000); 1286254885Sdumbbell 1287254885Sdumbbell lvds->panel_pwr_delay = RBIOS8(lcd_info + 0x24); 1288254885Sdumbbell lvds->panel_digon_delay = RBIOS16(lcd_info + 0x38) & 0xf; 1289254885Sdumbbell lvds->panel_blon_delay = (RBIOS16(lcd_info + 0x38) >> 4) & 0xf; 1290254885Sdumbbell 1291254885Sdumbbell lvds->panel_ref_divider = RBIOS16(lcd_info + 0x2e); 1292254885Sdumbbell lvds->panel_post_divider = RBIOS8(lcd_info + 0x30); 1293254885Sdumbbell lvds->panel_fb_divider = RBIOS16(lcd_info + 0x31); 1294254885Sdumbbell if ((lvds->panel_ref_divider != 0) && 1295254885Sdumbbell (lvds->panel_fb_divider > 3)) 1296254885Sdumbbell lvds->use_bios_dividers = true; 1297254885Sdumbbell 1298254885Sdumbbell panel_setup = RBIOS32(lcd_info + 0x39); 1299254885Sdumbbell lvds->lvds_gen_cntl = 0xff00; 1300254885Sdumbbell if (panel_setup & 0x1) 1301254885Sdumbbell lvds->lvds_gen_cntl |= RADEON_LVDS_PANEL_FORMAT; 1302254885Sdumbbell 1303254885Sdumbbell if ((panel_setup >> 4) & 0x1) 1304254885Sdumbbell lvds->lvds_gen_cntl |= RADEON_LVDS_PANEL_TYPE; 1305254885Sdumbbell 1306254885Sdumbbell switch ((panel_setup >> 8) & 0x7) { 1307254885Sdumbbell case 0: 1308254885Sdumbbell lvds->lvds_gen_cntl |= RADEON_LVDS_NO_FM; 1309254885Sdumbbell break; 1310254885Sdumbbell case 1: 1311254885Sdumbbell lvds->lvds_gen_cntl |= RADEON_LVDS_2_GREY; 1312254885Sdumbbell break; 1313254885Sdumbbell case 2: 1314254885Sdumbbell lvds->lvds_gen_cntl |= RADEON_LVDS_4_GREY; 1315254885Sdumbbell break; 1316254885Sdumbbell default: 1317254885Sdumbbell break; 1318254885Sdumbbell } 1319254885Sdumbbell 1320254885Sdumbbell if ((panel_setup >> 16) & 0x1) 1321254885Sdumbbell lvds->lvds_gen_cntl |= RADEON_LVDS_FP_POL_LOW; 1322254885Sdumbbell 1323254885Sdumbbell if ((panel_setup >> 17) & 0x1) 1324254885Sdumbbell lvds->lvds_gen_cntl |= RADEON_LVDS_LP_POL_LOW; 1325254885Sdumbbell 1326254885Sdumbbell if ((panel_setup >> 18) & 0x1) 1327254885Sdumbbell lvds->lvds_gen_cntl |= RADEON_LVDS_DTM_POL_LOW; 1328254885Sdumbbell 1329254885Sdumbbell if ((panel_setup >> 23) & 0x1) 1330254885Sdumbbell lvds->lvds_gen_cntl |= RADEON_LVDS_BL_CLK_SEL; 1331254885Sdumbbell 1332254885Sdumbbell lvds->lvds_gen_cntl |= (panel_setup & 0xf0000000); 1333254885Sdumbbell 1334254885Sdumbbell for (i = 0; i < 32; i++) { 1335254885Sdumbbell tmp = RBIOS16(lcd_info + 64 + i * 2); 1336254885Sdumbbell if (tmp == 0) 1337254885Sdumbbell break; 1338254885Sdumbbell 1339254885Sdumbbell if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) && 1340254885Sdumbbell (RBIOS16(tmp + 2) == lvds->native_mode.vdisplay)) { 1341254885Sdumbbell lvds->native_mode.htotal = lvds->native_mode.hdisplay + 1342254885Sdumbbell (RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8; 1343254885Sdumbbell lvds->native_mode.hsync_start = lvds->native_mode.hdisplay + 1344254885Sdumbbell (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - 1) * 8; 1345254885Sdumbbell lvds->native_mode.hsync_end = lvds->native_mode.hsync_start + 1346254885Sdumbbell (RBIOS8(tmp + 23) * 8); 1347254885Sdumbbell 1348254885Sdumbbell lvds->native_mode.vtotal = lvds->native_mode.vdisplay + 1349254885Sdumbbell (RBIOS16(tmp + 24) - RBIOS16(tmp + 26)); 1350254885Sdumbbell lvds->native_mode.vsync_start = lvds->native_mode.vdisplay + 1351254885Sdumbbell ((RBIOS16(tmp + 28) & 0x7ff) - RBIOS16(tmp + 26)); 1352254885Sdumbbell lvds->native_mode.vsync_end = lvds->native_mode.vsync_start + 1353254885Sdumbbell ((RBIOS16(tmp + 28) & 0xf800) >> 11); 1354254885Sdumbbell 1355254885Sdumbbell lvds->native_mode.clock = RBIOS16(tmp + 9) * 10; 1356254885Sdumbbell lvds->native_mode.flags = 0; 1357254885Sdumbbell /* set crtc values */ 1358254885Sdumbbell drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); 1359254885Sdumbbell 1360254885Sdumbbell } 1361254885Sdumbbell } 1362254885Sdumbbell } else { 1363254885Sdumbbell DRM_INFO("No panel info found in BIOS\n"); 1364254885Sdumbbell lvds = radeon_legacy_get_lvds_info_from_regs(rdev); 1365254885Sdumbbell } 1366254885Sdumbbell 1367254885Sdumbbell if (lvds) 1368254885Sdumbbell encoder->native_mode = lvds->native_mode; 1369254885Sdumbbell return lvds; 1370254885Sdumbbell} 1371254885Sdumbbell 1372254885Sdumbbellstatic const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = { 1373254885Sdumbbell {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_R100 */ 1374254885Sdumbbell {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_RV100 */ 1375254885Sdumbbell {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RS100 */ 1376254885Sdumbbell {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_RV200 */ 1377254885Sdumbbell {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_RS200 */ 1378254885Sdumbbell {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_R200 */ 1379254885Sdumbbell {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, /* CHIP_RV250 */ 1380254885Sdumbbell {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RS300 */ 1381254885Sdumbbell {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /* CHIP_RV280 */ 1382254885Sdumbbell {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R300 */ 1383254885Sdumbbell {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R350 */ 1384254885Sdumbbell {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RV350 */ 1385254885Sdumbbell {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RV380 */ 1386254885Sdumbbell {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R420 */ 1387254885Sdumbbell {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R423 */ 1388254885Sdumbbell {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RV410 */ 1389254885Sdumbbell { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS400 */ 1390254885Sdumbbell { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS480 */ 1391254885Sdumbbell}; 1392254885Sdumbbell 1393254885Sdumbbellbool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder, 1394254885Sdumbbell struct radeon_encoder_int_tmds *tmds) 1395254885Sdumbbell{ 1396254885Sdumbbell struct drm_device *dev = encoder->base.dev; 1397254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 1398254885Sdumbbell int i; 1399254885Sdumbbell 1400254885Sdumbbell for (i = 0; i < 4; i++) { 1401254885Sdumbbell tmds->tmds_pll[i].value = 1402254885Sdumbbell default_tmds_pll[rdev->family][i].value; 1403254885Sdumbbell tmds->tmds_pll[i].freq = default_tmds_pll[rdev->family][i].freq; 1404254885Sdumbbell } 1405254885Sdumbbell 1406254885Sdumbbell return true; 1407254885Sdumbbell} 1408254885Sdumbbell 1409254885Sdumbbellbool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, 1410254885Sdumbbell struct radeon_encoder_int_tmds *tmds) 1411254885Sdumbbell{ 1412254885Sdumbbell struct drm_device *dev = encoder->base.dev; 1413254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 1414254885Sdumbbell uint16_t tmds_info; 1415254885Sdumbbell int i, n; 1416254885Sdumbbell uint8_t ver; 1417254885Sdumbbell 1418254885Sdumbbell tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); 1419254885Sdumbbell 1420254885Sdumbbell if (tmds_info) { 1421254885Sdumbbell ver = RBIOS8(tmds_info); 1422254885Sdumbbell DRM_DEBUG_KMS("DFP table revision: %d\n", ver); 1423254885Sdumbbell if (ver == 3) { 1424254885Sdumbbell n = RBIOS8(tmds_info + 5) + 1; 1425254885Sdumbbell if (n > 4) 1426254885Sdumbbell n = 4; 1427254885Sdumbbell for (i = 0; i < n; i++) { 1428254885Sdumbbell tmds->tmds_pll[i].value = 1429254885Sdumbbell RBIOS32(tmds_info + i * 10 + 0x08); 1430254885Sdumbbell tmds->tmds_pll[i].freq = 1431254885Sdumbbell RBIOS16(tmds_info + i * 10 + 0x10); 1432254885Sdumbbell DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n", 1433254885Sdumbbell tmds->tmds_pll[i].freq, 1434254885Sdumbbell tmds->tmds_pll[i].value); 1435254885Sdumbbell } 1436254885Sdumbbell } else if (ver == 4) { 1437254885Sdumbbell int stride = 0; 1438254885Sdumbbell n = RBIOS8(tmds_info + 5) + 1; 1439254885Sdumbbell if (n > 4) 1440254885Sdumbbell n = 4; 1441254885Sdumbbell for (i = 0; i < n; i++) { 1442254885Sdumbbell tmds->tmds_pll[i].value = 1443254885Sdumbbell RBIOS32(tmds_info + stride + 0x08); 1444254885Sdumbbell tmds->tmds_pll[i].freq = 1445254885Sdumbbell RBIOS16(tmds_info + stride + 0x10); 1446254885Sdumbbell if (i == 0) 1447254885Sdumbbell stride += 10; 1448254885Sdumbbell else 1449254885Sdumbbell stride += 6; 1450254885Sdumbbell DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n", 1451254885Sdumbbell tmds->tmds_pll[i].freq, 1452254885Sdumbbell tmds->tmds_pll[i].value); 1453254885Sdumbbell } 1454254885Sdumbbell } 1455254885Sdumbbell } else { 1456254885Sdumbbell DRM_INFO("No TMDS info found in BIOS\n"); 1457254885Sdumbbell return false; 1458254885Sdumbbell } 1459254885Sdumbbell return true; 1460254885Sdumbbell} 1461254885Sdumbbell 1462254885Sdumbbellbool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder, 1463254885Sdumbbell struct radeon_encoder_ext_tmds *tmds) 1464254885Sdumbbell{ 1465254885Sdumbbell struct drm_device *dev = encoder->base.dev; 1466254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 1467254885Sdumbbell struct radeon_i2c_bus_rec i2c_bus; 1468254885Sdumbbell 1469254885Sdumbbell /* default for macs */ 1470254885Sdumbbell i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); 1471254885Sdumbbell tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); 1472254885Sdumbbell 1473254885Sdumbbell /* XXX some macs have duallink chips */ 1474254885Sdumbbell switch (rdev->mode_info.connector_table) { 1475254885Sdumbbell case CT_POWERBOOK_EXTERNAL: 1476254885Sdumbbell case CT_MINI_EXTERNAL: 1477254885Sdumbbell default: 1478254885Sdumbbell tmds->dvo_chip = DVO_SIL164; 1479254885Sdumbbell tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */ 1480254885Sdumbbell break; 1481254885Sdumbbell } 1482254885Sdumbbell 1483254885Sdumbbell return true; 1484254885Sdumbbell} 1485254885Sdumbbell 1486254885Sdumbbellbool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder, 1487254885Sdumbbell struct radeon_encoder_ext_tmds *tmds) 1488254885Sdumbbell{ 1489254885Sdumbbell struct drm_device *dev = encoder->base.dev; 1490254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 1491254885Sdumbbell uint16_t offset; 1492254885Sdumbbell uint8_t ver; 1493254885Sdumbbell enum radeon_combios_ddc gpio; 1494254885Sdumbbell struct radeon_i2c_bus_rec i2c_bus; 1495254885Sdumbbell 1496254885Sdumbbell tmds->i2c_bus = NULL; 1497254885Sdumbbell if (rdev->flags & RADEON_IS_IGP) { 1498254885Sdumbbell i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); 1499254885Sdumbbell tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); 1500254885Sdumbbell tmds->dvo_chip = DVO_SIL164; 1501254885Sdumbbell tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */ 1502254885Sdumbbell } else { 1503254885Sdumbbell offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); 1504254885Sdumbbell if (offset) { 1505254885Sdumbbell ver = RBIOS8(offset); 1506254885Sdumbbell DRM_DEBUG_KMS("External TMDS Table revision: %d\n", ver); 1507254885Sdumbbell tmds->slave_addr = RBIOS8(offset + 4 + 2); 1508254885Sdumbbell tmds->slave_addr >>= 1; /* 7 bit addressing */ 1509254885Sdumbbell gpio = RBIOS8(offset + 4 + 3); 1510254885Sdumbbell if (gpio == DDC_LCD) { 1511254885Sdumbbell /* MM i2c */ 1512254885Sdumbbell i2c_bus.valid = true; 1513254885Sdumbbell i2c_bus.hw_capable = true; 1514254885Sdumbbell i2c_bus.mm_i2c = true; 1515254885Sdumbbell i2c_bus.i2c_id = 0xa0; 1516254885Sdumbbell } else 1517254885Sdumbbell i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0); 1518254885Sdumbbell tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); 1519254885Sdumbbell } 1520254885Sdumbbell } 1521254885Sdumbbell 1522254885Sdumbbell if (!tmds->i2c_bus) { 1523254885Sdumbbell DRM_INFO("No valid Ext TMDS info found in BIOS\n"); 1524254885Sdumbbell return false; 1525254885Sdumbbell } 1526254885Sdumbbell 1527254885Sdumbbell return true; 1528254885Sdumbbell} 1529254885Sdumbbell 1530254885Sdumbbellbool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) 1531254885Sdumbbell{ 1532254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 1533254885Sdumbbell struct radeon_i2c_bus_rec ddc_i2c; 1534254885Sdumbbell struct radeon_hpd hpd; 1535254885Sdumbbell 1536254885Sdumbbell rdev->mode_info.connector_table = radeon_connector_table; 1537254885Sdumbbell if (rdev->mode_info.connector_table == CT_NONE) { 1538254885Sdumbbell#ifdef CONFIG_PPC_PMAC 1539254885Sdumbbell if (of_machine_is_compatible("PowerBook3,3")) { 1540254885Sdumbbell /* powerbook with VGA */ 1541254885Sdumbbell rdev->mode_info.connector_table = CT_POWERBOOK_VGA; 1542254885Sdumbbell } else if (of_machine_is_compatible("PowerBook3,4") || 1543254885Sdumbbell of_machine_is_compatible("PowerBook3,5")) { 1544254885Sdumbbell /* powerbook with internal tmds */ 1545254885Sdumbbell rdev->mode_info.connector_table = CT_POWERBOOK_INTERNAL; 1546254885Sdumbbell } else if (of_machine_is_compatible("PowerBook5,1") || 1547254885Sdumbbell of_machine_is_compatible("PowerBook5,2") || 1548254885Sdumbbell of_machine_is_compatible("PowerBook5,3") || 1549254885Sdumbbell of_machine_is_compatible("PowerBook5,4") || 1550254885Sdumbbell of_machine_is_compatible("PowerBook5,5")) { 1551254885Sdumbbell /* powerbook with external single link tmds (sil164) */ 1552254885Sdumbbell rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL; 1553254885Sdumbbell } else if (of_machine_is_compatible("PowerBook5,6")) { 1554254885Sdumbbell /* powerbook with external dual or single link tmds */ 1555254885Sdumbbell rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL; 1556254885Sdumbbell } else if (of_machine_is_compatible("PowerBook5,7") || 1557254885Sdumbbell of_machine_is_compatible("PowerBook5,8") || 1558254885Sdumbbell of_machine_is_compatible("PowerBook5,9")) { 1559254885Sdumbbell /* PowerBook6,2 ? */ 1560254885Sdumbbell /* powerbook with external dual link tmds (sil1178?) */ 1561254885Sdumbbell rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL; 1562254885Sdumbbell } else if (of_machine_is_compatible("PowerBook4,1") || 1563254885Sdumbbell of_machine_is_compatible("PowerBook4,2") || 1564254885Sdumbbell of_machine_is_compatible("PowerBook4,3") || 1565254885Sdumbbell of_machine_is_compatible("PowerBook6,3") || 1566254885Sdumbbell of_machine_is_compatible("PowerBook6,5") || 1567254885Sdumbbell of_machine_is_compatible("PowerBook6,7")) { 1568254885Sdumbbell /* ibook */ 1569254885Sdumbbell rdev->mode_info.connector_table = CT_IBOOK; 1570254885Sdumbbell } else if (of_machine_is_compatible("PowerMac3,5")) { 1571254885Sdumbbell /* PowerMac G4 Silver radeon 7500 */ 1572254885Sdumbbell rdev->mode_info.connector_table = CT_MAC_G4_SILVER; 1573254885Sdumbbell } else if (of_machine_is_compatible("PowerMac4,4")) { 1574254885Sdumbbell /* emac */ 1575254885Sdumbbell rdev->mode_info.connector_table = CT_EMAC; 1576254885Sdumbbell } else if (of_machine_is_compatible("PowerMac10,1")) { 1577254885Sdumbbell /* mini with internal tmds */ 1578254885Sdumbbell rdev->mode_info.connector_table = CT_MINI_INTERNAL; 1579254885Sdumbbell } else if (of_machine_is_compatible("PowerMac10,2")) { 1580254885Sdumbbell /* mini with external tmds */ 1581254885Sdumbbell rdev->mode_info.connector_table = CT_MINI_EXTERNAL; 1582254885Sdumbbell } else if (of_machine_is_compatible("PowerMac12,1")) { 1583254885Sdumbbell /* PowerMac8,1 ? */ 1584254885Sdumbbell /* imac g5 isight */ 1585254885Sdumbbell rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT; 1586254885Sdumbbell } else if ((dev->pci_device == 0x4a48) && 1587254885Sdumbbell (dev->pci_subvendor == 0x1002) && 1588254885Sdumbbell (dev->pci_subdevice == 0x4a48)) { 1589254885Sdumbbell /* Mac X800 */ 1590254885Sdumbbell rdev->mode_info.connector_table = CT_MAC_X800; 1591254885Sdumbbell } else if ((of_machine_is_compatible("PowerMac7,2") || 1592254885Sdumbbell of_machine_is_compatible("PowerMac7,3")) && 1593254885Sdumbbell (dev->pci_device == 0x4150) && 1594254885Sdumbbell (dev->pci_subvendor == 0x1002) && 1595254885Sdumbbell (dev->pci_subdevice == 0x4150)) { 1596254885Sdumbbell /* Mac G5 tower 9600 */ 1597254885Sdumbbell rdev->mode_info.connector_table = CT_MAC_G5_9600; 1598254885Sdumbbell } else if ((dev->pci_device == 0x4c66) && 1599254885Sdumbbell (dev->pci_subvendor == 0x1002) && 1600254885Sdumbbell (dev->pci_subdevice == 0x4c66)) { 1601254885Sdumbbell /* SAM440ep RV250 embedded board */ 1602254885Sdumbbell rdev->mode_info.connector_table = CT_SAM440EP; 1603254885Sdumbbell } else 1604254885Sdumbbell#endif /* CONFIG_PPC_PMAC */ 1605254885Sdumbbell#ifdef CONFIG_PPC64 1606254885Sdumbbell if (ASIC_IS_RN50(rdev)) 1607254885Sdumbbell rdev->mode_info.connector_table = CT_RN50_POWER; 1608254885Sdumbbell else 1609254885Sdumbbell#endif 1610254885Sdumbbell rdev->mode_info.connector_table = CT_GENERIC; 1611254885Sdumbbell } 1612254885Sdumbbell 1613254885Sdumbbell switch (rdev->mode_info.connector_table) { 1614254885Sdumbbell case CT_GENERIC: 1615254885Sdumbbell DRM_INFO("Connector Table: %d (generic)\n", 1616254885Sdumbbell rdev->mode_info.connector_table); 1617254885Sdumbbell /* these are the most common settings */ 1618254885Sdumbbell if (rdev->flags & RADEON_SINGLE_CRTC) { 1619254885Sdumbbell /* VGA - primary dac */ 1620254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); 1621254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1622254885Sdumbbell radeon_add_legacy_encoder(dev, 1623254885Sdumbbell radeon_get_encoder_enum(dev, 1624254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 1625254885Sdumbbell 1), 1626254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 1627254885Sdumbbell radeon_add_legacy_connector(dev, 0, 1628254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 1629254885Sdumbbell DRM_MODE_CONNECTOR_VGA, 1630254885Sdumbbell &ddc_i2c, 1631254885Sdumbbell CONNECTOR_OBJECT_ID_VGA, 1632254885Sdumbbell &hpd); 1633254885Sdumbbell } else if (rdev->flags & RADEON_IS_MOBILITY) { 1634254885Sdumbbell /* LVDS */ 1635254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0); 1636254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1637254885Sdumbbell radeon_add_legacy_encoder(dev, 1638254885Sdumbbell radeon_get_encoder_enum(dev, 1639254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT, 1640254885Sdumbbell 0), 1641254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT); 1642254885Sdumbbell radeon_add_legacy_connector(dev, 0, 1643254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT, 1644254885Sdumbbell DRM_MODE_CONNECTOR_LVDS, 1645254885Sdumbbell &ddc_i2c, 1646254885Sdumbbell CONNECTOR_OBJECT_ID_LVDS, 1647254885Sdumbbell &hpd); 1648254885Sdumbbell 1649254885Sdumbbell /* VGA - primary dac */ 1650254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); 1651254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1652254885Sdumbbell radeon_add_legacy_encoder(dev, 1653254885Sdumbbell radeon_get_encoder_enum(dev, 1654254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 1655254885Sdumbbell 1), 1656254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 1657254885Sdumbbell radeon_add_legacy_connector(dev, 1, 1658254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 1659254885Sdumbbell DRM_MODE_CONNECTOR_VGA, 1660254885Sdumbbell &ddc_i2c, 1661254885Sdumbbell CONNECTOR_OBJECT_ID_VGA, 1662254885Sdumbbell &hpd); 1663254885Sdumbbell } else { 1664254885Sdumbbell /* DVI-I - tv dac, int tmds */ 1665254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); 1666254885Sdumbbell hpd.hpd = RADEON_HPD_1; 1667254885Sdumbbell radeon_add_legacy_encoder(dev, 1668254885Sdumbbell radeon_get_encoder_enum(dev, 1669254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT, 1670254885Sdumbbell 0), 1671254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT); 1672254885Sdumbbell radeon_add_legacy_encoder(dev, 1673254885Sdumbbell radeon_get_encoder_enum(dev, 1674254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 1675254885Sdumbbell 2), 1676254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT); 1677254885Sdumbbell radeon_add_legacy_connector(dev, 0, 1678254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT | 1679254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 1680254885Sdumbbell DRM_MODE_CONNECTOR_DVII, 1681254885Sdumbbell &ddc_i2c, 1682254885Sdumbbell CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, 1683254885Sdumbbell &hpd); 1684254885Sdumbbell 1685254885Sdumbbell /* VGA - primary dac */ 1686254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); 1687254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1688254885Sdumbbell radeon_add_legacy_encoder(dev, 1689254885Sdumbbell radeon_get_encoder_enum(dev, 1690254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 1691254885Sdumbbell 1), 1692254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 1693254885Sdumbbell radeon_add_legacy_connector(dev, 1, 1694254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 1695254885Sdumbbell DRM_MODE_CONNECTOR_VGA, 1696254885Sdumbbell &ddc_i2c, 1697254885Sdumbbell CONNECTOR_OBJECT_ID_VGA, 1698254885Sdumbbell &hpd); 1699254885Sdumbbell } 1700254885Sdumbbell 1701254885Sdumbbell if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) { 1702254885Sdumbbell /* TV - tv dac */ 1703254885Sdumbbell ddc_i2c.valid = false; 1704254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1705254885Sdumbbell radeon_add_legacy_encoder(dev, 1706254885Sdumbbell radeon_get_encoder_enum(dev, 1707254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 1708254885Sdumbbell 2), 1709254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT); 1710254885Sdumbbell radeon_add_legacy_connector(dev, 2, 1711254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 1712254885Sdumbbell DRM_MODE_CONNECTOR_SVIDEO, 1713254885Sdumbbell &ddc_i2c, 1714254885Sdumbbell CONNECTOR_OBJECT_ID_SVIDEO, 1715254885Sdumbbell &hpd); 1716254885Sdumbbell } 1717254885Sdumbbell break; 1718254885Sdumbbell case CT_IBOOK: 1719254885Sdumbbell DRM_INFO("Connector Table: %d (ibook)\n", 1720254885Sdumbbell rdev->mode_info.connector_table); 1721254885Sdumbbell /* LVDS */ 1722254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); 1723254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1724254885Sdumbbell radeon_add_legacy_encoder(dev, 1725254885Sdumbbell radeon_get_encoder_enum(dev, 1726254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT, 1727254885Sdumbbell 0), 1728254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT); 1729254885Sdumbbell radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, 1730254885Sdumbbell DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, 1731254885Sdumbbell CONNECTOR_OBJECT_ID_LVDS, 1732254885Sdumbbell &hpd); 1733254885Sdumbbell /* VGA - TV DAC */ 1734254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); 1735254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1736254885Sdumbbell radeon_add_legacy_encoder(dev, 1737254885Sdumbbell radeon_get_encoder_enum(dev, 1738254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 1739254885Sdumbbell 2), 1740254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT); 1741254885Sdumbbell radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, 1742254885Sdumbbell DRM_MODE_CONNECTOR_VGA, &ddc_i2c, 1743254885Sdumbbell CONNECTOR_OBJECT_ID_VGA, 1744254885Sdumbbell &hpd); 1745254885Sdumbbell /* TV - TV DAC */ 1746254885Sdumbbell ddc_i2c.valid = false; 1747254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1748254885Sdumbbell radeon_add_legacy_encoder(dev, 1749254885Sdumbbell radeon_get_encoder_enum(dev, 1750254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 1751254885Sdumbbell 2), 1752254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT); 1753254885Sdumbbell radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, 1754254885Sdumbbell DRM_MODE_CONNECTOR_SVIDEO, 1755254885Sdumbbell &ddc_i2c, 1756254885Sdumbbell CONNECTOR_OBJECT_ID_SVIDEO, 1757254885Sdumbbell &hpd); 1758254885Sdumbbell break; 1759254885Sdumbbell case CT_POWERBOOK_EXTERNAL: 1760254885Sdumbbell DRM_INFO("Connector Table: %d (powerbook external tmds)\n", 1761254885Sdumbbell rdev->mode_info.connector_table); 1762254885Sdumbbell /* LVDS */ 1763254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); 1764254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1765254885Sdumbbell radeon_add_legacy_encoder(dev, 1766254885Sdumbbell radeon_get_encoder_enum(dev, 1767254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT, 1768254885Sdumbbell 0), 1769254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT); 1770254885Sdumbbell radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, 1771254885Sdumbbell DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, 1772254885Sdumbbell CONNECTOR_OBJECT_ID_LVDS, 1773254885Sdumbbell &hpd); 1774254885Sdumbbell /* DVI-I - primary dac, ext tmds */ 1775254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); 1776254885Sdumbbell hpd.hpd = RADEON_HPD_2; /* ??? */ 1777254885Sdumbbell radeon_add_legacy_encoder(dev, 1778254885Sdumbbell radeon_get_encoder_enum(dev, 1779254885Sdumbbell ATOM_DEVICE_DFP2_SUPPORT, 1780254885Sdumbbell 0), 1781254885Sdumbbell ATOM_DEVICE_DFP2_SUPPORT); 1782254885Sdumbbell radeon_add_legacy_encoder(dev, 1783254885Sdumbbell radeon_get_encoder_enum(dev, 1784254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 1785254885Sdumbbell 1), 1786254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 1787254885Sdumbbell /* XXX some are SL */ 1788254885Sdumbbell radeon_add_legacy_connector(dev, 1, 1789254885Sdumbbell ATOM_DEVICE_DFP2_SUPPORT | 1790254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 1791254885Sdumbbell DRM_MODE_CONNECTOR_DVII, &ddc_i2c, 1792254885Sdumbbell CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, 1793254885Sdumbbell &hpd); 1794254885Sdumbbell /* TV - TV DAC */ 1795254885Sdumbbell ddc_i2c.valid = false; 1796254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1797254885Sdumbbell radeon_add_legacy_encoder(dev, 1798254885Sdumbbell radeon_get_encoder_enum(dev, 1799254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 1800254885Sdumbbell 2), 1801254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT); 1802254885Sdumbbell radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, 1803254885Sdumbbell DRM_MODE_CONNECTOR_SVIDEO, 1804254885Sdumbbell &ddc_i2c, 1805254885Sdumbbell CONNECTOR_OBJECT_ID_SVIDEO, 1806254885Sdumbbell &hpd); 1807254885Sdumbbell break; 1808254885Sdumbbell case CT_POWERBOOK_INTERNAL: 1809254885Sdumbbell DRM_INFO("Connector Table: %d (powerbook internal tmds)\n", 1810254885Sdumbbell rdev->mode_info.connector_table); 1811254885Sdumbbell /* LVDS */ 1812254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); 1813254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1814254885Sdumbbell radeon_add_legacy_encoder(dev, 1815254885Sdumbbell radeon_get_encoder_enum(dev, 1816254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT, 1817254885Sdumbbell 0), 1818254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT); 1819254885Sdumbbell radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, 1820254885Sdumbbell DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, 1821254885Sdumbbell CONNECTOR_OBJECT_ID_LVDS, 1822254885Sdumbbell &hpd); 1823254885Sdumbbell /* DVI-I - primary dac, int tmds */ 1824254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); 1825254885Sdumbbell hpd.hpd = RADEON_HPD_1; /* ??? */ 1826254885Sdumbbell radeon_add_legacy_encoder(dev, 1827254885Sdumbbell radeon_get_encoder_enum(dev, 1828254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT, 1829254885Sdumbbell 0), 1830254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT); 1831254885Sdumbbell radeon_add_legacy_encoder(dev, 1832254885Sdumbbell radeon_get_encoder_enum(dev, 1833254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 1834254885Sdumbbell 1), 1835254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 1836254885Sdumbbell radeon_add_legacy_connector(dev, 1, 1837254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT | 1838254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 1839254885Sdumbbell DRM_MODE_CONNECTOR_DVII, &ddc_i2c, 1840254885Sdumbbell CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, 1841254885Sdumbbell &hpd); 1842254885Sdumbbell /* TV - TV DAC */ 1843254885Sdumbbell ddc_i2c.valid = false; 1844254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1845254885Sdumbbell radeon_add_legacy_encoder(dev, 1846254885Sdumbbell radeon_get_encoder_enum(dev, 1847254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 1848254885Sdumbbell 2), 1849254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT); 1850254885Sdumbbell radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, 1851254885Sdumbbell DRM_MODE_CONNECTOR_SVIDEO, 1852254885Sdumbbell &ddc_i2c, 1853254885Sdumbbell CONNECTOR_OBJECT_ID_SVIDEO, 1854254885Sdumbbell &hpd); 1855254885Sdumbbell break; 1856254885Sdumbbell case CT_POWERBOOK_VGA: 1857254885Sdumbbell DRM_INFO("Connector Table: %d (powerbook vga)\n", 1858254885Sdumbbell rdev->mode_info.connector_table); 1859254885Sdumbbell /* LVDS */ 1860254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); 1861254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1862254885Sdumbbell radeon_add_legacy_encoder(dev, 1863254885Sdumbbell radeon_get_encoder_enum(dev, 1864254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT, 1865254885Sdumbbell 0), 1866254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT); 1867254885Sdumbbell radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, 1868254885Sdumbbell DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, 1869254885Sdumbbell CONNECTOR_OBJECT_ID_LVDS, 1870254885Sdumbbell &hpd); 1871254885Sdumbbell /* VGA - primary dac */ 1872254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); 1873254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1874254885Sdumbbell radeon_add_legacy_encoder(dev, 1875254885Sdumbbell radeon_get_encoder_enum(dev, 1876254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 1877254885Sdumbbell 1), 1878254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 1879254885Sdumbbell radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT, 1880254885Sdumbbell DRM_MODE_CONNECTOR_VGA, &ddc_i2c, 1881254885Sdumbbell CONNECTOR_OBJECT_ID_VGA, 1882254885Sdumbbell &hpd); 1883254885Sdumbbell /* TV - TV DAC */ 1884254885Sdumbbell ddc_i2c.valid = false; 1885254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1886254885Sdumbbell radeon_add_legacy_encoder(dev, 1887254885Sdumbbell radeon_get_encoder_enum(dev, 1888254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 1889254885Sdumbbell 2), 1890254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT); 1891254885Sdumbbell radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, 1892254885Sdumbbell DRM_MODE_CONNECTOR_SVIDEO, 1893254885Sdumbbell &ddc_i2c, 1894254885Sdumbbell CONNECTOR_OBJECT_ID_SVIDEO, 1895254885Sdumbbell &hpd); 1896254885Sdumbbell break; 1897254885Sdumbbell case CT_MINI_EXTERNAL: 1898254885Sdumbbell DRM_INFO("Connector Table: %d (mini external tmds)\n", 1899254885Sdumbbell rdev->mode_info.connector_table); 1900254885Sdumbbell /* DVI-I - tv dac, ext tmds */ 1901254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); 1902254885Sdumbbell hpd.hpd = RADEON_HPD_2; /* ??? */ 1903254885Sdumbbell radeon_add_legacy_encoder(dev, 1904254885Sdumbbell radeon_get_encoder_enum(dev, 1905254885Sdumbbell ATOM_DEVICE_DFP2_SUPPORT, 1906254885Sdumbbell 0), 1907254885Sdumbbell ATOM_DEVICE_DFP2_SUPPORT); 1908254885Sdumbbell radeon_add_legacy_encoder(dev, 1909254885Sdumbbell radeon_get_encoder_enum(dev, 1910254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 1911254885Sdumbbell 2), 1912254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT); 1913254885Sdumbbell /* XXX are any DL? */ 1914254885Sdumbbell radeon_add_legacy_connector(dev, 0, 1915254885Sdumbbell ATOM_DEVICE_DFP2_SUPPORT | 1916254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 1917254885Sdumbbell DRM_MODE_CONNECTOR_DVII, &ddc_i2c, 1918254885Sdumbbell CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, 1919254885Sdumbbell &hpd); 1920254885Sdumbbell /* TV - TV DAC */ 1921254885Sdumbbell ddc_i2c.valid = false; 1922254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1923254885Sdumbbell radeon_add_legacy_encoder(dev, 1924254885Sdumbbell radeon_get_encoder_enum(dev, 1925254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 1926254885Sdumbbell 2), 1927254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT); 1928254885Sdumbbell radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, 1929254885Sdumbbell DRM_MODE_CONNECTOR_SVIDEO, 1930254885Sdumbbell &ddc_i2c, 1931254885Sdumbbell CONNECTOR_OBJECT_ID_SVIDEO, 1932254885Sdumbbell &hpd); 1933254885Sdumbbell break; 1934254885Sdumbbell case CT_MINI_INTERNAL: 1935254885Sdumbbell DRM_INFO("Connector Table: %d (mini internal tmds)\n", 1936254885Sdumbbell rdev->mode_info.connector_table); 1937254885Sdumbbell /* DVI-I - tv dac, int tmds */ 1938254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); 1939254885Sdumbbell hpd.hpd = RADEON_HPD_1; /* ??? */ 1940254885Sdumbbell radeon_add_legacy_encoder(dev, 1941254885Sdumbbell radeon_get_encoder_enum(dev, 1942254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT, 1943254885Sdumbbell 0), 1944254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT); 1945254885Sdumbbell radeon_add_legacy_encoder(dev, 1946254885Sdumbbell radeon_get_encoder_enum(dev, 1947254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 1948254885Sdumbbell 2), 1949254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT); 1950254885Sdumbbell radeon_add_legacy_connector(dev, 0, 1951254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT | 1952254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 1953254885Sdumbbell DRM_MODE_CONNECTOR_DVII, &ddc_i2c, 1954254885Sdumbbell CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, 1955254885Sdumbbell &hpd); 1956254885Sdumbbell /* TV - TV DAC */ 1957254885Sdumbbell ddc_i2c.valid = false; 1958254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1959254885Sdumbbell radeon_add_legacy_encoder(dev, 1960254885Sdumbbell radeon_get_encoder_enum(dev, 1961254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 1962254885Sdumbbell 2), 1963254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT); 1964254885Sdumbbell radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, 1965254885Sdumbbell DRM_MODE_CONNECTOR_SVIDEO, 1966254885Sdumbbell &ddc_i2c, 1967254885Sdumbbell CONNECTOR_OBJECT_ID_SVIDEO, 1968254885Sdumbbell &hpd); 1969254885Sdumbbell break; 1970254885Sdumbbell case CT_IMAC_G5_ISIGHT: 1971254885Sdumbbell DRM_INFO("Connector Table: %d (imac g5 isight)\n", 1972254885Sdumbbell rdev->mode_info.connector_table); 1973254885Sdumbbell /* DVI-D - int tmds */ 1974254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); 1975254885Sdumbbell hpd.hpd = RADEON_HPD_1; /* ??? */ 1976254885Sdumbbell radeon_add_legacy_encoder(dev, 1977254885Sdumbbell radeon_get_encoder_enum(dev, 1978254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT, 1979254885Sdumbbell 0), 1980254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT); 1981254885Sdumbbell radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT, 1982254885Sdumbbell DRM_MODE_CONNECTOR_DVID, &ddc_i2c, 1983254885Sdumbbell CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D, 1984254885Sdumbbell &hpd); 1985254885Sdumbbell /* VGA - tv dac */ 1986254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); 1987254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 1988254885Sdumbbell radeon_add_legacy_encoder(dev, 1989254885Sdumbbell radeon_get_encoder_enum(dev, 1990254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 1991254885Sdumbbell 2), 1992254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT); 1993254885Sdumbbell radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, 1994254885Sdumbbell DRM_MODE_CONNECTOR_VGA, &ddc_i2c, 1995254885Sdumbbell CONNECTOR_OBJECT_ID_VGA, 1996254885Sdumbbell &hpd); 1997254885Sdumbbell /* TV - TV DAC */ 1998254885Sdumbbell ddc_i2c.valid = false; 1999254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2000254885Sdumbbell radeon_add_legacy_encoder(dev, 2001254885Sdumbbell radeon_get_encoder_enum(dev, 2002254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 2003254885Sdumbbell 2), 2004254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT); 2005254885Sdumbbell radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, 2006254885Sdumbbell DRM_MODE_CONNECTOR_SVIDEO, 2007254885Sdumbbell &ddc_i2c, 2008254885Sdumbbell CONNECTOR_OBJECT_ID_SVIDEO, 2009254885Sdumbbell &hpd); 2010254885Sdumbbell break; 2011254885Sdumbbell case CT_EMAC: 2012254885Sdumbbell DRM_INFO("Connector Table: %d (emac)\n", 2013254885Sdumbbell rdev->mode_info.connector_table); 2014254885Sdumbbell /* VGA - primary dac */ 2015254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); 2016254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2017254885Sdumbbell radeon_add_legacy_encoder(dev, 2018254885Sdumbbell radeon_get_encoder_enum(dev, 2019254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 2020254885Sdumbbell 1), 2021254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 2022254885Sdumbbell radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT, 2023254885Sdumbbell DRM_MODE_CONNECTOR_VGA, &ddc_i2c, 2024254885Sdumbbell CONNECTOR_OBJECT_ID_VGA, 2025254885Sdumbbell &hpd); 2026254885Sdumbbell /* VGA - tv dac */ 2027254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); 2028254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2029254885Sdumbbell radeon_add_legacy_encoder(dev, 2030254885Sdumbbell radeon_get_encoder_enum(dev, 2031254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 2032254885Sdumbbell 2), 2033254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT); 2034254885Sdumbbell radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, 2035254885Sdumbbell DRM_MODE_CONNECTOR_VGA, &ddc_i2c, 2036254885Sdumbbell CONNECTOR_OBJECT_ID_VGA, 2037254885Sdumbbell &hpd); 2038254885Sdumbbell /* TV - TV DAC */ 2039254885Sdumbbell ddc_i2c.valid = false; 2040254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2041254885Sdumbbell radeon_add_legacy_encoder(dev, 2042254885Sdumbbell radeon_get_encoder_enum(dev, 2043254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 2044254885Sdumbbell 2), 2045254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT); 2046254885Sdumbbell radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, 2047254885Sdumbbell DRM_MODE_CONNECTOR_SVIDEO, 2048254885Sdumbbell &ddc_i2c, 2049254885Sdumbbell CONNECTOR_OBJECT_ID_SVIDEO, 2050254885Sdumbbell &hpd); 2051254885Sdumbbell break; 2052254885Sdumbbell case CT_RN50_POWER: 2053254885Sdumbbell DRM_INFO("Connector Table: %d (rn50-power)\n", 2054254885Sdumbbell rdev->mode_info.connector_table); 2055254885Sdumbbell /* VGA - primary dac */ 2056254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); 2057254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2058254885Sdumbbell radeon_add_legacy_encoder(dev, 2059254885Sdumbbell radeon_get_encoder_enum(dev, 2060254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 2061254885Sdumbbell 1), 2062254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 2063254885Sdumbbell radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT, 2064254885Sdumbbell DRM_MODE_CONNECTOR_VGA, &ddc_i2c, 2065254885Sdumbbell CONNECTOR_OBJECT_ID_VGA, 2066254885Sdumbbell &hpd); 2067254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); 2068254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2069254885Sdumbbell radeon_add_legacy_encoder(dev, 2070254885Sdumbbell radeon_get_encoder_enum(dev, 2071254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 2072254885Sdumbbell 2), 2073254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT); 2074254885Sdumbbell radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, 2075254885Sdumbbell DRM_MODE_CONNECTOR_VGA, &ddc_i2c, 2076254885Sdumbbell CONNECTOR_OBJECT_ID_VGA, 2077254885Sdumbbell &hpd); 2078254885Sdumbbell break; 2079254885Sdumbbell case CT_MAC_X800: 2080254885Sdumbbell DRM_INFO("Connector Table: %d (mac x800)\n", 2081254885Sdumbbell rdev->mode_info.connector_table); 2082254885Sdumbbell /* DVI - primary dac, internal tmds */ 2083254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); 2084254885Sdumbbell hpd.hpd = RADEON_HPD_1; /* ??? */ 2085254885Sdumbbell radeon_add_legacy_encoder(dev, 2086254885Sdumbbell radeon_get_encoder_enum(dev, 2087254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT, 2088254885Sdumbbell 0), 2089254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT); 2090254885Sdumbbell radeon_add_legacy_encoder(dev, 2091254885Sdumbbell radeon_get_encoder_enum(dev, 2092254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 2093254885Sdumbbell 1), 2094254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 2095254885Sdumbbell radeon_add_legacy_connector(dev, 0, 2096254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT | 2097254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 2098254885Sdumbbell DRM_MODE_CONNECTOR_DVII, &ddc_i2c, 2099254885Sdumbbell CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, 2100254885Sdumbbell &hpd); 2101254885Sdumbbell /* DVI - tv dac, dvo */ 2102254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); 2103254885Sdumbbell hpd.hpd = RADEON_HPD_2; /* ??? */ 2104254885Sdumbbell radeon_add_legacy_encoder(dev, 2105254885Sdumbbell radeon_get_encoder_enum(dev, 2106254885Sdumbbell ATOM_DEVICE_DFP2_SUPPORT, 2107254885Sdumbbell 0), 2108254885Sdumbbell ATOM_DEVICE_DFP2_SUPPORT); 2109254885Sdumbbell radeon_add_legacy_encoder(dev, 2110254885Sdumbbell radeon_get_encoder_enum(dev, 2111254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 2112254885Sdumbbell 2), 2113254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT); 2114254885Sdumbbell radeon_add_legacy_connector(dev, 1, 2115254885Sdumbbell ATOM_DEVICE_DFP2_SUPPORT | 2116254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 2117254885Sdumbbell DRM_MODE_CONNECTOR_DVII, &ddc_i2c, 2118254885Sdumbbell CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, 2119254885Sdumbbell &hpd); 2120254885Sdumbbell break; 2121254885Sdumbbell case CT_MAC_G5_9600: 2122254885Sdumbbell DRM_INFO("Connector Table: %d (mac g5 9600)\n", 2123254885Sdumbbell rdev->mode_info.connector_table); 2124254885Sdumbbell /* DVI - tv dac, dvo */ 2125254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); 2126254885Sdumbbell hpd.hpd = RADEON_HPD_1; /* ??? */ 2127254885Sdumbbell radeon_add_legacy_encoder(dev, 2128254885Sdumbbell radeon_get_encoder_enum(dev, 2129254885Sdumbbell ATOM_DEVICE_DFP2_SUPPORT, 2130254885Sdumbbell 0), 2131254885Sdumbbell ATOM_DEVICE_DFP2_SUPPORT); 2132254885Sdumbbell radeon_add_legacy_encoder(dev, 2133254885Sdumbbell radeon_get_encoder_enum(dev, 2134254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 2135254885Sdumbbell 2), 2136254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT); 2137254885Sdumbbell radeon_add_legacy_connector(dev, 0, 2138254885Sdumbbell ATOM_DEVICE_DFP2_SUPPORT | 2139254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 2140254885Sdumbbell DRM_MODE_CONNECTOR_DVII, &ddc_i2c, 2141254885Sdumbbell CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, 2142254885Sdumbbell &hpd); 2143254885Sdumbbell /* ADC - primary dac, internal tmds */ 2144254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); 2145254885Sdumbbell hpd.hpd = RADEON_HPD_2; /* ??? */ 2146254885Sdumbbell radeon_add_legacy_encoder(dev, 2147254885Sdumbbell radeon_get_encoder_enum(dev, 2148254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT, 2149254885Sdumbbell 0), 2150254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT); 2151254885Sdumbbell radeon_add_legacy_encoder(dev, 2152254885Sdumbbell radeon_get_encoder_enum(dev, 2153254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 2154254885Sdumbbell 1), 2155254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 2156254885Sdumbbell radeon_add_legacy_connector(dev, 1, 2157254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT | 2158254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 2159254885Sdumbbell DRM_MODE_CONNECTOR_DVII, &ddc_i2c, 2160254885Sdumbbell CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, 2161254885Sdumbbell &hpd); 2162254885Sdumbbell /* TV - TV DAC */ 2163254885Sdumbbell ddc_i2c.valid = false; 2164254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2165254885Sdumbbell radeon_add_legacy_encoder(dev, 2166254885Sdumbbell radeon_get_encoder_enum(dev, 2167254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 2168254885Sdumbbell 2), 2169254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT); 2170254885Sdumbbell radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, 2171254885Sdumbbell DRM_MODE_CONNECTOR_SVIDEO, 2172254885Sdumbbell &ddc_i2c, 2173254885Sdumbbell CONNECTOR_OBJECT_ID_SVIDEO, 2174254885Sdumbbell &hpd); 2175254885Sdumbbell break; 2176254885Sdumbbell case CT_SAM440EP: 2177254885Sdumbbell DRM_INFO("Connector Table: %d (SAM440ep embedded board)\n", 2178254885Sdumbbell rdev->mode_info.connector_table); 2179254885Sdumbbell /* LVDS */ 2180254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0); 2181254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2182254885Sdumbbell radeon_add_legacy_encoder(dev, 2183254885Sdumbbell radeon_get_encoder_enum(dev, 2184254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT, 2185254885Sdumbbell 0), 2186254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT); 2187254885Sdumbbell radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, 2188254885Sdumbbell DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, 2189254885Sdumbbell CONNECTOR_OBJECT_ID_LVDS, 2190254885Sdumbbell &hpd); 2191254885Sdumbbell /* DVI-I - secondary dac, int tmds */ 2192254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); 2193254885Sdumbbell hpd.hpd = RADEON_HPD_1; /* ??? */ 2194254885Sdumbbell radeon_add_legacy_encoder(dev, 2195254885Sdumbbell radeon_get_encoder_enum(dev, 2196254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT, 2197254885Sdumbbell 0), 2198254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT); 2199254885Sdumbbell radeon_add_legacy_encoder(dev, 2200254885Sdumbbell radeon_get_encoder_enum(dev, 2201254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 2202254885Sdumbbell 2), 2203254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT); 2204254885Sdumbbell radeon_add_legacy_connector(dev, 1, 2205254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT | 2206254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 2207254885Sdumbbell DRM_MODE_CONNECTOR_DVII, &ddc_i2c, 2208254885Sdumbbell CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, 2209254885Sdumbbell &hpd); 2210254885Sdumbbell /* VGA - primary dac */ 2211254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); 2212254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2213254885Sdumbbell radeon_add_legacy_encoder(dev, 2214254885Sdumbbell radeon_get_encoder_enum(dev, 2215254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 2216254885Sdumbbell 1), 2217254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 2218254885Sdumbbell radeon_add_legacy_connector(dev, 2, 2219254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 2220254885Sdumbbell DRM_MODE_CONNECTOR_VGA, &ddc_i2c, 2221254885Sdumbbell CONNECTOR_OBJECT_ID_VGA, 2222254885Sdumbbell &hpd); 2223254885Sdumbbell /* TV - TV DAC */ 2224254885Sdumbbell ddc_i2c.valid = false; 2225254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2226254885Sdumbbell radeon_add_legacy_encoder(dev, 2227254885Sdumbbell radeon_get_encoder_enum(dev, 2228254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 2229254885Sdumbbell 2), 2230254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT); 2231254885Sdumbbell radeon_add_legacy_connector(dev, 3, ATOM_DEVICE_TV1_SUPPORT, 2232254885Sdumbbell DRM_MODE_CONNECTOR_SVIDEO, 2233254885Sdumbbell &ddc_i2c, 2234254885Sdumbbell CONNECTOR_OBJECT_ID_SVIDEO, 2235254885Sdumbbell &hpd); 2236254885Sdumbbell break; 2237254885Sdumbbell case CT_MAC_G4_SILVER: 2238254885Sdumbbell DRM_INFO("Connector Table: %d (mac g4 silver)\n", 2239254885Sdumbbell rdev->mode_info.connector_table); 2240254885Sdumbbell /* DVI-I - tv dac, int tmds */ 2241254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); 2242254885Sdumbbell hpd.hpd = RADEON_HPD_1; /* ??? */ 2243254885Sdumbbell radeon_add_legacy_encoder(dev, 2244254885Sdumbbell radeon_get_encoder_enum(dev, 2245254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT, 2246254885Sdumbbell 0), 2247254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT); 2248254885Sdumbbell radeon_add_legacy_encoder(dev, 2249254885Sdumbbell radeon_get_encoder_enum(dev, 2250254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 2251254885Sdumbbell 2), 2252254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT); 2253254885Sdumbbell radeon_add_legacy_connector(dev, 0, 2254254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT | 2255254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 2256254885Sdumbbell DRM_MODE_CONNECTOR_DVII, &ddc_i2c, 2257254885Sdumbbell CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, 2258254885Sdumbbell &hpd); 2259254885Sdumbbell /* VGA - primary dac */ 2260254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); 2261254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2262254885Sdumbbell radeon_add_legacy_encoder(dev, 2263254885Sdumbbell radeon_get_encoder_enum(dev, 2264254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 2265254885Sdumbbell 1), 2266254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 2267254885Sdumbbell radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT, 2268254885Sdumbbell DRM_MODE_CONNECTOR_VGA, &ddc_i2c, 2269254885Sdumbbell CONNECTOR_OBJECT_ID_VGA, 2270254885Sdumbbell &hpd); 2271254885Sdumbbell /* TV - TV DAC */ 2272254885Sdumbbell ddc_i2c.valid = false; 2273254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2274254885Sdumbbell radeon_add_legacy_encoder(dev, 2275254885Sdumbbell radeon_get_encoder_enum(dev, 2276254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 2277254885Sdumbbell 2), 2278254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT); 2279254885Sdumbbell radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, 2280254885Sdumbbell DRM_MODE_CONNECTOR_SVIDEO, 2281254885Sdumbbell &ddc_i2c, 2282254885Sdumbbell CONNECTOR_OBJECT_ID_SVIDEO, 2283254885Sdumbbell &hpd); 2284254885Sdumbbell break; 2285254885Sdumbbell default: 2286254885Sdumbbell DRM_INFO("Connector table: %d (invalid)\n", 2287254885Sdumbbell rdev->mode_info.connector_table); 2288254885Sdumbbell return false; 2289254885Sdumbbell } 2290254885Sdumbbell 2291254885Sdumbbell radeon_link_encoder_connector(dev); 2292254885Sdumbbell 2293254885Sdumbbell return true; 2294254885Sdumbbell} 2295254885Sdumbbell 2296254885Sdumbbellstatic bool radeon_apply_legacy_quirks(struct drm_device *dev, 2297254885Sdumbbell int bios_index, 2298254885Sdumbbell enum radeon_combios_connector 2299254885Sdumbbell *legacy_connector, 2300254885Sdumbbell struct radeon_i2c_bus_rec *ddc_i2c, 2301254885Sdumbbell struct radeon_hpd *hpd) 2302254885Sdumbbell{ 2303254885Sdumbbell 2304254885Sdumbbell /* Certain IBM chipset RN50s have a BIOS reporting two VGAs, 2305254885Sdumbbell one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */ 2306254885Sdumbbell if (dev->pci_device == 0x515e && 2307254885Sdumbbell dev->pci_subvendor == 0x1014) { 2308254885Sdumbbell if (*legacy_connector == CONNECTOR_CRT_LEGACY && 2309254885Sdumbbell ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) 2310254885Sdumbbell return false; 2311254885Sdumbbell } 2312254885Sdumbbell 2313254885Sdumbbell /* X300 card with extra non-existent DVI port */ 2314254885Sdumbbell if (dev->pci_device == 0x5B60 && 2315254885Sdumbbell dev->pci_subvendor == 0x17af && 2316254885Sdumbbell dev->pci_subdevice == 0x201e && bios_index == 2) { 2317254885Sdumbbell if (*legacy_connector == CONNECTOR_DVI_I_LEGACY) 2318254885Sdumbbell return false; 2319254885Sdumbbell } 2320254885Sdumbbell 2321254885Sdumbbell return true; 2322254885Sdumbbell} 2323254885Sdumbbell 2324254885Sdumbbellstatic bool radeon_apply_legacy_tv_quirks(struct drm_device *dev) 2325254885Sdumbbell{ 2326254885Sdumbbell /* Acer 5102 has non-existent TV port */ 2327254885Sdumbbell if (dev->pci_device == 0x5975 && 2328254885Sdumbbell dev->pci_subvendor == 0x1025 && 2329254885Sdumbbell dev->pci_subdevice == 0x009f) 2330254885Sdumbbell return false; 2331254885Sdumbbell 2332254885Sdumbbell /* HP dc5750 has non-existent TV port */ 2333254885Sdumbbell if (dev->pci_device == 0x5974 && 2334254885Sdumbbell dev->pci_subvendor == 0x103c && 2335254885Sdumbbell dev->pci_subdevice == 0x280a) 2336254885Sdumbbell return false; 2337254885Sdumbbell 2338254885Sdumbbell /* MSI S270 has non-existent TV port */ 2339254885Sdumbbell if (dev->pci_device == 0x5955 && 2340254885Sdumbbell dev->pci_subvendor == 0x1462 && 2341254885Sdumbbell dev->pci_subdevice == 0x0131) 2342254885Sdumbbell return false; 2343254885Sdumbbell 2344254885Sdumbbell return true; 2345254885Sdumbbell} 2346254885Sdumbbell 2347254885Sdumbbellstatic uint16_t combios_check_dl_dvi(struct drm_device *dev, int is_dvi_d) 2348254885Sdumbbell{ 2349254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 2350254885Sdumbbell uint32_t ext_tmds_info; 2351254885Sdumbbell 2352254885Sdumbbell if (rdev->flags & RADEON_IS_IGP) { 2353254885Sdumbbell if (is_dvi_d) 2354254885Sdumbbell return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; 2355254885Sdumbbell else 2356254885Sdumbbell return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; 2357254885Sdumbbell } 2358254885Sdumbbell ext_tmds_info = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); 2359254885Sdumbbell if (ext_tmds_info) { 2360254885Sdumbbell uint8_t rev = RBIOS8(ext_tmds_info); 2361254885Sdumbbell uint8_t flags = RBIOS8(ext_tmds_info + 4 + 5); 2362254885Sdumbbell if (rev >= 3) { 2363254885Sdumbbell if (is_dvi_d) 2364254885Sdumbbell return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; 2365254885Sdumbbell else 2366254885Sdumbbell return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; 2367254885Sdumbbell } else { 2368254885Sdumbbell if (flags & 1) { 2369254885Sdumbbell if (is_dvi_d) 2370254885Sdumbbell return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; 2371254885Sdumbbell else 2372254885Sdumbbell return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; 2373254885Sdumbbell } 2374254885Sdumbbell } 2375254885Sdumbbell } 2376254885Sdumbbell if (is_dvi_d) 2377254885Sdumbbell return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; 2378254885Sdumbbell else 2379254885Sdumbbell return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; 2380254885Sdumbbell} 2381254885Sdumbbell 2382254885Sdumbbellbool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) 2383254885Sdumbbell{ 2384254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 2385254885Sdumbbell uint32_t conn_info, entry, devices; 2386254885Sdumbbell uint16_t tmp, connector_object_id; 2387254885Sdumbbell enum radeon_combios_ddc ddc_type; 2388254885Sdumbbell enum radeon_combios_connector connector; 2389254885Sdumbbell int i = 0; 2390254885Sdumbbell struct radeon_i2c_bus_rec ddc_i2c; 2391254885Sdumbbell struct radeon_hpd hpd; 2392254885Sdumbbell 2393254885Sdumbbell conn_info = combios_get_table_offset(dev, COMBIOS_CONNECTOR_INFO_TABLE); 2394254885Sdumbbell if (conn_info) { 2395254885Sdumbbell for (i = 0; i < 4; i++) { 2396254885Sdumbbell entry = conn_info + 2 + i * 2; 2397254885Sdumbbell 2398254885Sdumbbell if (!RBIOS16(entry)) 2399254885Sdumbbell break; 2400254885Sdumbbell 2401254885Sdumbbell tmp = RBIOS16(entry); 2402254885Sdumbbell 2403254885Sdumbbell connector = (tmp >> 12) & 0xf; 2404254885Sdumbbell 2405254885Sdumbbell ddc_type = (tmp >> 8) & 0xf; 2406254885Sdumbbell if (ddc_type == 5) 2407254885Sdumbbell ddc_i2c = radeon_combios_get_i2c_info_from_table(rdev); 2408254885Sdumbbell else 2409254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0); 2410254885Sdumbbell 2411254885Sdumbbell switch (connector) { 2412254885Sdumbbell case CONNECTOR_PROPRIETARY_LEGACY: 2413254885Sdumbbell case CONNECTOR_DVI_I_LEGACY: 2414254885Sdumbbell case CONNECTOR_DVI_D_LEGACY: 2415254885Sdumbbell if ((tmp >> 4) & 0x1) 2416254885Sdumbbell hpd.hpd = RADEON_HPD_2; 2417254885Sdumbbell else 2418254885Sdumbbell hpd.hpd = RADEON_HPD_1; 2419254885Sdumbbell break; 2420254885Sdumbbell default: 2421254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2422254885Sdumbbell break; 2423254885Sdumbbell } 2424254885Sdumbbell 2425254885Sdumbbell if (!radeon_apply_legacy_quirks(dev, i, &connector, 2426254885Sdumbbell &ddc_i2c, &hpd)) 2427254885Sdumbbell continue; 2428254885Sdumbbell 2429254885Sdumbbell switch (connector) { 2430254885Sdumbbell case CONNECTOR_PROPRIETARY_LEGACY: 2431254885Sdumbbell if ((tmp >> 4) & 0x1) 2432254885Sdumbbell devices = ATOM_DEVICE_DFP2_SUPPORT; 2433254885Sdumbbell else 2434254885Sdumbbell devices = ATOM_DEVICE_DFP1_SUPPORT; 2435254885Sdumbbell radeon_add_legacy_encoder(dev, 2436254885Sdumbbell radeon_get_encoder_enum 2437254885Sdumbbell (dev, devices, 0), 2438254885Sdumbbell devices); 2439254885Sdumbbell radeon_add_legacy_connector(dev, i, devices, 2440254885Sdumbbell legacy_connector_convert 2441254885Sdumbbell [connector], 2442254885Sdumbbell &ddc_i2c, 2443254885Sdumbbell CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D, 2444254885Sdumbbell &hpd); 2445254885Sdumbbell break; 2446254885Sdumbbell case CONNECTOR_CRT_LEGACY: 2447254885Sdumbbell if (tmp & 0x1) { 2448254885Sdumbbell devices = ATOM_DEVICE_CRT2_SUPPORT; 2449254885Sdumbbell radeon_add_legacy_encoder(dev, 2450254885Sdumbbell radeon_get_encoder_enum 2451254885Sdumbbell (dev, 2452254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 2453254885Sdumbbell 2), 2454254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT); 2455254885Sdumbbell } else { 2456254885Sdumbbell devices = ATOM_DEVICE_CRT1_SUPPORT; 2457254885Sdumbbell radeon_add_legacy_encoder(dev, 2458254885Sdumbbell radeon_get_encoder_enum 2459254885Sdumbbell (dev, 2460254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 2461254885Sdumbbell 1), 2462254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 2463254885Sdumbbell } 2464254885Sdumbbell radeon_add_legacy_connector(dev, 2465254885Sdumbbell i, 2466254885Sdumbbell devices, 2467254885Sdumbbell legacy_connector_convert 2468254885Sdumbbell [connector], 2469254885Sdumbbell &ddc_i2c, 2470254885Sdumbbell CONNECTOR_OBJECT_ID_VGA, 2471254885Sdumbbell &hpd); 2472254885Sdumbbell break; 2473254885Sdumbbell case CONNECTOR_DVI_I_LEGACY: 2474254885Sdumbbell devices = 0; 2475254885Sdumbbell if (tmp & 0x1) { 2476254885Sdumbbell devices |= ATOM_DEVICE_CRT2_SUPPORT; 2477254885Sdumbbell radeon_add_legacy_encoder(dev, 2478254885Sdumbbell radeon_get_encoder_enum 2479254885Sdumbbell (dev, 2480254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT, 2481254885Sdumbbell 2), 2482254885Sdumbbell ATOM_DEVICE_CRT2_SUPPORT); 2483254885Sdumbbell } else { 2484254885Sdumbbell devices |= ATOM_DEVICE_CRT1_SUPPORT; 2485254885Sdumbbell radeon_add_legacy_encoder(dev, 2486254885Sdumbbell radeon_get_encoder_enum 2487254885Sdumbbell (dev, 2488254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 2489254885Sdumbbell 1), 2490254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 2491254885Sdumbbell } 2492254885Sdumbbell /* RV100 board with external TDMS bit mis-set. 2493254885Sdumbbell * Actually uses internal TMDS, clear the bit. 2494254885Sdumbbell */ 2495254885Sdumbbell if (dev->pci_device == 0x5159 && 2496254885Sdumbbell dev->pci_subvendor == 0x1014 && 2497254885Sdumbbell dev->pci_subdevice == 0x029A) { 2498254885Sdumbbell tmp &= ~(1 << 4); 2499254885Sdumbbell } 2500254885Sdumbbell if ((tmp >> 4) & 0x1) { 2501254885Sdumbbell devices |= ATOM_DEVICE_DFP2_SUPPORT; 2502254885Sdumbbell radeon_add_legacy_encoder(dev, 2503254885Sdumbbell radeon_get_encoder_enum 2504254885Sdumbbell (dev, 2505254885Sdumbbell ATOM_DEVICE_DFP2_SUPPORT, 2506254885Sdumbbell 0), 2507254885Sdumbbell ATOM_DEVICE_DFP2_SUPPORT); 2508254885Sdumbbell connector_object_id = combios_check_dl_dvi(dev, 0); 2509254885Sdumbbell } else { 2510254885Sdumbbell devices |= ATOM_DEVICE_DFP1_SUPPORT; 2511254885Sdumbbell radeon_add_legacy_encoder(dev, 2512254885Sdumbbell radeon_get_encoder_enum 2513254885Sdumbbell (dev, 2514254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT, 2515254885Sdumbbell 0), 2516254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT); 2517254885Sdumbbell connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; 2518254885Sdumbbell } 2519254885Sdumbbell radeon_add_legacy_connector(dev, 2520254885Sdumbbell i, 2521254885Sdumbbell devices, 2522254885Sdumbbell legacy_connector_convert 2523254885Sdumbbell [connector], 2524254885Sdumbbell &ddc_i2c, 2525254885Sdumbbell connector_object_id, 2526254885Sdumbbell &hpd); 2527254885Sdumbbell break; 2528254885Sdumbbell case CONNECTOR_DVI_D_LEGACY: 2529254885Sdumbbell if ((tmp >> 4) & 0x1) { 2530254885Sdumbbell devices = ATOM_DEVICE_DFP2_SUPPORT; 2531254885Sdumbbell connector_object_id = combios_check_dl_dvi(dev, 1); 2532254885Sdumbbell } else { 2533254885Sdumbbell devices = ATOM_DEVICE_DFP1_SUPPORT; 2534254885Sdumbbell connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; 2535254885Sdumbbell } 2536254885Sdumbbell radeon_add_legacy_encoder(dev, 2537254885Sdumbbell radeon_get_encoder_enum 2538254885Sdumbbell (dev, devices, 0), 2539254885Sdumbbell devices); 2540254885Sdumbbell radeon_add_legacy_connector(dev, i, devices, 2541254885Sdumbbell legacy_connector_convert 2542254885Sdumbbell [connector], 2543254885Sdumbbell &ddc_i2c, 2544254885Sdumbbell connector_object_id, 2545254885Sdumbbell &hpd); 2546254885Sdumbbell break; 2547254885Sdumbbell case CONNECTOR_CTV_LEGACY: 2548254885Sdumbbell case CONNECTOR_STV_LEGACY: 2549254885Sdumbbell radeon_add_legacy_encoder(dev, 2550254885Sdumbbell radeon_get_encoder_enum 2551254885Sdumbbell (dev, 2552254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 2553254885Sdumbbell 2), 2554254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT); 2555254885Sdumbbell radeon_add_legacy_connector(dev, i, 2556254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 2557254885Sdumbbell legacy_connector_convert 2558254885Sdumbbell [connector], 2559254885Sdumbbell &ddc_i2c, 2560254885Sdumbbell CONNECTOR_OBJECT_ID_SVIDEO, 2561254885Sdumbbell &hpd); 2562254885Sdumbbell break; 2563254885Sdumbbell default: 2564254885Sdumbbell DRM_ERROR("Unknown connector type: %d\n", 2565254885Sdumbbell connector); 2566254885Sdumbbell continue; 2567254885Sdumbbell } 2568254885Sdumbbell 2569254885Sdumbbell } 2570254885Sdumbbell } else { 2571254885Sdumbbell uint16_t tmds_info = 2572254885Sdumbbell combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); 2573254885Sdumbbell if (tmds_info) { 2574254885Sdumbbell DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n"); 2575254885Sdumbbell 2576254885Sdumbbell radeon_add_legacy_encoder(dev, 2577254885Sdumbbell radeon_get_encoder_enum(dev, 2578254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 2579254885Sdumbbell 1), 2580254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 2581254885Sdumbbell radeon_add_legacy_encoder(dev, 2582254885Sdumbbell radeon_get_encoder_enum(dev, 2583254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT, 2584254885Sdumbbell 0), 2585254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT); 2586254885Sdumbbell 2587254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); 2588254885Sdumbbell hpd.hpd = RADEON_HPD_1; 2589254885Sdumbbell radeon_add_legacy_connector(dev, 2590254885Sdumbbell 0, 2591254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT | 2592254885Sdumbbell ATOM_DEVICE_DFP1_SUPPORT, 2593254885Sdumbbell DRM_MODE_CONNECTOR_DVII, 2594254885Sdumbbell &ddc_i2c, 2595254885Sdumbbell CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, 2596254885Sdumbbell &hpd); 2597254885Sdumbbell } else { 2598254885Sdumbbell uint16_t crt_info = 2599254885Sdumbbell combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); 2600254885Sdumbbell DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n"); 2601254885Sdumbbell if (crt_info) { 2602254885Sdumbbell radeon_add_legacy_encoder(dev, 2603254885Sdumbbell radeon_get_encoder_enum(dev, 2604254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 2605254885Sdumbbell 1), 2606254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT); 2607254885Sdumbbell ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); 2608254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2609254885Sdumbbell radeon_add_legacy_connector(dev, 2610254885Sdumbbell 0, 2611254885Sdumbbell ATOM_DEVICE_CRT1_SUPPORT, 2612254885Sdumbbell DRM_MODE_CONNECTOR_VGA, 2613254885Sdumbbell &ddc_i2c, 2614254885Sdumbbell CONNECTOR_OBJECT_ID_VGA, 2615254885Sdumbbell &hpd); 2616254885Sdumbbell } else { 2617254885Sdumbbell DRM_DEBUG_KMS("No connector info found\n"); 2618254885Sdumbbell return false; 2619254885Sdumbbell } 2620254885Sdumbbell } 2621254885Sdumbbell } 2622254885Sdumbbell 2623254885Sdumbbell if (rdev->flags & RADEON_IS_MOBILITY || rdev->flags & RADEON_IS_IGP) { 2624254885Sdumbbell uint16_t lcd_info = 2625254885Sdumbbell combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE); 2626254885Sdumbbell if (lcd_info) { 2627254885Sdumbbell uint16_t lcd_ddc_info = 2628254885Sdumbbell combios_get_table_offset(dev, 2629254885Sdumbbell COMBIOS_LCD_DDC_INFO_TABLE); 2630254885Sdumbbell 2631254885Sdumbbell radeon_add_legacy_encoder(dev, 2632254885Sdumbbell radeon_get_encoder_enum(dev, 2633254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT, 2634254885Sdumbbell 0), 2635254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT); 2636254885Sdumbbell 2637254885Sdumbbell if (lcd_ddc_info) { 2638254885Sdumbbell ddc_type = RBIOS8(lcd_ddc_info + 2); 2639254885Sdumbbell switch (ddc_type) { 2640254885Sdumbbell case DDC_LCD: 2641254885Sdumbbell ddc_i2c = 2642254885Sdumbbell combios_setup_i2c_bus(rdev, 2643254885Sdumbbell DDC_LCD, 2644254885Sdumbbell RBIOS32(lcd_ddc_info + 3), 2645254885Sdumbbell RBIOS32(lcd_ddc_info + 7)); 2646254885Sdumbbell radeon_i2c_add(rdev, &ddc_i2c, "LCD"); 2647254885Sdumbbell break; 2648254885Sdumbbell case DDC_GPIO: 2649254885Sdumbbell ddc_i2c = 2650254885Sdumbbell combios_setup_i2c_bus(rdev, 2651254885Sdumbbell DDC_GPIO, 2652254885Sdumbbell RBIOS32(lcd_ddc_info + 3), 2653254885Sdumbbell RBIOS32(lcd_ddc_info + 7)); 2654254885Sdumbbell radeon_i2c_add(rdev, &ddc_i2c, "LCD"); 2655254885Sdumbbell break; 2656254885Sdumbbell default: 2657254885Sdumbbell ddc_i2c = 2658254885Sdumbbell combios_setup_i2c_bus(rdev, ddc_type, 0, 0); 2659254885Sdumbbell break; 2660254885Sdumbbell } 2661254885Sdumbbell DRM_DEBUG_KMS("LCD DDC Info Table found!\n"); 2662254885Sdumbbell } else 2663254885Sdumbbell ddc_i2c.valid = false; 2664254885Sdumbbell 2665254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2666254885Sdumbbell radeon_add_legacy_connector(dev, 2667254885Sdumbbell 5, 2668254885Sdumbbell ATOM_DEVICE_LCD1_SUPPORT, 2669254885Sdumbbell DRM_MODE_CONNECTOR_LVDS, 2670254885Sdumbbell &ddc_i2c, 2671254885Sdumbbell CONNECTOR_OBJECT_ID_LVDS, 2672254885Sdumbbell &hpd); 2673254885Sdumbbell } 2674254885Sdumbbell } 2675254885Sdumbbell 2676254885Sdumbbell /* check TV table */ 2677254885Sdumbbell if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) { 2678254885Sdumbbell uint32_t tv_info = 2679254885Sdumbbell combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); 2680254885Sdumbbell if (tv_info) { 2681254885Sdumbbell if (RBIOS8(tv_info + 6) == 'T') { 2682254885Sdumbbell if (radeon_apply_legacy_tv_quirks(dev)) { 2683254885Sdumbbell hpd.hpd = RADEON_HPD_NONE; 2684254885Sdumbbell ddc_i2c.valid = false; 2685254885Sdumbbell radeon_add_legacy_encoder(dev, 2686254885Sdumbbell radeon_get_encoder_enum 2687254885Sdumbbell (dev, 2688254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 2689254885Sdumbbell 2), 2690254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT); 2691254885Sdumbbell radeon_add_legacy_connector(dev, 6, 2692254885Sdumbbell ATOM_DEVICE_TV1_SUPPORT, 2693254885Sdumbbell DRM_MODE_CONNECTOR_SVIDEO, 2694254885Sdumbbell &ddc_i2c, 2695254885Sdumbbell CONNECTOR_OBJECT_ID_SVIDEO, 2696254885Sdumbbell &hpd); 2697254885Sdumbbell } 2698254885Sdumbbell } 2699254885Sdumbbell } 2700254885Sdumbbell } 2701254885Sdumbbell 2702254885Sdumbbell radeon_link_encoder_connector(dev); 2703254885Sdumbbell 2704254885Sdumbbell return true; 2705254885Sdumbbell} 2706254885Sdumbbell 2707254885Sdumbbellstatic const char *thermal_controller_names[] = { 2708254885Sdumbbell "NONE", 2709254885Sdumbbell "lm63", 2710254885Sdumbbell "adm1032", 2711254885Sdumbbell}; 2712254885Sdumbbell 2713254885Sdumbbellvoid radeon_combios_get_power_modes(struct radeon_device *rdev) 2714254885Sdumbbell{ 2715254885Sdumbbell struct drm_device *dev = rdev->ddev; 2716254885Sdumbbell u16 offset, misc, misc2 = 0; 2717254885Sdumbbell u8 rev, blocks, tmp; 2718254885Sdumbbell int state_index = 0; 2719254885Sdumbbell struct radeon_i2c_bus_rec i2c_bus; 2720254885Sdumbbell 2721254885Sdumbbell rdev->pm.default_power_state_index = -1; 2722254885Sdumbbell 2723254885Sdumbbell /* allocate 2 power states */ 2724254885Sdumbbell rdev->pm.power_state = malloc(sizeof(struct radeon_power_state) * 2, 2725280183Sdumbbell DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 2726254885Sdumbbell if (rdev->pm.power_state) { 2727254885Sdumbbell /* allocate 1 clock mode per state */ 2728254885Sdumbbell rdev->pm.power_state[0].clock_info = 2729254885Sdumbbell malloc(sizeof(struct radeon_pm_clock_info) * 1, 2730280183Sdumbbell DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 2731254885Sdumbbell rdev->pm.power_state[1].clock_info = 2732254885Sdumbbell malloc(sizeof(struct radeon_pm_clock_info) * 1, 2733280183Sdumbbell DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 2734254885Sdumbbell if (!rdev->pm.power_state[0].clock_info || 2735254885Sdumbbell !rdev->pm.power_state[1].clock_info) 2736254885Sdumbbell goto pm_failed; 2737254885Sdumbbell } else 2738254885Sdumbbell goto pm_failed; 2739254885Sdumbbell 2740254885Sdumbbell /* check for a thermal chip */ 2741254885Sdumbbell offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE); 2742254885Sdumbbell if (offset) { 2743254885Sdumbbell u8 thermal_controller = 0, gpio = 0, i2c_addr = 0, clk_bit = 0, data_bit = 0; 2744254885Sdumbbell 2745254885Sdumbbell rev = RBIOS8(offset); 2746254885Sdumbbell 2747254885Sdumbbell if (rev == 0) { 2748254885Sdumbbell thermal_controller = RBIOS8(offset + 3); 2749254885Sdumbbell gpio = RBIOS8(offset + 4) & 0x3f; 2750254885Sdumbbell i2c_addr = RBIOS8(offset + 5); 2751254885Sdumbbell } else if (rev == 1) { 2752254885Sdumbbell thermal_controller = RBIOS8(offset + 4); 2753254885Sdumbbell gpio = RBIOS8(offset + 5) & 0x3f; 2754254885Sdumbbell i2c_addr = RBIOS8(offset + 6); 2755254885Sdumbbell } else if (rev == 2) { 2756254885Sdumbbell thermal_controller = RBIOS8(offset + 4); 2757254885Sdumbbell gpio = RBIOS8(offset + 5) & 0x3f; 2758254885Sdumbbell i2c_addr = RBIOS8(offset + 6); 2759254885Sdumbbell clk_bit = RBIOS8(offset + 0xa); 2760254885Sdumbbell data_bit = RBIOS8(offset + 0xb); 2761254885Sdumbbell } 2762254885Sdumbbell if ((thermal_controller > 0) && (thermal_controller < 3)) { 2763254885Sdumbbell DRM_INFO("Possible %s thermal controller at 0x%02x\n", 2764254885Sdumbbell thermal_controller_names[thermal_controller], 2765254885Sdumbbell i2c_addr >> 1); 2766254885Sdumbbell if (gpio == DDC_LCD) { 2767254885Sdumbbell /* MM i2c */ 2768254885Sdumbbell i2c_bus.valid = true; 2769254885Sdumbbell i2c_bus.hw_capable = true; 2770254885Sdumbbell i2c_bus.mm_i2c = true; 2771254885Sdumbbell i2c_bus.i2c_id = 0xa0; 2772254885Sdumbbell } else if (gpio == DDC_GPIO) 2773254885Sdumbbell i2c_bus = combios_setup_i2c_bus(rdev, gpio, 1 << clk_bit, 1 << data_bit); 2774254885Sdumbbell else 2775254885Sdumbbell i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0); 2776254885Sdumbbell rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); 2777254885Sdumbbell if (rdev->pm.i2c_bus) { 2778280183Sdumbbell#ifdef FREEBSD_WIP 2779254885Sdumbbell struct i2c_board_info info = { }; 2780254885Sdumbbell const char *name = thermal_controller_names[thermal_controller]; 2781254885Sdumbbell info.addr = i2c_addr >> 1; 2782254885Sdumbbell strlcpy(info.type, name, sizeof(info.type)); 2783254885Sdumbbell i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); 2784280183Sdumbbell#endif /* FREEBSD_WIP */ 2785254885Sdumbbell } 2786254885Sdumbbell } 2787254885Sdumbbell } else { 2788254885Sdumbbell /* boards with a thermal chip, but no overdrive table */ 2789254885Sdumbbell 2790254885Sdumbbell /* Asus 9600xt has an f75375 on the monid bus */ 2791254885Sdumbbell if ((dev->pci_device == 0x4152) && 2792254885Sdumbbell (dev->pci_subvendor == 0x1043) && 2793254885Sdumbbell (dev->pci_subdevice == 0xc002)) { 2794254885Sdumbbell i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); 2795254885Sdumbbell rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); 2796254885Sdumbbell if (rdev->pm.i2c_bus) { 2797280183Sdumbbell#ifdef FREEBSD_WIP 2798254885Sdumbbell struct i2c_board_info info = { }; 2799254885Sdumbbell const char *name = "f75375"; 2800254885Sdumbbell info.addr = 0x28; 2801254885Sdumbbell strlcpy(info.type, name, sizeof(info.type)); 2802254885Sdumbbell i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); 2803254885Sdumbbell DRM_INFO("Possible %s thermal controller at 0x%02x\n", 2804254885Sdumbbell name, info.addr); 2805280183Sdumbbell#endif /* FREEBSD_WIP */ 2806254885Sdumbbell } 2807254885Sdumbbell } 2808254885Sdumbbell } 2809254885Sdumbbell 2810254885Sdumbbell if (rdev->flags & RADEON_IS_MOBILITY) { 2811254885Sdumbbell offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE); 2812254885Sdumbbell if (offset) { 2813254885Sdumbbell rev = RBIOS8(offset); 2814254885Sdumbbell blocks = RBIOS8(offset + 0x2); 2815254885Sdumbbell /* power mode 0 tends to be the only valid one */ 2816254885Sdumbbell rdev->pm.power_state[state_index].num_clock_modes = 1; 2817254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].mclk = RBIOS32(offset + 0x5 + 0x2); 2818254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].sclk = RBIOS32(offset + 0x5 + 0x6); 2819254885Sdumbbell if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || 2820254885Sdumbbell (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) 2821254885Sdumbbell goto default_mode; 2822254885Sdumbbell rdev->pm.power_state[state_index].type = 2823254885Sdumbbell POWER_STATE_TYPE_BATTERY; 2824254885Sdumbbell misc = RBIOS16(offset + 0x5 + 0x0); 2825254885Sdumbbell if (rev > 4) 2826254885Sdumbbell misc2 = RBIOS16(offset + 0x5 + 0xe); 2827254885Sdumbbell rdev->pm.power_state[state_index].misc = misc; 2828254885Sdumbbell rdev->pm.power_state[state_index].misc2 = misc2; 2829254885Sdumbbell if (misc & 0x4) { 2830254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO; 2831254885Sdumbbell if (misc & 0x8) 2832254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = 2833254885Sdumbbell true; 2834254885Sdumbbell else 2835254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = 2836254885Sdumbbell false; 2837254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = true; 2838254885Sdumbbell if (rev < 6) { 2839254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg = 2840254885Sdumbbell RBIOS16(offset + 0x5 + 0xb) * 4; 2841254885Sdumbbell tmp = RBIOS8(offset + 0x5 + 0xd); 2842254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp); 2843254885Sdumbbell } else { 2844254885Sdumbbell u8 entries = RBIOS8(offset + 0x5 + 0xb); 2845254885Sdumbbell u16 voltage_table_offset = RBIOS16(offset + 0x5 + 0xc); 2846254885Sdumbbell if (entries && voltage_table_offset) { 2847254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg = 2848254885Sdumbbell RBIOS16(voltage_table_offset) * 4; 2849254885Sdumbbell tmp = RBIOS8(voltage_table_offset + 0x2); 2850254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp); 2851254885Sdumbbell } else 2852254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = false; 2853254885Sdumbbell } 2854254885Sdumbbell switch ((misc2 & 0x700) >> 8) { 2855254885Sdumbbell case 0: 2856254885Sdumbbell default: 2857254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 0; 2858254885Sdumbbell break; 2859254885Sdumbbell case 1: 2860254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 33; 2861254885Sdumbbell break; 2862254885Sdumbbell case 2: 2863254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 66; 2864254885Sdumbbell break; 2865254885Sdumbbell case 3: 2866254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 99; 2867254885Sdumbbell break; 2868254885Sdumbbell case 4: 2869254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 132; 2870254885Sdumbbell break; 2871254885Sdumbbell } 2872254885Sdumbbell } else 2873254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; 2874254885Sdumbbell if (rev > 6) 2875254885Sdumbbell rdev->pm.power_state[state_index].pcie_lanes = 2876254885Sdumbbell RBIOS8(offset + 0x5 + 0x10); 2877254885Sdumbbell rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; 2878254885Sdumbbell state_index++; 2879254885Sdumbbell } else { 2880254885Sdumbbell /* XXX figure out some good default low power mode for mobility cards w/out power tables */ 2881254885Sdumbbell } 2882254885Sdumbbell } else { 2883254885Sdumbbell /* XXX figure out some good default low power mode for desktop cards */ 2884254885Sdumbbell } 2885254885Sdumbbell 2886254885Sdumbbelldefault_mode: 2887254885Sdumbbell /* add the default mode */ 2888254885Sdumbbell rdev->pm.power_state[state_index].type = 2889254885Sdumbbell POWER_STATE_TYPE_DEFAULT; 2890254885Sdumbbell rdev->pm.power_state[state_index].num_clock_modes = 1; 2891254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; 2892254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; 2893254885Sdumbbell rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0]; 2894254885Sdumbbell if ((state_index > 0) && 2895254885Sdumbbell (rdev->pm.power_state[0].clock_info[0].voltage.type == VOLTAGE_GPIO)) 2896254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage = 2897254885Sdumbbell rdev->pm.power_state[0].clock_info[0].voltage; 2898254885Sdumbbell else 2899254885Sdumbbell rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; 2900254885Sdumbbell rdev->pm.power_state[state_index].pcie_lanes = 16; 2901254885Sdumbbell rdev->pm.power_state[state_index].flags = 0; 2902254885Sdumbbell rdev->pm.default_power_state_index = state_index; 2903254885Sdumbbell rdev->pm.num_power_states = state_index + 1; 2904254885Sdumbbell 2905254885Sdumbbell rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; 2906254885Sdumbbell rdev->pm.current_clock_mode_index = 0; 2907254885Sdumbbell return; 2908254885Sdumbbell 2909254885Sdumbbellpm_failed: 2910254885Sdumbbell rdev->pm.default_power_state_index = state_index; 2911254885Sdumbbell rdev->pm.num_power_states = 0; 2912254885Sdumbbell 2913254885Sdumbbell rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; 2914254885Sdumbbell rdev->pm.current_clock_mode_index = 0; 2915254885Sdumbbell} 2916254885Sdumbbell 2917254885Sdumbbellvoid radeon_external_tmds_setup(struct drm_encoder *encoder) 2918254885Sdumbbell{ 2919254885Sdumbbell struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 2920254885Sdumbbell struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv; 2921254885Sdumbbell 2922254885Sdumbbell if (!tmds) 2923254885Sdumbbell return; 2924254885Sdumbbell 2925254885Sdumbbell switch (tmds->dvo_chip) { 2926254885Sdumbbell case DVO_SIL164: 2927254885Sdumbbell /* sil 164 */ 2928254885Sdumbbell radeon_i2c_put_byte(tmds->i2c_bus, 2929254885Sdumbbell tmds->slave_addr, 2930254885Sdumbbell 0x08, 0x30); 2931254885Sdumbbell radeon_i2c_put_byte(tmds->i2c_bus, 2932254885Sdumbbell tmds->slave_addr, 2933254885Sdumbbell 0x09, 0x00); 2934254885Sdumbbell radeon_i2c_put_byte(tmds->i2c_bus, 2935254885Sdumbbell tmds->slave_addr, 2936254885Sdumbbell 0x0a, 0x90); 2937254885Sdumbbell radeon_i2c_put_byte(tmds->i2c_bus, 2938254885Sdumbbell tmds->slave_addr, 2939254885Sdumbbell 0x0c, 0x89); 2940254885Sdumbbell radeon_i2c_put_byte(tmds->i2c_bus, 2941254885Sdumbbell tmds->slave_addr, 2942254885Sdumbbell 0x08, 0x3b); 2943254885Sdumbbell break; 2944254885Sdumbbell case DVO_SIL1178: 2945254885Sdumbbell /* sil 1178 - untested */ 2946254885Sdumbbell /* 2947254885Sdumbbell * 0x0f, 0x44 2948254885Sdumbbell * 0x0f, 0x4c 2949254885Sdumbbell * 0x0e, 0x01 2950254885Sdumbbell * 0x0a, 0x80 2951254885Sdumbbell * 0x09, 0x30 2952254885Sdumbbell * 0x0c, 0xc9 2953254885Sdumbbell * 0x0d, 0x70 2954254885Sdumbbell * 0x08, 0x32 2955254885Sdumbbell * 0x08, 0x33 2956254885Sdumbbell */ 2957254885Sdumbbell break; 2958254885Sdumbbell default: 2959254885Sdumbbell break; 2960254885Sdumbbell } 2961254885Sdumbbell 2962254885Sdumbbell} 2963254885Sdumbbell 2964254885Sdumbbellbool radeon_combios_external_tmds_setup(struct drm_encoder *encoder) 2965254885Sdumbbell{ 2966254885Sdumbbell struct drm_device *dev = encoder->dev; 2967254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 2968254885Sdumbbell struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 2969254885Sdumbbell uint16_t offset; 2970254885Sdumbbell uint8_t blocks, slave_addr, rev; 2971254885Sdumbbell uint32_t index, id; 2972254885Sdumbbell uint32_t reg, val, and_mask, or_mask; 2973254885Sdumbbell struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv; 2974254885Sdumbbell 2975254885Sdumbbell if (!tmds) 2976254885Sdumbbell return false; 2977254885Sdumbbell 2978254885Sdumbbell if (rdev->flags & RADEON_IS_IGP) { 2979254885Sdumbbell offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_ON_TABLE); 2980254885Sdumbbell rev = RBIOS8(offset); 2981254885Sdumbbell if (offset) { 2982254885Sdumbbell rev = RBIOS8(offset); 2983254885Sdumbbell if (rev > 1) { 2984254885Sdumbbell blocks = RBIOS8(offset + 3); 2985254885Sdumbbell index = offset + 4; 2986254885Sdumbbell while (blocks > 0) { 2987254885Sdumbbell id = RBIOS16(index); 2988254885Sdumbbell index += 2; 2989254885Sdumbbell switch (id >> 13) { 2990254885Sdumbbell case 0: 2991254885Sdumbbell reg = (id & 0x1fff) * 4; 2992254885Sdumbbell val = RBIOS32(index); 2993254885Sdumbbell index += 4; 2994254885Sdumbbell WREG32(reg, val); 2995254885Sdumbbell break; 2996254885Sdumbbell case 2: 2997254885Sdumbbell reg = (id & 0x1fff) * 4; 2998254885Sdumbbell and_mask = RBIOS32(index); 2999254885Sdumbbell index += 4; 3000254885Sdumbbell or_mask = RBIOS32(index); 3001254885Sdumbbell index += 4; 3002254885Sdumbbell val = RREG32(reg); 3003254885Sdumbbell val = (val & and_mask) | or_mask; 3004254885Sdumbbell WREG32(reg, val); 3005254885Sdumbbell break; 3006254885Sdumbbell case 3: 3007254885Sdumbbell val = RBIOS16(index); 3008254885Sdumbbell index += 2; 3009280183Sdumbbell udelay(val); 3010254885Sdumbbell break; 3011254885Sdumbbell case 4: 3012254885Sdumbbell val = RBIOS16(index); 3013254885Sdumbbell index += 2; 3014280183Sdumbbell mdelay(val); 3015254885Sdumbbell break; 3016254885Sdumbbell case 6: 3017254885Sdumbbell slave_addr = id & 0xff; 3018254885Sdumbbell slave_addr >>= 1; /* 7 bit addressing */ 3019254885Sdumbbell index++; 3020254885Sdumbbell reg = RBIOS8(index); 3021254885Sdumbbell index++; 3022254885Sdumbbell val = RBIOS8(index); 3023254885Sdumbbell index++; 3024254885Sdumbbell radeon_i2c_put_byte(tmds->i2c_bus, 3025254885Sdumbbell slave_addr, 3026254885Sdumbbell reg, val); 3027254885Sdumbbell break; 3028254885Sdumbbell default: 3029254885Sdumbbell DRM_ERROR("Unknown id %d\n", id >> 13); 3030254885Sdumbbell break; 3031254885Sdumbbell } 3032254885Sdumbbell blocks--; 3033254885Sdumbbell } 3034254885Sdumbbell return true; 3035254885Sdumbbell } 3036254885Sdumbbell } 3037254885Sdumbbell } else { 3038254885Sdumbbell offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); 3039254885Sdumbbell if (offset) { 3040254885Sdumbbell index = offset + 10; 3041254885Sdumbbell id = RBIOS16(index); 3042254885Sdumbbell while (id != 0xffff) { 3043254885Sdumbbell index += 2; 3044254885Sdumbbell switch (id >> 13) { 3045254885Sdumbbell case 0: 3046254885Sdumbbell reg = (id & 0x1fff) * 4; 3047254885Sdumbbell val = RBIOS32(index); 3048254885Sdumbbell WREG32(reg, val); 3049254885Sdumbbell break; 3050254885Sdumbbell case 2: 3051254885Sdumbbell reg = (id & 0x1fff) * 4; 3052254885Sdumbbell and_mask = RBIOS32(index); 3053254885Sdumbbell index += 4; 3054254885Sdumbbell or_mask = RBIOS32(index); 3055254885Sdumbbell index += 4; 3056254885Sdumbbell val = RREG32(reg); 3057254885Sdumbbell val = (val & and_mask) | or_mask; 3058254885Sdumbbell WREG32(reg, val); 3059254885Sdumbbell break; 3060254885Sdumbbell case 4: 3061254885Sdumbbell val = RBIOS16(index); 3062254885Sdumbbell index += 2; 3063280183Sdumbbell udelay(val); 3064254885Sdumbbell break; 3065254885Sdumbbell case 5: 3066254885Sdumbbell reg = id & 0x1fff; 3067254885Sdumbbell and_mask = RBIOS32(index); 3068254885Sdumbbell index += 4; 3069254885Sdumbbell or_mask = RBIOS32(index); 3070254885Sdumbbell index += 4; 3071254885Sdumbbell val = RREG32_PLL(reg); 3072254885Sdumbbell val = (val & and_mask) | or_mask; 3073254885Sdumbbell WREG32_PLL(reg, val); 3074254885Sdumbbell break; 3075254885Sdumbbell case 6: 3076254885Sdumbbell reg = id & 0x1fff; 3077254885Sdumbbell val = RBIOS8(index); 3078254885Sdumbbell index += 1; 3079254885Sdumbbell radeon_i2c_put_byte(tmds->i2c_bus, 3080254885Sdumbbell tmds->slave_addr, 3081254885Sdumbbell reg, val); 3082254885Sdumbbell break; 3083254885Sdumbbell default: 3084254885Sdumbbell DRM_ERROR("Unknown id %d\n", id >> 13); 3085254885Sdumbbell break; 3086254885Sdumbbell } 3087254885Sdumbbell id = RBIOS16(index); 3088254885Sdumbbell } 3089254885Sdumbbell return true; 3090254885Sdumbbell } 3091254885Sdumbbell } 3092254885Sdumbbell return false; 3093254885Sdumbbell} 3094254885Sdumbbell 3095254885Sdumbbellstatic void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset) 3096254885Sdumbbell{ 3097254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 3098254885Sdumbbell 3099254885Sdumbbell if (offset) { 3100254885Sdumbbell while (RBIOS16(offset)) { 3101254885Sdumbbell uint16_t cmd = ((RBIOS16(offset) & 0xe000) >> 13); 3102254885Sdumbbell uint32_t addr = (RBIOS16(offset) & 0x1fff); 3103254885Sdumbbell uint32_t val, and_mask, or_mask; 3104254885Sdumbbell uint32_t tmp; 3105254885Sdumbbell 3106254885Sdumbbell offset += 2; 3107254885Sdumbbell switch (cmd) { 3108254885Sdumbbell case 0: 3109254885Sdumbbell val = RBIOS32(offset); 3110254885Sdumbbell offset += 4; 3111254885Sdumbbell WREG32(addr, val); 3112254885Sdumbbell break; 3113254885Sdumbbell case 1: 3114254885Sdumbbell val = RBIOS32(offset); 3115254885Sdumbbell offset += 4; 3116254885Sdumbbell WREG32(addr, val); 3117254885Sdumbbell break; 3118254885Sdumbbell case 2: 3119254885Sdumbbell and_mask = RBIOS32(offset); 3120254885Sdumbbell offset += 4; 3121254885Sdumbbell or_mask = RBIOS32(offset); 3122254885Sdumbbell offset += 4; 3123254885Sdumbbell tmp = RREG32(addr); 3124254885Sdumbbell tmp &= and_mask; 3125254885Sdumbbell tmp |= or_mask; 3126254885Sdumbbell WREG32(addr, tmp); 3127254885Sdumbbell break; 3128254885Sdumbbell case 3: 3129254885Sdumbbell and_mask = RBIOS32(offset); 3130254885Sdumbbell offset += 4; 3131254885Sdumbbell or_mask = RBIOS32(offset); 3132254885Sdumbbell offset += 4; 3133254885Sdumbbell tmp = RREG32(addr); 3134254885Sdumbbell tmp &= and_mask; 3135254885Sdumbbell tmp |= or_mask; 3136254885Sdumbbell WREG32(addr, tmp); 3137254885Sdumbbell break; 3138254885Sdumbbell case 4: 3139254885Sdumbbell val = RBIOS16(offset); 3140254885Sdumbbell offset += 2; 3141280183Sdumbbell udelay(val); 3142254885Sdumbbell break; 3143254885Sdumbbell case 5: 3144254885Sdumbbell val = RBIOS16(offset); 3145254885Sdumbbell offset += 2; 3146254885Sdumbbell switch (addr) { 3147254885Sdumbbell case 8: 3148254885Sdumbbell while (val--) { 3149254885Sdumbbell if (! 3150254885Sdumbbell (RREG32_PLL 3151254885Sdumbbell (RADEON_CLK_PWRMGT_CNTL) & 3152254885Sdumbbell RADEON_MC_BUSY)) 3153254885Sdumbbell break; 3154254885Sdumbbell } 3155254885Sdumbbell break; 3156254885Sdumbbell case 9: 3157254885Sdumbbell while (val--) { 3158254885Sdumbbell if ((RREG32(RADEON_MC_STATUS) & 3159254885Sdumbbell RADEON_MC_IDLE)) 3160254885Sdumbbell break; 3161254885Sdumbbell } 3162254885Sdumbbell break; 3163254885Sdumbbell default: 3164254885Sdumbbell break; 3165254885Sdumbbell } 3166254885Sdumbbell break; 3167254885Sdumbbell default: 3168254885Sdumbbell break; 3169254885Sdumbbell } 3170254885Sdumbbell } 3171254885Sdumbbell } 3172254885Sdumbbell} 3173254885Sdumbbell 3174254885Sdumbbellstatic void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) 3175254885Sdumbbell{ 3176254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 3177254885Sdumbbell 3178254885Sdumbbell if (offset) { 3179254885Sdumbbell while (RBIOS8(offset)) { 3180254885Sdumbbell uint8_t cmd = ((RBIOS8(offset) & 0xc0) >> 6); 3181254885Sdumbbell uint8_t addr = (RBIOS8(offset) & 0x3f); 3182254885Sdumbbell uint32_t val, shift, tmp; 3183254885Sdumbbell uint32_t and_mask, or_mask; 3184254885Sdumbbell 3185254885Sdumbbell offset++; 3186254885Sdumbbell switch (cmd) { 3187254885Sdumbbell case 0: 3188254885Sdumbbell val = RBIOS32(offset); 3189254885Sdumbbell offset += 4; 3190254885Sdumbbell WREG32_PLL(addr, val); 3191254885Sdumbbell break; 3192254885Sdumbbell case 1: 3193254885Sdumbbell shift = RBIOS8(offset) * 8; 3194254885Sdumbbell offset++; 3195254885Sdumbbell and_mask = RBIOS8(offset) << shift; 3196254885Sdumbbell and_mask |= ~(0xff << shift); 3197254885Sdumbbell offset++; 3198254885Sdumbbell or_mask = RBIOS8(offset) << shift; 3199254885Sdumbbell offset++; 3200254885Sdumbbell tmp = RREG32_PLL(addr); 3201254885Sdumbbell tmp &= and_mask; 3202254885Sdumbbell tmp |= or_mask; 3203254885Sdumbbell WREG32_PLL(addr, tmp); 3204254885Sdumbbell break; 3205254885Sdumbbell case 2: 3206254885Sdumbbell case 3: 3207254885Sdumbbell tmp = 1000; 3208254885Sdumbbell switch (addr) { 3209254885Sdumbbell case 1: 3210280183Sdumbbell udelay(150); 3211254885Sdumbbell break; 3212254885Sdumbbell case 2: 3213280183Sdumbbell mdelay(1); 3214254885Sdumbbell break; 3215254885Sdumbbell case 3: 3216254885Sdumbbell while (tmp--) { 3217254885Sdumbbell if (! 3218254885Sdumbbell (RREG32_PLL 3219254885Sdumbbell (RADEON_CLK_PWRMGT_CNTL) & 3220254885Sdumbbell RADEON_MC_BUSY)) 3221254885Sdumbbell break; 3222254885Sdumbbell } 3223254885Sdumbbell break; 3224254885Sdumbbell case 4: 3225254885Sdumbbell while (tmp--) { 3226254885Sdumbbell if (RREG32_PLL 3227254885Sdumbbell (RADEON_CLK_PWRMGT_CNTL) & 3228254885Sdumbbell RADEON_DLL_READY) 3229254885Sdumbbell break; 3230254885Sdumbbell } 3231254885Sdumbbell break; 3232254885Sdumbbell case 5: 3233254885Sdumbbell tmp = 3234254885Sdumbbell RREG32_PLL(RADEON_CLK_PWRMGT_CNTL); 3235254885Sdumbbell if (tmp & RADEON_CG_NO1_DEBUG_0) { 3236254885Sdumbbell#if 0 3237254885Sdumbbell uint32_t mclk_cntl = 3238254885Sdumbbell RREG32_PLL 3239254885Sdumbbell (RADEON_MCLK_CNTL); 3240254885Sdumbbell mclk_cntl &= 0xffff0000; 3241254885Sdumbbell /*mclk_cntl |= 0x00001111;*//* ??? */ 3242254885Sdumbbell WREG32_PLL(RADEON_MCLK_CNTL, 3243254885Sdumbbell mclk_cntl); 3244280183Sdumbbell mdelay(10); 3245254885Sdumbbell#endif 3246254885Sdumbbell WREG32_PLL 3247254885Sdumbbell (RADEON_CLK_PWRMGT_CNTL, 3248254885Sdumbbell tmp & 3249254885Sdumbbell ~RADEON_CG_NO1_DEBUG_0); 3250280183Sdumbbell mdelay(10); 3251254885Sdumbbell } 3252254885Sdumbbell break; 3253254885Sdumbbell default: 3254254885Sdumbbell break; 3255254885Sdumbbell } 3256254885Sdumbbell break; 3257254885Sdumbbell default: 3258254885Sdumbbell break; 3259254885Sdumbbell } 3260254885Sdumbbell } 3261254885Sdumbbell } 3262254885Sdumbbell} 3263254885Sdumbbell 3264254885Sdumbbellstatic void combios_parse_ram_reset_table(struct drm_device *dev, 3265254885Sdumbbell uint16_t offset) 3266254885Sdumbbell{ 3267254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 3268254885Sdumbbell uint32_t tmp; 3269254885Sdumbbell 3270254885Sdumbbell if (offset) { 3271254885Sdumbbell uint8_t val = RBIOS8(offset); 3272254885Sdumbbell while (val != 0xff) { 3273254885Sdumbbell offset++; 3274254885Sdumbbell 3275254885Sdumbbell if (val == 0x0f) { 3276254885Sdumbbell uint32_t channel_complete_mask; 3277254885Sdumbbell 3278254885Sdumbbell if (ASIC_IS_R300(rdev)) 3279254885Sdumbbell channel_complete_mask = 3280254885Sdumbbell R300_MEM_PWRUP_COMPLETE; 3281254885Sdumbbell else 3282254885Sdumbbell channel_complete_mask = 3283254885Sdumbbell RADEON_MEM_PWRUP_COMPLETE; 3284254885Sdumbbell tmp = 20000; 3285254885Sdumbbell while (tmp--) { 3286254885Sdumbbell if ((RREG32(RADEON_MEM_STR_CNTL) & 3287254885Sdumbbell channel_complete_mask) == 3288254885Sdumbbell channel_complete_mask) 3289254885Sdumbbell break; 3290254885Sdumbbell } 3291254885Sdumbbell } else { 3292254885Sdumbbell uint32_t or_mask = RBIOS16(offset); 3293254885Sdumbbell offset += 2; 3294254885Sdumbbell 3295254885Sdumbbell tmp = RREG32(RADEON_MEM_SDRAM_MODE_REG); 3296254885Sdumbbell tmp &= RADEON_SDRAM_MODE_MASK; 3297254885Sdumbbell tmp |= or_mask; 3298254885Sdumbbell WREG32(RADEON_MEM_SDRAM_MODE_REG, tmp); 3299254885Sdumbbell 3300254885Sdumbbell or_mask = val << 24; 3301254885Sdumbbell tmp = RREG32(RADEON_MEM_SDRAM_MODE_REG); 3302254885Sdumbbell tmp &= RADEON_B3MEM_RESET_MASK; 3303254885Sdumbbell tmp |= or_mask; 3304254885Sdumbbell WREG32(RADEON_MEM_SDRAM_MODE_REG, tmp); 3305254885Sdumbbell } 3306254885Sdumbbell val = RBIOS8(offset); 3307254885Sdumbbell } 3308254885Sdumbbell } 3309254885Sdumbbell} 3310254885Sdumbbell 3311254885Sdumbbellstatic uint32_t combios_detect_ram(struct drm_device *dev, int ram, 3312254885Sdumbbell int mem_addr_mapping) 3313254885Sdumbbell{ 3314254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 3315254885Sdumbbell uint32_t mem_cntl; 3316254885Sdumbbell uint32_t mem_size; 3317254885Sdumbbell uint32_t addr = 0; 3318254885Sdumbbell 3319254885Sdumbbell mem_cntl = RREG32(RADEON_MEM_CNTL); 3320254885Sdumbbell if (mem_cntl & RV100_HALF_MODE) 3321254885Sdumbbell ram /= 2; 3322254885Sdumbbell mem_size = ram; 3323254885Sdumbbell mem_cntl &= ~(0xff << 8); 3324254885Sdumbbell mem_cntl |= (mem_addr_mapping & 0xff) << 8; 3325254885Sdumbbell WREG32(RADEON_MEM_CNTL, mem_cntl); 3326254885Sdumbbell RREG32(RADEON_MEM_CNTL); 3327254885Sdumbbell 3328254885Sdumbbell /* sdram reset ? */ 3329254885Sdumbbell 3330254885Sdumbbell /* something like this???? */ 3331254885Sdumbbell while (ram--) { 3332254885Sdumbbell addr = ram * 1024 * 1024; 3333254885Sdumbbell /* write to each page */ 3334254885Sdumbbell WREG32_IDX((addr) | RADEON_MM_APER, 0xdeadbeef); 3335254885Sdumbbell /* read back and verify */ 3336254885Sdumbbell if (RREG32_IDX((addr) | RADEON_MM_APER) != 0xdeadbeef) 3337254885Sdumbbell return 0; 3338254885Sdumbbell } 3339254885Sdumbbell 3340254885Sdumbbell return mem_size; 3341254885Sdumbbell} 3342254885Sdumbbell 3343254885Sdumbbellstatic void combios_write_ram_size(struct drm_device *dev) 3344254885Sdumbbell{ 3345254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 3346254885Sdumbbell uint8_t rev; 3347254885Sdumbbell uint16_t offset; 3348254885Sdumbbell uint32_t mem_size = 0; 3349254885Sdumbbell uint32_t mem_cntl = 0; 3350254885Sdumbbell 3351254885Sdumbbell /* should do something smarter here I guess... */ 3352254885Sdumbbell if (rdev->flags & RADEON_IS_IGP) 3353254885Sdumbbell return; 3354254885Sdumbbell 3355254885Sdumbbell /* first check detected mem table */ 3356254885Sdumbbell offset = combios_get_table_offset(dev, COMBIOS_DETECTED_MEM_TABLE); 3357254885Sdumbbell if (offset) { 3358254885Sdumbbell rev = RBIOS8(offset); 3359254885Sdumbbell if (rev < 3) { 3360254885Sdumbbell mem_cntl = RBIOS32(offset + 1); 3361254885Sdumbbell mem_size = RBIOS16(offset + 5); 3362254885Sdumbbell if ((rdev->family < CHIP_R200) && 3363254885Sdumbbell !ASIC_IS_RN50(rdev)) 3364254885Sdumbbell WREG32(RADEON_MEM_CNTL, mem_cntl); 3365254885Sdumbbell } 3366254885Sdumbbell } 3367254885Sdumbbell 3368254885Sdumbbell if (!mem_size) { 3369254885Sdumbbell offset = 3370254885Sdumbbell combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE); 3371254885Sdumbbell if (offset) { 3372254885Sdumbbell rev = RBIOS8(offset - 1); 3373254885Sdumbbell if (rev < 1) { 3374254885Sdumbbell if ((rdev->family < CHIP_R200) 3375254885Sdumbbell && !ASIC_IS_RN50(rdev)) { 3376254885Sdumbbell int ram = 0; 3377254885Sdumbbell int mem_addr_mapping = 0; 3378254885Sdumbbell 3379254885Sdumbbell while (RBIOS8(offset)) { 3380254885Sdumbbell ram = RBIOS8(offset); 3381254885Sdumbbell mem_addr_mapping = 3382254885Sdumbbell RBIOS8(offset + 1); 3383254885Sdumbbell if (mem_addr_mapping != 0x25) 3384254885Sdumbbell ram *= 2; 3385254885Sdumbbell mem_size = 3386254885Sdumbbell combios_detect_ram(dev, ram, 3387254885Sdumbbell mem_addr_mapping); 3388254885Sdumbbell if (mem_size) 3389254885Sdumbbell break; 3390254885Sdumbbell offset += 2; 3391254885Sdumbbell } 3392254885Sdumbbell } else 3393254885Sdumbbell mem_size = RBIOS8(offset); 3394254885Sdumbbell } else { 3395254885Sdumbbell mem_size = RBIOS8(offset); 3396254885Sdumbbell mem_size *= 2; /* convert to MB */ 3397254885Sdumbbell } 3398254885Sdumbbell } 3399254885Sdumbbell } 3400254885Sdumbbell 3401254885Sdumbbell mem_size *= (1024 * 1024); /* convert to bytes */ 3402254885Sdumbbell WREG32(RADEON_CONFIG_MEMSIZE, mem_size); 3403254885Sdumbbell} 3404254885Sdumbbell 3405254885Sdumbbellvoid radeon_combios_asic_init(struct drm_device *dev) 3406254885Sdumbbell{ 3407254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 3408254885Sdumbbell uint16_t table; 3409254885Sdumbbell 3410254885Sdumbbell /* port hardcoded mac stuff from radeonfb */ 3411254885Sdumbbell if (rdev->bios == NULL) 3412254885Sdumbbell return; 3413254885Sdumbbell 3414254885Sdumbbell /* ASIC INIT 1 */ 3415254885Sdumbbell table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_1_TABLE); 3416254885Sdumbbell if (table) 3417254885Sdumbbell combios_parse_mmio_table(dev, table); 3418254885Sdumbbell 3419254885Sdumbbell /* PLL INIT */ 3420254885Sdumbbell table = combios_get_table_offset(dev, COMBIOS_PLL_INIT_TABLE); 3421254885Sdumbbell if (table) 3422254885Sdumbbell combios_parse_pll_table(dev, table); 3423254885Sdumbbell 3424254885Sdumbbell /* ASIC INIT 2 */ 3425254885Sdumbbell table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_2_TABLE); 3426254885Sdumbbell if (table) 3427254885Sdumbbell combios_parse_mmio_table(dev, table); 3428254885Sdumbbell 3429254885Sdumbbell if (!(rdev->flags & RADEON_IS_IGP)) { 3430254885Sdumbbell /* ASIC INIT 4 */ 3431254885Sdumbbell table = 3432254885Sdumbbell combios_get_table_offset(dev, COMBIOS_ASIC_INIT_4_TABLE); 3433254885Sdumbbell if (table) 3434254885Sdumbbell combios_parse_mmio_table(dev, table); 3435254885Sdumbbell 3436254885Sdumbbell /* RAM RESET */ 3437254885Sdumbbell table = combios_get_table_offset(dev, COMBIOS_RAM_RESET_TABLE); 3438254885Sdumbbell if (table) 3439254885Sdumbbell combios_parse_ram_reset_table(dev, table); 3440254885Sdumbbell 3441254885Sdumbbell /* ASIC INIT 3 */ 3442254885Sdumbbell table = 3443254885Sdumbbell combios_get_table_offset(dev, COMBIOS_ASIC_INIT_3_TABLE); 3444254885Sdumbbell if (table) 3445254885Sdumbbell combios_parse_mmio_table(dev, table); 3446254885Sdumbbell 3447254885Sdumbbell /* write CONFIG_MEMSIZE */ 3448254885Sdumbbell combios_write_ram_size(dev); 3449254885Sdumbbell } 3450254885Sdumbbell 3451254885Sdumbbell /* quirk for rs4xx HP nx6125 laptop to make it resume 3452254885Sdumbbell * - it hangs on resume inside the dynclk 1 table. 3453254885Sdumbbell */ 3454254885Sdumbbell if (rdev->family == CHIP_RS480 && 3455254885Sdumbbell dev->pci_subvendor == 0x103c && 3456254885Sdumbbell dev->pci_subdevice == 0x308b) 3457254885Sdumbbell return; 3458254885Sdumbbell 3459254885Sdumbbell /* quirk for rs4xx HP dv5000 laptop to make it resume 3460254885Sdumbbell * - it hangs on resume inside the dynclk 1 table. 3461254885Sdumbbell */ 3462254885Sdumbbell if (rdev->family == CHIP_RS480 && 3463254885Sdumbbell dev->pci_subvendor == 0x103c && 3464254885Sdumbbell dev->pci_subdevice == 0x30a4) 3465254885Sdumbbell return; 3466254885Sdumbbell 3467254885Sdumbbell /* quirk for rs4xx Compaq Presario V5245EU laptop to make it resume 3468254885Sdumbbell * - it hangs on resume inside the dynclk 1 table. 3469254885Sdumbbell */ 3470254885Sdumbbell if (rdev->family == CHIP_RS480 && 3471254885Sdumbbell dev->pci_subvendor == 0x103c && 3472254885Sdumbbell dev->pci_subdevice == 0x30ae) 3473254885Sdumbbell return; 3474254885Sdumbbell 3475254885Sdumbbell /* DYN CLK 1 */ 3476254885Sdumbbell table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE); 3477254885Sdumbbell if (table) 3478254885Sdumbbell combios_parse_pll_table(dev, table); 3479254885Sdumbbell 3480254885Sdumbbell} 3481254885Sdumbbell 3482254885Sdumbbellvoid radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev) 3483254885Sdumbbell{ 3484254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 3485254885Sdumbbell uint32_t bios_0_scratch, bios_6_scratch, bios_7_scratch; 3486254885Sdumbbell 3487254885Sdumbbell bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); 3488254885Sdumbbell bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); 3489254885Sdumbbell bios_7_scratch = RREG32(RADEON_BIOS_7_SCRATCH); 3490254885Sdumbbell 3491254885Sdumbbell /* let the bios control the backlight */ 3492254885Sdumbbell bios_0_scratch &= ~RADEON_DRIVER_BRIGHTNESS_EN; 3493254885Sdumbbell 3494254885Sdumbbell /* tell the bios not to handle mode switching */ 3495254885Sdumbbell bios_6_scratch |= (RADEON_DISPLAY_SWITCHING_DIS | 3496254885Sdumbbell RADEON_ACC_MODE_CHANGE); 3497254885Sdumbbell 3498254885Sdumbbell /* tell the bios a driver is loaded */ 3499254885Sdumbbell bios_7_scratch |= RADEON_DRV_LOADED; 3500254885Sdumbbell 3501254885Sdumbbell WREG32(RADEON_BIOS_0_SCRATCH, bios_0_scratch); 3502254885Sdumbbell WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch); 3503254885Sdumbbell WREG32(RADEON_BIOS_7_SCRATCH, bios_7_scratch); 3504254885Sdumbbell} 3505254885Sdumbbell 3506254885Sdumbbellvoid radeon_combios_output_lock(struct drm_encoder *encoder, bool lock) 3507254885Sdumbbell{ 3508254885Sdumbbell struct drm_device *dev = encoder->dev; 3509254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 3510254885Sdumbbell uint32_t bios_6_scratch; 3511254885Sdumbbell 3512254885Sdumbbell bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); 3513254885Sdumbbell 3514254885Sdumbbell if (lock) 3515254885Sdumbbell bios_6_scratch |= RADEON_DRIVER_CRITICAL; 3516254885Sdumbbell else 3517254885Sdumbbell bios_6_scratch &= ~RADEON_DRIVER_CRITICAL; 3518254885Sdumbbell 3519254885Sdumbbell WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch); 3520254885Sdumbbell} 3521254885Sdumbbell 3522254885Sdumbbellvoid 3523254885Sdumbbellradeon_combios_connected_scratch_regs(struct drm_connector *connector, 3524254885Sdumbbell struct drm_encoder *encoder, 3525254885Sdumbbell bool connected) 3526254885Sdumbbell{ 3527254885Sdumbbell struct drm_device *dev = connector->dev; 3528254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 3529254885Sdumbbell struct radeon_connector *radeon_connector = 3530254885Sdumbbell to_radeon_connector(connector); 3531254885Sdumbbell struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 3532254885Sdumbbell uint32_t bios_4_scratch = RREG32(RADEON_BIOS_4_SCRATCH); 3533254885Sdumbbell uint32_t bios_5_scratch = RREG32(RADEON_BIOS_5_SCRATCH); 3534254885Sdumbbell 3535254885Sdumbbell if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) && 3536254885Sdumbbell (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) { 3537254885Sdumbbell if (connected) { 3538254885Sdumbbell DRM_DEBUG_KMS("TV1 connected\n"); 3539254885Sdumbbell /* fix me */ 3540254885Sdumbbell bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO; 3541254885Sdumbbell /*save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP; */ 3542254885Sdumbbell bios_5_scratch |= RADEON_TV1_ON; 3543254885Sdumbbell bios_5_scratch |= RADEON_ACC_REQ_TV1; 3544254885Sdumbbell } else { 3545254885Sdumbbell DRM_DEBUG_KMS("TV1 disconnected\n"); 3546254885Sdumbbell bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK; 3547254885Sdumbbell bios_5_scratch &= ~RADEON_TV1_ON; 3548254885Sdumbbell bios_5_scratch &= ~RADEON_ACC_REQ_TV1; 3549254885Sdumbbell } 3550254885Sdumbbell } 3551254885Sdumbbell if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) && 3552254885Sdumbbell (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) { 3553254885Sdumbbell if (connected) { 3554254885Sdumbbell DRM_DEBUG_KMS("LCD1 connected\n"); 3555254885Sdumbbell bios_4_scratch |= RADEON_LCD1_ATTACHED; 3556254885Sdumbbell bios_5_scratch |= RADEON_LCD1_ON; 3557254885Sdumbbell bios_5_scratch |= RADEON_ACC_REQ_LCD1; 3558254885Sdumbbell } else { 3559254885Sdumbbell DRM_DEBUG_KMS("LCD1 disconnected\n"); 3560254885Sdumbbell bios_4_scratch &= ~RADEON_LCD1_ATTACHED; 3561254885Sdumbbell bios_5_scratch &= ~RADEON_LCD1_ON; 3562254885Sdumbbell bios_5_scratch &= ~RADEON_ACC_REQ_LCD1; 3563254885Sdumbbell } 3564254885Sdumbbell } 3565254885Sdumbbell if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) && 3566254885Sdumbbell (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) { 3567254885Sdumbbell if (connected) { 3568254885Sdumbbell DRM_DEBUG_KMS("CRT1 connected\n"); 3569254885Sdumbbell bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR; 3570254885Sdumbbell bios_5_scratch |= RADEON_CRT1_ON; 3571254885Sdumbbell bios_5_scratch |= RADEON_ACC_REQ_CRT1; 3572254885Sdumbbell } else { 3573254885Sdumbbell DRM_DEBUG_KMS("CRT1 disconnected\n"); 3574254885Sdumbbell bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK; 3575254885Sdumbbell bios_5_scratch &= ~RADEON_CRT1_ON; 3576254885Sdumbbell bios_5_scratch &= ~RADEON_ACC_REQ_CRT1; 3577254885Sdumbbell } 3578254885Sdumbbell } 3579254885Sdumbbell if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) && 3580254885Sdumbbell (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) { 3581254885Sdumbbell if (connected) { 3582254885Sdumbbell DRM_DEBUG_KMS("CRT2 connected\n"); 3583254885Sdumbbell bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR; 3584254885Sdumbbell bios_5_scratch |= RADEON_CRT2_ON; 3585254885Sdumbbell bios_5_scratch |= RADEON_ACC_REQ_CRT2; 3586254885Sdumbbell } else { 3587254885Sdumbbell DRM_DEBUG_KMS("CRT2 disconnected\n"); 3588254885Sdumbbell bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK; 3589254885Sdumbbell bios_5_scratch &= ~RADEON_CRT2_ON; 3590254885Sdumbbell bios_5_scratch &= ~RADEON_ACC_REQ_CRT2; 3591254885Sdumbbell } 3592254885Sdumbbell } 3593254885Sdumbbell if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) && 3594254885Sdumbbell (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) { 3595254885Sdumbbell if (connected) { 3596254885Sdumbbell DRM_DEBUG_KMS("DFP1 connected\n"); 3597254885Sdumbbell bios_4_scratch |= RADEON_DFP1_ATTACHED; 3598254885Sdumbbell bios_5_scratch |= RADEON_DFP1_ON; 3599254885Sdumbbell bios_5_scratch |= RADEON_ACC_REQ_DFP1; 3600254885Sdumbbell } else { 3601254885Sdumbbell DRM_DEBUG_KMS("DFP1 disconnected\n"); 3602254885Sdumbbell bios_4_scratch &= ~RADEON_DFP1_ATTACHED; 3603254885Sdumbbell bios_5_scratch &= ~RADEON_DFP1_ON; 3604254885Sdumbbell bios_5_scratch &= ~RADEON_ACC_REQ_DFP1; 3605254885Sdumbbell } 3606254885Sdumbbell } 3607254885Sdumbbell if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) && 3608254885Sdumbbell (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) { 3609254885Sdumbbell if (connected) { 3610254885Sdumbbell DRM_DEBUG_KMS("DFP2 connected\n"); 3611254885Sdumbbell bios_4_scratch |= RADEON_DFP2_ATTACHED; 3612254885Sdumbbell bios_5_scratch |= RADEON_DFP2_ON; 3613254885Sdumbbell bios_5_scratch |= RADEON_ACC_REQ_DFP2; 3614254885Sdumbbell } else { 3615254885Sdumbbell DRM_DEBUG_KMS("DFP2 disconnected\n"); 3616254885Sdumbbell bios_4_scratch &= ~RADEON_DFP2_ATTACHED; 3617254885Sdumbbell bios_5_scratch &= ~RADEON_DFP2_ON; 3618254885Sdumbbell bios_5_scratch &= ~RADEON_ACC_REQ_DFP2; 3619254885Sdumbbell } 3620254885Sdumbbell } 3621254885Sdumbbell WREG32(RADEON_BIOS_4_SCRATCH, bios_4_scratch); 3622254885Sdumbbell WREG32(RADEON_BIOS_5_SCRATCH, bios_5_scratch); 3623254885Sdumbbell} 3624254885Sdumbbell 3625254885Sdumbbellvoid 3626254885Sdumbbellradeon_combios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc) 3627254885Sdumbbell{ 3628254885Sdumbbell struct drm_device *dev = encoder->dev; 3629254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 3630254885Sdumbbell struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 3631254885Sdumbbell uint32_t bios_5_scratch = RREG32(RADEON_BIOS_5_SCRATCH); 3632254885Sdumbbell 3633254885Sdumbbell if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { 3634254885Sdumbbell bios_5_scratch &= ~RADEON_TV1_CRTC_MASK; 3635254885Sdumbbell bios_5_scratch |= (crtc << RADEON_TV1_CRTC_SHIFT); 3636254885Sdumbbell } 3637254885Sdumbbell if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) { 3638254885Sdumbbell bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK; 3639254885Sdumbbell bios_5_scratch |= (crtc << RADEON_CRT1_CRTC_SHIFT); 3640254885Sdumbbell } 3641254885Sdumbbell if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) { 3642254885Sdumbbell bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK; 3643254885Sdumbbell bios_5_scratch |= (crtc << RADEON_CRT2_CRTC_SHIFT); 3644254885Sdumbbell } 3645254885Sdumbbell if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) { 3646254885Sdumbbell bios_5_scratch &= ~RADEON_LCD1_CRTC_MASK; 3647254885Sdumbbell bios_5_scratch |= (crtc << RADEON_LCD1_CRTC_SHIFT); 3648254885Sdumbbell } 3649254885Sdumbbell if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) { 3650254885Sdumbbell bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK; 3651254885Sdumbbell bios_5_scratch |= (crtc << RADEON_DFP1_CRTC_SHIFT); 3652254885Sdumbbell } 3653254885Sdumbbell if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) { 3654254885Sdumbbell bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK; 3655254885Sdumbbell bios_5_scratch |= (crtc << RADEON_DFP2_CRTC_SHIFT); 3656254885Sdumbbell } 3657254885Sdumbbell WREG32(RADEON_BIOS_5_SCRATCH, bios_5_scratch); 3658254885Sdumbbell} 3659254885Sdumbbell 3660254885Sdumbbellvoid 3661254885Sdumbbellradeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on) 3662254885Sdumbbell{ 3663254885Sdumbbell struct drm_device *dev = encoder->dev; 3664254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 3665254885Sdumbbell struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 3666254885Sdumbbell uint32_t bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); 3667254885Sdumbbell 3668254885Sdumbbell if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) { 3669254885Sdumbbell if (on) 3670254885Sdumbbell bios_6_scratch |= RADEON_TV_DPMS_ON; 3671254885Sdumbbell else 3672254885Sdumbbell bios_6_scratch &= ~RADEON_TV_DPMS_ON; 3673254885Sdumbbell } 3674254885Sdumbbell if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) { 3675254885Sdumbbell if (on) 3676254885Sdumbbell bios_6_scratch |= RADEON_CRT_DPMS_ON; 3677254885Sdumbbell else 3678254885Sdumbbell bios_6_scratch &= ~RADEON_CRT_DPMS_ON; 3679254885Sdumbbell } 3680254885Sdumbbell if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { 3681254885Sdumbbell if (on) 3682254885Sdumbbell bios_6_scratch |= RADEON_LCD_DPMS_ON; 3683254885Sdumbbell else 3684254885Sdumbbell bios_6_scratch &= ~RADEON_LCD_DPMS_ON; 3685254885Sdumbbell } 3686254885Sdumbbell if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { 3687254885Sdumbbell if (on) 3688254885Sdumbbell bios_6_scratch |= RADEON_DFP_DPMS_ON; 3689254885Sdumbbell else 3690254885Sdumbbell bios_6_scratch &= ~RADEON_DFP_DPMS_ON; 3691254885Sdumbbell } 3692254885Sdumbbell WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch); 3693254885Sdumbbell} 3694