162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright 2004 ATI Technologies Inc., Markham, Ontario
362306a36Sopenharmony_ci * Copyright 2007-8 Advanced Micro Devices, Inc.
462306a36Sopenharmony_ci * Copyright 2008 Red Hat Inc.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
762306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
862306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation
962306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1062306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
1162306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
1262306a36Sopenharmony_ci *
1362306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
1462306a36Sopenharmony_ci * all copies or substantial portions of the Software.
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1762306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1862306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1962306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
2062306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2162306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2262306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
2362306a36Sopenharmony_ci *
2462306a36Sopenharmony_ci * Authors: Dave Airlie
2562306a36Sopenharmony_ci *          Alex Deucher
2662306a36Sopenharmony_ci */
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#include <linux/pci.h>
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#include <drm/drm_device.h>
3162306a36Sopenharmony_ci#include <drm/radeon_drm.h>
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#include "radeon.h"
3462306a36Sopenharmony_ci#include "radeon_legacy_encoders.h"
3562306a36Sopenharmony_ci#include "atom.h"
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#ifdef CONFIG_PPC_PMAC
3862306a36Sopenharmony_ci/* not sure which of these are needed */
3962306a36Sopenharmony_ci#include <asm/machdep.h>
4062306a36Sopenharmony_ci#include <asm/pmac_feature.h>
4162306a36Sopenharmony_ci#include <asm/prom.h>
4262306a36Sopenharmony_ci#endif /* CONFIG_PPC_PMAC */
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/* old legacy ATI BIOS routines */
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/* COMBIOS table offsets */
4762306a36Sopenharmony_cienum radeon_combios_table_offset {
4862306a36Sopenharmony_ci	/* absolute offset tables */
4962306a36Sopenharmony_ci	COMBIOS_ASIC_INIT_1_TABLE,
5062306a36Sopenharmony_ci	COMBIOS_BIOS_SUPPORT_TABLE,
5162306a36Sopenharmony_ci	COMBIOS_DAC_PROGRAMMING_TABLE,
5262306a36Sopenharmony_ci	COMBIOS_MAX_COLOR_DEPTH_TABLE,
5362306a36Sopenharmony_ci	COMBIOS_CRTC_INFO_TABLE,
5462306a36Sopenharmony_ci	COMBIOS_PLL_INFO_TABLE,
5562306a36Sopenharmony_ci	COMBIOS_TV_INFO_TABLE,
5662306a36Sopenharmony_ci	COMBIOS_DFP_INFO_TABLE,
5762306a36Sopenharmony_ci	COMBIOS_HW_CONFIG_INFO_TABLE,
5862306a36Sopenharmony_ci	COMBIOS_MULTIMEDIA_INFO_TABLE,
5962306a36Sopenharmony_ci	COMBIOS_TV_STD_PATCH_TABLE,
6062306a36Sopenharmony_ci	COMBIOS_LCD_INFO_TABLE,
6162306a36Sopenharmony_ci	COMBIOS_MOBILE_INFO_TABLE,
6262306a36Sopenharmony_ci	COMBIOS_PLL_INIT_TABLE,
6362306a36Sopenharmony_ci	COMBIOS_MEM_CONFIG_TABLE,
6462306a36Sopenharmony_ci	COMBIOS_SAVE_MASK_TABLE,
6562306a36Sopenharmony_ci	COMBIOS_HARDCODED_EDID_TABLE,
6662306a36Sopenharmony_ci	COMBIOS_ASIC_INIT_2_TABLE,
6762306a36Sopenharmony_ci	COMBIOS_CONNECTOR_INFO_TABLE,
6862306a36Sopenharmony_ci	COMBIOS_DYN_CLK_1_TABLE,
6962306a36Sopenharmony_ci	COMBIOS_RESERVED_MEM_TABLE,
7062306a36Sopenharmony_ci	COMBIOS_EXT_TMDS_INFO_TABLE,
7162306a36Sopenharmony_ci	COMBIOS_MEM_CLK_INFO_TABLE,
7262306a36Sopenharmony_ci	COMBIOS_EXT_DAC_INFO_TABLE,
7362306a36Sopenharmony_ci	COMBIOS_MISC_INFO_TABLE,
7462306a36Sopenharmony_ci	COMBIOS_CRT_INFO_TABLE,
7562306a36Sopenharmony_ci	COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE,
7662306a36Sopenharmony_ci	COMBIOS_COMPONENT_VIDEO_INFO_TABLE,
7762306a36Sopenharmony_ci	COMBIOS_FAN_SPEED_INFO_TABLE,
7862306a36Sopenharmony_ci	COMBIOS_OVERDRIVE_INFO_TABLE,
7962306a36Sopenharmony_ci	COMBIOS_OEM_INFO_TABLE,
8062306a36Sopenharmony_ci	COMBIOS_DYN_CLK_2_TABLE,
8162306a36Sopenharmony_ci	COMBIOS_POWER_CONNECTOR_INFO_TABLE,
8262306a36Sopenharmony_ci	COMBIOS_I2C_INFO_TABLE,
8362306a36Sopenharmony_ci	/* relative offset tables */
8462306a36Sopenharmony_ci	COMBIOS_ASIC_INIT_3_TABLE,	/* offset from misc info */
8562306a36Sopenharmony_ci	COMBIOS_ASIC_INIT_4_TABLE,	/* offset from misc info */
8662306a36Sopenharmony_ci	COMBIOS_DETECTED_MEM_TABLE,	/* offset from misc info */
8762306a36Sopenharmony_ci	COMBIOS_ASIC_INIT_5_TABLE,	/* offset from misc info */
8862306a36Sopenharmony_ci	COMBIOS_RAM_RESET_TABLE,	/* offset from mem config */
8962306a36Sopenharmony_ci	COMBIOS_POWERPLAY_INFO_TABLE,	/* offset from mobile info */
9062306a36Sopenharmony_ci	COMBIOS_GPIO_INFO_TABLE,	/* offset from mobile info */
9162306a36Sopenharmony_ci	COMBIOS_LCD_DDC_INFO_TABLE,	/* offset from mobile info */
9262306a36Sopenharmony_ci	COMBIOS_TMDS_POWER_TABLE,	/* offset from mobile info */
9362306a36Sopenharmony_ci	COMBIOS_TMDS_POWER_ON_TABLE,	/* offset from tmds power */
9462306a36Sopenharmony_ci	COMBIOS_TMDS_POWER_OFF_TABLE,	/* offset from tmds power */
9562306a36Sopenharmony_ci};
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_cienum radeon_combios_ddc {
9862306a36Sopenharmony_ci	DDC_NONE_DETECTED,
9962306a36Sopenharmony_ci	DDC_MONID,
10062306a36Sopenharmony_ci	DDC_DVI,
10162306a36Sopenharmony_ci	DDC_VGA,
10262306a36Sopenharmony_ci	DDC_CRT2,
10362306a36Sopenharmony_ci	DDC_LCD,
10462306a36Sopenharmony_ci	DDC_GPIO,
10562306a36Sopenharmony_ci};
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_cienum radeon_combios_connector {
10862306a36Sopenharmony_ci	CONNECTOR_NONE_LEGACY,
10962306a36Sopenharmony_ci	CONNECTOR_PROPRIETARY_LEGACY,
11062306a36Sopenharmony_ci	CONNECTOR_CRT_LEGACY,
11162306a36Sopenharmony_ci	CONNECTOR_DVI_I_LEGACY,
11262306a36Sopenharmony_ci	CONNECTOR_DVI_D_LEGACY,
11362306a36Sopenharmony_ci	CONNECTOR_CTV_LEGACY,
11462306a36Sopenharmony_ci	CONNECTOR_STV_LEGACY,
11562306a36Sopenharmony_ci	CONNECTOR_UNSUPPORTED_LEGACY
11662306a36Sopenharmony_ci};
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_cistatic const int legacy_connector_convert[] = {
11962306a36Sopenharmony_ci	DRM_MODE_CONNECTOR_Unknown,
12062306a36Sopenharmony_ci	DRM_MODE_CONNECTOR_DVID,
12162306a36Sopenharmony_ci	DRM_MODE_CONNECTOR_VGA,
12262306a36Sopenharmony_ci	DRM_MODE_CONNECTOR_DVII,
12362306a36Sopenharmony_ci	DRM_MODE_CONNECTOR_DVID,
12462306a36Sopenharmony_ci	DRM_MODE_CONNECTOR_Composite,
12562306a36Sopenharmony_ci	DRM_MODE_CONNECTOR_SVIDEO,
12662306a36Sopenharmony_ci	DRM_MODE_CONNECTOR_Unknown,
12762306a36Sopenharmony_ci};
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_cistatic uint16_t combios_get_table_offset(struct drm_device *dev,
13062306a36Sopenharmony_ci					 enum radeon_combios_table_offset table)
13162306a36Sopenharmony_ci{
13262306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
13362306a36Sopenharmony_ci	int rev, size;
13462306a36Sopenharmony_ci	uint16_t offset = 0, check_offset;
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	if (!rdev->bios)
13762306a36Sopenharmony_ci		return 0;
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	switch (table) {
14062306a36Sopenharmony_ci		/* absolute offset tables */
14162306a36Sopenharmony_ci	case COMBIOS_ASIC_INIT_1_TABLE:
14262306a36Sopenharmony_ci		check_offset = 0xc;
14362306a36Sopenharmony_ci		break;
14462306a36Sopenharmony_ci	case COMBIOS_BIOS_SUPPORT_TABLE:
14562306a36Sopenharmony_ci		check_offset = 0x14;
14662306a36Sopenharmony_ci		break;
14762306a36Sopenharmony_ci	case COMBIOS_DAC_PROGRAMMING_TABLE:
14862306a36Sopenharmony_ci		check_offset = 0x2a;
14962306a36Sopenharmony_ci		break;
15062306a36Sopenharmony_ci	case COMBIOS_MAX_COLOR_DEPTH_TABLE:
15162306a36Sopenharmony_ci		check_offset = 0x2c;
15262306a36Sopenharmony_ci		break;
15362306a36Sopenharmony_ci	case COMBIOS_CRTC_INFO_TABLE:
15462306a36Sopenharmony_ci		check_offset = 0x2e;
15562306a36Sopenharmony_ci		break;
15662306a36Sopenharmony_ci	case COMBIOS_PLL_INFO_TABLE:
15762306a36Sopenharmony_ci		check_offset = 0x30;
15862306a36Sopenharmony_ci		break;
15962306a36Sopenharmony_ci	case COMBIOS_TV_INFO_TABLE:
16062306a36Sopenharmony_ci		check_offset = 0x32;
16162306a36Sopenharmony_ci		break;
16262306a36Sopenharmony_ci	case COMBIOS_DFP_INFO_TABLE:
16362306a36Sopenharmony_ci		check_offset = 0x34;
16462306a36Sopenharmony_ci		break;
16562306a36Sopenharmony_ci	case COMBIOS_HW_CONFIG_INFO_TABLE:
16662306a36Sopenharmony_ci		check_offset = 0x36;
16762306a36Sopenharmony_ci		break;
16862306a36Sopenharmony_ci	case COMBIOS_MULTIMEDIA_INFO_TABLE:
16962306a36Sopenharmony_ci		check_offset = 0x38;
17062306a36Sopenharmony_ci		break;
17162306a36Sopenharmony_ci	case COMBIOS_TV_STD_PATCH_TABLE:
17262306a36Sopenharmony_ci		check_offset = 0x3e;
17362306a36Sopenharmony_ci		break;
17462306a36Sopenharmony_ci	case COMBIOS_LCD_INFO_TABLE:
17562306a36Sopenharmony_ci		check_offset = 0x40;
17662306a36Sopenharmony_ci		break;
17762306a36Sopenharmony_ci	case COMBIOS_MOBILE_INFO_TABLE:
17862306a36Sopenharmony_ci		check_offset = 0x42;
17962306a36Sopenharmony_ci		break;
18062306a36Sopenharmony_ci	case COMBIOS_PLL_INIT_TABLE:
18162306a36Sopenharmony_ci		check_offset = 0x46;
18262306a36Sopenharmony_ci		break;
18362306a36Sopenharmony_ci	case COMBIOS_MEM_CONFIG_TABLE:
18462306a36Sopenharmony_ci		check_offset = 0x48;
18562306a36Sopenharmony_ci		break;
18662306a36Sopenharmony_ci	case COMBIOS_SAVE_MASK_TABLE:
18762306a36Sopenharmony_ci		check_offset = 0x4a;
18862306a36Sopenharmony_ci		break;
18962306a36Sopenharmony_ci	case COMBIOS_HARDCODED_EDID_TABLE:
19062306a36Sopenharmony_ci		check_offset = 0x4c;
19162306a36Sopenharmony_ci		break;
19262306a36Sopenharmony_ci	case COMBIOS_ASIC_INIT_2_TABLE:
19362306a36Sopenharmony_ci		check_offset = 0x4e;
19462306a36Sopenharmony_ci		break;
19562306a36Sopenharmony_ci	case COMBIOS_CONNECTOR_INFO_TABLE:
19662306a36Sopenharmony_ci		check_offset = 0x50;
19762306a36Sopenharmony_ci		break;
19862306a36Sopenharmony_ci	case COMBIOS_DYN_CLK_1_TABLE:
19962306a36Sopenharmony_ci		check_offset = 0x52;
20062306a36Sopenharmony_ci		break;
20162306a36Sopenharmony_ci	case COMBIOS_RESERVED_MEM_TABLE:
20262306a36Sopenharmony_ci		check_offset = 0x54;
20362306a36Sopenharmony_ci		break;
20462306a36Sopenharmony_ci	case COMBIOS_EXT_TMDS_INFO_TABLE:
20562306a36Sopenharmony_ci		check_offset = 0x58;
20662306a36Sopenharmony_ci		break;
20762306a36Sopenharmony_ci	case COMBIOS_MEM_CLK_INFO_TABLE:
20862306a36Sopenharmony_ci		check_offset = 0x5a;
20962306a36Sopenharmony_ci		break;
21062306a36Sopenharmony_ci	case COMBIOS_EXT_DAC_INFO_TABLE:
21162306a36Sopenharmony_ci		check_offset = 0x5c;
21262306a36Sopenharmony_ci		break;
21362306a36Sopenharmony_ci	case COMBIOS_MISC_INFO_TABLE:
21462306a36Sopenharmony_ci		check_offset = 0x5e;
21562306a36Sopenharmony_ci		break;
21662306a36Sopenharmony_ci	case COMBIOS_CRT_INFO_TABLE:
21762306a36Sopenharmony_ci		check_offset = 0x60;
21862306a36Sopenharmony_ci		break;
21962306a36Sopenharmony_ci	case COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE:
22062306a36Sopenharmony_ci		check_offset = 0x62;
22162306a36Sopenharmony_ci		break;
22262306a36Sopenharmony_ci	case COMBIOS_COMPONENT_VIDEO_INFO_TABLE:
22362306a36Sopenharmony_ci		check_offset = 0x64;
22462306a36Sopenharmony_ci		break;
22562306a36Sopenharmony_ci	case COMBIOS_FAN_SPEED_INFO_TABLE:
22662306a36Sopenharmony_ci		check_offset = 0x66;
22762306a36Sopenharmony_ci		break;
22862306a36Sopenharmony_ci	case COMBIOS_OVERDRIVE_INFO_TABLE:
22962306a36Sopenharmony_ci		check_offset = 0x68;
23062306a36Sopenharmony_ci		break;
23162306a36Sopenharmony_ci	case COMBIOS_OEM_INFO_TABLE:
23262306a36Sopenharmony_ci		check_offset = 0x6a;
23362306a36Sopenharmony_ci		break;
23462306a36Sopenharmony_ci	case COMBIOS_DYN_CLK_2_TABLE:
23562306a36Sopenharmony_ci		check_offset = 0x6c;
23662306a36Sopenharmony_ci		break;
23762306a36Sopenharmony_ci	case COMBIOS_POWER_CONNECTOR_INFO_TABLE:
23862306a36Sopenharmony_ci		check_offset = 0x6e;
23962306a36Sopenharmony_ci		break;
24062306a36Sopenharmony_ci	case COMBIOS_I2C_INFO_TABLE:
24162306a36Sopenharmony_ci		check_offset = 0x70;
24262306a36Sopenharmony_ci		break;
24362306a36Sopenharmony_ci		/* relative offset tables */
24462306a36Sopenharmony_ci	case COMBIOS_ASIC_INIT_3_TABLE:	/* offset from misc info */
24562306a36Sopenharmony_ci		check_offset =
24662306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
24762306a36Sopenharmony_ci		if (check_offset) {
24862306a36Sopenharmony_ci			rev = RBIOS8(check_offset);
24962306a36Sopenharmony_ci			if (rev > 0) {
25062306a36Sopenharmony_ci				check_offset = RBIOS16(check_offset + 0x3);
25162306a36Sopenharmony_ci				if (check_offset)
25262306a36Sopenharmony_ci					offset = check_offset;
25362306a36Sopenharmony_ci			}
25462306a36Sopenharmony_ci		}
25562306a36Sopenharmony_ci		break;
25662306a36Sopenharmony_ci	case COMBIOS_ASIC_INIT_4_TABLE:	/* offset from misc info */
25762306a36Sopenharmony_ci		check_offset =
25862306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
25962306a36Sopenharmony_ci		if (check_offset) {
26062306a36Sopenharmony_ci			rev = RBIOS8(check_offset);
26162306a36Sopenharmony_ci			if (rev > 0) {
26262306a36Sopenharmony_ci				check_offset = RBIOS16(check_offset + 0x5);
26362306a36Sopenharmony_ci				if (check_offset)
26462306a36Sopenharmony_ci					offset = check_offset;
26562306a36Sopenharmony_ci			}
26662306a36Sopenharmony_ci		}
26762306a36Sopenharmony_ci		break;
26862306a36Sopenharmony_ci	case COMBIOS_DETECTED_MEM_TABLE:	/* offset from misc info */
26962306a36Sopenharmony_ci		check_offset =
27062306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
27162306a36Sopenharmony_ci		if (check_offset) {
27262306a36Sopenharmony_ci			rev = RBIOS8(check_offset);
27362306a36Sopenharmony_ci			if (rev > 0) {
27462306a36Sopenharmony_ci				check_offset = RBIOS16(check_offset + 0x7);
27562306a36Sopenharmony_ci				if (check_offset)
27662306a36Sopenharmony_ci					offset = check_offset;
27762306a36Sopenharmony_ci			}
27862306a36Sopenharmony_ci		}
27962306a36Sopenharmony_ci		break;
28062306a36Sopenharmony_ci	case COMBIOS_ASIC_INIT_5_TABLE:	/* offset from misc info */
28162306a36Sopenharmony_ci		check_offset =
28262306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
28362306a36Sopenharmony_ci		if (check_offset) {
28462306a36Sopenharmony_ci			rev = RBIOS8(check_offset);
28562306a36Sopenharmony_ci			if (rev == 2) {
28662306a36Sopenharmony_ci				check_offset = RBIOS16(check_offset + 0x9);
28762306a36Sopenharmony_ci				if (check_offset)
28862306a36Sopenharmony_ci					offset = check_offset;
28962306a36Sopenharmony_ci			}
29062306a36Sopenharmony_ci		}
29162306a36Sopenharmony_ci		break;
29262306a36Sopenharmony_ci	case COMBIOS_RAM_RESET_TABLE:	/* offset from mem config */
29362306a36Sopenharmony_ci		check_offset =
29462306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE);
29562306a36Sopenharmony_ci		if (check_offset) {
29662306a36Sopenharmony_ci			while (RBIOS8(check_offset++));
29762306a36Sopenharmony_ci			check_offset += 2;
29862306a36Sopenharmony_ci			if (check_offset)
29962306a36Sopenharmony_ci				offset = check_offset;
30062306a36Sopenharmony_ci		}
30162306a36Sopenharmony_ci		break;
30262306a36Sopenharmony_ci	case COMBIOS_POWERPLAY_INFO_TABLE:	/* offset from mobile info */
30362306a36Sopenharmony_ci		check_offset =
30462306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
30562306a36Sopenharmony_ci		if (check_offset) {
30662306a36Sopenharmony_ci			check_offset = RBIOS16(check_offset + 0x11);
30762306a36Sopenharmony_ci			if (check_offset)
30862306a36Sopenharmony_ci				offset = check_offset;
30962306a36Sopenharmony_ci		}
31062306a36Sopenharmony_ci		break;
31162306a36Sopenharmony_ci	case COMBIOS_GPIO_INFO_TABLE:	/* offset from mobile info */
31262306a36Sopenharmony_ci		check_offset =
31362306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
31462306a36Sopenharmony_ci		if (check_offset) {
31562306a36Sopenharmony_ci			check_offset = RBIOS16(check_offset + 0x13);
31662306a36Sopenharmony_ci			if (check_offset)
31762306a36Sopenharmony_ci				offset = check_offset;
31862306a36Sopenharmony_ci		}
31962306a36Sopenharmony_ci		break;
32062306a36Sopenharmony_ci	case COMBIOS_LCD_DDC_INFO_TABLE:	/* offset from mobile info */
32162306a36Sopenharmony_ci		check_offset =
32262306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
32362306a36Sopenharmony_ci		if (check_offset) {
32462306a36Sopenharmony_ci			check_offset = RBIOS16(check_offset + 0x15);
32562306a36Sopenharmony_ci			if (check_offset)
32662306a36Sopenharmony_ci				offset = check_offset;
32762306a36Sopenharmony_ci		}
32862306a36Sopenharmony_ci		break;
32962306a36Sopenharmony_ci	case COMBIOS_TMDS_POWER_TABLE:	/* offset from mobile info */
33062306a36Sopenharmony_ci		check_offset =
33162306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
33262306a36Sopenharmony_ci		if (check_offset) {
33362306a36Sopenharmony_ci			check_offset = RBIOS16(check_offset + 0x17);
33462306a36Sopenharmony_ci			if (check_offset)
33562306a36Sopenharmony_ci				offset = check_offset;
33662306a36Sopenharmony_ci		}
33762306a36Sopenharmony_ci		break;
33862306a36Sopenharmony_ci	case COMBIOS_TMDS_POWER_ON_TABLE:	/* offset from tmds power */
33962306a36Sopenharmony_ci		check_offset =
34062306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE);
34162306a36Sopenharmony_ci		if (check_offset) {
34262306a36Sopenharmony_ci			check_offset = RBIOS16(check_offset + 0x2);
34362306a36Sopenharmony_ci			if (check_offset)
34462306a36Sopenharmony_ci				offset = check_offset;
34562306a36Sopenharmony_ci		}
34662306a36Sopenharmony_ci		break;
34762306a36Sopenharmony_ci	case COMBIOS_TMDS_POWER_OFF_TABLE:	/* offset from tmds power */
34862306a36Sopenharmony_ci		check_offset =
34962306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE);
35062306a36Sopenharmony_ci		if (check_offset) {
35162306a36Sopenharmony_ci			check_offset = RBIOS16(check_offset + 0x4);
35262306a36Sopenharmony_ci			if (check_offset)
35362306a36Sopenharmony_ci				offset = check_offset;
35462306a36Sopenharmony_ci		}
35562306a36Sopenharmony_ci		break;
35662306a36Sopenharmony_ci	default:
35762306a36Sopenharmony_ci		check_offset = 0;
35862306a36Sopenharmony_ci		break;
35962306a36Sopenharmony_ci	}
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci	size = RBIOS8(rdev->bios_header_start + 0x6);
36262306a36Sopenharmony_ci	/* check absolute offset tables */
36362306a36Sopenharmony_ci	if (table < COMBIOS_ASIC_INIT_3_TABLE && check_offset && check_offset < size)
36462306a36Sopenharmony_ci		offset = RBIOS16(rdev->bios_header_start + check_offset);
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci	return offset;
36762306a36Sopenharmony_ci}
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_cibool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
37062306a36Sopenharmony_ci{
37162306a36Sopenharmony_ci	int edid_info, size;
37262306a36Sopenharmony_ci	struct edid *edid;
37362306a36Sopenharmony_ci	unsigned char *raw;
37462306a36Sopenharmony_ci	edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE);
37562306a36Sopenharmony_ci	if (!edid_info)
37662306a36Sopenharmony_ci		return false;
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci	raw = rdev->bios + edid_info;
37962306a36Sopenharmony_ci	size = EDID_LENGTH * (raw[0x7e] + 1);
38062306a36Sopenharmony_ci	edid = kmalloc(size, GFP_KERNEL);
38162306a36Sopenharmony_ci	if (edid == NULL)
38262306a36Sopenharmony_ci		return false;
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci	memcpy((unsigned char *)edid, raw, size);
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci	if (!drm_edid_is_valid(edid)) {
38762306a36Sopenharmony_ci		kfree(edid);
38862306a36Sopenharmony_ci		return false;
38962306a36Sopenharmony_ci	}
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	rdev->mode_info.bios_hardcoded_edid = edid;
39262306a36Sopenharmony_ci	rdev->mode_info.bios_hardcoded_edid_size = size;
39362306a36Sopenharmony_ci	return true;
39462306a36Sopenharmony_ci}
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci/* this is used for atom LCDs as well */
39762306a36Sopenharmony_cistruct edid *
39862306a36Sopenharmony_ciradeon_bios_get_hardcoded_edid(struct radeon_device *rdev)
39962306a36Sopenharmony_ci{
40062306a36Sopenharmony_ci	struct edid *edid;
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci	if (rdev->mode_info.bios_hardcoded_edid) {
40362306a36Sopenharmony_ci		edid = kmalloc(rdev->mode_info.bios_hardcoded_edid_size, GFP_KERNEL);
40462306a36Sopenharmony_ci		if (edid) {
40562306a36Sopenharmony_ci			memcpy((unsigned char *)edid,
40662306a36Sopenharmony_ci			       (unsigned char *)rdev->mode_info.bios_hardcoded_edid,
40762306a36Sopenharmony_ci			       rdev->mode_info.bios_hardcoded_edid_size);
40862306a36Sopenharmony_ci			return edid;
40962306a36Sopenharmony_ci		}
41062306a36Sopenharmony_ci	}
41162306a36Sopenharmony_ci	return NULL;
41262306a36Sopenharmony_ci}
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_cistatic struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev,
41562306a36Sopenharmony_ci						       enum radeon_combios_ddc ddc,
41662306a36Sopenharmony_ci						       u32 clk_mask,
41762306a36Sopenharmony_ci						       u32 data_mask)
41862306a36Sopenharmony_ci{
41962306a36Sopenharmony_ci	struct radeon_i2c_bus_rec i2c;
42062306a36Sopenharmony_ci	int ddc_line = 0;
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	/* ddc id            = mask reg
42362306a36Sopenharmony_ci	 * DDC_NONE_DETECTED = none
42462306a36Sopenharmony_ci	 * DDC_DVI           = RADEON_GPIO_DVI_DDC
42562306a36Sopenharmony_ci	 * DDC_VGA           = RADEON_GPIO_VGA_DDC
42662306a36Sopenharmony_ci	 * DDC_LCD           = RADEON_GPIOPAD_MASK
42762306a36Sopenharmony_ci	 * DDC_GPIO          = RADEON_MDGPIO_MASK
42862306a36Sopenharmony_ci	 * r1xx
42962306a36Sopenharmony_ci	 * DDC_MONID         = RADEON_GPIO_MONID
43062306a36Sopenharmony_ci	 * DDC_CRT2          = RADEON_GPIO_CRT2_DDC
43162306a36Sopenharmony_ci	 * r200
43262306a36Sopenharmony_ci	 * DDC_MONID         = RADEON_GPIO_MONID
43362306a36Sopenharmony_ci	 * DDC_CRT2          = RADEON_GPIO_DVI_DDC
43462306a36Sopenharmony_ci	 * r300/r350
43562306a36Sopenharmony_ci	 * DDC_MONID         = RADEON_GPIO_DVI_DDC
43662306a36Sopenharmony_ci	 * DDC_CRT2          = RADEON_GPIO_DVI_DDC
43762306a36Sopenharmony_ci	 * rv2xx/rv3xx
43862306a36Sopenharmony_ci	 * DDC_MONID         = RADEON_GPIO_MONID
43962306a36Sopenharmony_ci	 * DDC_CRT2          = RADEON_GPIO_MONID
44062306a36Sopenharmony_ci	 * rs3xx/rs4xx
44162306a36Sopenharmony_ci	 * DDC_MONID         = RADEON_GPIOPAD_MASK
44262306a36Sopenharmony_ci	 * DDC_CRT2          = RADEON_GPIO_MONID
44362306a36Sopenharmony_ci	 */
44462306a36Sopenharmony_ci	switch (ddc) {
44562306a36Sopenharmony_ci	case DDC_NONE_DETECTED:
44662306a36Sopenharmony_ci	default:
44762306a36Sopenharmony_ci		ddc_line = 0;
44862306a36Sopenharmony_ci		break;
44962306a36Sopenharmony_ci	case DDC_DVI:
45062306a36Sopenharmony_ci		ddc_line = RADEON_GPIO_DVI_DDC;
45162306a36Sopenharmony_ci		break;
45262306a36Sopenharmony_ci	case DDC_VGA:
45362306a36Sopenharmony_ci		ddc_line = RADEON_GPIO_VGA_DDC;
45462306a36Sopenharmony_ci		break;
45562306a36Sopenharmony_ci	case DDC_LCD:
45662306a36Sopenharmony_ci		ddc_line = RADEON_GPIOPAD_MASK;
45762306a36Sopenharmony_ci		break;
45862306a36Sopenharmony_ci	case DDC_GPIO:
45962306a36Sopenharmony_ci		ddc_line = RADEON_MDGPIO_MASK;
46062306a36Sopenharmony_ci		break;
46162306a36Sopenharmony_ci	case DDC_MONID:
46262306a36Sopenharmony_ci		if (rdev->family == CHIP_RS300 ||
46362306a36Sopenharmony_ci		    rdev->family == CHIP_RS400 ||
46462306a36Sopenharmony_ci		    rdev->family == CHIP_RS480)
46562306a36Sopenharmony_ci			ddc_line = RADEON_GPIOPAD_MASK;
46662306a36Sopenharmony_ci		else if (rdev->family == CHIP_R300 ||
46762306a36Sopenharmony_ci			 rdev->family == CHIP_R350) {
46862306a36Sopenharmony_ci			ddc_line = RADEON_GPIO_DVI_DDC;
46962306a36Sopenharmony_ci			ddc = DDC_DVI;
47062306a36Sopenharmony_ci		} else
47162306a36Sopenharmony_ci			ddc_line = RADEON_GPIO_MONID;
47262306a36Sopenharmony_ci		break;
47362306a36Sopenharmony_ci	case DDC_CRT2:
47462306a36Sopenharmony_ci		if (rdev->family == CHIP_R200 ||
47562306a36Sopenharmony_ci		    rdev->family == CHIP_R300 ||
47662306a36Sopenharmony_ci		    rdev->family == CHIP_R350) {
47762306a36Sopenharmony_ci			ddc_line = RADEON_GPIO_DVI_DDC;
47862306a36Sopenharmony_ci			ddc = DDC_DVI;
47962306a36Sopenharmony_ci		} else if (rdev->family == CHIP_RS300 ||
48062306a36Sopenharmony_ci			   rdev->family == CHIP_RS400 ||
48162306a36Sopenharmony_ci			   rdev->family == CHIP_RS480)
48262306a36Sopenharmony_ci			ddc_line = RADEON_GPIO_MONID;
48362306a36Sopenharmony_ci		else if (rdev->family >= CHIP_RV350) {
48462306a36Sopenharmony_ci			ddc_line = RADEON_GPIO_MONID;
48562306a36Sopenharmony_ci			ddc = DDC_MONID;
48662306a36Sopenharmony_ci		} else
48762306a36Sopenharmony_ci			ddc_line = RADEON_GPIO_CRT2_DDC;
48862306a36Sopenharmony_ci		break;
48962306a36Sopenharmony_ci	}
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci	if (ddc_line == RADEON_GPIOPAD_MASK) {
49262306a36Sopenharmony_ci		i2c.mask_clk_reg = RADEON_GPIOPAD_MASK;
49362306a36Sopenharmony_ci		i2c.mask_data_reg = RADEON_GPIOPAD_MASK;
49462306a36Sopenharmony_ci		i2c.a_clk_reg = RADEON_GPIOPAD_A;
49562306a36Sopenharmony_ci		i2c.a_data_reg = RADEON_GPIOPAD_A;
49662306a36Sopenharmony_ci		i2c.en_clk_reg = RADEON_GPIOPAD_EN;
49762306a36Sopenharmony_ci		i2c.en_data_reg = RADEON_GPIOPAD_EN;
49862306a36Sopenharmony_ci		i2c.y_clk_reg = RADEON_GPIOPAD_Y;
49962306a36Sopenharmony_ci		i2c.y_data_reg = RADEON_GPIOPAD_Y;
50062306a36Sopenharmony_ci	} else if (ddc_line == RADEON_MDGPIO_MASK) {
50162306a36Sopenharmony_ci		i2c.mask_clk_reg = RADEON_MDGPIO_MASK;
50262306a36Sopenharmony_ci		i2c.mask_data_reg = RADEON_MDGPIO_MASK;
50362306a36Sopenharmony_ci		i2c.a_clk_reg = RADEON_MDGPIO_A;
50462306a36Sopenharmony_ci		i2c.a_data_reg = RADEON_MDGPIO_A;
50562306a36Sopenharmony_ci		i2c.en_clk_reg = RADEON_MDGPIO_EN;
50662306a36Sopenharmony_ci		i2c.en_data_reg = RADEON_MDGPIO_EN;
50762306a36Sopenharmony_ci		i2c.y_clk_reg = RADEON_MDGPIO_Y;
50862306a36Sopenharmony_ci		i2c.y_data_reg = RADEON_MDGPIO_Y;
50962306a36Sopenharmony_ci	} else {
51062306a36Sopenharmony_ci		i2c.mask_clk_reg = ddc_line;
51162306a36Sopenharmony_ci		i2c.mask_data_reg = ddc_line;
51262306a36Sopenharmony_ci		i2c.a_clk_reg = ddc_line;
51362306a36Sopenharmony_ci		i2c.a_data_reg = ddc_line;
51462306a36Sopenharmony_ci		i2c.en_clk_reg = ddc_line;
51562306a36Sopenharmony_ci		i2c.en_data_reg = ddc_line;
51662306a36Sopenharmony_ci		i2c.y_clk_reg = ddc_line;
51762306a36Sopenharmony_ci		i2c.y_data_reg = ddc_line;
51862306a36Sopenharmony_ci	}
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci	if (clk_mask && data_mask) {
52162306a36Sopenharmony_ci		/* system specific masks */
52262306a36Sopenharmony_ci		i2c.mask_clk_mask = clk_mask;
52362306a36Sopenharmony_ci		i2c.mask_data_mask = data_mask;
52462306a36Sopenharmony_ci		i2c.a_clk_mask = clk_mask;
52562306a36Sopenharmony_ci		i2c.a_data_mask = data_mask;
52662306a36Sopenharmony_ci		i2c.en_clk_mask = clk_mask;
52762306a36Sopenharmony_ci		i2c.en_data_mask = data_mask;
52862306a36Sopenharmony_ci		i2c.y_clk_mask = clk_mask;
52962306a36Sopenharmony_ci		i2c.y_data_mask = data_mask;
53062306a36Sopenharmony_ci	} else if ((ddc_line == RADEON_GPIOPAD_MASK) ||
53162306a36Sopenharmony_ci		   (ddc_line == RADEON_MDGPIO_MASK)) {
53262306a36Sopenharmony_ci		/* default gpiopad masks */
53362306a36Sopenharmony_ci		i2c.mask_clk_mask = (0x20 << 8);
53462306a36Sopenharmony_ci		i2c.mask_data_mask = 0x80;
53562306a36Sopenharmony_ci		i2c.a_clk_mask = (0x20 << 8);
53662306a36Sopenharmony_ci		i2c.a_data_mask = 0x80;
53762306a36Sopenharmony_ci		i2c.en_clk_mask = (0x20 << 8);
53862306a36Sopenharmony_ci		i2c.en_data_mask = 0x80;
53962306a36Sopenharmony_ci		i2c.y_clk_mask = (0x20 << 8);
54062306a36Sopenharmony_ci		i2c.y_data_mask = 0x80;
54162306a36Sopenharmony_ci	} else {
54262306a36Sopenharmony_ci		/* default masks for ddc pads */
54362306a36Sopenharmony_ci		i2c.mask_clk_mask = RADEON_GPIO_MASK_1;
54462306a36Sopenharmony_ci		i2c.mask_data_mask = RADEON_GPIO_MASK_0;
54562306a36Sopenharmony_ci		i2c.a_clk_mask = RADEON_GPIO_A_1;
54662306a36Sopenharmony_ci		i2c.a_data_mask = RADEON_GPIO_A_0;
54762306a36Sopenharmony_ci		i2c.en_clk_mask = RADEON_GPIO_EN_1;
54862306a36Sopenharmony_ci		i2c.en_data_mask = RADEON_GPIO_EN_0;
54962306a36Sopenharmony_ci		i2c.y_clk_mask = RADEON_GPIO_Y_1;
55062306a36Sopenharmony_ci		i2c.y_data_mask = RADEON_GPIO_Y_0;
55162306a36Sopenharmony_ci	}
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci	switch (rdev->family) {
55462306a36Sopenharmony_ci	case CHIP_R100:
55562306a36Sopenharmony_ci	case CHIP_RV100:
55662306a36Sopenharmony_ci	case CHIP_RS100:
55762306a36Sopenharmony_ci	case CHIP_RV200:
55862306a36Sopenharmony_ci	case CHIP_RS200:
55962306a36Sopenharmony_ci	case CHIP_RS300:
56062306a36Sopenharmony_ci		switch (ddc_line) {
56162306a36Sopenharmony_ci		case RADEON_GPIO_DVI_DDC:
56262306a36Sopenharmony_ci			i2c.hw_capable = true;
56362306a36Sopenharmony_ci			break;
56462306a36Sopenharmony_ci		default:
56562306a36Sopenharmony_ci			i2c.hw_capable = false;
56662306a36Sopenharmony_ci			break;
56762306a36Sopenharmony_ci		}
56862306a36Sopenharmony_ci		break;
56962306a36Sopenharmony_ci	case CHIP_R200:
57062306a36Sopenharmony_ci		switch (ddc_line) {
57162306a36Sopenharmony_ci		case RADEON_GPIO_DVI_DDC:
57262306a36Sopenharmony_ci		case RADEON_GPIO_MONID:
57362306a36Sopenharmony_ci			i2c.hw_capable = true;
57462306a36Sopenharmony_ci			break;
57562306a36Sopenharmony_ci		default:
57662306a36Sopenharmony_ci			i2c.hw_capable = false;
57762306a36Sopenharmony_ci			break;
57862306a36Sopenharmony_ci		}
57962306a36Sopenharmony_ci		break;
58062306a36Sopenharmony_ci	case CHIP_RV250:
58162306a36Sopenharmony_ci	case CHIP_RV280:
58262306a36Sopenharmony_ci		switch (ddc_line) {
58362306a36Sopenharmony_ci		case RADEON_GPIO_VGA_DDC:
58462306a36Sopenharmony_ci		case RADEON_GPIO_DVI_DDC:
58562306a36Sopenharmony_ci		case RADEON_GPIO_CRT2_DDC:
58662306a36Sopenharmony_ci			i2c.hw_capable = true;
58762306a36Sopenharmony_ci			break;
58862306a36Sopenharmony_ci		default:
58962306a36Sopenharmony_ci			i2c.hw_capable = false;
59062306a36Sopenharmony_ci			break;
59162306a36Sopenharmony_ci		}
59262306a36Sopenharmony_ci		break;
59362306a36Sopenharmony_ci	case CHIP_R300:
59462306a36Sopenharmony_ci	case CHIP_R350:
59562306a36Sopenharmony_ci		switch (ddc_line) {
59662306a36Sopenharmony_ci		case RADEON_GPIO_VGA_DDC:
59762306a36Sopenharmony_ci		case RADEON_GPIO_DVI_DDC:
59862306a36Sopenharmony_ci			i2c.hw_capable = true;
59962306a36Sopenharmony_ci			break;
60062306a36Sopenharmony_ci		default:
60162306a36Sopenharmony_ci			i2c.hw_capable = false;
60262306a36Sopenharmony_ci			break;
60362306a36Sopenharmony_ci		}
60462306a36Sopenharmony_ci		break;
60562306a36Sopenharmony_ci	case CHIP_RV350:
60662306a36Sopenharmony_ci	case CHIP_RV380:
60762306a36Sopenharmony_ci	case CHIP_RS400:
60862306a36Sopenharmony_ci	case CHIP_RS480:
60962306a36Sopenharmony_ci		switch (ddc_line) {
61062306a36Sopenharmony_ci		case RADEON_GPIO_VGA_DDC:
61162306a36Sopenharmony_ci		case RADEON_GPIO_DVI_DDC:
61262306a36Sopenharmony_ci			i2c.hw_capable = true;
61362306a36Sopenharmony_ci			break;
61462306a36Sopenharmony_ci		case RADEON_GPIO_MONID:
61562306a36Sopenharmony_ci			/* hw i2c on RADEON_GPIO_MONID doesn't seem to work
61662306a36Sopenharmony_ci			 * reliably on some pre-r4xx hardware; not sure why.
61762306a36Sopenharmony_ci			 */
61862306a36Sopenharmony_ci			i2c.hw_capable = false;
61962306a36Sopenharmony_ci			break;
62062306a36Sopenharmony_ci		default:
62162306a36Sopenharmony_ci			i2c.hw_capable = false;
62262306a36Sopenharmony_ci			break;
62362306a36Sopenharmony_ci		}
62462306a36Sopenharmony_ci		break;
62562306a36Sopenharmony_ci	default:
62662306a36Sopenharmony_ci		i2c.hw_capable = false;
62762306a36Sopenharmony_ci		break;
62862306a36Sopenharmony_ci	}
62962306a36Sopenharmony_ci	i2c.mm_i2c = false;
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci	i2c.i2c_id = ddc;
63262306a36Sopenharmony_ci	i2c.hpd = RADEON_HPD_NONE;
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ci	if (ddc_line)
63562306a36Sopenharmony_ci		i2c.valid = true;
63662306a36Sopenharmony_ci	else
63762306a36Sopenharmony_ci		i2c.valid = false;
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ci	return i2c;
64062306a36Sopenharmony_ci}
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_cistatic struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev)
64362306a36Sopenharmony_ci{
64462306a36Sopenharmony_ci	struct drm_device *dev = rdev->ddev;
64562306a36Sopenharmony_ci	struct radeon_i2c_bus_rec i2c;
64662306a36Sopenharmony_ci	u16 offset;
64762306a36Sopenharmony_ci	u8 id, blocks, clk, data;
64862306a36Sopenharmony_ci	int i;
64962306a36Sopenharmony_ci
65062306a36Sopenharmony_ci	i2c.valid = false;
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_ci	offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE);
65362306a36Sopenharmony_ci	if (offset) {
65462306a36Sopenharmony_ci		blocks = RBIOS8(offset + 2);
65562306a36Sopenharmony_ci		for (i = 0; i < blocks; i++) {
65662306a36Sopenharmony_ci			id = RBIOS8(offset + 3 + (i * 5) + 0);
65762306a36Sopenharmony_ci			if (id == 136) {
65862306a36Sopenharmony_ci				clk = RBIOS8(offset + 3 + (i * 5) + 3);
65962306a36Sopenharmony_ci				data = RBIOS8(offset + 3 + (i * 5) + 4);
66062306a36Sopenharmony_ci				/* gpiopad */
66162306a36Sopenharmony_ci				i2c = combios_setup_i2c_bus(rdev, DDC_MONID,
66262306a36Sopenharmony_ci							    (1 << clk), (1 << data));
66362306a36Sopenharmony_ci				break;
66462306a36Sopenharmony_ci			}
66562306a36Sopenharmony_ci		}
66662306a36Sopenharmony_ci	}
66762306a36Sopenharmony_ci	return i2c;
66862306a36Sopenharmony_ci}
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_civoid radeon_combios_i2c_init(struct radeon_device *rdev)
67162306a36Sopenharmony_ci{
67262306a36Sopenharmony_ci	struct drm_device *dev = rdev->ddev;
67362306a36Sopenharmony_ci	struct radeon_i2c_bus_rec i2c;
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ci	/* actual hw pads
67662306a36Sopenharmony_ci	 * r1xx/rs2xx/rs3xx
67762306a36Sopenharmony_ci	 * 0x60, 0x64, 0x68, 0x6c, gpiopads, mm
67862306a36Sopenharmony_ci	 * r200
67962306a36Sopenharmony_ci	 * 0x60, 0x64, 0x68, mm
68062306a36Sopenharmony_ci	 * r300/r350
68162306a36Sopenharmony_ci	 * 0x60, 0x64, mm
68262306a36Sopenharmony_ci	 * rv2xx/rv3xx/rs4xx
68362306a36Sopenharmony_ci	 * 0x60, 0x64, 0x68, gpiopads, mm
68462306a36Sopenharmony_ci	 */
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ci	/* 0x60 */
68762306a36Sopenharmony_ci	i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
68862306a36Sopenharmony_ci	rdev->i2c_bus[0] = radeon_i2c_create(dev, &i2c, "DVI_DDC");
68962306a36Sopenharmony_ci	/* 0x64 */
69062306a36Sopenharmony_ci	i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
69162306a36Sopenharmony_ci	rdev->i2c_bus[1] = radeon_i2c_create(dev, &i2c, "VGA_DDC");
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_ci	/* mm i2c */
69462306a36Sopenharmony_ci	i2c.valid = true;
69562306a36Sopenharmony_ci	i2c.hw_capable = true;
69662306a36Sopenharmony_ci	i2c.mm_i2c = true;
69762306a36Sopenharmony_ci	i2c.i2c_id = 0xa0;
69862306a36Sopenharmony_ci	rdev->i2c_bus[2] = radeon_i2c_create(dev, &i2c, "MM_I2C");
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci	if (rdev->family == CHIP_R300 ||
70162306a36Sopenharmony_ci	    rdev->family == CHIP_R350) {
70262306a36Sopenharmony_ci		/* only 2 sw i2c pads */
70362306a36Sopenharmony_ci	} else if (rdev->family == CHIP_RS300 ||
70462306a36Sopenharmony_ci		   rdev->family == CHIP_RS400 ||
70562306a36Sopenharmony_ci		   rdev->family == CHIP_RS480) {
70662306a36Sopenharmony_ci		/* 0x68 */
70762306a36Sopenharmony_ci		i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
70862306a36Sopenharmony_ci		rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ci		/* gpiopad */
71162306a36Sopenharmony_ci		i2c = radeon_combios_get_i2c_info_from_table(rdev);
71262306a36Sopenharmony_ci		if (i2c.valid)
71362306a36Sopenharmony_ci			rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK");
71462306a36Sopenharmony_ci	} else if ((rdev->family == CHIP_R200) ||
71562306a36Sopenharmony_ci		   (rdev->family >= CHIP_R300)) {
71662306a36Sopenharmony_ci		/* 0x68 */
71762306a36Sopenharmony_ci		i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
71862306a36Sopenharmony_ci		rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
71962306a36Sopenharmony_ci	} else {
72062306a36Sopenharmony_ci		/* 0x68 */
72162306a36Sopenharmony_ci		i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
72262306a36Sopenharmony_ci		rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
72362306a36Sopenharmony_ci		/* 0x6c */
72462306a36Sopenharmony_ci		i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
72562306a36Sopenharmony_ci		rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "CRT2_DDC");
72662306a36Sopenharmony_ci	}
72762306a36Sopenharmony_ci}
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_cibool radeon_combios_get_clock_info(struct drm_device *dev)
73062306a36Sopenharmony_ci{
73162306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
73262306a36Sopenharmony_ci	uint16_t pll_info;
73362306a36Sopenharmony_ci	struct radeon_pll *p1pll = &rdev->clock.p1pll;
73462306a36Sopenharmony_ci	struct radeon_pll *p2pll = &rdev->clock.p2pll;
73562306a36Sopenharmony_ci	struct radeon_pll *spll = &rdev->clock.spll;
73662306a36Sopenharmony_ci	struct radeon_pll *mpll = &rdev->clock.mpll;
73762306a36Sopenharmony_ci	int8_t rev;
73862306a36Sopenharmony_ci	uint16_t sclk, mclk;
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci	pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE);
74162306a36Sopenharmony_ci	if (pll_info) {
74262306a36Sopenharmony_ci		rev = RBIOS8(pll_info);
74362306a36Sopenharmony_ci
74462306a36Sopenharmony_ci		/* pixel clocks */
74562306a36Sopenharmony_ci		p1pll->reference_freq = RBIOS16(pll_info + 0xe);
74662306a36Sopenharmony_ci		p1pll->reference_div = RBIOS16(pll_info + 0x10);
74762306a36Sopenharmony_ci		p1pll->pll_out_min = RBIOS32(pll_info + 0x12);
74862306a36Sopenharmony_ci		p1pll->pll_out_max = RBIOS32(pll_info + 0x16);
74962306a36Sopenharmony_ci		p1pll->lcd_pll_out_min = p1pll->pll_out_min;
75062306a36Sopenharmony_ci		p1pll->lcd_pll_out_max = p1pll->pll_out_max;
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_ci		if (rev > 9) {
75362306a36Sopenharmony_ci			p1pll->pll_in_min = RBIOS32(pll_info + 0x36);
75462306a36Sopenharmony_ci			p1pll->pll_in_max = RBIOS32(pll_info + 0x3a);
75562306a36Sopenharmony_ci		} else {
75662306a36Sopenharmony_ci			p1pll->pll_in_min = 40;
75762306a36Sopenharmony_ci			p1pll->pll_in_max = 500;
75862306a36Sopenharmony_ci		}
75962306a36Sopenharmony_ci		*p2pll = *p1pll;
76062306a36Sopenharmony_ci
76162306a36Sopenharmony_ci		/* system clock */
76262306a36Sopenharmony_ci		spll->reference_freq = RBIOS16(pll_info + 0x1a);
76362306a36Sopenharmony_ci		spll->reference_div = RBIOS16(pll_info + 0x1c);
76462306a36Sopenharmony_ci		spll->pll_out_min = RBIOS32(pll_info + 0x1e);
76562306a36Sopenharmony_ci		spll->pll_out_max = RBIOS32(pll_info + 0x22);
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_ci		if (rev > 10) {
76862306a36Sopenharmony_ci			spll->pll_in_min = RBIOS32(pll_info + 0x48);
76962306a36Sopenharmony_ci			spll->pll_in_max = RBIOS32(pll_info + 0x4c);
77062306a36Sopenharmony_ci		} else {
77162306a36Sopenharmony_ci			/* ??? */
77262306a36Sopenharmony_ci			spll->pll_in_min = 40;
77362306a36Sopenharmony_ci			spll->pll_in_max = 500;
77462306a36Sopenharmony_ci		}
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_ci		/* memory clock */
77762306a36Sopenharmony_ci		mpll->reference_freq = RBIOS16(pll_info + 0x26);
77862306a36Sopenharmony_ci		mpll->reference_div = RBIOS16(pll_info + 0x28);
77962306a36Sopenharmony_ci		mpll->pll_out_min = RBIOS32(pll_info + 0x2a);
78062306a36Sopenharmony_ci		mpll->pll_out_max = RBIOS32(pll_info + 0x2e);
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ci		if (rev > 10) {
78362306a36Sopenharmony_ci			mpll->pll_in_min = RBIOS32(pll_info + 0x5a);
78462306a36Sopenharmony_ci			mpll->pll_in_max = RBIOS32(pll_info + 0x5e);
78562306a36Sopenharmony_ci		} else {
78662306a36Sopenharmony_ci			/* ??? */
78762306a36Sopenharmony_ci			mpll->pll_in_min = 40;
78862306a36Sopenharmony_ci			mpll->pll_in_max = 500;
78962306a36Sopenharmony_ci		}
79062306a36Sopenharmony_ci
79162306a36Sopenharmony_ci		/* default sclk/mclk */
79262306a36Sopenharmony_ci		sclk = RBIOS16(pll_info + 0xa);
79362306a36Sopenharmony_ci		mclk = RBIOS16(pll_info + 0x8);
79462306a36Sopenharmony_ci		if (sclk == 0)
79562306a36Sopenharmony_ci			sclk = 200 * 100;
79662306a36Sopenharmony_ci		if (mclk == 0)
79762306a36Sopenharmony_ci			mclk = 200 * 100;
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ci		rdev->clock.default_sclk = sclk;
80062306a36Sopenharmony_ci		rdev->clock.default_mclk = mclk;
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci		if (RBIOS32(pll_info + 0x16))
80362306a36Sopenharmony_ci			rdev->clock.max_pixel_clock = RBIOS32(pll_info + 0x16);
80462306a36Sopenharmony_ci		else
80562306a36Sopenharmony_ci			rdev->clock.max_pixel_clock = 35000; /* might need something asic specific */
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_ci		return true;
80862306a36Sopenharmony_ci	}
80962306a36Sopenharmony_ci	return false;
81062306a36Sopenharmony_ci}
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_cibool radeon_combios_sideport_present(struct radeon_device *rdev)
81362306a36Sopenharmony_ci{
81462306a36Sopenharmony_ci	struct drm_device *dev = rdev->ddev;
81562306a36Sopenharmony_ci	u16 igp_info;
81662306a36Sopenharmony_ci
81762306a36Sopenharmony_ci	/* sideport is AMD only */
81862306a36Sopenharmony_ci	if (rdev->family == CHIP_RS400)
81962306a36Sopenharmony_ci		return false;
82062306a36Sopenharmony_ci
82162306a36Sopenharmony_ci	igp_info = combios_get_table_offset(dev, COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE);
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_ci	if (igp_info) {
82462306a36Sopenharmony_ci		if (RBIOS16(igp_info + 0x4))
82562306a36Sopenharmony_ci			return true;
82662306a36Sopenharmony_ci	}
82762306a36Sopenharmony_ci	return false;
82862306a36Sopenharmony_ci}
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_cistatic const uint32_t default_primarydac_adj[CHIP_LAST] = {
83162306a36Sopenharmony_ci	0x00000808,		/* r100  */
83262306a36Sopenharmony_ci	0x00000808,		/* rv100 */
83362306a36Sopenharmony_ci	0x00000808,		/* rs100 */
83462306a36Sopenharmony_ci	0x00000808,		/* rv200 */
83562306a36Sopenharmony_ci	0x00000808,		/* rs200 */
83662306a36Sopenharmony_ci	0x00000808,		/* r200  */
83762306a36Sopenharmony_ci	0x00000808,		/* rv250 */
83862306a36Sopenharmony_ci	0x00000000,		/* rs300 */
83962306a36Sopenharmony_ci	0x00000808,		/* rv280 */
84062306a36Sopenharmony_ci	0x00000808,		/* r300  */
84162306a36Sopenharmony_ci	0x00000808,		/* r350  */
84262306a36Sopenharmony_ci	0x00000808,		/* rv350 */
84362306a36Sopenharmony_ci	0x00000808,		/* rv380 */
84462306a36Sopenharmony_ci	0x00000808,		/* r420  */
84562306a36Sopenharmony_ci	0x00000808,		/* r423  */
84662306a36Sopenharmony_ci	0x00000808,		/* rv410 */
84762306a36Sopenharmony_ci	0x00000000,		/* rs400 */
84862306a36Sopenharmony_ci	0x00000000,		/* rs480 */
84962306a36Sopenharmony_ci};
85062306a36Sopenharmony_ci
85162306a36Sopenharmony_cistatic void radeon_legacy_get_primary_dac_info_from_table(struct radeon_device *rdev,
85262306a36Sopenharmony_ci							  struct radeon_encoder_primary_dac *p_dac)
85362306a36Sopenharmony_ci{
85462306a36Sopenharmony_ci	p_dac->ps2_pdac_adj = default_primarydac_adj[rdev->family];
85562306a36Sopenharmony_ci	return;
85662306a36Sopenharmony_ci}
85762306a36Sopenharmony_ci
85862306a36Sopenharmony_cistruct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct
85962306a36Sopenharmony_ci								       radeon_encoder
86062306a36Sopenharmony_ci								       *encoder)
86162306a36Sopenharmony_ci{
86262306a36Sopenharmony_ci	struct drm_device *dev = encoder->base.dev;
86362306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
86462306a36Sopenharmony_ci	uint16_t dac_info;
86562306a36Sopenharmony_ci	uint8_t rev, bg, dac;
86662306a36Sopenharmony_ci	struct radeon_encoder_primary_dac *p_dac;
86762306a36Sopenharmony_ci	int found = 0;
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_ci	p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac),
87062306a36Sopenharmony_ci			GFP_KERNEL);
87162306a36Sopenharmony_ci
87262306a36Sopenharmony_ci	if (!p_dac)
87362306a36Sopenharmony_ci		return NULL;
87462306a36Sopenharmony_ci
87562306a36Sopenharmony_ci	/* check CRT table */
87662306a36Sopenharmony_ci	dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
87762306a36Sopenharmony_ci	if (dac_info) {
87862306a36Sopenharmony_ci		rev = RBIOS8(dac_info) & 0x3;
87962306a36Sopenharmony_ci		if (rev < 2) {
88062306a36Sopenharmony_ci			bg = RBIOS8(dac_info + 0x2) & 0xf;
88162306a36Sopenharmony_ci			dac = (RBIOS8(dac_info + 0x2) >> 4) & 0xf;
88262306a36Sopenharmony_ci			p_dac->ps2_pdac_adj = (bg << 8) | (dac);
88362306a36Sopenharmony_ci		} else {
88462306a36Sopenharmony_ci			bg = RBIOS8(dac_info + 0x2) & 0xf;
88562306a36Sopenharmony_ci			dac = RBIOS8(dac_info + 0x3) & 0xf;
88662306a36Sopenharmony_ci			p_dac->ps2_pdac_adj = (bg << 8) | (dac);
88762306a36Sopenharmony_ci		}
88862306a36Sopenharmony_ci		/* if the values are zeros, use the table */
88962306a36Sopenharmony_ci		if ((dac == 0) || (bg == 0))
89062306a36Sopenharmony_ci			found = 0;
89162306a36Sopenharmony_ci		else
89262306a36Sopenharmony_ci			found = 1;
89362306a36Sopenharmony_ci	}
89462306a36Sopenharmony_ci
89562306a36Sopenharmony_ci	/* quirks */
89662306a36Sopenharmony_ci	/* Radeon 7000 (RV100) */
89762306a36Sopenharmony_ci	if (((rdev->pdev->device == 0x5159) &&
89862306a36Sopenharmony_ci	    (rdev->pdev->subsystem_vendor == 0x174B) &&
89962306a36Sopenharmony_ci	    (rdev->pdev->subsystem_device == 0x7c28)) ||
90062306a36Sopenharmony_ci	/* Radeon 9100 (R200) */
90162306a36Sopenharmony_ci	   ((rdev->pdev->device == 0x514D) &&
90262306a36Sopenharmony_ci	    (rdev->pdev->subsystem_vendor == 0x174B) &&
90362306a36Sopenharmony_ci	    (rdev->pdev->subsystem_device == 0x7149))) {
90462306a36Sopenharmony_ci		/* vbios value is bad, use the default */
90562306a36Sopenharmony_ci		found = 0;
90662306a36Sopenharmony_ci	}
90762306a36Sopenharmony_ci
90862306a36Sopenharmony_ci	if (!found) /* fallback to defaults */
90962306a36Sopenharmony_ci		radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac);
91062306a36Sopenharmony_ci
91162306a36Sopenharmony_ci	return p_dac;
91262306a36Sopenharmony_ci}
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_cienum radeon_tv_std
91562306a36Sopenharmony_ciradeon_combios_get_tv_info(struct radeon_device *rdev)
91662306a36Sopenharmony_ci{
91762306a36Sopenharmony_ci	struct drm_device *dev = rdev->ddev;
91862306a36Sopenharmony_ci	uint16_t tv_info;
91962306a36Sopenharmony_ci	enum radeon_tv_std tv_std = TV_STD_NTSC;
92062306a36Sopenharmony_ci
92162306a36Sopenharmony_ci	tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
92262306a36Sopenharmony_ci	if (tv_info) {
92362306a36Sopenharmony_ci		if (RBIOS8(tv_info + 6) == 'T') {
92462306a36Sopenharmony_ci			switch (RBIOS8(tv_info + 7) & 0xf) {
92562306a36Sopenharmony_ci			case 1:
92662306a36Sopenharmony_ci				tv_std = TV_STD_NTSC;
92762306a36Sopenharmony_ci				DRM_DEBUG_KMS("Default TV standard: NTSC\n");
92862306a36Sopenharmony_ci				break;
92962306a36Sopenharmony_ci			case 2:
93062306a36Sopenharmony_ci				tv_std = TV_STD_PAL;
93162306a36Sopenharmony_ci				DRM_DEBUG_KMS("Default TV standard: PAL\n");
93262306a36Sopenharmony_ci				break;
93362306a36Sopenharmony_ci			case 3:
93462306a36Sopenharmony_ci				tv_std = TV_STD_PAL_M;
93562306a36Sopenharmony_ci				DRM_DEBUG_KMS("Default TV standard: PAL-M\n");
93662306a36Sopenharmony_ci				break;
93762306a36Sopenharmony_ci			case 4:
93862306a36Sopenharmony_ci				tv_std = TV_STD_PAL_60;
93962306a36Sopenharmony_ci				DRM_DEBUG_KMS("Default TV standard: PAL-60\n");
94062306a36Sopenharmony_ci				break;
94162306a36Sopenharmony_ci			case 5:
94262306a36Sopenharmony_ci				tv_std = TV_STD_NTSC_J;
94362306a36Sopenharmony_ci				DRM_DEBUG_KMS("Default TV standard: NTSC-J\n");
94462306a36Sopenharmony_ci				break;
94562306a36Sopenharmony_ci			case 6:
94662306a36Sopenharmony_ci				tv_std = TV_STD_SCART_PAL;
94762306a36Sopenharmony_ci				DRM_DEBUG_KMS("Default TV standard: SCART-PAL\n");
94862306a36Sopenharmony_ci				break;
94962306a36Sopenharmony_ci			default:
95062306a36Sopenharmony_ci				tv_std = TV_STD_NTSC;
95162306a36Sopenharmony_ci				DRM_DEBUG_KMS
95262306a36Sopenharmony_ci				    ("Unknown TV standard; defaulting to NTSC\n");
95362306a36Sopenharmony_ci				break;
95462306a36Sopenharmony_ci			}
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_ci			switch ((RBIOS8(tv_info + 9) >> 2) & 0x3) {
95762306a36Sopenharmony_ci			case 0:
95862306a36Sopenharmony_ci				DRM_DEBUG_KMS("29.498928713 MHz TV ref clk\n");
95962306a36Sopenharmony_ci				break;
96062306a36Sopenharmony_ci			case 1:
96162306a36Sopenharmony_ci				DRM_DEBUG_KMS("28.636360000 MHz TV ref clk\n");
96262306a36Sopenharmony_ci				break;
96362306a36Sopenharmony_ci			case 2:
96462306a36Sopenharmony_ci				DRM_DEBUG_KMS("14.318180000 MHz TV ref clk\n");
96562306a36Sopenharmony_ci				break;
96662306a36Sopenharmony_ci			case 3:
96762306a36Sopenharmony_ci				DRM_DEBUG_KMS("27.000000000 MHz TV ref clk\n");
96862306a36Sopenharmony_ci				break;
96962306a36Sopenharmony_ci			default:
97062306a36Sopenharmony_ci				break;
97162306a36Sopenharmony_ci			}
97262306a36Sopenharmony_ci		}
97362306a36Sopenharmony_ci	}
97462306a36Sopenharmony_ci	return tv_std;
97562306a36Sopenharmony_ci}
97662306a36Sopenharmony_ci
97762306a36Sopenharmony_cistatic const uint32_t default_tvdac_adj[CHIP_LAST] = {
97862306a36Sopenharmony_ci	0x00000000,		/* r100  */
97962306a36Sopenharmony_ci	0x00280000,		/* rv100 */
98062306a36Sopenharmony_ci	0x00000000,		/* rs100 */
98162306a36Sopenharmony_ci	0x00880000,		/* rv200 */
98262306a36Sopenharmony_ci	0x00000000,		/* rs200 */
98362306a36Sopenharmony_ci	0x00000000,		/* r200  */
98462306a36Sopenharmony_ci	0x00770000,		/* rv250 */
98562306a36Sopenharmony_ci	0x00290000,		/* rs300 */
98662306a36Sopenharmony_ci	0x00560000,		/* rv280 */
98762306a36Sopenharmony_ci	0x00780000,		/* r300  */
98862306a36Sopenharmony_ci	0x00770000,		/* r350  */
98962306a36Sopenharmony_ci	0x00780000,		/* rv350 */
99062306a36Sopenharmony_ci	0x00780000,		/* rv380 */
99162306a36Sopenharmony_ci	0x01080000,		/* r420  */
99262306a36Sopenharmony_ci	0x01080000,		/* r423  */
99362306a36Sopenharmony_ci	0x01080000,		/* rv410 */
99462306a36Sopenharmony_ci	0x00780000,		/* rs400 */
99562306a36Sopenharmony_ci	0x00780000,		/* rs480 */
99662306a36Sopenharmony_ci};
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_cistatic void radeon_legacy_get_tv_dac_info_from_table(struct radeon_device *rdev,
99962306a36Sopenharmony_ci						     struct radeon_encoder_tv_dac *tv_dac)
100062306a36Sopenharmony_ci{
100162306a36Sopenharmony_ci	tv_dac->ps2_tvdac_adj = default_tvdac_adj[rdev->family];
100262306a36Sopenharmony_ci	if ((rdev->flags & RADEON_IS_MOBILITY) && (rdev->family == CHIP_RV250))
100362306a36Sopenharmony_ci		tv_dac->ps2_tvdac_adj = 0x00880000;
100462306a36Sopenharmony_ci	tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
100562306a36Sopenharmony_ci	tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
100662306a36Sopenharmony_ci	return;
100762306a36Sopenharmony_ci}
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_cistruct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
101062306a36Sopenharmony_ci							     radeon_encoder
101162306a36Sopenharmony_ci							     *encoder)
101262306a36Sopenharmony_ci{
101362306a36Sopenharmony_ci	struct drm_device *dev = encoder->base.dev;
101462306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
101562306a36Sopenharmony_ci	uint16_t dac_info;
101662306a36Sopenharmony_ci	uint8_t rev, bg, dac;
101762306a36Sopenharmony_ci	struct radeon_encoder_tv_dac *tv_dac;
101862306a36Sopenharmony_ci	int found = 0;
101962306a36Sopenharmony_ci
102062306a36Sopenharmony_ci	tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL);
102162306a36Sopenharmony_ci	if (!tv_dac)
102262306a36Sopenharmony_ci		return NULL;
102362306a36Sopenharmony_ci
102462306a36Sopenharmony_ci	/* first check TV table */
102562306a36Sopenharmony_ci	dac_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
102662306a36Sopenharmony_ci	if (dac_info) {
102762306a36Sopenharmony_ci		rev = RBIOS8(dac_info + 0x3);
102862306a36Sopenharmony_ci		if (rev > 4) {
102962306a36Sopenharmony_ci			bg = RBIOS8(dac_info + 0xc) & 0xf;
103062306a36Sopenharmony_ci			dac = RBIOS8(dac_info + 0xd) & 0xf;
103162306a36Sopenharmony_ci			tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
103262306a36Sopenharmony_ci
103362306a36Sopenharmony_ci			bg = RBIOS8(dac_info + 0xe) & 0xf;
103462306a36Sopenharmony_ci			dac = RBIOS8(dac_info + 0xf) & 0xf;
103562306a36Sopenharmony_ci			tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20);
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_ci			bg = RBIOS8(dac_info + 0x10) & 0xf;
103862306a36Sopenharmony_ci			dac = RBIOS8(dac_info + 0x11) & 0xf;
103962306a36Sopenharmony_ci			tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
104062306a36Sopenharmony_ci			/* if the values are all zeros, use the table */
104162306a36Sopenharmony_ci			if (tv_dac->ps2_tvdac_adj)
104262306a36Sopenharmony_ci				found = 1;
104362306a36Sopenharmony_ci		} else if (rev > 1) {
104462306a36Sopenharmony_ci			bg = RBIOS8(dac_info + 0xc) & 0xf;
104562306a36Sopenharmony_ci			dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf;
104662306a36Sopenharmony_ci			tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
104762306a36Sopenharmony_ci
104862306a36Sopenharmony_ci			bg = RBIOS8(dac_info + 0xd) & 0xf;
104962306a36Sopenharmony_ci			dac = (RBIOS8(dac_info + 0xd) >> 4) & 0xf;
105062306a36Sopenharmony_ci			tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20);
105162306a36Sopenharmony_ci
105262306a36Sopenharmony_ci			bg = RBIOS8(dac_info + 0xe) & 0xf;
105362306a36Sopenharmony_ci			dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf;
105462306a36Sopenharmony_ci			tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
105562306a36Sopenharmony_ci			/* if the values are all zeros, use the table */
105662306a36Sopenharmony_ci			if (tv_dac->ps2_tvdac_adj)
105762306a36Sopenharmony_ci				found = 1;
105862306a36Sopenharmony_ci		}
105962306a36Sopenharmony_ci		tv_dac->tv_std = radeon_combios_get_tv_info(rdev);
106062306a36Sopenharmony_ci	}
106162306a36Sopenharmony_ci	if (!found) {
106262306a36Sopenharmony_ci		/* then check CRT table */
106362306a36Sopenharmony_ci		dac_info =
106462306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
106562306a36Sopenharmony_ci		if (dac_info) {
106662306a36Sopenharmony_ci			rev = RBIOS8(dac_info) & 0x3;
106762306a36Sopenharmony_ci			if (rev < 2) {
106862306a36Sopenharmony_ci				bg = RBIOS8(dac_info + 0x3) & 0xf;
106962306a36Sopenharmony_ci				dac = (RBIOS8(dac_info + 0x3) >> 4) & 0xf;
107062306a36Sopenharmony_ci				tv_dac->ps2_tvdac_adj =
107162306a36Sopenharmony_ci				    (bg << 16) | (dac << 20);
107262306a36Sopenharmony_ci				tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
107362306a36Sopenharmony_ci				tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
107462306a36Sopenharmony_ci				/* if the values are all zeros, use the table */
107562306a36Sopenharmony_ci				if (tv_dac->ps2_tvdac_adj)
107662306a36Sopenharmony_ci					found = 1;
107762306a36Sopenharmony_ci			} else {
107862306a36Sopenharmony_ci				bg = RBIOS8(dac_info + 0x4) & 0xf;
107962306a36Sopenharmony_ci				dac = RBIOS8(dac_info + 0x5) & 0xf;
108062306a36Sopenharmony_ci				tv_dac->ps2_tvdac_adj =
108162306a36Sopenharmony_ci				    (bg << 16) | (dac << 20);
108262306a36Sopenharmony_ci				tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
108362306a36Sopenharmony_ci				tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
108462306a36Sopenharmony_ci				/* if the values are all zeros, use the table */
108562306a36Sopenharmony_ci				if (tv_dac->ps2_tvdac_adj)
108662306a36Sopenharmony_ci					found = 1;
108762306a36Sopenharmony_ci			}
108862306a36Sopenharmony_ci		} else {
108962306a36Sopenharmony_ci			DRM_INFO("No TV DAC info found in BIOS\n");
109062306a36Sopenharmony_ci		}
109162306a36Sopenharmony_ci	}
109262306a36Sopenharmony_ci
109362306a36Sopenharmony_ci	if (!found) /* fallback to defaults */
109462306a36Sopenharmony_ci		radeon_legacy_get_tv_dac_info_from_table(rdev, tv_dac);
109562306a36Sopenharmony_ci
109662306a36Sopenharmony_ci	return tv_dac;
109762306a36Sopenharmony_ci}
109862306a36Sopenharmony_ci
109962306a36Sopenharmony_cistatic struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct
110062306a36Sopenharmony_ci									 radeon_device
110162306a36Sopenharmony_ci									 *rdev)
110262306a36Sopenharmony_ci{
110362306a36Sopenharmony_ci	struct radeon_encoder_lvds *lvds;
110462306a36Sopenharmony_ci	uint32_t fp_vert_stretch, fp_horz_stretch;
110562306a36Sopenharmony_ci	uint32_t ppll_div_sel, ppll_val;
110662306a36Sopenharmony_ci	uint32_t lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL);
110762306a36Sopenharmony_ci
110862306a36Sopenharmony_ci	lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL);
110962306a36Sopenharmony_ci
111062306a36Sopenharmony_ci	if (!lvds)
111162306a36Sopenharmony_ci		return NULL;
111262306a36Sopenharmony_ci
111362306a36Sopenharmony_ci	fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH);
111462306a36Sopenharmony_ci	fp_horz_stretch = RREG32(RADEON_FP_HORZ_STRETCH);
111562306a36Sopenharmony_ci
111662306a36Sopenharmony_ci	/* These should be fail-safe defaults, fingers crossed */
111762306a36Sopenharmony_ci	lvds->panel_pwr_delay = 200;
111862306a36Sopenharmony_ci	lvds->panel_vcc_delay = 2000;
111962306a36Sopenharmony_ci
112062306a36Sopenharmony_ci	lvds->lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
112162306a36Sopenharmony_ci	lvds->panel_digon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) & 0xf;
112262306a36Sopenharmony_ci	lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf;
112362306a36Sopenharmony_ci
112462306a36Sopenharmony_ci	if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE)
112562306a36Sopenharmony_ci		lvds->native_mode.vdisplay =
112662306a36Sopenharmony_ci		    ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >>
112762306a36Sopenharmony_ci		     RADEON_VERT_PANEL_SHIFT) + 1;
112862306a36Sopenharmony_ci	else
112962306a36Sopenharmony_ci		lvds->native_mode.vdisplay =
113062306a36Sopenharmony_ci		    (RREG32(RADEON_CRTC_V_TOTAL_DISP) >> 16) + 1;
113162306a36Sopenharmony_ci
113262306a36Sopenharmony_ci	if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE)
113362306a36Sopenharmony_ci		lvds->native_mode.hdisplay =
113462306a36Sopenharmony_ci		    (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >>
113562306a36Sopenharmony_ci		      RADEON_HORZ_PANEL_SHIFT) + 1) * 8;
113662306a36Sopenharmony_ci	else
113762306a36Sopenharmony_ci		lvds->native_mode.hdisplay =
113862306a36Sopenharmony_ci		    ((RREG32(RADEON_CRTC_H_TOTAL_DISP) >> 16) + 1) * 8;
113962306a36Sopenharmony_ci
114062306a36Sopenharmony_ci	if ((lvds->native_mode.hdisplay < 640) ||
114162306a36Sopenharmony_ci	    (lvds->native_mode.vdisplay < 480)) {
114262306a36Sopenharmony_ci		lvds->native_mode.hdisplay = 640;
114362306a36Sopenharmony_ci		lvds->native_mode.vdisplay = 480;
114462306a36Sopenharmony_ci	}
114562306a36Sopenharmony_ci
114662306a36Sopenharmony_ci	ppll_div_sel = RREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
114762306a36Sopenharmony_ci	ppll_val = RREG32_PLL(RADEON_PPLL_DIV_0 + ppll_div_sel);
114862306a36Sopenharmony_ci	if ((ppll_val & 0x000707ff) == 0x1bb)
114962306a36Sopenharmony_ci		lvds->use_bios_dividers = false;
115062306a36Sopenharmony_ci	else {
115162306a36Sopenharmony_ci		lvds->panel_ref_divider =
115262306a36Sopenharmony_ci		    RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff;
115362306a36Sopenharmony_ci		lvds->panel_post_divider = (ppll_val >> 16) & 0x7;
115462306a36Sopenharmony_ci		lvds->panel_fb_divider = ppll_val & 0x7ff;
115562306a36Sopenharmony_ci
115662306a36Sopenharmony_ci		if ((lvds->panel_ref_divider != 0) &&
115762306a36Sopenharmony_ci		    (lvds->panel_fb_divider > 3))
115862306a36Sopenharmony_ci			lvds->use_bios_dividers = true;
115962306a36Sopenharmony_ci	}
116062306a36Sopenharmony_ci	lvds->panel_vcc_delay = 200;
116162306a36Sopenharmony_ci
116262306a36Sopenharmony_ci	DRM_INFO("Panel info derived from registers\n");
116362306a36Sopenharmony_ci	DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay,
116462306a36Sopenharmony_ci		 lvds->native_mode.vdisplay);
116562306a36Sopenharmony_ci
116662306a36Sopenharmony_ci	return lvds;
116762306a36Sopenharmony_ci}
116862306a36Sopenharmony_ci
116962306a36Sopenharmony_cistruct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
117062306a36Sopenharmony_ci							 *encoder)
117162306a36Sopenharmony_ci{
117262306a36Sopenharmony_ci	struct drm_device *dev = encoder->base.dev;
117362306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
117462306a36Sopenharmony_ci	uint16_t lcd_info;
117562306a36Sopenharmony_ci	uint32_t panel_setup;
117662306a36Sopenharmony_ci	char stmp[30];
117762306a36Sopenharmony_ci	int tmp, i;
117862306a36Sopenharmony_ci	struct radeon_encoder_lvds *lvds = NULL;
117962306a36Sopenharmony_ci
118062306a36Sopenharmony_ci	lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
118162306a36Sopenharmony_ci
118262306a36Sopenharmony_ci	if (lcd_info) {
118362306a36Sopenharmony_ci		lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL);
118462306a36Sopenharmony_ci
118562306a36Sopenharmony_ci		if (!lvds)
118662306a36Sopenharmony_ci			return NULL;
118762306a36Sopenharmony_ci
118862306a36Sopenharmony_ci		for (i = 0; i < 24; i++)
118962306a36Sopenharmony_ci			stmp[i] = RBIOS8(lcd_info + i + 1);
119062306a36Sopenharmony_ci		stmp[24] = 0;
119162306a36Sopenharmony_ci
119262306a36Sopenharmony_ci		DRM_INFO("Panel ID String: %s\n", stmp);
119362306a36Sopenharmony_ci
119462306a36Sopenharmony_ci		lvds->native_mode.hdisplay = RBIOS16(lcd_info + 0x19);
119562306a36Sopenharmony_ci		lvds->native_mode.vdisplay = RBIOS16(lcd_info + 0x1b);
119662306a36Sopenharmony_ci
119762306a36Sopenharmony_ci		DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay,
119862306a36Sopenharmony_ci			 lvds->native_mode.vdisplay);
119962306a36Sopenharmony_ci
120062306a36Sopenharmony_ci		lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c);
120162306a36Sopenharmony_ci		lvds->panel_vcc_delay = min_t(u16, lvds->panel_vcc_delay, 2000);
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_ci		lvds->panel_pwr_delay = RBIOS8(lcd_info + 0x24);
120462306a36Sopenharmony_ci		lvds->panel_digon_delay = RBIOS16(lcd_info + 0x38) & 0xf;
120562306a36Sopenharmony_ci		lvds->panel_blon_delay = (RBIOS16(lcd_info + 0x38) >> 4) & 0xf;
120662306a36Sopenharmony_ci
120762306a36Sopenharmony_ci		lvds->panel_ref_divider = RBIOS16(lcd_info + 0x2e);
120862306a36Sopenharmony_ci		lvds->panel_post_divider = RBIOS8(lcd_info + 0x30);
120962306a36Sopenharmony_ci		lvds->panel_fb_divider = RBIOS16(lcd_info + 0x31);
121062306a36Sopenharmony_ci		if ((lvds->panel_ref_divider != 0) &&
121162306a36Sopenharmony_ci		    (lvds->panel_fb_divider > 3))
121262306a36Sopenharmony_ci			lvds->use_bios_dividers = true;
121362306a36Sopenharmony_ci
121462306a36Sopenharmony_ci		panel_setup = RBIOS32(lcd_info + 0x39);
121562306a36Sopenharmony_ci		lvds->lvds_gen_cntl = 0xff00;
121662306a36Sopenharmony_ci		if (panel_setup & 0x1)
121762306a36Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_PANEL_FORMAT;
121862306a36Sopenharmony_ci
121962306a36Sopenharmony_ci		if ((panel_setup >> 4) & 0x1)
122062306a36Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_PANEL_TYPE;
122162306a36Sopenharmony_ci
122262306a36Sopenharmony_ci		switch ((panel_setup >> 8) & 0x7) {
122362306a36Sopenharmony_ci		case 0:
122462306a36Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_NO_FM;
122562306a36Sopenharmony_ci			break;
122662306a36Sopenharmony_ci		case 1:
122762306a36Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_2_GREY;
122862306a36Sopenharmony_ci			break;
122962306a36Sopenharmony_ci		case 2:
123062306a36Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_4_GREY;
123162306a36Sopenharmony_ci			break;
123262306a36Sopenharmony_ci		default:
123362306a36Sopenharmony_ci			break;
123462306a36Sopenharmony_ci		}
123562306a36Sopenharmony_ci
123662306a36Sopenharmony_ci		if ((panel_setup >> 16) & 0x1)
123762306a36Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_FP_POL_LOW;
123862306a36Sopenharmony_ci
123962306a36Sopenharmony_ci		if ((panel_setup >> 17) & 0x1)
124062306a36Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_LP_POL_LOW;
124162306a36Sopenharmony_ci
124262306a36Sopenharmony_ci		if ((panel_setup >> 18) & 0x1)
124362306a36Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_DTM_POL_LOW;
124462306a36Sopenharmony_ci
124562306a36Sopenharmony_ci		if ((panel_setup >> 23) & 0x1)
124662306a36Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_BL_CLK_SEL;
124762306a36Sopenharmony_ci
124862306a36Sopenharmony_ci		lvds->lvds_gen_cntl |= (panel_setup & 0xf0000000);
124962306a36Sopenharmony_ci
125062306a36Sopenharmony_ci		for (i = 0; i < 32; i++) {
125162306a36Sopenharmony_ci			tmp = RBIOS16(lcd_info + 64 + i * 2);
125262306a36Sopenharmony_ci			if (tmp == 0)
125362306a36Sopenharmony_ci				break;
125462306a36Sopenharmony_ci
125562306a36Sopenharmony_ci			if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) &&
125662306a36Sopenharmony_ci			    (RBIOS16(tmp + 2) == lvds->native_mode.vdisplay)) {
125762306a36Sopenharmony_ci				u32 hss = (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - 1) * 8;
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ci				if (hss > lvds->native_mode.hdisplay)
126062306a36Sopenharmony_ci					hss = (10 - 1) * 8;
126162306a36Sopenharmony_ci
126262306a36Sopenharmony_ci				lvds->native_mode.htotal = lvds->native_mode.hdisplay +
126362306a36Sopenharmony_ci					(RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8;
126462306a36Sopenharmony_ci				lvds->native_mode.hsync_start = lvds->native_mode.hdisplay +
126562306a36Sopenharmony_ci					hss;
126662306a36Sopenharmony_ci				lvds->native_mode.hsync_end = lvds->native_mode.hsync_start +
126762306a36Sopenharmony_ci					(RBIOS8(tmp + 23) * 8);
126862306a36Sopenharmony_ci
126962306a36Sopenharmony_ci				lvds->native_mode.vtotal = lvds->native_mode.vdisplay +
127062306a36Sopenharmony_ci					(RBIOS16(tmp + 24) - RBIOS16(tmp + 26));
127162306a36Sopenharmony_ci				lvds->native_mode.vsync_start = lvds->native_mode.vdisplay +
127262306a36Sopenharmony_ci					((RBIOS16(tmp + 28) & 0x7ff) - RBIOS16(tmp + 26));
127362306a36Sopenharmony_ci				lvds->native_mode.vsync_end = lvds->native_mode.vsync_start +
127462306a36Sopenharmony_ci					((RBIOS16(tmp + 28) & 0xf800) >> 11);
127562306a36Sopenharmony_ci
127662306a36Sopenharmony_ci				lvds->native_mode.clock = RBIOS16(tmp + 9) * 10;
127762306a36Sopenharmony_ci				lvds->native_mode.flags = 0;
127862306a36Sopenharmony_ci				/* set crtc values */
127962306a36Sopenharmony_ci				drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
128062306a36Sopenharmony_ci
128162306a36Sopenharmony_ci			}
128262306a36Sopenharmony_ci		}
128362306a36Sopenharmony_ci	} else {
128462306a36Sopenharmony_ci		DRM_INFO("No panel info found in BIOS\n");
128562306a36Sopenharmony_ci		lvds = radeon_legacy_get_lvds_info_from_regs(rdev);
128662306a36Sopenharmony_ci	}
128762306a36Sopenharmony_ci
128862306a36Sopenharmony_ci	if (lvds)
128962306a36Sopenharmony_ci		encoder->native_mode = lvds->native_mode;
129062306a36Sopenharmony_ci	return lvds;
129162306a36Sopenharmony_ci}
129262306a36Sopenharmony_ci
129362306a36Sopenharmony_cistatic const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = {
129462306a36Sopenharmony_ci	{{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/* CHIP_R100  */
129562306a36Sopenharmony_ci	{{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/* CHIP_RV100 */
129662306a36Sopenharmony_ci	{{0, 0}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_RS100 */
129762306a36Sopenharmony_ci	{{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/* CHIP_RV200 */
129862306a36Sopenharmony_ci	{{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/* CHIP_RS200 */
129962306a36Sopenharmony_ci	{{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/* CHIP_R200  */
130062306a36Sopenharmony_ci	{{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}},	/* CHIP_RV250 */
130162306a36Sopenharmony_ci	{{0, 0}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_RS300 */
130262306a36Sopenharmony_ci	{{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}},	/* CHIP_RV280 */
130362306a36Sopenharmony_ci	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_R300  */
130462306a36Sopenharmony_ci	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_R350  */
130562306a36Sopenharmony_ci	{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/* CHIP_RV350 */
130662306a36Sopenharmony_ci	{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/* CHIP_RV380 */
130762306a36Sopenharmony_ci	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_R420  */
130862306a36Sopenharmony_ci	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_R423  */
130962306a36Sopenharmony_ci	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_RV410 */
131062306a36Sopenharmony_ci	{ {0, 0}, {0, 0}, {0, 0}, {0, 0} },	/* CHIP_RS400 */
131162306a36Sopenharmony_ci	{ {0, 0}, {0, 0}, {0, 0}, {0, 0} },	/* CHIP_RS480 */
131262306a36Sopenharmony_ci};
131362306a36Sopenharmony_ci
131462306a36Sopenharmony_cibool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
131562306a36Sopenharmony_ci					    struct radeon_encoder_int_tmds *tmds)
131662306a36Sopenharmony_ci{
131762306a36Sopenharmony_ci	struct drm_device *dev = encoder->base.dev;
131862306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
131962306a36Sopenharmony_ci	int i;
132062306a36Sopenharmony_ci
132162306a36Sopenharmony_ci	for (i = 0; i < 4; i++) {
132262306a36Sopenharmony_ci		tmds->tmds_pll[i].value =
132362306a36Sopenharmony_ci			default_tmds_pll[rdev->family][i].value;
132462306a36Sopenharmony_ci		tmds->tmds_pll[i].freq = default_tmds_pll[rdev->family][i].freq;
132562306a36Sopenharmony_ci	}
132662306a36Sopenharmony_ci
132762306a36Sopenharmony_ci	return true;
132862306a36Sopenharmony_ci}
132962306a36Sopenharmony_ci
133062306a36Sopenharmony_cibool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
133162306a36Sopenharmony_ci					      struct radeon_encoder_int_tmds *tmds)
133262306a36Sopenharmony_ci{
133362306a36Sopenharmony_ci	struct drm_device *dev = encoder->base.dev;
133462306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
133562306a36Sopenharmony_ci	uint16_t tmds_info;
133662306a36Sopenharmony_ci	int i, n;
133762306a36Sopenharmony_ci	uint8_t ver;
133862306a36Sopenharmony_ci
133962306a36Sopenharmony_ci	tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
134062306a36Sopenharmony_ci
134162306a36Sopenharmony_ci	if (tmds_info) {
134262306a36Sopenharmony_ci		ver = RBIOS8(tmds_info);
134362306a36Sopenharmony_ci		DRM_DEBUG_KMS("DFP table revision: %d\n", ver);
134462306a36Sopenharmony_ci		if (ver == 3) {
134562306a36Sopenharmony_ci			n = RBIOS8(tmds_info + 5) + 1;
134662306a36Sopenharmony_ci			if (n > 4)
134762306a36Sopenharmony_ci				n = 4;
134862306a36Sopenharmony_ci			for (i = 0; i < n; i++) {
134962306a36Sopenharmony_ci				tmds->tmds_pll[i].value =
135062306a36Sopenharmony_ci				    RBIOS32(tmds_info + i * 10 + 0x08);
135162306a36Sopenharmony_ci				tmds->tmds_pll[i].freq =
135262306a36Sopenharmony_ci				    RBIOS16(tmds_info + i * 10 + 0x10);
135362306a36Sopenharmony_ci				DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n",
135462306a36Sopenharmony_ci					  tmds->tmds_pll[i].freq,
135562306a36Sopenharmony_ci					  tmds->tmds_pll[i].value);
135662306a36Sopenharmony_ci			}
135762306a36Sopenharmony_ci		} else if (ver == 4) {
135862306a36Sopenharmony_ci			int stride = 0;
135962306a36Sopenharmony_ci			n = RBIOS8(tmds_info + 5) + 1;
136062306a36Sopenharmony_ci			if (n > 4)
136162306a36Sopenharmony_ci				n = 4;
136262306a36Sopenharmony_ci			for (i = 0; i < n; i++) {
136362306a36Sopenharmony_ci				tmds->tmds_pll[i].value =
136462306a36Sopenharmony_ci				    RBIOS32(tmds_info + stride + 0x08);
136562306a36Sopenharmony_ci				tmds->tmds_pll[i].freq =
136662306a36Sopenharmony_ci				    RBIOS16(tmds_info + stride + 0x10);
136762306a36Sopenharmony_ci				if (i == 0)
136862306a36Sopenharmony_ci					stride += 10;
136962306a36Sopenharmony_ci				else
137062306a36Sopenharmony_ci					stride += 6;
137162306a36Sopenharmony_ci				DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n",
137262306a36Sopenharmony_ci					  tmds->tmds_pll[i].freq,
137362306a36Sopenharmony_ci					  tmds->tmds_pll[i].value);
137462306a36Sopenharmony_ci			}
137562306a36Sopenharmony_ci		}
137662306a36Sopenharmony_ci	} else {
137762306a36Sopenharmony_ci		DRM_INFO("No TMDS info found in BIOS\n");
137862306a36Sopenharmony_ci		return false;
137962306a36Sopenharmony_ci	}
138062306a36Sopenharmony_ci	return true;
138162306a36Sopenharmony_ci}
138262306a36Sopenharmony_ci
138362306a36Sopenharmony_cibool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
138462306a36Sopenharmony_ci						struct radeon_encoder_ext_tmds *tmds)
138562306a36Sopenharmony_ci{
138662306a36Sopenharmony_ci	struct drm_device *dev = encoder->base.dev;
138762306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
138862306a36Sopenharmony_ci	struct radeon_i2c_bus_rec i2c_bus;
138962306a36Sopenharmony_ci
139062306a36Sopenharmony_ci	/* default for macs */
139162306a36Sopenharmony_ci	i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
139262306a36Sopenharmony_ci	tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
139362306a36Sopenharmony_ci
139462306a36Sopenharmony_ci	/* XXX some macs have duallink chips */
139562306a36Sopenharmony_ci	switch (rdev->mode_info.connector_table) {
139662306a36Sopenharmony_ci	case CT_POWERBOOK_EXTERNAL:
139762306a36Sopenharmony_ci	case CT_MINI_EXTERNAL:
139862306a36Sopenharmony_ci	default:
139962306a36Sopenharmony_ci		tmds->dvo_chip = DVO_SIL164;
140062306a36Sopenharmony_ci		tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
140162306a36Sopenharmony_ci		break;
140262306a36Sopenharmony_ci	}
140362306a36Sopenharmony_ci
140462306a36Sopenharmony_ci	return true;
140562306a36Sopenharmony_ci}
140662306a36Sopenharmony_ci
140762306a36Sopenharmony_cibool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
140862306a36Sopenharmony_ci						  struct radeon_encoder_ext_tmds *tmds)
140962306a36Sopenharmony_ci{
141062306a36Sopenharmony_ci	struct drm_device *dev = encoder->base.dev;
141162306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
141262306a36Sopenharmony_ci	uint16_t offset;
141362306a36Sopenharmony_ci	uint8_t ver;
141462306a36Sopenharmony_ci	enum radeon_combios_ddc gpio;
141562306a36Sopenharmony_ci	struct radeon_i2c_bus_rec i2c_bus;
141662306a36Sopenharmony_ci
141762306a36Sopenharmony_ci	tmds->i2c_bus = NULL;
141862306a36Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP) {
141962306a36Sopenharmony_ci		i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
142062306a36Sopenharmony_ci		tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
142162306a36Sopenharmony_ci		tmds->dvo_chip = DVO_SIL164;
142262306a36Sopenharmony_ci		tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
142362306a36Sopenharmony_ci	} else {
142462306a36Sopenharmony_ci		offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
142562306a36Sopenharmony_ci		if (offset) {
142662306a36Sopenharmony_ci			ver = RBIOS8(offset);
142762306a36Sopenharmony_ci			DRM_DEBUG_KMS("External TMDS Table revision: %d\n", ver);
142862306a36Sopenharmony_ci			tmds->slave_addr = RBIOS8(offset + 4 + 2);
142962306a36Sopenharmony_ci			tmds->slave_addr >>= 1; /* 7 bit addressing */
143062306a36Sopenharmony_ci			gpio = RBIOS8(offset + 4 + 3);
143162306a36Sopenharmony_ci			if (gpio == DDC_LCD) {
143262306a36Sopenharmony_ci				/* MM i2c */
143362306a36Sopenharmony_ci				i2c_bus.valid = true;
143462306a36Sopenharmony_ci				i2c_bus.hw_capable = true;
143562306a36Sopenharmony_ci				i2c_bus.mm_i2c = true;
143662306a36Sopenharmony_ci				i2c_bus.i2c_id = 0xa0;
143762306a36Sopenharmony_ci			} else
143862306a36Sopenharmony_ci				i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0);
143962306a36Sopenharmony_ci			tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
144062306a36Sopenharmony_ci		}
144162306a36Sopenharmony_ci	}
144262306a36Sopenharmony_ci
144362306a36Sopenharmony_ci	if (!tmds->i2c_bus) {
144462306a36Sopenharmony_ci		DRM_INFO("No valid Ext TMDS info found in BIOS\n");
144562306a36Sopenharmony_ci		return false;
144662306a36Sopenharmony_ci	}
144762306a36Sopenharmony_ci
144862306a36Sopenharmony_ci	return true;
144962306a36Sopenharmony_ci}
145062306a36Sopenharmony_ci
145162306a36Sopenharmony_cibool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
145262306a36Sopenharmony_ci{
145362306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
145462306a36Sopenharmony_ci	struct radeon_i2c_bus_rec ddc_i2c;
145562306a36Sopenharmony_ci	struct radeon_hpd hpd;
145662306a36Sopenharmony_ci
145762306a36Sopenharmony_ci	rdev->mode_info.connector_table = radeon_connector_table;
145862306a36Sopenharmony_ci	if (rdev->mode_info.connector_table == CT_NONE) {
145962306a36Sopenharmony_ci#ifdef CONFIG_PPC_PMAC
146062306a36Sopenharmony_ci		if (of_machine_is_compatible("PowerBook3,3")) {
146162306a36Sopenharmony_ci			/* powerbook with VGA */
146262306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_POWERBOOK_VGA;
146362306a36Sopenharmony_ci		} else if (of_machine_is_compatible("PowerBook3,4") ||
146462306a36Sopenharmony_ci			   of_machine_is_compatible("PowerBook3,5")) {
146562306a36Sopenharmony_ci			/* powerbook with internal tmds */
146662306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_POWERBOOK_INTERNAL;
146762306a36Sopenharmony_ci		} else if (of_machine_is_compatible("PowerBook5,1") ||
146862306a36Sopenharmony_ci			   of_machine_is_compatible("PowerBook5,2") ||
146962306a36Sopenharmony_ci			   of_machine_is_compatible("PowerBook5,3") ||
147062306a36Sopenharmony_ci			   of_machine_is_compatible("PowerBook5,4") ||
147162306a36Sopenharmony_ci			   of_machine_is_compatible("PowerBook5,5")) {
147262306a36Sopenharmony_ci			/* powerbook with external single link tmds (sil164) */
147362306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
147462306a36Sopenharmony_ci		} else if (of_machine_is_compatible("PowerBook5,6")) {
147562306a36Sopenharmony_ci			/* powerbook with external dual or single link tmds */
147662306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
147762306a36Sopenharmony_ci		} else if (of_machine_is_compatible("PowerBook5,7") ||
147862306a36Sopenharmony_ci			   of_machine_is_compatible("PowerBook5,8") ||
147962306a36Sopenharmony_ci			   of_machine_is_compatible("PowerBook5,9")) {
148062306a36Sopenharmony_ci			/* PowerBook6,2 ? */
148162306a36Sopenharmony_ci			/* powerbook with external dual link tmds (sil1178?) */
148262306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
148362306a36Sopenharmony_ci		} else if (of_machine_is_compatible("PowerBook4,1") ||
148462306a36Sopenharmony_ci			   of_machine_is_compatible("PowerBook4,2") ||
148562306a36Sopenharmony_ci			   of_machine_is_compatible("PowerBook4,3") ||
148662306a36Sopenharmony_ci			   of_machine_is_compatible("PowerBook6,3") ||
148762306a36Sopenharmony_ci			   of_machine_is_compatible("PowerBook6,5") ||
148862306a36Sopenharmony_ci			   of_machine_is_compatible("PowerBook6,7")) {
148962306a36Sopenharmony_ci			/* ibook */
149062306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_IBOOK;
149162306a36Sopenharmony_ci		} else if (of_machine_is_compatible("PowerMac3,5")) {
149262306a36Sopenharmony_ci			/* PowerMac G4 Silver radeon 7500 */
149362306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_MAC_G4_SILVER;
149462306a36Sopenharmony_ci		} else if (of_machine_is_compatible("PowerMac4,4")) {
149562306a36Sopenharmony_ci			/* emac */
149662306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_EMAC;
149762306a36Sopenharmony_ci		} else if (of_machine_is_compatible("PowerMac10,1")) {
149862306a36Sopenharmony_ci			/* mini with internal tmds */
149962306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_MINI_INTERNAL;
150062306a36Sopenharmony_ci		} else if (of_machine_is_compatible("PowerMac10,2")) {
150162306a36Sopenharmony_ci			/* mini with external tmds */
150262306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_MINI_EXTERNAL;
150362306a36Sopenharmony_ci		} else if (of_machine_is_compatible("PowerMac12,1")) {
150462306a36Sopenharmony_ci			/* PowerMac8,1 ? */
150562306a36Sopenharmony_ci			/* imac g5 isight */
150662306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT;
150762306a36Sopenharmony_ci		} else if ((rdev->pdev->device == 0x4a48) &&
150862306a36Sopenharmony_ci			   (rdev->pdev->subsystem_vendor == 0x1002) &&
150962306a36Sopenharmony_ci			   (rdev->pdev->subsystem_device == 0x4a48)) {
151062306a36Sopenharmony_ci			/* Mac X800 */
151162306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_MAC_X800;
151262306a36Sopenharmony_ci		} else if ((of_machine_is_compatible("PowerMac7,2") ||
151362306a36Sopenharmony_ci			    of_machine_is_compatible("PowerMac7,3")) &&
151462306a36Sopenharmony_ci			   (rdev->pdev->device == 0x4150) &&
151562306a36Sopenharmony_ci			   (rdev->pdev->subsystem_vendor == 0x1002) &&
151662306a36Sopenharmony_ci			   (rdev->pdev->subsystem_device == 0x4150)) {
151762306a36Sopenharmony_ci			/* Mac G5 tower 9600 */
151862306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_MAC_G5_9600;
151962306a36Sopenharmony_ci		} else if ((rdev->pdev->device == 0x4c66) &&
152062306a36Sopenharmony_ci			   (rdev->pdev->subsystem_vendor == 0x1002) &&
152162306a36Sopenharmony_ci			   (rdev->pdev->subsystem_device == 0x4c66)) {
152262306a36Sopenharmony_ci			/* SAM440ep RV250 embedded board */
152362306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_SAM440EP;
152462306a36Sopenharmony_ci		} else
152562306a36Sopenharmony_ci#endif /* CONFIG_PPC_PMAC */
152662306a36Sopenharmony_ci#ifdef CONFIG_PPC64
152762306a36Sopenharmony_ci		if (ASIC_IS_RN50(rdev))
152862306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_RN50_POWER;
152962306a36Sopenharmony_ci		else
153062306a36Sopenharmony_ci#endif
153162306a36Sopenharmony_ci			rdev->mode_info.connector_table = CT_GENERIC;
153262306a36Sopenharmony_ci	}
153362306a36Sopenharmony_ci
153462306a36Sopenharmony_ci	switch (rdev->mode_info.connector_table) {
153562306a36Sopenharmony_ci	case CT_GENERIC:
153662306a36Sopenharmony_ci		DRM_INFO("Connector Table: %d (generic)\n",
153762306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
153862306a36Sopenharmony_ci		/* these are the most common settings */
153962306a36Sopenharmony_ci		if (rdev->flags & RADEON_SINGLE_CRTC) {
154062306a36Sopenharmony_ci			/* VGA - primary dac */
154162306a36Sopenharmony_ci			ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
154262306a36Sopenharmony_ci			hpd.hpd = RADEON_HPD_NONE;
154362306a36Sopenharmony_ci			radeon_add_legacy_encoder(dev,
154462306a36Sopenharmony_ci						  radeon_get_encoder_enum(dev,
154562306a36Sopenharmony_ci									ATOM_DEVICE_CRT1_SUPPORT,
154662306a36Sopenharmony_ci									1),
154762306a36Sopenharmony_ci						  ATOM_DEVICE_CRT1_SUPPORT);
154862306a36Sopenharmony_ci			radeon_add_legacy_connector(dev, 0,
154962306a36Sopenharmony_ci						    ATOM_DEVICE_CRT1_SUPPORT,
155062306a36Sopenharmony_ci						    DRM_MODE_CONNECTOR_VGA,
155162306a36Sopenharmony_ci						    &ddc_i2c,
155262306a36Sopenharmony_ci						    CONNECTOR_OBJECT_ID_VGA,
155362306a36Sopenharmony_ci						    &hpd);
155462306a36Sopenharmony_ci		} else if (rdev->flags & RADEON_IS_MOBILITY) {
155562306a36Sopenharmony_ci			/* LVDS */
155662306a36Sopenharmony_ci			ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0);
155762306a36Sopenharmony_ci			hpd.hpd = RADEON_HPD_NONE;
155862306a36Sopenharmony_ci			radeon_add_legacy_encoder(dev,
155962306a36Sopenharmony_ci						  radeon_get_encoder_enum(dev,
156062306a36Sopenharmony_ci									ATOM_DEVICE_LCD1_SUPPORT,
156162306a36Sopenharmony_ci									0),
156262306a36Sopenharmony_ci						  ATOM_DEVICE_LCD1_SUPPORT);
156362306a36Sopenharmony_ci			radeon_add_legacy_connector(dev, 0,
156462306a36Sopenharmony_ci						    ATOM_DEVICE_LCD1_SUPPORT,
156562306a36Sopenharmony_ci						    DRM_MODE_CONNECTOR_LVDS,
156662306a36Sopenharmony_ci						    &ddc_i2c,
156762306a36Sopenharmony_ci						    CONNECTOR_OBJECT_ID_LVDS,
156862306a36Sopenharmony_ci						    &hpd);
156962306a36Sopenharmony_ci
157062306a36Sopenharmony_ci			/* VGA - primary dac */
157162306a36Sopenharmony_ci			ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
157262306a36Sopenharmony_ci			hpd.hpd = RADEON_HPD_NONE;
157362306a36Sopenharmony_ci			radeon_add_legacy_encoder(dev,
157462306a36Sopenharmony_ci						  radeon_get_encoder_enum(dev,
157562306a36Sopenharmony_ci									ATOM_DEVICE_CRT1_SUPPORT,
157662306a36Sopenharmony_ci									1),
157762306a36Sopenharmony_ci						  ATOM_DEVICE_CRT1_SUPPORT);
157862306a36Sopenharmony_ci			radeon_add_legacy_connector(dev, 1,
157962306a36Sopenharmony_ci						    ATOM_DEVICE_CRT1_SUPPORT,
158062306a36Sopenharmony_ci						    DRM_MODE_CONNECTOR_VGA,
158162306a36Sopenharmony_ci						    &ddc_i2c,
158262306a36Sopenharmony_ci						    CONNECTOR_OBJECT_ID_VGA,
158362306a36Sopenharmony_ci						    &hpd);
158462306a36Sopenharmony_ci		} else {
158562306a36Sopenharmony_ci			/* DVI-I - tv dac, int tmds */
158662306a36Sopenharmony_ci			ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
158762306a36Sopenharmony_ci			hpd.hpd = RADEON_HPD_1;
158862306a36Sopenharmony_ci			radeon_add_legacy_encoder(dev,
158962306a36Sopenharmony_ci						  radeon_get_encoder_enum(dev,
159062306a36Sopenharmony_ci									ATOM_DEVICE_DFP1_SUPPORT,
159162306a36Sopenharmony_ci									0),
159262306a36Sopenharmony_ci						  ATOM_DEVICE_DFP1_SUPPORT);
159362306a36Sopenharmony_ci			radeon_add_legacy_encoder(dev,
159462306a36Sopenharmony_ci						  radeon_get_encoder_enum(dev,
159562306a36Sopenharmony_ci									ATOM_DEVICE_CRT2_SUPPORT,
159662306a36Sopenharmony_ci									2),
159762306a36Sopenharmony_ci						  ATOM_DEVICE_CRT2_SUPPORT);
159862306a36Sopenharmony_ci			radeon_add_legacy_connector(dev, 0,
159962306a36Sopenharmony_ci						    ATOM_DEVICE_DFP1_SUPPORT |
160062306a36Sopenharmony_ci						    ATOM_DEVICE_CRT2_SUPPORT,
160162306a36Sopenharmony_ci						    DRM_MODE_CONNECTOR_DVII,
160262306a36Sopenharmony_ci						    &ddc_i2c,
160362306a36Sopenharmony_ci						    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
160462306a36Sopenharmony_ci						    &hpd);
160562306a36Sopenharmony_ci
160662306a36Sopenharmony_ci			/* VGA - primary dac */
160762306a36Sopenharmony_ci			ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
160862306a36Sopenharmony_ci			hpd.hpd = RADEON_HPD_NONE;
160962306a36Sopenharmony_ci			radeon_add_legacy_encoder(dev,
161062306a36Sopenharmony_ci						  radeon_get_encoder_enum(dev,
161162306a36Sopenharmony_ci									ATOM_DEVICE_CRT1_SUPPORT,
161262306a36Sopenharmony_ci									1),
161362306a36Sopenharmony_ci						  ATOM_DEVICE_CRT1_SUPPORT);
161462306a36Sopenharmony_ci			radeon_add_legacy_connector(dev, 1,
161562306a36Sopenharmony_ci						    ATOM_DEVICE_CRT1_SUPPORT,
161662306a36Sopenharmony_ci						    DRM_MODE_CONNECTOR_VGA,
161762306a36Sopenharmony_ci						    &ddc_i2c,
161862306a36Sopenharmony_ci						    CONNECTOR_OBJECT_ID_VGA,
161962306a36Sopenharmony_ci						    &hpd);
162062306a36Sopenharmony_ci		}
162162306a36Sopenharmony_ci
162262306a36Sopenharmony_ci		if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) {
162362306a36Sopenharmony_ci			/* TV - tv dac */
162462306a36Sopenharmony_ci			ddc_i2c.valid = false;
162562306a36Sopenharmony_ci			hpd.hpd = RADEON_HPD_NONE;
162662306a36Sopenharmony_ci			radeon_add_legacy_encoder(dev,
162762306a36Sopenharmony_ci						  radeon_get_encoder_enum(dev,
162862306a36Sopenharmony_ci									ATOM_DEVICE_TV1_SUPPORT,
162962306a36Sopenharmony_ci									2),
163062306a36Sopenharmony_ci						  ATOM_DEVICE_TV1_SUPPORT);
163162306a36Sopenharmony_ci			radeon_add_legacy_connector(dev, 2,
163262306a36Sopenharmony_ci						    ATOM_DEVICE_TV1_SUPPORT,
163362306a36Sopenharmony_ci						    DRM_MODE_CONNECTOR_SVIDEO,
163462306a36Sopenharmony_ci						    &ddc_i2c,
163562306a36Sopenharmony_ci						    CONNECTOR_OBJECT_ID_SVIDEO,
163662306a36Sopenharmony_ci						    &hpd);
163762306a36Sopenharmony_ci		}
163862306a36Sopenharmony_ci		break;
163962306a36Sopenharmony_ci	case CT_IBOOK:
164062306a36Sopenharmony_ci		DRM_INFO("Connector Table: %d (ibook)\n",
164162306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
164262306a36Sopenharmony_ci		/* LVDS */
164362306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
164462306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
164562306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
164662306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
164762306a36Sopenharmony_ci								ATOM_DEVICE_LCD1_SUPPORT,
164862306a36Sopenharmony_ci								0),
164962306a36Sopenharmony_ci					  ATOM_DEVICE_LCD1_SUPPORT);
165062306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
165162306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
165262306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_LVDS,
165362306a36Sopenharmony_ci					    &hpd);
165462306a36Sopenharmony_ci		/* VGA - TV DAC */
165562306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
165662306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
165762306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
165862306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
165962306a36Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
166062306a36Sopenharmony_ci								2),
166162306a36Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
166262306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
166362306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
166462306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
166562306a36Sopenharmony_ci					    &hpd);
166662306a36Sopenharmony_ci		/* TV - TV DAC */
166762306a36Sopenharmony_ci		ddc_i2c.valid = false;
166862306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
166962306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
167062306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
167162306a36Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
167262306a36Sopenharmony_ci								2),
167362306a36Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
167462306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
167562306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
167662306a36Sopenharmony_ci					    &ddc_i2c,
167762306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
167862306a36Sopenharmony_ci					    &hpd);
167962306a36Sopenharmony_ci		break;
168062306a36Sopenharmony_ci	case CT_POWERBOOK_EXTERNAL:
168162306a36Sopenharmony_ci		DRM_INFO("Connector Table: %d (powerbook external tmds)\n",
168262306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
168362306a36Sopenharmony_ci		/* LVDS */
168462306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
168562306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
168662306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
168762306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
168862306a36Sopenharmony_ci								ATOM_DEVICE_LCD1_SUPPORT,
168962306a36Sopenharmony_ci								0),
169062306a36Sopenharmony_ci					  ATOM_DEVICE_LCD1_SUPPORT);
169162306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
169262306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
169362306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_LVDS,
169462306a36Sopenharmony_ci					    &hpd);
169562306a36Sopenharmony_ci		/* DVI-I - primary dac, ext tmds */
169662306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
169762306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_2; /* ??? */
169862306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
169962306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
170062306a36Sopenharmony_ci								ATOM_DEVICE_DFP2_SUPPORT,
170162306a36Sopenharmony_ci								0),
170262306a36Sopenharmony_ci					  ATOM_DEVICE_DFP2_SUPPORT);
170362306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
170462306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
170562306a36Sopenharmony_ci								ATOM_DEVICE_CRT1_SUPPORT,
170662306a36Sopenharmony_ci								1),
170762306a36Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
170862306a36Sopenharmony_ci		/* XXX some are SL */
170962306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 1,
171062306a36Sopenharmony_ci					    ATOM_DEVICE_DFP2_SUPPORT |
171162306a36Sopenharmony_ci					    ATOM_DEVICE_CRT1_SUPPORT,
171262306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
171362306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
171462306a36Sopenharmony_ci					    &hpd);
171562306a36Sopenharmony_ci		/* TV - TV DAC */
171662306a36Sopenharmony_ci		ddc_i2c.valid = false;
171762306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
171862306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
171962306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
172062306a36Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
172162306a36Sopenharmony_ci								2),
172262306a36Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
172362306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
172462306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
172562306a36Sopenharmony_ci					    &ddc_i2c,
172662306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
172762306a36Sopenharmony_ci					    &hpd);
172862306a36Sopenharmony_ci		break;
172962306a36Sopenharmony_ci	case CT_POWERBOOK_INTERNAL:
173062306a36Sopenharmony_ci		DRM_INFO("Connector Table: %d (powerbook internal tmds)\n",
173162306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
173262306a36Sopenharmony_ci		/* LVDS */
173362306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
173462306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
173562306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
173662306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
173762306a36Sopenharmony_ci								ATOM_DEVICE_LCD1_SUPPORT,
173862306a36Sopenharmony_ci								0),
173962306a36Sopenharmony_ci					  ATOM_DEVICE_LCD1_SUPPORT);
174062306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
174162306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
174262306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_LVDS,
174362306a36Sopenharmony_ci					    &hpd);
174462306a36Sopenharmony_ci		/* DVI-I - primary dac, int tmds */
174562306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
174662306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_1; /* ??? */
174762306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
174862306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
174962306a36Sopenharmony_ci								ATOM_DEVICE_DFP1_SUPPORT,
175062306a36Sopenharmony_ci								0),
175162306a36Sopenharmony_ci					  ATOM_DEVICE_DFP1_SUPPORT);
175262306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
175362306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
175462306a36Sopenharmony_ci								ATOM_DEVICE_CRT1_SUPPORT,
175562306a36Sopenharmony_ci								1),
175662306a36Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
175762306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 1,
175862306a36Sopenharmony_ci					    ATOM_DEVICE_DFP1_SUPPORT |
175962306a36Sopenharmony_ci					    ATOM_DEVICE_CRT1_SUPPORT,
176062306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
176162306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
176262306a36Sopenharmony_ci					    &hpd);
176362306a36Sopenharmony_ci		/* TV - TV DAC */
176462306a36Sopenharmony_ci		ddc_i2c.valid = false;
176562306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
176662306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
176762306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
176862306a36Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
176962306a36Sopenharmony_ci								2),
177062306a36Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
177162306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
177262306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
177362306a36Sopenharmony_ci					    &ddc_i2c,
177462306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
177562306a36Sopenharmony_ci					    &hpd);
177662306a36Sopenharmony_ci		break;
177762306a36Sopenharmony_ci	case CT_POWERBOOK_VGA:
177862306a36Sopenharmony_ci		DRM_INFO("Connector Table: %d (powerbook vga)\n",
177962306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
178062306a36Sopenharmony_ci		/* LVDS */
178162306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
178262306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
178362306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
178462306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
178562306a36Sopenharmony_ci								ATOM_DEVICE_LCD1_SUPPORT,
178662306a36Sopenharmony_ci								0),
178762306a36Sopenharmony_ci					  ATOM_DEVICE_LCD1_SUPPORT);
178862306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
178962306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
179062306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_LVDS,
179162306a36Sopenharmony_ci					    &hpd);
179262306a36Sopenharmony_ci		/* VGA - primary dac */
179362306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
179462306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
179562306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
179662306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
179762306a36Sopenharmony_ci								ATOM_DEVICE_CRT1_SUPPORT,
179862306a36Sopenharmony_ci								1),
179962306a36Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
180062306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
180162306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
180262306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
180362306a36Sopenharmony_ci					    &hpd);
180462306a36Sopenharmony_ci		/* TV - TV DAC */
180562306a36Sopenharmony_ci		ddc_i2c.valid = false;
180662306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
180762306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
180862306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
180962306a36Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
181062306a36Sopenharmony_ci								2),
181162306a36Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
181262306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
181362306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
181462306a36Sopenharmony_ci					    &ddc_i2c,
181562306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
181662306a36Sopenharmony_ci					    &hpd);
181762306a36Sopenharmony_ci		break;
181862306a36Sopenharmony_ci	case CT_MINI_EXTERNAL:
181962306a36Sopenharmony_ci		DRM_INFO("Connector Table: %d (mini external tmds)\n",
182062306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
182162306a36Sopenharmony_ci		/* DVI-I - tv dac, ext tmds */
182262306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
182362306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_2; /* ??? */
182462306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
182562306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
182662306a36Sopenharmony_ci								ATOM_DEVICE_DFP2_SUPPORT,
182762306a36Sopenharmony_ci								0),
182862306a36Sopenharmony_ci					  ATOM_DEVICE_DFP2_SUPPORT);
182962306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
183062306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
183162306a36Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
183262306a36Sopenharmony_ci								2),
183362306a36Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
183462306a36Sopenharmony_ci		/* XXX are any DL? */
183562306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 0,
183662306a36Sopenharmony_ci					    ATOM_DEVICE_DFP2_SUPPORT |
183762306a36Sopenharmony_ci					    ATOM_DEVICE_CRT2_SUPPORT,
183862306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
183962306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
184062306a36Sopenharmony_ci					    &hpd);
184162306a36Sopenharmony_ci		/* TV - TV DAC */
184262306a36Sopenharmony_ci		ddc_i2c.valid = false;
184362306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
184462306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
184562306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
184662306a36Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
184762306a36Sopenharmony_ci								2),
184862306a36Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
184962306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
185062306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
185162306a36Sopenharmony_ci					    &ddc_i2c,
185262306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
185362306a36Sopenharmony_ci					    &hpd);
185462306a36Sopenharmony_ci		break;
185562306a36Sopenharmony_ci	case CT_MINI_INTERNAL:
185662306a36Sopenharmony_ci		DRM_INFO("Connector Table: %d (mini internal tmds)\n",
185762306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
185862306a36Sopenharmony_ci		/* DVI-I - tv dac, int tmds */
185962306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
186062306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_1; /* ??? */
186162306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
186262306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
186362306a36Sopenharmony_ci								ATOM_DEVICE_DFP1_SUPPORT,
186462306a36Sopenharmony_ci								0),
186562306a36Sopenharmony_ci					  ATOM_DEVICE_DFP1_SUPPORT);
186662306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
186762306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
186862306a36Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
186962306a36Sopenharmony_ci								2),
187062306a36Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
187162306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 0,
187262306a36Sopenharmony_ci					    ATOM_DEVICE_DFP1_SUPPORT |
187362306a36Sopenharmony_ci					    ATOM_DEVICE_CRT2_SUPPORT,
187462306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
187562306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
187662306a36Sopenharmony_ci					    &hpd);
187762306a36Sopenharmony_ci		/* TV - TV DAC */
187862306a36Sopenharmony_ci		ddc_i2c.valid = false;
187962306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
188062306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
188162306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
188262306a36Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
188362306a36Sopenharmony_ci								2),
188462306a36Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
188562306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
188662306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
188762306a36Sopenharmony_ci					    &ddc_i2c,
188862306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
188962306a36Sopenharmony_ci					    &hpd);
189062306a36Sopenharmony_ci		break;
189162306a36Sopenharmony_ci	case CT_IMAC_G5_ISIGHT:
189262306a36Sopenharmony_ci		DRM_INFO("Connector Table: %d (imac g5 isight)\n",
189362306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
189462306a36Sopenharmony_ci		/* DVI-D - int tmds */
189562306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
189662306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_1; /* ??? */
189762306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
189862306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
189962306a36Sopenharmony_ci								ATOM_DEVICE_DFP1_SUPPORT,
190062306a36Sopenharmony_ci								0),
190162306a36Sopenharmony_ci					  ATOM_DEVICE_DFP1_SUPPORT);
190262306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT,
190362306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVID, &ddc_i2c,
190462306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
190562306a36Sopenharmony_ci					    &hpd);
190662306a36Sopenharmony_ci		/* VGA - tv dac */
190762306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
190862306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
190962306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
191062306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
191162306a36Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
191262306a36Sopenharmony_ci								2),
191362306a36Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
191462306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
191562306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
191662306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
191762306a36Sopenharmony_ci					    &hpd);
191862306a36Sopenharmony_ci		/* TV - TV DAC */
191962306a36Sopenharmony_ci		ddc_i2c.valid = false;
192062306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
192162306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
192262306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
192362306a36Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
192462306a36Sopenharmony_ci								2),
192562306a36Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
192662306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
192762306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
192862306a36Sopenharmony_ci					    &ddc_i2c,
192962306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
193062306a36Sopenharmony_ci					    &hpd);
193162306a36Sopenharmony_ci		break;
193262306a36Sopenharmony_ci	case CT_EMAC:
193362306a36Sopenharmony_ci		DRM_INFO("Connector Table: %d (emac)\n",
193462306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
193562306a36Sopenharmony_ci		/* VGA - primary dac */
193662306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
193762306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
193862306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
193962306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
194062306a36Sopenharmony_ci								ATOM_DEVICE_CRT1_SUPPORT,
194162306a36Sopenharmony_ci								1),
194262306a36Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
194362306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT,
194462306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
194562306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
194662306a36Sopenharmony_ci					    &hpd);
194762306a36Sopenharmony_ci		/* VGA - tv dac */
194862306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
194962306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
195062306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
195162306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
195262306a36Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
195362306a36Sopenharmony_ci								2),
195462306a36Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
195562306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
195662306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
195762306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
195862306a36Sopenharmony_ci					    &hpd);
195962306a36Sopenharmony_ci		/* TV - TV DAC */
196062306a36Sopenharmony_ci		ddc_i2c.valid = false;
196162306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
196262306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
196362306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
196462306a36Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
196562306a36Sopenharmony_ci								2),
196662306a36Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
196762306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
196862306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
196962306a36Sopenharmony_ci					    &ddc_i2c,
197062306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
197162306a36Sopenharmony_ci					    &hpd);
197262306a36Sopenharmony_ci		break;
197362306a36Sopenharmony_ci	case CT_RN50_POWER:
197462306a36Sopenharmony_ci		DRM_INFO("Connector Table: %d (rn50-power)\n",
197562306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
197662306a36Sopenharmony_ci		/* VGA - primary dac */
197762306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
197862306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
197962306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
198062306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
198162306a36Sopenharmony_ci								ATOM_DEVICE_CRT1_SUPPORT,
198262306a36Sopenharmony_ci								1),
198362306a36Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
198462306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT,
198562306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
198662306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
198762306a36Sopenharmony_ci					    &hpd);
198862306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
198962306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
199062306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
199162306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
199262306a36Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
199362306a36Sopenharmony_ci								2),
199462306a36Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
199562306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
199662306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
199762306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
199862306a36Sopenharmony_ci					    &hpd);
199962306a36Sopenharmony_ci		break;
200062306a36Sopenharmony_ci	case CT_MAC_X800:
200162306a36Sopenharmony_ci		DRM_INFO("Connector Table: %d (mac x800)\n",
200262306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
200362306a36Sopenharmony_ci		/* DVI - primary dac, internal tmds */
200462306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
200562306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_1; /* ??? */
200662306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
200762306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
200862306a36Sopenharmony_ci								  ATOM_DEVICE_DFP1_SUPPORT,
200962306a36Sopenharmony_ci								  0),
201062306a36Sopenharmony_ci					  ATOM_DEVICE_DFP1_SUPPORT);
201162306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
201262306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
201362306a36Sopenharmony_ci								  ATOM_DEVICE_CRT1_SUPPORT,
201462306a36Sopenharmony_ci								  1),
201562306a36Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
201662306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 0,
201762306a36Sopenharmony_ci					    ATOM_DEVICE_DFP1_SUPPORT |
201862306a36Sopenharmony_ci					    ATOM_DEVICE_CRT1_SUPPORT,
201962306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
202062306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
202162306a36Sopenharmony_ci					    &hpd);
202262306a36Sopenharmony_ci		/* DVI - tv dac, dvo */
202362306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
202462306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_2; /* ??? */
202562306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
202662306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
202762306a36Sopenharmony_ci								  ATOM_DEVICE_DFP2_SUPPORT,
202862306a36Sopenharmony_ci								  0),
202962306a36Sopenharmony_ci					  ATOM_DEVICE_DFP2_SUPPORT);
203062306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
203162306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
203262306a36Sopenharmony_ci								  ATOM_DEVICE_CRT2_SUPPORT,
203362306a36Sopenharmony_ci								  2),
203462306a36Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
203562306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 1,
203662306a36Sopenharmony_ci					    ATOM_DEVICE_DFP2_SUPPORT |
203762306a36Sopenharmony_ci					    ATOM_DEVICE_CRT2_SUPPORT,
203862306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
203962306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
204062306a36Sopenharmony_ci					    &hpd);
204162306a36Sopenharmony_ci		break;
204262306a36Sopenharmony_ci	case CT_MAC_G5_9600:
204362306a36Sopenharmony_ci		DRM_INFO("Connector Table: %d (mac g5 9600)\n",
204462306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
204562306a36Sopenharmony_ci		/* DVI - tv dac, dvo */
204662306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
204762306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_1; /* ??? */
204862306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
204962306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
205062306a36Sopenharmony_ci								  ATOM_DEVICE_DFP2_SUPPORT,
205162306a36Sopenharmony_ci								  0),
205262306a36Sopenharmony_ci					  ATOM_DEVICE_DFP2_SUPPORT);
205362306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
205462306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
205562306a36Sopenharmony_ci								  ATOM_DEVICE_CRT2_SUPPORT,
205662306a36Sopenharmony_ci								  2),
205762306a36Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
205862306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 0,
205962306a36Sopenharmony_ci					    ATOM_DEVICE_DFP2_SUPPORT |
206062306a36Sopenharmony_ci					    ATOM_DEVICE_CRT2_SUPPORT,
206162306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
206262306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
206362306a36Sopenharmony_ci					    &hpd);
206462306a36Sopenharmony_ci		/* ADC - primary dac, internal tmds */
206562306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
206662306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_2; /* ??? */
206762306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
206862306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
206962306a36Sopenharmony_ci								  ATOM_DEVICE_DFP1_SUPPORT,
207062306a36Sopenharmony_ci								  0),
207162306a36Sopenharmony_ci					  ATOM_DEVICE_DFP1_SUPPORT);
207262306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
207362306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
207462306a36Sopenharmony_ci								  ATOM_DEVICE_CRT1_SUPPORT,
207562306a36Sopenharmony_ci								  1),
207662306a36Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
207762306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 1,
207862306a36Sopenharmony_ci					    ATOM_DEVICE_DFP1_SUPPORT |
207962306a36Sopenharmony_ci					    ATOM_DEVICE_CRT1_SUPPORT,
208062306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
208162306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
208262306a36Sopenharmony_ci					    &hpd);
208362306a36Sopenharmony_ci		/* TV - TV DAC */
208462306a36Sopenharmony_ci		ddc_i2c.valid = false;
208562306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
208662306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
208762306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
208862306a36Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
208962306a36Sopenharmony_ci								2),
209062306a36Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
209162306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
209262306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
209362306a36Sopenharmony_ci					    &ddc_i2c,
209462306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
209562306a36Sopenharmony_ci					    &hpd);
209662306a36Sopenharmony_ci		break;
209762306a36Sopenharmony_ci	case CT_SAM440EP:
209862306a36Sopenharmony_ci		DRM_INFO("Connector Table: %d (SAM440ep embedded board)\n",
209962306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
210062306a36Sopenharmony_ci		/* LVDS */
210162306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0);
210262306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
210362306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
210462306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
210562306a36Sopenharmony_ci								ATOM_DEVICE_LCD1_SUPPORT,
210662306a36Sopenharmony_ci								0),
210762306a36Sopenharmony_ci					  ATOM_DEVICE_LCD1_SUPPORT);
210862306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
210962306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
211062306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_LVDS,
211162306a36Sopenharmony_ci					    &hpd);
211262306a36Sopenharmony_ci		/* DVI-I - secondary dac, int tmds */
211362306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
211462306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_1; /* ??? */
211562306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
211662306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
211762306a36Sopenharmony_ci								ATOM_DEVICE_DFP1_SUPPORT,
211862306a36Sopenharmony_ci								0),
211962306a36Sopenharmony_ci					  ATOM_DEVICE_DFP1_SUPPORT);
212062306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
212162306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
212262306a36Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
212362306a36Sopenharmony_ci								2),
212462306a36Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
212562306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 1,
212662306a36Sopenharmony_ci					    ATOM_DEVICE_DFP1_SUPPORT |
212762306a36Sopenharmony_ci					    ATOM_DEVICE_CRT2_SUPPORT,
212862306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
212962306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
213062306a36Sopenharmony_ci					    &hpd);
213162306a36Sopenharmony_ci		/* VGA - primary dac */
213262306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
213362306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
213462306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
213562306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
213662306a36Sopenharmony_ci								ATOM_DEVICE_CRT1_SUPPORT,
213762306a36Sopenharmony_ci								1),
213862306a36Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
213962306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 2,
214062306a36Sopenharmony_ci					    ATOM_DEVICE_CRT1_SUPPORT,
214162306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
214262306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
214362306a36Sopenharmony_ci					    &hpd);
214462306a36Sopenharmony_ci		/* TV - TV DAC */
214562306a36Sopenharmony_ci		ddc_i2c.valid = false;
214662306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
214762306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
214862306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
214962306a36Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
215062306a36Sopenharmony_ci								2),
215162306a36Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
215262306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 3, ATOM_DEVICE_TV1_SUPPORT,
215362306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
215462306a36Sopenharmony_ci					    &ddc_i2c,
215562306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
215662306a36Sopenharmony_ci					    &hpd);
215762306a36Sopenharmony_ci		break;
215862306a36Sopenharmony_ci	case CT_MAC_G4_SILVER:
215962306a36Sopenharmony_ci		DRM_INFO("Connector Table: %d (mac g4 silver)\n",
216062306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
216162306a36Sopenharmony_ci		/* DVI-I - tv dac, int tmds */
216262306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
216362306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_1; /* ??? */
216462306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
216562306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
216662306a36Sopenharmony_ci								ATOM_DEVICE_DFP1_SUPPORT,
216762306a36Sopenharmony_ci								0),
216862306a36Sopenharmony_ci					  ATOM_DEVICE_DFP1_SUPPORT);
216962306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
217062306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
217162306a36Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
217262306a36Sopenharmony_ci								2),
217362306a36Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
217462306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 0,
217562306a36Sopenharmony_ci					    ATOM_DEVICE_DFP1_SUPPORT |
217662306a36Sopenharmony_ci					    ATOM_DEVICE_CRT2_SUPPORT,
217762306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
217862306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
217962306a36Sopenharmony_ci					    &hpd);
218062306a36Sopenharmony_ci		/* VGA - primary dac */
218162306a36Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
218262306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
218362306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
218462306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
218562306a36Sopenharmony_ci								ATOM_DEVICE_CRT1_SUPPORT,
218662306a36Sopenharmony_ci								1),
218762306a36Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
218862306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
218962306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
219062306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
219162306a36Sopenharmony_ci					    &hpd);
219262306a36Sopenharmony_ci		/* TV - TV DAC */
219362306a36Sopenharmony_ci		ddc_i2c.valid = false;
219462306a36Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
219562306a36Sopenharmony_ci		radeon_add_legacy_encoder(dev,
219662306a36Sopenharmony_ci					  radeon_get_encoder_enum(dev,
219762306a36Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
219862306a36Sopenharmony_ci								2),
219962306a36Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
220062306a36Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
220162306a36Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
220262306a36Sopenharmony_ci					    &ddc_i2c,
220362306a36Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
220462306a36Sopenharmony_ci					    &hpd);
220562306a36Sopenharmony_ci		break;
220662306a36Sopenharmony_ci	default:
220762306a36Sopenharmony_ci		DRM_INFO("Connector table: %d (invalid)\n",
220862306a36Sopenharmony_ci			 rdev->mode_info.connector_table);
220962306a36Sopenharmony_ci		return false;
221062306a36Sopenharmony_ci	}
221162306a36Sopenharmony_ci
221262306a36Sopenharmony_ci	radeon_link_encoder_connector(dev);
221362306a36Sopenharmony_ci
221462306a36Sopenharmony_ci	return true;
221562306a36Sopenharmony_ci}
221662306a36Sopenharmony_ci
221762306a36Sopenharmony_cistatic bool radeon_apply_legacy_quirks(struct drm_device *dev,
221862306a36Sopenharmony_ci				       int bios_index,
221962306a36Sopenharmony_ci				       enum radeon_combios_connector
222062306a36Sopenharmony_ci				       *legacy_connector,
222162306a36Sopenharmony_ci				       struct radeon_i2c_bus_rec *ddc_i2c,
222262306a36Sopenharmony_ci				       struct radeon_hpd *hpd)
222362306a36Sopenharmony_ci{
222462306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
222562306a36Sopenharmony_ci
222662306a36Sopenharmony_ci	/* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
222762306a36Sopenharmony_ci	   one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */
222862306a36Sopenharmony_ci	if (rdev->pdev->device == 0x515e &&
222962306a36Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x1014) {
223062306a36Sopenharmony_ci		if (*legacy_connector == CONNECTOR_CRT_LEGACY &&
223162306a36Sopenharmony_ci		    ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
223262306a36Sopenharmony_ci			return false;
223362306a36Sopenharmony_ci	}
223462306a36Sopenharmony_ci
223562306a36Sopenharmony_ci	/* X300 card with extra non-existent DVI port */
223662306a36Sopenharmony_ci	if (rdev->pdev->device == 0x5B60 &&
223762306a36Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x17af &&
223862306a36Sopenharmony_ci	    rdev->pdev->subsystem_device == 0x201e && bios_index == 2) {
223962306a36Sopenharmony_ci		if (*legacy_connector == CONNECTOR_DVI_I_LEGACY)
224062306a36Sopenharmony_ci			return false;
224162306a36Sopenharmony_ci	}
224262306a36Sopenharmony_ci
224362306a36Sopenharmony_ci	return true;
224462306a36Sopenharmony_ci}
224562306a36Sopenharmony_ci
224662306a36Sopenharmony_cistatic bool radeon_apply_legacy_tv_quirks(struct drm_device *dev)
224762306a36Sopenharmony_ci{
224862306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
224962306a36Sopenharmony_ci
225062306a36Sopenharmony_ci	/* Acer 5102 has non-existent TV port */
225162306a36Sopenharmony_ci	if (rdev->pdev->device == 0x5975 &&
225262306a36Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x1025 &&
225362306a36Sopenharmony_ci	    rdev->pdev->subsystem_device == 0x009f)
225462306a36Sopenharmony_ci		return false;
225562306a36Sopenharmony_ci
225662306a36Sopenharmony_ci	/* HP dc5750 has non-existent TV port */
225762306a36Sopenharmony_ci	if (rdev->pdev->device == 0x5974 &&
225862306a36Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x103c &&
225962306a36Sopenharmony_ci	    rdev->pdev->subsystem_device == 0x280a)
226062306a36Sopenharmony_ci		return false;
226162306a36Sopenharmony_ci
226262306a36Sopenharmony_ci	/* MSI S270 has non-existent TV port */
226362306a36Sopenharmony_ci	if (rdev->pdev->device == 0x5955 &&
226462306a36Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x1462 &&
226562306a36Sopenharmony_ci	    rdev->pdev->subsystem_device == 0x0131)
226662306a36Sopenharmony_ci		return false;
226762306a36Sopenharmony_ci
226862306a36Sopenharmony_ci	return true;
226962306a36Sopenharmony_ci}
227062306a36Sopenharmony_ci
227162306a36Sopenharmony_cistatic uint16_t combios_check_dl_dvi(struct drm_device *dev, int is_dvi_d)
227262306a36Sopenharmony_ci{
227362306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
227462306a36Sopenharmony_ci	uint32_t ext_tmds_info;
227562306a36Sopenharmony_ci
227662306a36Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP) {
227762306a36Sopenharmony_ci		if (is_dvi_d)
227862306a36Sopenharmony_ci			return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
227962306a36Sopenharmony_ci		else
228062306a36Sopenharmony_ci			return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
228162306a36Sopenharmony_ci	}
228262306a36Sopenharmony_ci	ext_tmds_info = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
228362306a36Sopenharmony_ci	if (ext_tmds_info) {
228462306a36Sopenharmony_ci		uint8_t rev = RBIOS8(ext_tmds_info);
228562306a36Sopenharmony_ci		uint8_t flags = RBIOS8(ext_tmds_info + 4 + 5);
228662306a36Sopenharmony_ci		if (rev >= 3) {
228762306a36Sopenharmony_ci			if (is_dvi_d)
228862306a36Sopenharmony_ci				return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
228962306a36Sopenharmony_ci			else
229062306a36Sopenharmony_ci				return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
229162306a36Sopenharmony_ci		} else {
229262306a36Sopenharmony_ci			if (flags & 1) {
229362306a36Sopenharmony_ci				if (is_dvi_d)
229462306a36Sopenharmony_ci					return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
229562306a36Sopenharmony_ci				else
229662306a36Sopenharmony_ci					return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
229762306a36Sopenharmony_ci			}
229862306a36Sopenharmony_ci		}
229962306a36Sopenharmony_ci	}
230062306a36Sopenharmony_ci	if (is_dvi_d)
230162306a36Sopenharmony_ci		return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
230262306a36Sopenharmony_ci	else
230362306a36Sopenharmony_ci		return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
230462306a36Sopenharmony_ci}
230562306a36Sopenharmony_ci
230662306a36Sopenharmony_cibool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
230762306a36Sopenharmony_ci{
230862306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
230962306a36Sopenharmony_ci	uint32_t conn_info, entry, devices;
231062306a36Sopenharmony_ci	uint16_t tmp, connector_object_id;
231162306a36Sopenharmony_ci	enum radeon_combios_ddc ddc_type;
231262306a36Sopenharmony_ci	enum radeon_combios_connector connector;
231362306a36Sopenharmony_ci	int i = 0;
231462306a36Sopenharmony_ci	struct radeon_i2c_bus_rec ddc_i2c;
231562306a36Sopenharmony_ci	struct radeon_hpd hpd;
231662306a36Sopenharmony_ci
231762306a36Sopenharmony_ci	conn_info = combios_get_table_offset(dev, COMBIOS_CONNECTOR_INFO_TABLE);
231862306a36Sopenharmony_ci	if (conn_info) {
231962306a36Sopenharmony_ci		for (i = 0; i < 4; i++) {
232062306a36Sopenharmony_ci			entry = conn_info + 2 + i * 2;
232162306a36Sopenharmony_ci
232262306a36Sopenharmony_ci			if (!RBIOS16(entry))
232362306a36Sopenharmony_ci				break;
232462306a36Sopenharmony_ci
232562306a36Sopenharmony_ci			tmp = RBIOS16(entry);
232662306a36Sopenharmony_ci
232762306a36Sopenharmony_ci			connector = (tmp >> 12) & 0xf;
232862306a36Sopenharmony_ci
232962306a36Sopenharmony_ci			ddc_type = (tmp >> 8) & 0xf;
233062306a36Sopenharmony_ci			if (ddc_type == 5)
233162306a36Sopenharmony_ci				ddc_i2c = radeon_combios_get_i2c_info_from_table(rdev);
233262306a36Sopenharmony_ci			else
233362306a36Sopenharmony_ci				ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0);
233462306a36Sopenharmony_ci
233562306a36Sopenharmony_ci			switch (connector) {
233662306a36Sopenharmony_ci			case CONNECTOR_PROPRIETARY_LEGACY:
233762306a36Sopenharmony_ci			case CONNECTOR_DVI_I_LEGACY:
233862306a36Sopenharmony_ci			case CONNECTOR_DVI_D_LEGACY:
233962306a36Sopenharmony_ci				if ((tmp >> 4) & 0x1)
234062306a36Sopenharmony_ci					hpd.hpd = RADEON_HPD_2;
234162306a36Sopenharmony_ci				else
234262306a36Sopenharmony_ci					hpd.hpd = RADEON_HPD_1;
234362306a36Sopenharmony_ci				break;
234462306a36Sopenharmony_ci			default:
234562306a36Sopenharmony_ci				hpd.hpd = RADEON_HPD_NONE;
234662306a36Sopenharmony_ci				break;
234762306a36Sopenharmony_ci			}
234862306a36Sopenharmony_ci
234962306a36Sopenharmony_ci			if (!radeon_apply_legacy_quirks(dev, i, &connector,
235062306a36Sopenharmony_ci							&ddc_i2c, &hpd))
235162306a36Sopenharmony_ci				continue;
235262306a36Sopenharmony_ci
235362306a36Sopenharmony_ci			switch (connector) {
235462306a36Sopenharmony_ci			case CONNECTOR_PROPRIETARY_LEGACY:
235562306a36Sopenharmony_ci				if ((tmp >> 4) & 0x1)
235662306a36Sopenharmony_ci					devices = ATOM_DEVICE_DFP2_SUPPORT;
235762306a36Sopenharmony_ci				else
235862306a36Sopenharmony_ci					devices = ATOM_DEVICE_DFP1_SUPPORT;
235962306a36Sopenharmony_ci				radeon_add_legacy_encoder(dev,
236062306a36Sopenharmony_ci							  radeon_get_encoder_enum
236162306a36Sopenharmony_ci							  (dev, devices, 0),
236262306a36Sopenharmony_ci							  devices);
236362306a36Sopenharmony_ci				radeon_add_legacy_connector(dev, i, devices,
236462306a36Sopenharmony_ci							    legacy_connector_convert
236562306a36Sopenharmony_ci							    [connector],
236662306a36Sopenharmony_ci							    &ddc_i2c,
236762306a36Sopenharmony_ci							    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
236862306a36Sopenharmony_ci							    &hpd);
236962306a36Sopenharmony_ci				break;
237062306a36Sopenharmony_ci			case CONNECTOR_CRT_LEGACY:
237162306a36Sopenharmony_ci				if (tmp & 0x1) {
237262306a36Sopenharmony_ci					devices = ATOM_DEVICE_CRT2_SUPPORT;
237362306a36Sopenharmony_ci					radeon_add_legacy_encoder(dev,
237462306a36Sopenharmony_ci								  radeon_get_encoder_enum
237562306a36Sopenharmony_ci								  (dev,
237662306a36Sopenharmony_ci								   ATOM_DEVICE_CRT2_SUPPORT,
237762306a36Sopenharmony_ci								   2),
237862306a36Sopenharmony_ci								  ATOM_DEVICE_CRT2_SUPPORT);
237962306a36Sopenharmony_ci				} else {
238062306a36Sopenharmony_ci					devices = ATOM_DEVICE_CRT1_SUPPORT;
238162306a36Sopenharmony_ci					radeon_add_legacy_encoder(dev,
238262306a36Sopenharmony_ci								  radeon_get_encoder_enum
238362306a36Sopenharmony_ci								  (dev,
238462306a36Sopenharmony_ci								   ATOM_DEVICE_CRT1_SUPPORT,
238562306a36Sopenharmony_ci								   1),
238662306a36Sopenharmony_ci								  ATOM_DEVICE_CRT1_SUPPORT);
238762306a36Sopenharmony_ci				}
238862306a36Sopenharmony_ci				radeon_add_legacy_connector(dev,
238962306a36Sopenharmony_ci							    i,
239062306a36Sopenharmony_ci							    devices,
239162306a36Sopenharmony_ci							    legacy_connector_convert
239262306a36Sopenharmony_ci							    [connector],
239362306a36Sopenharmony_ci							    &ddc_i2c,
239462306a36Sopenharmony_ci							    CONNECTOR_OBJECT_ID_VGA,
239562306a36Sopenharmony_ci							    &hpd);
239662306a36Sopenharmony_ci				break;
239762306a36Sopenharmony_ci			case CONNECTOR_DVI_I_LEGACY:
239862306a36Sopenharmony_ci				devices = 0;
239962306a36Sopenharmony_ci				if (tmp & 0x1) {
240062306a36Sopenharmony_ci					devices |= ATOM_DEVICE_CRT2_SUPPORT;
240162306a36Sopenharmony_ci					radeon_add_legacy_encoder(dev,
240262306a36Sopenharmony_ci								  radeon_get_encoder_enum
240362306a36Sopenharmony_ci								  (dev,
240462306a36Sopenharmony_ci								   ATOM_DEVICE_CRT2_SUPPORT,
240562306a36Sopenharmony_ci								   2),
240662306a36Sopenharmony_ci								  ATOM_DEVICE_CRT2_SUPPORT);
240762306a36Sopenharmony_ci				} else {
240862306a36Sopenharmony_ci					devices |= ATOM_DEVICE_CRT1_SUPPORT;
240962306a36Sopenharmony_ci					radeon_add_legacy_encoder(dev,
241062306a36Sopenharmony_ci								  radeon_get_encoder_enum
241162306a36Sopenharmony_ci								  (dev,
241262306a36Sopenharmony_ci								   ATOM_DEVICE_CRT1_SUPPORT,
241362306a36Sopenharmony_ci								   1),
241462306a36Sopenharmony_ci								  ATOM_DEVICE_CRT1_SUPPORT);
241562306a36Sopenharmony_ci				}
241662306a36Sopenharmony_ci				/* RV100 board with external TDMS bit mis-set.
241762306a36Sopenharmony_ci				 * Actually uses internal TMDS, clear the bit.
241862306a36Sopenharmony_ci				 */
241962306a36Sopenharmony_ci				if (rdev->pdev->device == 0x5159 &&
242062306a36Sopenharmony_ci				    rdev->pdev->subsystem_vendor == 0x1014 &&
242162306a36Sopenharmony_ci				    rdev->pdev->subsystem_device == 0x029A) {
242262306a36Sopenharmony_ci					tmp &= ~(1 << 4);
242362306a36Sopenharmony_ci				}
242462306a36Sopenharmony_ci				if ((tmp >> 4) & 0x1) {
242562306a36Sopenharmony_ci					devices |= ATOM_DEVICE_DFP2_SUPPORT;
242662306a36Sopenharmony_ci					radeon_add_legacy_encoder(dev,
242762306a36Sopenharmony_ci								  radeon_get_encoder_enum
242862306a36Sopenharmony_ci								  (dev,
242962306a36Sopenharmony_ci								   ATOM_DEVICE_DFP2_SUPPORT,
243062306a36Sopenharmony_ci								   0),
243162306a36Sopenharmony_ci								  ATOM_DEVICE_DFP2_SUPPORT);
243262306a36Sopenharmony_ci					connector_object_id = combios_check_dl_dvi(dev, 0);
243362306a36Sopenharmony_ci				} else {
243462306a36Sopenharmony_ci					devices |= ATOM_DEVICE_DFP1_SUPPORT;
243562306a36Sopenharmony_ci					radeon_add_legacy_encoder(dev,
243662306a36Sopenharmony_ci								  radeon_get_encoder_enum
243762306a36Sopenharmony_ci								  (dev,
243862306a36Sopenharmony_ci								   ATOM_DEVICE_DFP1_SUPPORT,
243962306a36Sopenharmony_ci								   0),
244062306a36Sopenharmony_ci								  ATOM_DEVICE_DFP1_SUPPORT);
244162306a36Sopenharmony_ci					connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
244262306a36Sopenharmony_ci				}
244362306a36Sopenharmony_ci				radeon_add_legacy_connector(dev,
244462306a36Sopenharmony_ci							    i,
244562306a36Sopenharmony_ci							    devices,
244662306a36Sopenharmony_ci							    legacy_connector_convert
244762306a36Sopenharmony_ci							    [connector],
244862306a36Sopenharmony_ci							    &ddc_i2c,
244962306a36Sopenharmony_ci							    connector_object_id,
245062306a36Sopenharmony_ci							    &hpd);
245162306a36Sopenharmony_ci				break;
245262306a36Sopenharmony_ci			case CONNECTOR_DVI_D_LEGACY:
245362306a36Sopenharmony_ci				if ((tmp >> 4) & 0x1) {
245462306a36Sopenharmony_ci					devices = ATOM_DEVICE_DFP2_SUPPORT;
245562306a36Sopenharmony_ci					connector_object_id = combios_check_dl_dvi(dev, 1);
245662306a36Sopenharmony_ci				} else {
245762306a36Sopenharmony_ci					devices = ATOM_DEVICE_DFP1_SUPPORT;
245862306a36Sopenharmony_ci					connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
245962306a36Sopenharmony_ci				}
246062306a36Sopenharmony_ci				radeon_add_legacy_encoder(dev,
246162306a36Sopenharmony_ci							  radeon_get_encoder_enum
246262306a36Sopenharmony_ci							  (dev, devices, 0),
246362306a36Sopenharmony_ci							  devices);
246462306a36Sopenharmony_ci				radeon_add_legacy_connector(dev, i, devices,
246562306a36Sopenharmony_ci							    legacy_connector_convert
246662306a36Sopenharmony_ci							    [connector],
246762306a36Sopenharmony_ci							    &ddc_i2c,
246862306a36Sopenharmony_ci							    connector_object_id,
246962306a36Sopenharmony_ci							    &hpd);
247062306a36Sopenharmony_ci				break;
247162306a36Sopenharmony_ci			case CONNECTOR_CTV_LEGACY:
247262306a36Sopenharmony_ci			case CONNECTOR_STV_LEGACY:
247362306a36Sopenharmony_ci				radeon_add_legacy_encoder(dev,
247462306a36Sopenharmony_ci							  radeon_get_encoder_enum
247562306a36Sopenharmony_ci							  (dev,
247662306a36Sopenharmony_ci							   ATOM_DEVICE_TV1_SUPPORT,
247762306a36Sopenharmony_ci							   2),
247862306a36Sopenharmony_ci							  ATOM_DEVICE_TV1_SUPPORT);
247962306a36Sopenharmony_ci				radeon_add_legacy_connector(dev, i,
248062306a36Sopenharmony_ci							    ATOM_DEVICE_TV1_SUPPORT,
248162306a36Sopenharmony_ci							    legacy_connector_convert
248262306a36Sopenharmony_ci							    [connector],
248362306a36Sopenharmony_ci							    &ddc_i2c,
248462306a36Sopenharmony_ci							    CONNECTOR_OBJECT_ID_SVIDEO,
248562306a36Sopenharmony_ci							    &hpd);
248662306a36Sopenharmony_ci				break;
248762306a36Sopenharmony_ci			default:
248862306a36Sopenharmony_ci				DRM_ERROR("Unknown connector type: %d\n",
248962306a36Sopenharmony_ci					  connector);
249062306a36Sopenharmony_ci				continue;
249162306a36Sopenharmony_ci			}
249262306a36Sopenharmony_ci
249362306a36Sopenharmony_ci		}
249462306a36Sopenharmony_ci	} else {
249562306a36Sopenharmony_ci		uint16_t tmds_info =
249662306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
249762306a36Sopenharmony_ci		if (tmds_info) {
249862306a36Sopenharmony_ci			DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n");
249962306a36Sopenharmony_ci
250062306a36Sopenharmony_ci			radeon_add_legacy_encoder(dev,
250162306a36Sopenharmony_ci						  radeon_get_encoder_enum(dev,
250262306a36Sopenharmony_ci									ATOM_DEVICE_CRT1_SUPPORT,
250362306a36Sopenharmony_ci									1),
250462306a36Sopenharmony_ci						  ATOM_DEVICE_CRT1_SUPPORT);
250562306a36Sopenharmony_ci			radeon_add_legacy_encoder(dev,
250662306a36Sopenharmony_ci						  radeon_get_encoder_enum(dev,
250762306a36Sopenharmony_ci									ATOM_DEVICE_DFP1_SUPPORT,
250862306a36Sopenharmony_ci									0),
250962306a36Sopenharmony_ci						  ATOM_DEVICE_DFP1_SUPPORT);
251062306a36Sopenharmony_ci
251162306a36Sopenharmony_ci			ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
251262306a36Sopenharmony_ci			hpd.hpd = RADEON_HPD_1;
251362306a36Sopenharmony_ci			radeon_add_legacy_connector(dev,
251462306a36Sopenharmony_ci						    0,
251562306a36Sopenharmony_ci						    ATOM_DEVICE_CRT1_SUPPORT |
251662306a36Sopenharmony_ci						    ATOM_DEVICE_DFP1_SUPPORT,
251762306a36Sopenharmony_ci						    DRM_MODE_CONNECTOR_DVII,
251862306a36Sopenharmony_ci						    &ddc_i2c,
251962306a36Sopenharmony_ci						    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
252062306a36Sopenharmony_ci						    &hpd);
252162306a36Sopenharmony_ci		} else {
252262306a36Sopenharmony_ci			uint16_t crt_info =
252362306a36Sopenharmony_ci				combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
252462306a36Sopenharmony_ci			DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n");
252562306a36Sopenharmony_ci			if (crt_info) {
252662306a36Sopenharmony_ci				radeon_add_legacy_encoder(dev,
252762306a36Sopenharmony_ci							  radeon_get_encoder_enum(dev,
252862306a36Sopenharmony_ci										ATOM_DEVICE_CRT1_SUPPORT,
252962306a36Sopenharmony_ci										1),
253062306a36Sopenharmony_ci							  ATOM_DEVICE_CRT1_SUPPORT);
253162306a36Sopenharmony_ci				ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
253262306a36Sopenharmony_ci				hpd.hpd = RADEON_HPD_NONE;
253362306a36Sopenharmony_ci				radeon_add_legacy_connector(dev,
253462306a36Sopenharmony_ci							    0,
253562306a36Sopenharmony_ci							    ATOM_DEVICE_CRT1_SUPPORT,
253662306a36Sopenharmony_ci							    DRM_MODE_CONNECTOR_VGA,
253762306a36Sopenharmony_ci							    &ddc_i2c,
253862306a36Sopenharmony_ci							    CONNECTOR_OBJECT_ID_VGA,
253962306a36Sopenharmony_ci							    &hpd);
254062306a36Sopenharmony_ci			} else {
254162306a36Sopenharmony_ci				DRM_DEBUG_KMS("No connector info found\n");
254262306a36Sopenharmony_ci				return false;
254362306a36Sopenharmony_ci			}
254462306a36Sopenharmony_ci		}
254562306a36Sopenharmony_ci	}
254662306a36Sopenharmony_ci
254762306a36Sopenharmony_ci	if (rdev->flags & RADEON_IS_MOBILITY || rdev->flags & RADEON_IS_IGP) {
254862306a36Sopenharmony_ci		uint16_t lcd_info =
254962306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
255062306a36Sopenharmony_ci		if (lcd_info) {
255162306a36Sopenharmony_ci			uint16_t lcd_ddc_info =
255262306a36Sopenharmony_ci			    combios_get_table_offset(dev,
255362306a36Sopenharmony_ci						     COMBIOS_LCD_DDC_INFO_TABLE);
255462306a36Sopenharmony_ci
255562306a36Sopenharmony_ci			radeon_add_legacy_encoder(dev,
255662306a36Sopenharmony_ci						  radeon_get_encoder_enum(dev,
255762306a36Sopenharmony_ci									ATOM_DEVICE_LCD1_SUPPORT,
255862306a36Sopenharmony_ci									0),
255962306a36Sopenharmony_ci						  ATOM_DEVICE_LCD1_SUPPORT);
256062306a36Sopenharmony_ci
256162306a36Sopenharmony_ci			if (lcd_ddc_info) {
256262306a36Sopenharmony_ci				ddc_type = RBIOS8(lcd_ddc_info + 2);
256362306a36Sopenharmony_ci				switch (ddc_type) {
256462306a36Sopenharmony_ci				case DDC_LCD:
256562306a36Sopenharmony_ci					ddc_i2c =
256662306a36Sopenharmony_ci						combios_setup_i2c_bus(rdev,
256762306a36Sopenharmony_ci								      DDC_LCD,
256862306a36Sopenharmony_ci								      RBIOS32(lcd_ddc_info + 3),
256962306a36Sopenharmony_ci								      RBIOS32(lcd_ddc_info + 7));
257062306a36Sopenharmony_ci					radeon_i2c_add(rdev, &ddc_i2c, "LCD");
257162306a36Sopenharmony_ci					break;
257262306a36Sopenharmony_ci				case DDC_GPIO:
257362306a36Sopenharmony_ci					ddc_i2c =
257462306a36Sopenharmony_ci						combios_setup_i2c_bus(rdev,
257562306a36Sopenharmony_ci								      DDC_GPIO,
257662306a36Sopenharmony_ci								      RBIOS32(lcd_ddc_info + 3),
257762306a36Sopenharmony_ci								      RBIOS32(lcd_ddc_info + 7));
257862306a36Sopenharmony_ci					radeon_i2c_add(rdev, &ddc_i2c, "LCD");
257962306a36Sopenharmony_ci					break;
258062306a36Sopenharmony_ci				default:
258162306a36Sopenharmony_ci					ddc_i2c =
258262306a36Sopenharmony_ci						combios_setup_i2c_bus(rdev, ddc_type, 0, 0);
258362306a36Sopenharmony_ci					break;
258462306a36Sopenharmony_ci				}
258562306a36Sopenharmony_ci				DRM_DEBUG_KMS("LCD DDC Info Table found!\n");
258662306a36Sopenharmony_ci			} else
258762306a36Sopenharmony_ci				ddc_i2c.valid = false;
258862306a36Sopenharmony_ci
258962306a36Sopenharmony_ci			hpd.hpd = RADEON_HPD_NONE;
259062306a36Sopenharmony_ci			radeon_add_legacy_connector(dev,
259162306a36Sopenharmony_ci						    5,
259262306a36Sopenharmony_ci						    ATOM_DEVICE_LCD1_SUPPORT,
259362306a36Sopenharmony_ci						    DRM_MODE_CONNECTOR_LVDS,
259462306a36Sopenharmony_ci						    &ddc_i2c,
259562306a36Sopenharmony_ci						    CONNECTOR_OBJECT_ID_LVDS,
259662306a36Sopenharmony_ci						    &hpd);
259762306a36Sopenharmony_ci		}
259862306a36Sopenharmony_ci	}
259962306a36Sopenharmony_ci
260062306a36Sopenharmony_ci	/* check TV table */
260162306a36Sopenharmony_ci	if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) {
260262306a36Sopenharmony_ci		uint32_t tv_info =
260362306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
260462306a36Sopenharmony_ci		if (tv_info) {
260562306a36Sopenharmony_ci			if (RBIOS8(tv_info + 6) == 'T') {
260662306a36Sopenharmony_ci				if (radeon_apply_legacy_tv_quirks(dev)) {
260762306a36Sopenharmony_ci					hpd.hpd = RADEON_HPD_NONE;
260862306a36Sopenharmony_ci					ddc_i2c.valid = false;
260962306a36Sopenharmony_ci					radeon_add_legacy_encoder(dev,
261062306a36Sopenharmony_ci								  radeon_get_encoder_enum
261162306a36Sopenharmony_ci								  (dev,
261262306a36Sopenharmony_ci								   ATOM_DEVICE_TV1_SUPPORT,
261362306a36Sopenharmony_ci								   2),
261462306a36Sopenharmony_ci								  ATOM_DEVICE_TV1_SUPPORT);
261562306a36Sopenharmony_ci					radeon_add_legacy_connector(dev, 6,
261662306a36Sopenharmony_ci								    ATOM_DEVICE_TV1_SUPPORT,
261762306a36Sopenharmony_ci								    DRM_MODE_CONNECTOR_SVIDEO,
261862306a36Sopenharmony_ci								    &ddc_i2c,
261962306a36Sopenharmony_ci								    CONNECTOR_OBJECT_ID_SVIDEO,
262062306a36Sopenharmony_ci								    &hpd);
262162306a36Sopenharmony_ci				}
262262306a36Sopenharmony_ci			}
262362306a36Sopenharmony_ci		}
262462306a36Sopenharmony_ci	}
262562306a36Sopenharmony_ci
262662306a36Sopenharmony_ci	radeon_link_encoder_connector(dev);
262762306a36Sopenharmony_ci
262862306a36Sopenharmony_ci	return true;
262962306a36Sopenharmony_ci}
263062306a36Sopenharmony_ci
263162306a36Sopenharmony_cistatic const char *thermal_controller_names[] = {
263262306a36Sopenharmony_ci	"NONE",
263362306a36Sopenharmony_ci	"lm63",
263462306a36Sopenharmony_ci	"adm1032",
263562306a36Sopenharmony_ci};
263662306a36Sopenharmony_ci
263762306a36Sopenharmony_civoid radeon_combios_get_power_modes(struct radeon_device *rdev)
263862306a36Sopenharmony_ci{
263962306a36Sopenharmony_ci	struct drm_device *dev = rdev->ddev;
264062306a36Sopenharmony_ci	u16 offset, misc, misc2 = 0;
264162306a36Sopenharmony_ci	u8 rev, tmp;
264262306a36Sopenharmony_ci	int state_index = 0;
264362306a36Sopenharmony_ci	struct radeon_i2c_bus_rec i2c_bus;
264462306a36Sopenharmony_ci
264562306a36Sopenharmony_ci	rdev->pm.default_power_state_index = -1;
264662306a36Sopenharmony_ci
264762306a36Sopenharmony_ci	/* allocate 2 power states */
264862306a36Sopenharmony_ci	rdev->pm.power_state = kcalloc(2, sizeof(struct radeon_power_state),
264962306a36Sopenharmony_ci				       GFP_KERNEL);
265062306a36Sopenharmony_ci	if (rdev->pm.power_state) {
265162306a36Sopenharmony_ci		/* allocate 1 clock mode per state */
265262306a36Sopenharmony_ci		rdev->pm.power_state[0].clock_info =
265362306a36Sopenharmony_ci			kcalloc(1, sizeof(struct radeon_pm_clock_info),
265462306a36Sopenharmony_ci				GFP_KERNEL);
265562306a36Sopenharmony_ci		rdev->pm.power_state[1].clock_info =
265662306a36Sopenharmony_ci			kcalloc(1, sizeof(struct radeon_pm_clock_info),
265762306a36Sopenharmony_ci				GFP_KERNEL);
265862306a36Sopenharmony_ci		if (!rdev->pm.power_state[0].clock_info ||
265962306a36Sopenharmony_ci		    !rdev->pm.power_state[1].clock_info)
266062306a36Sopenharmony_ci			goto pm_failed;
266162306a36Sopenharmony_ci	} else
266262306a36Sopenharmony_ci		goto pm_failed;
266362306a36Sopenharmony_ci
266462306a36Sopenharmony_ci	/* check for a thermal chip */
266562306a36Sopenharmony_ci	offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE);
266662306a36Sopenharmony_ci	if (offset) {
266762306a36Sopenharmony_ci		u8 thermal_controller = 0, gpio = 0, i2c_addr = 0, clk_bit = 0, data_bit = 0;
266862306a36Sopenharmony_ci
266962306a36Sopenharmony_ci		rev = RBIOS8(offset);
267062306a36Sopenharmony_ci
267162306a36Sopenharmony_ci		if (rev == 0) {
267262306a36Sopenharmony_ci			thermal_controller = RBIOS8(offset + 3);
267362306a36Sopenharmony_ci			gpio = RBIOS8(offset + 4) & 0x3f;
267462306a36Sopenharmony_ci			i2c_addr = RBIOS8(offset + 5);
267562306a36Sopenharmony_ci		} else if (rev == 1) {
267662306a36Sopenharmony_ci			thermal_controller = RBIOS8(offset + 4);
267762306a36Sopenharmony_ci			gpio = RBIOS8(offset + 5) & 0x3f;
267862306a36Sopenharmony_ci			i2c_addr = RBIOS8(offset + 6);
267962306a36Sopenharmony_ci		} else if (rev == 2) {
268062306a36Sopenharmony_ci			thermal_controller = RBIOS8(offset + 4);
268162306a36Sopenharmony_ci			gpio = RBIOS8(offset + 5) & 0x3f;
268262306a36Sopenharmony_ci			i2c_addr = RBIOS8(offset + 6);
268362306a36Sopenharmony_ci			clk_bit = RBIOS8(offset + 0xa);
268462306a36Sopenharmony_ci			data_bit = RBIOS8(offset + 0xb);
268562306a36Sopenharmony_ci		}
268662306a36Sopenharmony_ci		if ((thermal_controller > 0) && (thermal_controller < 3)) {
268762306a36Sopenharmony_ci			DRM_INFO("Possible %s thermal controller at 0x%02x\n",
268862306a36Sopenharmony_ci				 thermal_controller_names[thermal_controller],
268962306a36Sopenharmony_ci				 i2c_addr >> 1);
269062306a36Sopenharmony_ci			if (gpio == DDC_LCD) {
269162306a36Sopenharmony_ci				/* MM i2c */
269262306a36Sopenharmony_ci				i2c_bus.valid = true;
269362306a36Sopenharmony_ci				i2c_bus.hw_capable = true;
269462306a36Sopenharmony_ci				i2c_bus.mm_i2c = true;
269562306a36Sopenharmony_ci				i2c_bus.i2c_id = 0xa0;
269662306a36Sopenharmony_ci			} else if (gpio == DDC_GPIO)
269762306a36Sopenharmony_ci				i2c_bus = combios_setup_i2c_bus(rdev, gpio, 1 << clk_bit, 1 << data_bit);
269862306a36Sopenharmony_ci			else
269962306a36Sopenharmony_ci				i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0);
270062306a36Sopenharmony_ci			rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
270162306a36Sopenharmony_ci			if (rdev->pm.i2c_bus) {
270262306a36Sopenharmony_ci				struct i2c_board_info info = { };
270362306a36Sopenharmony_ci				const char *name = thermal_controller_names[thermal_controller];
270462306a36Sopenharmony_ci				info.addr = i2c_addr >> 1;
270562306a36Sopenharmony_ci				strscpy(info.type, name, sizeof(info.type));
270662306a36Sopenharmony_ci				i2c_new_client_device(&rdev->pm.i2c_bus->adapter, &info);
270762306a36Sopenharmony_ci			}
270862306a36Sopenharmony_ci		}
270962306a36Sopenharmony_ci	} else {
271062306a36Sopenharmony_ci		/* boards with a thermal chip, but no overdrive table */
271162306a36Sopenharmony_ci
271262306a36Sopenharmony_ci		/* Asus 9600xt has an f75375 on the monid bus */
271362306a36Sopenharmony_ci		if ((rdev->pdev->device == 0x4152) &&
271462306a36Sopenharmony_ci		    (rdev->pdev->subsystem_vendor == 0x1043) &&
271562306a36Sopenharmony_ci		    (rdev->pdev->subsystem_device == 0xc002)) {
271662306a36Sopenharmony_ci			i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
271762306a36Sopenharmony_ci			rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
271862306a36Sopenharmony_ci			if (rdev->pm.i2c_bus) {
271962306a36Sopenharmony_ci				struct i2c_board_info info = { };
272062306a36Sopenharmony_ci				const char *name = "f75375";
272162306a36Sopenharmony_ci				info.addr = 0x28;
272262306a36Sopenharmony_ci				strscpy(info.type, name, sizeof(info.type));
272362306a36Sopenharmony_ci				i2c_new_client_device(&rdev->pm.i2c_bus->adapter, &info);
272462306a36Sopenharmony_ci				DRM_INFO("Possible %s thermal controller at 0x%02x\n",
272562306a36Sopenharmony_ci					 name, info.addr);
272662306a36Sopenharmony_ci			}
272762306a36Sopenharmony_ci		}
272862306a36Sopenharmony_ci	}
272962306a36Sopenharmony_ci
273062306a36Sopenharmony_ci	if (rdev->flags & RADEON_IS_MOBILITY) {
273162306a36Sopenharmony_ci		offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE);
273262306a36Sopenharmony_ci		if (offset) {
273362306a36Sopenharmony_ci			rev = RBIOS8(offset);
273462306a36Sopenharmony_ci			/* power mode 0 tends to be the only valid one */
273562306a36Sopenharmony_ci			rdev->pm.power_state[state_index].num_clock_modes = 1;
273662306a36Sopenharmony_ci			rdev->pm.power_state[state_index].clock_info[0].mclk = RBIOS32(offset + 0x5 + 0x2);
273762306a36Sopenharmony_ci			rdev->pm.power_state[state_index].clock_info[0].sclk = RBIOS32(offset + 0x5 + 0x6);
273862306a36Sopenharmony_ci			if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
273962306a36Sopenharmony_ci			    (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
274062306a36Sopenharmony_ci				goto default_mode;
274162306a36Sopenharmony_ci			rdev->pm.power_state[state_index].type =
274262306a36Sopenharmony_ci				POWER_STATE_TYPE_BATTERY;
274362306a36Sopenharmony_ci			misc = RBIOS16(offset + 0x5 + 0x0);
274462306a36Sopenharmony_ci			if (rev > 4)
274562306a36Sopenharmony_ci				misc2 = RBIOS16(offset + 0x5 + 0xe);
274662306a36Sopenharmony_ci			rdev->pm.power_state[state_index].misc = misc;
274762306a36Sopenharmony_ci			rdev->pm.power_state[state_index].misc2 = misc2;
274862306a36Sopenharmony_ci			if (misc & 0x4) {
274962306a36Sopenharmony_ci				rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO;
275062306a36Sopenharmony_ci				if (misc & 0x8)
275162306a36Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
275262306a36Sopenharmony_ci						true;
275362306a36Sopenharmony_ci				else
275462306a36Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
275562306a36Sopenharmony_ci						false;
275662306a36Sopenharmony_ci				rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = true;
275762306a36Sopenharmony_ci				if (rev < 6) {
275862306a36Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg =
275962306a36Sopenharmony_ci						RBIOS16(offset + 0x5 + 0xb) * 4;
276062306a36Sopenharmony_ci					tmp = RBIOS8(offset + 0x5 + 0xd);
276162306a36Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp);
276262306a36Sopenharmony_ci				} else {
276362306a36Sopenharmony_ci					u8 entries = RBIOS8(offset + 0x5 + 0xb);
276462306a36Sopenharmony_ci					u16 voltage_table_offset = RBIOS16(offset + 0x5 + 0xc);
276562306a36Sopenharmony_ci					if (entries && voltage_table_offset) {
276662306a36Sopenharmony_ci						rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg =
276762306a36Sopenharmony_ci							RBIOS16(voltage_table_offset) * 4;
276862306a36Sopenharmony_ci						tmp = RBIOS8(voltage_table_offset + 0x2);
276962306a36Sopenharmony_ci						rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp);
277062306a36Sopenharmony_ci					} else
277162306a36Sopenharmony_ci						rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = false;
277262306a36Sopenharmony_ci				}
277362306a36Sopenharmony_ci				switch ((misc2 & 0x700) >> 8) {
277462306a36Sopenharmony_ci				case 0:
277562306a36Sopenharmony_ci				default:
277662306a36Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 0;
277762306a36Sopenharmony_ci					break;
277862306a36Sopenharmony_ci				case 1:
277962306a36Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 33;
278062306a36Sopenharmony_ci					break;
278162306a36Sopenharmony_ci				case 2:
278262306a36Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 66;
278362306a36Sopenharmony_ci					break;
278462306a36Sopenharmony_ci				case 3:
278562306a36Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 99;
278662306a36Sopenharmony_ci					break;
278762306a36Sopenharmony_ci				case 4:
278862306a36Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 132;
278962306a36Sopenharmony_ci					break;
279062306a36Sopenharmony_ci				}
279162306a36Sopenharmony_ci			} else
279262306a36Sopenharmony_ci				rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
279362306a36Sopenharmony_ci			if (rev > 6)
279462306a36Sopenharmony_ci				rdev->pm.power_state[state_index].pcie_lanes =
279562306a36Sopenharmony_ci					RBIOS8(offset + 0x5 + 0x10);
279662306a36Sopenharmony_ci			rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
279762306a36Sopenharmony_ci			state_index++;
279862306a36Sopenharmony_ci		} else {
279962306a36Sopenharmony_ci			/* XXX figure out some good default low power mode for mobility cards w/out power tables */
280062306a36Sopenharmony_ci		}
280162306a36Sopenharmony_ci	} else {
280262306a36Sopenharmony_ci		/* XXX figure out some good default low power mode for desktop cards */
280362306a36Sopenharmony_ci	}
280462306a36Sopenharmony_ci
280562306a36Sopenharmony_cidefault_mode:
280662306a36Sopenharmony_ci	/* add the default mode */
280762306a36Sopenharmony_ci	rdev->pm.power_state[state_index].type =
280862306a36Sopenharmony_ci		POWER_STATE_TYPE_DEFAULT;
280962306a36Sopenharmony_ci	rdev->pm.power_state[state_index].num_clock_modes = 1;
281062306a36Sopenharmony_ci	rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
281162306a36Sopenharmony_ci	rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
281262306a36Sopenharmony_ci	rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0];
281362306a36Sopenharmony_ci	if ((state_index > 0) &&
281462306a36Sopenharmony_ci	    (rdev->pm.power_state[0].clock_info[0].voltage.type == VOLTAGE_GPIO))
281562306a36Sopenharmony_ci		rdev->pm.power_state[state_index].clock_info[0].voltage =
281662306a36Sopenharmony_ci			rdev->pm.power_state[0].clock_info[0].voltage;
281762306a36Sopenharmony_ci	else
281862306a36Sopenharmony_ci		rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
281962306a36Sopenharmony_ci	rdev->pm.power_state[state_index].pcie_lanes = 16;
282062306a36Sopenharmony_ci	rdev->pm.power_state[state_index].flags = 0;
282162306a36Sopenharmony_ci	rdev->pm.default_power_state_index = state_index;
282262306a36Sopenharmony_ci	rdev->pm.num_power_states = state_index + 1;
282362306a36Sopenharmony_ci
282462306a36Sopenharmony_ci	rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
282562306a36Sopenharmony_ci	rdev->pm.current_clock_mode_index = 0;
282662306a36Sopenharmony_ci	return;
282762306a36Sopenharmony_ci
282862306a36Sopenharmony_cipm_failed:
282962306a36Sopenharmony_ci	rdev->pm.default_power_state_index = state_index;
283062306a36Sopenharmony_ci	rdev->pm.num_power_states = 0;
283162306a36Sopenharmony_ci
283262306a36Sopenharmony_ci	rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
283362306a36Sopenharmony_ci	rdev->pm.current_clock_mode_index = 0;
283462306a36Sopenharmony_ci}
283562306a36Sopenharmony_ci
283662306a36Sopenharmony_civoid radeon_external_tmds_setup(struct drm_encoder *encoder)
283762306a36Sopenharmony_ci{
283862306a36Sopenharmony_ci	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
283962306a36Sopenharmony_ci	struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
284062306a36Sopenharmony_ci
284162306a36Sopenharmony_ci	if (!tmds)
284262306a36Sopenharmony_ci		return;
284362306a36Sopenharmony_ci
284462306a36Sopenharmony_ci	switch (tmds->dvo_chip) {
284562306a36Sopenharmony_ci	case DVO_SIL164:
284662306a36Sopenharmony_ci		/* sil 164 */
284762306a36Sopenharmony_ci		radeon_i2c_put_byte(tmds->i2c_bus,
284862306a36Sopenharmony_ci				    tmds->slave_addr,
284962306a36Sopenharmony_ci				    0x08, 0x30);
285062306a36Sopenharmony_ci		radeon_i2c_put_byte(tmds->i2c_bus,
285162306a36Sopenharmony_ci				       tmds->slave_addr,
285262306a36Sopenharmony_ci				       0x09, 0x00);
285362306a36Sopenharmony_ci		radeon_i2c_put_byte(tmds->i2c_bus,
285462306a36Sopenharmony_ci				    tmds->slave_addr,
285562306a36Sopenharmony_ci				    0x0a, 0x90);
285662306a36Sopenharmony_ci		radeon_i2c_put_byte(tmds->i2c_bus,
285762306a36Sopenharmony_ci				    tmds->slave_addr,
285862306a36Sopenharmony_ci				    0x0c, 0x89);
285962306a36Sopenharmony_ci		radeon_i2c_put_byte(tmds->i2c_bus,
286062306a36Sopenharmony_ci				       tmds->slave_addr,
286162306a36Sopenharmony_ci				       0x08, 0x3b);
286262306a36Sopenharmony_ci		break;
286362306a36Sopenharmony_ci	case DVO_SIL1178:
286462306a36Sopenharmony_ci		/* sil 1178 - untested */
286562306a36Sopenharmony_ci		/*
286662306a36Sopenharmony_ci		 * 0x0f, 0x44
286762306a36Sopenharmony_ci		 * 0x0f, 0x4c
286862306a36Sopenharmony_ci		 * 0x0e, 0x01
286962306a36Sopenharmony_ci		 * 0x0a, 0x80
287062306a36Sopenharmony_ci		 * 0x09, 0x30
287162306a36Sopenharmony_ci		 * 0x0c, 0xc9
287262306a36Sopenharmony_ci		 * 0x0d, 0x70
287362306a36Sopenharmony_ci		 * 0x08, 0x32
287462306a36Sopenharmony_ci		 * 0x08, 0x33
287562306a36Sopenharmony_ci		 */
287662306a36Sopenharmony_ci		break;
287762306a36Sopenharmony_ci	default:
287862306a36Sopenharmony_ci		break;
287962306a36Sopenharmony_ci	}
288062306a36Sopenharmony_ci
288162306a36Sopenharmony_ci}
288262306a36Sopenharmony_ci
288362306a36Sopenharmony_cibool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
288462306a36Sopenharmony_ci{
288562306a36Sopenharmony_ci	struct drm_device *dev = encoder->dev;
288662306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
288762306a36Sopenharmony_ci	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
288862306a36Sopenharmony_ci	uint16_t offset;
288962306a36Sopenharmony_ci	uint8_t blocks, slave_addr, rev;
289062306a36Sopenharmony_ci	uint32_t index, id;
289162306a36Sopenharmony_ci	uint32_t reg, val, and_mask, or_mask;
289262306a36Sopenharmony_ci	struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
289362306a36Sopenharmony_ci
289462306a36Sopenharmony_ci	if (!tmds)
289562306a36Sopenharmony_ci		return false;
289662306a36Sopenharmony_ci
289762306a36Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP) {
289862306a36Sopenharmony_ci		offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_ON_TABLE);
289962306a36Sopenharmony_ci		rev = RBIOS8(offset);
290062306a36Sopenharmony_ci		if (offset) {
290162306a36Sopenharmony_ci			rev = RBIOS8(offset);
290262306a36Sopenharmony_ci			if (rev > 1) {
290362306a36Sopenharmony_ci				blocks = RBIOS8(offset + 3);
290462306a36Sopenharmony_ci				index = offset + 4;
290562306a36Sopenharmony_ci				while (blocks > 0) {
290662306a36Sopenharmony_ci					id = RBIOS16(index);
290762306a36Sopenharmony_ci					index += 2;
290862306a36Sopenharmony_ci					switch (id >> 13) {
290962306a36Sopenharmony_ci					case 0:
291062306a36Sopenharmony_ci						reg = (id & 0x1fff) * 4;
291162306a36Sopenharmony_ci						val = RBIOS32(index);
291262306a36Sopenharmony_ci						index += 4;
291362306a36Sopenharmony_ci						WREG32(reg, val);
291462306a36Sopenharmony_ci						break;
291562306a36Sopenharmony_ci					case 2:
291662306a36Sopenharmony_ci						reg = (id & 0x1fff) * 4;
291762306a36Sopenharmony_ci						and_mask = RBIOS32(index);
291862306a36Sopenharmony_ci						index += 4;
291962306a36Sopenharmony_ci						or_mask = RBIOS32(index);
292062306a36Sopenharmony_ci						index += 4;
292162306a36Sopenharmony_ci						val = RREG32(reg);
292262306a36Sopenharmony_ci						val = (val & and_mask) | or_mask;
292362306a36Sopenharmony_ci						WREG32(reg, val);
292462306a36Sopenharmony_ci						break;
292562306a36Sopenharmony_ci					case 3:
292662306a36Sopenharmony_ci						val = RBIOS16(index);
292762306a36Sopenharmony_ci						index += 2;
292862306a36Sopenharmony_ci						udelay(val);
292962306a36Sopenharmony_ci						break;
293062306a36Sopenharmony_ci					case 4:
293162306a36Sopenharmony_ci						val = RBIOS16(index);
293262306a36Sopenharmony_ci						index += 2;
293362306a36Sopenharmony_ci						mdelay(val);
293462306a36Sopenharmony_ci						break;
293562306a36Sopenharmony_ci					case 6:
293662306a36Sopenharmony_ci						slave_addr = id & 0xff;
293762306a36Sopenharmony_ci						slave_addr >>= 1; /* 7 bit addressing */
293862306a36Sopenharmony_ci						index++;
293962306a36Sopenharmony_ci						reg = RBIOS8(index);
294062306a36Sopenharmony_ci						index++;
294162306a36Sopenharmony_ci						val = RBIOS8(index);
294262306a36Sopenharmony_ci						index++;
294362306a36Sopenharmony_ci						radeon_i2c_put_byte(tmds->i2c_bus,
294462306a36Sopenharmony_ci								    slave_addr,
294562306a36Sopenharmony_ci								    reg, val);
294662306a36Sopenharmony_ci						break;
294762306a36Sopenharmony_ci					default:
294862306a36Sopenharmony_ci						DRM_ERROR("Unknown id %d\n", id >> 13);
294962306a36Sopenharmony_ci						break;
295062306a36Sopenharmony_ci					}
295162306a36Sopenharmony_ci					blocks--;
295262306a36Sopenharmony_ci				}
295362306a36Sopenharmony_ci				return true;
295462306a36Sopenharmony_ci			}
295562306a36Sopenharmony_ci		}
295662306a36Sopenharmony_ci	} else {
295762306a36Sopenharmony_ci		offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
295862306a36Sopenharmony_ci		if (offset) {
295962306a36Sopenharmony_ci			index = offset + 10;
296062306a36Sopenharmony_ci			id = RBIOS16(index);
296162306a36Sopenharmony_ci			while (id != 0xffff) {
296262306a36Sopenharmony_ci				index += 2;
296362306a36Sopenharmony_ci				switch (id >> 13) {
296462306a36Sopenharmony_ci				case 0:
296562306a36Sopenharmony_ci					reg = (id & 0x1fff) * 4;
296662306a36Sopenharmony_ci					val = RBIOS32(index);
296762306a36Sopenharmony_ci					WREG32(reg, val);
296862306a36Sopenharmony_ci					break;
296962306a36Sopenharmony_ci				case 2:
297062306a36Sopenharmony_ci					reg = (id & 0x1fff) * 4;
297162306a36Sopenharmony_ci					and_mask = RBIOS32(index);
297262306a36Sopenharmony_ci					index += 4;
297362306a36Sopenharmony_ci					or_mask = RBIOS32(index);
297462306a36Sopenharmony_ci					index += 4;
297562306a36Sopenharmony_ci					val = RREG32(reg);
297662306a36Sopenharmony_ci					val = (val & and_mask) | or_mask;
297762306a36Sopenharmony_ci					WREG32(reg, val);
297862306a36Sopenharmony_ci					break;
297962306a36Sopenharmony_ci				case 4:
298062306a36Sopenharmony_ci					val = RBIOS16(index);
298162306a36Sopenharmony_ci					index += 2;
298262306a36Sopenharmony_ci					udelay(val);
298362306a36Sopenharmony_ci					break;
298462306a36Sopenharmony_ci				case 5:
298562306a36Sopenharmony_ci					reg = id & 0x1fff;
298662306a36Sopenharmony_ci					and_mask = RBIOS32(index);
298762306a36Sopenharmony_ci					index += 4;
298862306a36Sopenharmony_ci					or_mask = RBIOS32(index);
298962306a36Sopenharmony_ci					index += 4;
299062306a36Sopenharmony_ci					val = RREG32_PLL(reg);
299162306a36Sopenharmony_ci					val = (val & and_mask) | or_mask;
299262306a36Sopenharmony_ci					WREG32_PLL(reg, val);
299362306a36Sopenharmony_ci					break;
299462306a36Sopenharmony_ci				case 6:
299562306a36Sopenharmony_ci					reg = id & 0x1fff;
299662306a36Sopenharmony_ci					val = RBIOS8(index);
299762306a36Sopenharmony_ci					index += 1;
299862306a36Sopenharmony_ci					radeon_i2c_put_byte(tmds->i2c_bus,
299962306a36Sopenharmony_ci							    tmds->slave_addr,
300062306a36Sopenharmony_ci							    reg, val);
300162306a36Sopenharmony_ci					break;
300262306a36Sopenharmony_ci				default:
300362306a36Sopenharmony_ci					DRM_ERROR("Unknown id %d\n", id >> 13);
300462306a36Sopenharmony_ci					break;
300562306a36Sopenharmony_ci				}
300662306a36Sopenharmony_ci				id = RBIOS16(index);
300762306a36Sopenharmony_ci			}
300862306a36Sopenharmony_ci			return true;
300962306a36Sopenharmony_ci		}
301062306a36Sopenharmony_ci	}
301162306a36Sopenharmony_ci	return false;
301262306a36Sopenharmony_ci}
301362306a36Sopenharmony_ci
301462306a36Sopenharmony_cistatic void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset)
301562306a36Sopenharmony_ci{
301662306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
301762306a36Sopenharmony_ci
301862306a36Sopenharmony_ci	if (offset) {
301962306a36Sopenharmony_ci		while (RBIOS16(offset)) {
302062306a36Sopenharmony_ci			uint16_t cmd = ((RBIOS16(offset) & 0xe000) >> 13);
302162306a36Sopenharmony_ci			uint32_t addr = (RBIOS16(offset) & 0x1fff);
302262306a36Sopenharmony_ci			uint32_t val, and_mask, or_mask;
302362306a36Sopenharmony_ci			uint32_t tmp;
302462306a36Sopenharmony_ci
302562306a36Sopenharmony_ci			offset += 2;
302662306a36Sopenharmony_ci			switch (cmd) {
302762306a36Sopenharmony_ci			case 0:
302862306a36Sopenharmony_ci				val = RBIOS32(offset);
302962306a36Sopenharmony_ci				offset += 4;
303062306a36Sopenharmony_ci				WREG32(addr, val);
303162306a36Sopenharmony_ci				break;
303262306a36Sopenharmony_ci			case 1:
303362306a36Sopenharmony_ci				val = RBIOS32(offset);
303462306a36Sopenharmony_ci				offset += 4;
303562306a36Sopenharmony_ci				WREG32(addr, val);
303662306a36Sopenharmony_ci				break;
303762306a36Sopenharmony_ci			case 2:
303862306a36Sopenharmony_ci				and_mask = RBIOS32(offset);
303962306a36Sopenharmony_ci				offset += 4;
304062306a36Sopenharmony_ci				or_mask = RBIOS32(offset);
304162306a36Sopenharmony_ci				offset += 4;
304262306a36Sopenharmony_ci				tmp = RREG32(addr);
304362306a36Sopenharmony_ci				tmp &= and_mask;
304462306a36Sopenharmony_ci				tmp |= or_mask;
304562306a36Sopenharmony_ci				WREG32(addr, tmp);
304662306a36Sopenharmony_ci				break;
304762306a36Sopenharmony_ci			case 3:
304862306a36Sopenharmony_ci				and_mask = RBIOS32(offset);
304962306a36Sopenharmony_ci				offset += 4;
305062306a36Sopenharmony_ci				or_mask = RBIOS32(offset);
305162306a36Sopenharmony_ci				offset += 4;
305262306a36Sopenharmony_ci				tmp = RREG32(addr);
305362306a36Sopenharmony_ci				tmp &= and_mask;
305462306a36Sopenharmony_ci				tmp |= or_mask;
305562306a36Sopenharmony_ci				WREG32(addr, tmp);
305662306a36Sopenharmony_ci				break;
305762306a36Sopenharmony_ci			case 4:
305862306a36Sopenharmony_ci				val = RBIOS16(offset);
305962306a36Sopenharmony_ci				offset += 2;
306062306a36Sopenharmony_ci				udelay(val);
306162306a36Sopenharmony_ci				break;
306262306a36Sopenharmony_ci			case 5:
306362306a36Sopenharmony_ci				val = RBIOS16(offset);
306462306a36Sopenharmony_ci				offset += 2;
306562306a36Sopenharmony_ci				switch (addr) {
306662306a36Sopenharmony_ci				case 8:
306762306a36Sopenharmony_ci					while (val--) {
306862306a36Sopenharmony_ci						if (!
306962306a36Sopenharmony_ci						    (RREG32_PLL
307062306a36Sopenharmony_ci						     (RADEON_CLK_PWRMGT_CNTL) &
307162306a36Sopenharmony_ci						     RADEON_MC_BUSY))
307262306a36Sopenharmony_ci							break;
307362306a36Sopenharmony_ci					}
307462306a36Sopenharmony_ci					break;
307562306a36Sopenharmony_ci				case 9:
307662306a36Sopenharmony_ci					while (val--) {
307762306a36Sopenharmony_ci						if ((RREG32(RADEON_MC_STATUS) &
307862306a36Sopenharmony_ci						     RADEON_MC_IDLE))
307962306a36Sopenharmony_ci							break;
308062306a36Sopenharmony_ci					}
308162306a36Sopenharmony_ci					break;
308262306a36Sopenharmony_ci				default:
308362306a36Sopenharmony_ci					break;
308462306a36Sopenharmony_ci				}
308562306a36Sopenharmony_ci				break;
308662306a36Sopenharmony_ci			default:
308762306a36Sopenharmony_ci				break;
308862306a36Sopenharmony_ci			}
308962306a36Sopenharmony_ci		}
309062306a36Sopenharmony_ci	}
309162306a36Sopenharmony_ci}
309262306a36Sopenharmony_ci
309362306a36Sopenharmony_cistatic void combios_parse_pll_table(struct drm_device *dev, uint16_t offset)
309462306a36Sopenharmony_ci{
309562306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
309662306a36Sopenharmony_ci
309762306a36Sopenharmony_ci	if (offset) {
309862306a36Sopenharmony_ci		while (RBIOS8(offset)) {
309962306a36Sopenharmony_ci			uint8_t cmd = ((RBIOS8(offset) & 0xc0) >> 6);
310062306a36Sopenharmony_ci			uint8_t addr = (RBIOS8(offset) & 0x3f);
310162306a36Sopenharmony_ci			uint32_t val, shift, tmp;
310262306a36Sopenharmony_ci			uint32_t and_mask, or_mask;
310362306a36Sopenharmony_ci
310462306a36Sopenharmony_ci			offset++;
310562306a36Sopenharmony_ci			switch (cmd) {
310662306a36Sopenharmony_ci			case 0:
310762306a36Sopenharmony_ci				val = RBIOS32(offset);
310862306a36Sopenharmony_ci				offset += 4;
310962306a36Sopenharmony_ci				WREG32_PLL(addr, val);
311062306a36Sopenharmony_ci				break;
311162306a36Sopenharmony_ci			case 1:
311262306a36Sopenharmony_ci				shift = RBIOS8(offset) * 8;
311362306a36Sopenharmony_ci				offset++;
311462306a36Sopenharmony_ci				and_mask = RBIOS8(offset) << shift;
311562306a36Sopenharmony_ci				and_mask |= ~(0xff << shift);
311662306a36Sopenharmony_ci				offset++;
311762306a36Sopenharmony_ci				or_mask = RBIOS8(offset) << shift;
311862306a36Sopenharmony_ci				offset++;
311962306a36Sopenharmony_ci				tmp = RREG32_PLL(addr);
312062306a36Sopenharmony_ci				tmp &= and_mask;
312162306a36Sopenharmony_ci				tmp |= or_mask;
312262306a36Sopenharmony_ci				WREG32_PLL(addr, tmp);
312362306a36Sopenharmony_ci				break;
312462306a36Sopenharmony_ci			case 2:
312562306a36Sopenharmony_ci			case 3:
312662306a36Sopenharmony_ci				tmp = 1000;
312762306a36Sopenharmony_ci				switch (addr) {
312862306a36Sopenharmony_ci				case 1:
312962306a36Sopenharmony_ci					udelay(150);
313062306a36Sopenharmony_ci					break;
313162306a36Sopenharmony_ci				case 2:
313262306a36Sopenharmony_ci					mdelay(1);
313362306a36Sopenharmony_ci					break;
313462306a36Sopenharmony_ci				case 3:
313562306a36Sopenharmony_ci					while (tmp--) {
313662306a36Sopenharmony_ci						if (!
313762306a36Sopenharmony_ci						    (RREG32_PLL
313862306a36Sopenharmony_ci						     (RADEON_CLK_PWRMGT_CNTL) &
313962306a36Sopenharmony_ci						     RADEON_MC_BUSY))
314062306a36Sopenharmony_ci							break;
314162306a36Sopenharmony_ci					}
314262306a36Sopenharmony_ci					break;
314362306a36Sopenharmony_ci				case 4:
314462306a36Sopenharmony_ci					while (tmp--) {
314562306a36Sopenharmony_ci						if (RREG32_PLL
314662306a36Sopenharmony_ci						    (RADEON_CLK_PWRMGT_CNTL) &
314762306a36Sopenharmony_ci						    RADEON_DLL_READY)
314862306a36Sopenharmony_ci							break;
314962306a36Sopenharmony_ci					}
315062306a36Sopenharmony_ci					break;
315162306a36Sopenharmony_ci				case 5:
315262306a36Sopenharmony_ci					tmp =
315362306a36Sopenharmony_ci					    RREG32_PLL(RADEON_CLK_PWRMGT_CNTL);
315462306a36Sopenharmony_ci					if (tmp & RADEON_CG_NO1_DEBUG_0) {
315562306a36Sopenharmony_ci#if 0
315662306a36Sopenharmony_ci						uint32_t mclk_cntl =
315762306a36Sopenharmony_ci						    RREG32_PLL
315862306a36Sopenharmony_ci						    (RADEON_MCLK_CNTL);
315962306a36Sopenharmony_ci						mclk_cntl &= 0xffff0000;
316062306a36Sopenharmony_ci						/*mclk_cntl |= 0x00001111;*//* ??? */
316162306a36Sopenharmony_ci						WREG32_PLL(RADEON_MCLK_CNTL,
316262306a36Sopenharmony_ci							   mclk_cntl);
316362306a36Sopenharmony_ci						mdelay(10);
316462306a36Sopenharmony_ci#endif
316562306a36Sopenharmony_ci						WREG32_PLL
316662306a36Sopenharmony_ci						    (RADEON_CLK_PWRMGT_CNTL,
316762306a36Sopenharmony_ci						     tmp &
316862306a36Sopenharmony_ci						     ~RADEON_CG_NO1_DEBUG_0);
316962306a36Sopenharmony_ci						mdelay(10);
317062306a36Sopenharmony_ci					}
317162306a36Sopenharmony_ci					break;
317262306a36Sopenharmony_ci				default:
317362306a36Sopenharmony_ci					break;
317462306a36Sopenharmony_ci				}
317562306a36Sopenharmony_ci				break;
317662306a36Sopenharmony_ci			default:
317762306a36Sopenharmony_ci				break;
317862306a36Sopenharmony_ci			}
317962306a36Sopenharmony_ci		}
318062306a36Sopenharmony_ci	}
318162306a36Sopenharmony_ci}
318262306a36Sopenharmony_ci
318362306a36Sopenharmony_cistatic void combios_parse_ram_reset_table(struct drm_device *dev,
318462306a36Sopenharmony_ci					  uint16_t offset)
318562306a36Sopenharmony_ci{
318662306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
318762306a36Sopenharmony_ci	uint32_t tmp;
318862306a36Sopenharmony_ci
318962306a36Sopenharmony_ci	if (offset) {
319062306a36Sopenharmony_ci		uint8_t val = RBIOS8(offset);
319162306a36Sopenharmony_ci		while (val != 0xff) {
319262306a36Sopenharmony_ci			offset++;
319362306a36Sopenharmony_ci
319462306a36Sopenharmony_ci			if (val == 0x0f) {
319562306a36Sopenharmony_ci				uint32_t channel_complete_mask;
319662306a36Sopenharmony_ci
319762306a36Sopenharmony_ci				if (ASIC_IS_R300(rdev))
319862306a36Sopenharmony_ci					channel_complete_mask =
319962306a36Sopenharmony_ci					    R300_MEM_PWRUP_COMPLETE;
320062306a36Sopenharmony_ci				else
320162306a36Sopenharmony_ci					channel_complete_mask =
320262306a36Sopenharmony_ci					    RADEON_MEM_PWRUP_COMPLETE;
320362306a36Sopenharmony_ci				tmp = 20000;
320462306a36Sopenharmony_ci				while (tmp--) {
320562306a36Sopenharmony_ci					if ((RREG32(RADEON_MEM_STR_CNTL) &
320662306a36Sopenharmony_ci					     channel_complete_mask) ==
320762306a36Sopenharmony_ci					    channel_complete_mask)
320862306a36Sopenharmony_ci						break;
320962306a36Sopenharmony_ci				}
321062306a36Sopenharmony_ci			} else {
321162306a36Sopenharmony_ci				uint32_t or_mask = RBIOS16(offset);
321262306a36Sopenharmony_ci				offset += 2;
321362306a36Sopenharmony_ci
321462306a36Sopenharmony_ci				tmp = RREG32(RADEON_MEM_SDRAM_MODE_REG);
321562306a36Sopenharmony_ci				tmp &= RADEON_SDRAM_MODE_MASK;
321662306a36Sopenharmony_ci				tmp |= or_mask;
321762306a36Sopenharmony_ci				WREG32(RADEON_MEM_SDRAM_MODE_REG, tmp);
321862306a36Sopenharmony_ci
321962306a36Sopenharmony_ci				or_mask = val << 24;
322062306a36Sopenharmony_ci				tmp = RREG32(RADEON_MEM_SDRAM_MODE_REG);
322162306a36Sopenharmony_ci				tmp &= RADEON_B3MEM_RESET_MASK;
322262306a36Sopenharmony_ci				tmp |= or_mask;
322362306a36Sopenharmony_ci				WREG32(RADEON_MEM_SDRAM_MODE_REG, tmp);
322462306a36Sopenharmony_ci			}
322562306a36Sopenharmony_ci			val = RBIOS8(offset);
322662306a36Sopenharmony_ci		}
322762306a36Sopenharmony_ci	}
322862306a36Sopenharmony_ci}
322962306a36Sopenharmony_ci
323062306a36Sopenharmony_cistatic uint32_t combios_detect_ram(struct drm_device *dev, int ram,
323162306a36Sopenharmony_ci				   int mem_addr_mapping)
323262306a36Sopenharmony_ci{
323362306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
323462306a36Sopenharmony_ci	uint32_t mem_cntl;
323562306a36Sopenharmony_ci	uint32_t mem_size;
323662306a36Sopenharmony_ci	uint32_t addr = 0;
323762306a36Sopenharmony_ci
323862306a36Sopenharmony_ci	mem_cntl = RREG32(RADEON_MEM_CNTL);
323962306a36Sopenharmony_ci	if (mem_cntl & RV100_HALF_MODE)
324062306a36Sopenharmony_ci		ram /= 2;
324162306a36Sopenharmony_ci	mem_size = ram;
324262306a36Sopenharmony_ci	mem_cntl &= ~(0xff << 8);
324362306a36Sopenharmony_ci	mem_cntl |= (mem_addr_mapping & 0xff) << 8;
324462306a36Sopenharmony_ci	WREG32(RADEON_MEM_CNTL, mem_cntl);
324562306a36Sopenharmony_ci	RREG32(RADEON_MEM_CNTL);
324662306a36Sopenharmony_ci
324762306a36Sopenharmony_ci	/* sdram reset ? */
324862306a36Sopenharmony_ci
324962306a36Sopenharmony_ci	/* something like this????  */
325062306a36Sopenharmony_ci	while (ram--) {
325162306a36Sopenharmony_ci		addr = ram * 1024 * 1024;
325262306a36Sopenharmony_ci		/* write to each page */
325362306a36Sopenharmony_ci		WREG32_IDX((addr) | RADEON_MM_APER, 0xdeadbeef);
325462306a36Sopenharmony_ci		/* read back and verify */
325562306a36Sopenharmony_ci		if (RREG32_IDX((addr) | RADEON_MM_APER) != 0xdeadbeef)
325662306a36Sopenharmony_ci			return 0;
325762306a36Sopenharmony_ci	}
325862306a36Sopenharmony_ci
325962306a36Sopenharmony_ci	return mem_size;
326062306a36Sopenharmony_ci}
326162306a36Sopenharmony_ci
326262306a36Sopenharmony_cistatic void combios_write_ram_size(struct drm_device *dev)
326362306a36Sopenharmony_ci{
326462306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
326562306a36Sopenharmony_ci	uint8_t rev;
326662306a36Sopenharmony_ci	uint16_t offset;
326762306a36Sopenharmony_ci	uint32_t mem_size = 0;
326862306a36Sopenharmony_ci	uint32_t mem_cntl = 0;
326962306a36Sopenharmony_ci
327062306a36Sopenharmony_ci	/* should do something smarter here I guess... */
327162306a36Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP)
327262306a36Sopenharmony_ci		return;
327362306a36Sopenharmony_ci
327462306a36Sopenharmony_ci	/* first check detected mem table */
327562306a36Sopenharmony_ci	offset = combios_get_table_offset(dev, COMBIOS_DETECTED_MEM_TABLE);
327662306a36Sopenharmony_ci	if (offset) {
327762306a36Sopenharmony_ci		rev = RBIOS8(offset);
327862306a36Sopenharmony_ci		if (rev < 3) {
327962306a36Sopenharmony_ci			mem_cntl = RBIOS32(offset + 1);
328062306a36Sopenharmony_ci			mem_size = RBIOS16(offset + 5);
328162306a36Sopenharmony_ci			if ((rdev->family < CHIP_R200) &&
328262306a36Sopenharmony_ci			    !ASIC_IS_RN50(rdev))
328362306a36Sopenharmony_ci				WREG32(RADEON_MEM_CNTL, mem_cntl);
328462306a36Sopenharmony_ci		}
328562306a36Sopenharmony_ci	}
328662306a36Sopenharmony_ci
328762306a36Sopenharmony_ci	if (!mem_size) {
328862306a36Sopenharmony_ci		offset =
328962306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE);
329062306a36Sopenharmony_ci		if (offset) {
329162306a36Sopenharmony_ci			rev = RBIOS8(offset - 1);
329262306a36Sopenharmony_ci			if (rev < 1) {
329362306a36Sopenharmony_ci				if ((rdev->family < CHIP_R200)
329462306a36Sopenharmony_ci				    && !ASIC_IS_RN50(rdev)) {
329562306a36Sopenharmony_ci					int ram = 0;
329662306a36Sopenharmony_ci					int mem_addr_mapping = 0;
329762306a36Sopenharmony_ci
329862306a36Sopenharmony_ci					while (RBIOS8(offset)) {
329962306a36Sopenharmony_ci						ram = RBIOS8(offset);
330062306a36Sopenharmony_ci						mem_addr_mapping =
330162306a36Sopenharmony_ci						    RBIOS8(offset + 1);
330262306a36Sopenharmony_ci						if (mem_addr_mapping != 0x25)
330362306a36Sopenharmony_ci							ram *= 2;
330462306a36Sopenharmony_ci						mem_size =
330562306a36Sopenharmony_ci						    combios_detect_ram(dev, ram,
330662306a36Sopenharmony_ci								       mem_addr_mapping);
330762306a36Sopenharmony_ci						if (mem_size)
330862306a36Sopenharmony_ci							break;
330962306a36Sopenharmony_ci						offset += 2;
331062306a36Sopenharmony_ci					}
331162306a36Sopenharmony_ci				} else
331262306a36Sopenharmony_ci					mem_size = RBIOS8(offset);
331362306a36Sopenharmony_ci			} else {
331462306a36Sopenharmony_ci				mem_size = RBIOS8(offset);
331562306a36Sopenharmony_ci				mem_size *= 2;	/* convert to MB */
331662306a36Sopenharmony_ci			}
331762306a36Sopenharmony_ci		}
331862306a36Sopenharmony_ci	}
331962306a36Sopenharmony_ci
332062306a36Sopenharmony_ci	mem_size *= (1024 * 1024);	/* convert to bytes */
332162306a36Sopenharmony_ci	WREG32(RADEON_CONFIG_MEMSIZE, mem_size);
332262306a36Sopenharmony_ci}
332362306a36Sopenharmony_ci
332462306a36Sopenharmony_civoid radeon_combios_asic_init(struct drm_device *dev)
332562306a36Sopenharmony_ci{
332662306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
332762306a36Sopenharmony_ci	uint16_t table;
332862306a36Sopenharmony_ci
332962306a36Sopenharmony_ci	/* port hardcoded mac stuff from radeonfb */
333062306a36Sopenharmony_ci	if (rdev->bios == NULL)
333162306a36Sopenharmony_ci		return;
333262306a36Sopenharmony_ci
333362306a36Sopenharmony_ci	/* ASIC INIT 1 */
333462306a36Sopenharmony_ci	table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_1_TABLE);
333562306a36Sopenharmony_ci	if (table)
333662306a36Sopenharmony_ci		combios_parse_mmio_table(dev, table);
333762306a36Sopenharmony_ci
333862306a36Sopenharmony_ci	/* PLL INIT */
333962306a36Sopenharmony_ci	table = combios_get_table_offset(dev, COMBIOS_PLL_INIT_TABLE);
334062306a36Sopenharmony_ci	if (table)
334162306a36Sopenharmony_ci		combios_parse_pll_table(dev, table);
334262306a36Sopenharmony_ci
334362306a36Sopenharmony_ci	/* ASIC INIT 2 */
334462306a36Sopenharmony_ci	table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_2_TABLE);
334562306a36Sopenharmony_ci	if (table)
334662306a36Sopenharmony_ci		combios_parse_mmio_table(dev, table);
334762306a36Sopenharmony_ci
334862306a36Sopenharmony_ci	if (!(rdev->flags & RADEON_IS_IGP)) {
334962306a36Sopenharmony_ci		/* ASIC INIT 4 */
335062306a36Sopenharmony_ci		table =
335162306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_ASIC_INIT_4_TABLE);
335262306a36Sopenharmony_ci		if (table)
335362306a36Sopenharmony_ci			combios_parse_mmio_table(dev, table);
335462306a36Sopenharmony_ci
335562306a36Sopenharmony_ci		/* RAM RESET */
335662306a36Sopenharmony_ci		table = combios_get_table_offset(dev, COMBIOS_RAM_RESET_TABLE);
335762306a36Sopenharmony_ci		if (table)
335862306a36Sopenharmony_ci			combios_parse_ram_reset_table(dev, table);
335962306a36Sopenharmony_ci
336062306a36Sopenharmony_ci		/* ASIC INIT 3 */
336162306a36Sopenharmony_ci		table =
336262306a36Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_ASIC_INIT_3_TABLE);
336362306a36Sopenharmony_ci		if (table)
336462306a36Sopenharmony_ci			combios_parse_mmio_table(dev, table);
336562306a36Sopenharmony_ci
336662306a36Sopenharmony_ci		/* write CONFIG_MEMSIZE */
336762306a36Sopenharmony_ci		combios_write_ram_size(dev);
336862306a36Sopenharmony_ci	}
336962306a36Sopenharmony_ci
337062306a36Sopenharmony_ci	/* quirk for rs4xx HP nx6125 laptop to make it resume
337162306a36Sopenharmony_ci	 * - it hangs on resume inside the dynclk 1 table.
337262306a36Sopenharmony_ci	 */
337362306a36Sopenharmony_ci	if (rdev->family == CHIP_RS480 &&
337462306a36Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x103c &&
337562306a36Sopenharmony_ci	    rdev->pdev->subsystem_device == 0x308b)
337662306a36Sopenharmony_ci		return;
337762306a36Sopenharmony_ci
337862306a36Sopenharmony_ci	/* quirk for rs4xx HP dv5000 laptop to make it resume
337962306a36Sopenharmony_ci	 * - it hangs on resume inside the dynclk 1 table.
338062306a36Sopenharmony_ci	 */
338162306a36Sopenharmony_ci	if (rdev->family == CHIP_RS480 &&
338262306a36Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x103c &&
338362306a36Sopenharmony_ci	    rdev->pdev->subsystem_device == 0x30a4)
338462306a36Sopenharmony_ci		return;
338562306a36Sopenharmony_ci
338662306a36Sopenharmony_ci	/* quirk for rs4xx Compaq Presario V5245EU laptop to make it resume
338762306a36Sopenharmony_ci	 * - it hangs on resume inside the dynclk 1 table.
338862306a36Sopenharmony_ci	 */
338962306a36Sopenharmony_ci	if (rdev->family == CHIP_RS480 &&
339062306a36Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x103c &&
339162306a36Sopenharmony_ci	    rdev->pdev->subsystem_device == 0x30ae)
339262306a36Sopenharmony_ci		return;
339362306a36Sopenharmony_ci
339462306a36Sopenharmony_ci	/* quirk for rs4xx HP Compaq dc5750 Small Form Factor to make it resume
339562306a36Sopenharmony_ci	 * - it hangs on resume inside the dynclk 1 table.
339662306a36Sopenharmony_ci	 */
339762306a36Sopenharmony_ci	if (rdev->family == CHIP_RS480 &&
339862306a36Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x103c &&
339962306a36Sopenharmony_ci	    rdev->pdev->subsystem_device == 0x280a)
340062306a36Sopenharmony_ci		return;
340162306a36Sopenharmony_ci	/* quirk for rs4xx Toshiba Sattellite L20-183 latop to make it resume
340262306a36Sopenharmony_ci	 * - it hangs on resume inside the dynclk 1 table.
340362306a36Sopenharmony_ci	 */
340462306a36Sopenharmony_ci	if (rdev->family == CHIP_RS400 &&
340562306a36Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x1179 &&
340662306a36Sopenharmony_ci	    rdev->pdev->subsystem_device == 0xff31)
340762306a36Sopenharmony_ci	        return;
340862306a36Sopenharmony_ci
340962306a36Sopenharmony_ci	/* DYN CLK 1 */
341062306a36Sopenharmony_ci	table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE);
341162306a36Sopenharmony_ci	if (table)
341262306a36Sopenharmony_ci		combios_parse_pll_table(dev, table);
341362306a36Sopenharmony_ci
341462306a36Sopenharmony_ci}
341562306a36Sopenharmony_ci
341662306a36Sopenharmony_civoid radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev)
341762306a36Sopenharmony_ci{
341862306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
341962306a36Sopenharmony_ci	uint32_t bios_0_scratch, bios_6_scratch, bios_7_scratch;
342062306a36Sopenharmony_ci
342162306a36Sopenharmony_ci	bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);
342262306a36Sopenharmony_ci	bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
342362306a36Sopenharmony_ci	bios_7_scratch = RREG32(RADEON_BIOS_7_SCRATCH);
342462306a36Sopenharmony_ci
342562306a36Sopenharmony_ci	/* let the bios control the backlight */
342662306a36Sopenharmony_ci	bios_0_scratch &= ~RADEON_DRIVER_BRIGHTNESS_EN;
342762306a36Sopenharmony_ci
342862306a36Sopenharmony_ci	/* tell the bios not to handle mode switching */
342962306a36Sopenharmony_ci	bios_6_scratch |= (RADEON_DISPLAY_SWITCHING_DIS |
343062306a36Sopenharmony_ci			   RADEON_ACC_MODE_CHANGE);
343162306a36Sopenharmony_ci
343262306a36Sopenharmony_ci	/* tell the bios a driver is loaded */
343362306a36Sopenharmony_ci	bios_7_scratch |= RADEON_DRV_LOADED;
343462306a36Sopenharmony_ci
343562306a36Sopenharmony_ci	WREG32(RADEON_BIOS_0_SCRATCH, bios_0_scratch);
343662306a36Sopenharmony_ci	WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
343762306a36Sopenharmony_ci	WREG32(RADEON_BIOS_7_SCRATCH, bios_7_scratch);
343862306a36Sopenharmony_ci}
343962306a36Sopenharmony_ci
344062306a36Sopenharmony_civoid radeon_combios_output_lock(struct drm_encoder *encoder, bool lock)
344162306a36Sopenharmony_ci{
344262306a36Sopenharmony_ci	struct drm_device *dev = encoder->dev;
344362306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
344462306a36Sopenharmony_ci	uint32_t bios_6_scratch;
344562306a36Sopenharmony_ci
344662306a36Sopenharmony_ci	bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
344762306a36Sopenharmony_ci
344862306a36Sopenharmony_ci	if (lock)
344962306a36Sopenharmony_ci		bios_6_scratch |= RADEON_DRIVER_CRITICAL;
345062306a36Sopenharmony_ci	else
345162306a36Sopenharmony_ci		bios_6_scratch &= ~RADEON_DRIVER_CRITICAL;
345262306a36Sopenharmony_ci
345362306a36Sopenharmony_ci	WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
345462306a36Sopenharmony_ci}
345562306a36Sopenharmony_ci
345662306a36Sopenharmony_civoid
345762306a36Sopenharmony_ciradeon_combios_connected_scratch_regs(struct drm_connector *connector,
345862306a36Sopenharmony_ci				      struct drm_encoder *encoder,
345962306a36Sopenharmony_ci				      bool connected)
346062306a36Sopenharmony_ci{
346162306a36Sopenharmony_ci	struct drm_device *dev = connector->dev;
346262306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
346362306a36Sopenharmony_ci	struct radeon_connector *radeon_connector =
346462306a36Sopenharmony_ci	    to_radeon_connector(connector);
346562306a36Sopenharmony_ci	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
346662306a36Sopenharmony_ci	uint32_t bios_4_scratch = RREG32(RADEON_BIOS_4_SCRATCH);
346762306a36Sopenharmony_ci	uint32_t bios_5_scratch = RREG32(RADEON_BIOS_5_SCRATCH);
346862306a36Sopenharmony_ci
346962306a36Sopenharmony_ci	if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) &&
347062306a36Sopenharmony_ci	    (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) {
347162306a36Sopenharmony_ci		if (connected) {
347262306a36Sopenharmony_ci			DRM_DEBUG_KMS("TV1 connected\n");
347362306a36Sopenharmony_ci			/* fix me */
347462306a36Sopenharmony_ci			bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO;
347562306a36Sopenharmony_ci			/*save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP; */
347662306a36Sopenharmony_ci			bios_5_scratch |= RADEON_TV1_ON;
347762306a36Sopenharmony_ci			bios_5_scratch |= RADEON_ACC_REQ_TV1;
347862306a36Sopenharmony_ci		} else {
347962306a36Sopenharmony_ci			DRM_DEBUG_KMS("TV1 disconnected\n");
348062306a36Sopenharmony_ci			bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK;
348162306a36Sopenharmony_ci			bios_5_scratch &= ~RADEON_TV1_ON;
348262306a36Sopenharmony_ci			bios_5_scratch &= ~RADEON_ACC_REQ_TV1;
348362306a36Sopenharmony_ci		}
348462306a36Sopenharmony_ci	}
348562306a36Sopenharmony_ci	if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) &&
348662306a36Sopenharmony_ci	    (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) {
348762306a36Sopenharmony_ci		if (connected) {
348862306a36Sopenharmony_ci			DRM_DEBUG_KMS("LCD1 connected\n");
348962306a36Sopenharmony_ci			bios_4_scratch |= RADEON_LCD1_ATTACHED;
349062306a36Sopenharmony_ci			bios_5_scratch |= RADEON_LCD1_ON;
349162306a36Sopenharmony_ci			bios_5_scratch |= RADEON_ACC_REQ_LCD1;
349262306a36Sopenharmony_ci		} else {
349362306a36Sopenharmony_ci			DRM_DEBUG_KMS("LCD1 disconnected\n");
349462306a36Sopenharmony_ci			bios_4_scratch &= ~RADEON_LCD1_ATTACHED;
349562306a36Sopenharmony_ci			bios_5_scratch &= ~RADEON_LCD1_ON;
349662306a36Sopenharmony_ci			bios_5_scratch &= ~RADEON_ACC_REQ_LCD1;
349762306a36Sopenharmony_ci		}
349862306a36Sopenharmony_ci	}
349962306a36Sopenharmony_ci	if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) &&
350062306a36Sopenharmony_ci	    (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) {
350162306a36Sopenharmony_ci		if (connected) {
350262306a36Sopenharmony_ci			DRM_DEBUG_KMS("CRT1 connected\n");
350362306a36Sopenharmony_ci			bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR;
350462306a36Sopenharmony_ci			bios_5_scratch |= RADEON_CRT1_ON;
350562306a36Sopenharmony_ci			bios_5_scratch |= RADEON_ACC_REQ_CRT1;
350662306a36Sopenharmony_ci		} else {
350762306a36Sopenharmony_ci			DRM_DEBUG_KMS("CRT1 disconnected\n");
350862306a36Sopenharmony_ci			bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK;
350962306a36Sopenharmony_ci			bios_5_scratch &= ~RADEON_CRT1_ON;
351062306a36Sopenharmony_ci			bios_5_scratch &= ~RADEON_ACC_REQ_CRT1;
351162306a36Sopenharmony_ci		}
351262306a36Sopenharmony_ci	}
351362306a36Sopenharmony_ci	if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) &&
351462306a36Sopenharmony_ci	    (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) {
351562306a36Sopenharmony_ci		if (connected) {
351662306a36Sopenharmony_ci			DRM_DEBUG_KMS("CRT2 connected\n");
351762306a36Sopenharmony_ci			bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR;
351862306a36Sopenharmony_ci			bios_5_scratch |= RADEON_CRT2_ON;
351962306a36Sopenharmony_ci			bios_5_scratch |= RADEON_ACC_REQ_CRT2;
352062306a36Sopenharmony_ci		} else {
352162306a36Sopenharmony_ci			DRM_DEBUG_KMS("CRT2 disconnected\n");
352262306a36Sopenharmony_ci			bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK;
352362306a36Sopenharmony_ci			bios_5_scratch &= ~RADEON_CRT2_ON;
352462306a36Sopenharmony_ci			bios_5_scratch &= ~RADEON_ACC_REQ_CRT2;
352562306a36Sopenharmony_ci		}
352662306a36Sopenharmony_ci	}
352762306a36Sopenharmony_ci	if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) &&
352862306a36Sopenharmony_ci	    (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) {
352962306a36Sopenharmony_ci		if (connected) {
353062306a36Sopenharmony_ci			DRM_DEBUG_KMS("DFP1 connected\n");
353162306a36Sopenharmony_ci			bios_4_scratch |= RADEON_DFP1_ATTACHED;
353262306a36Sopenharmony_ci			bios_5_scratch |= RADEON_DFP1_ON;
353362306a36Sopenharmony_ci			bios_5_scratch |= RADEON_ACC_REQ_DFP1;
353462306a36Sopenharmony_ci		} else {
353562306a36Sopenharmony_ci			DRM_DEBUG_KMS("DFP1 disconnected\n");
353662306a36Sopenharmony_ci			bios_4_scratch &= ~RADEON_DFP1_ATTACHED;
353762306a36Sopenharmony_ci			bios_5_scratch &= ~RADEON_DFP1_ON;
353862306a36Sopenharmony_ci			bios_5_scratch &= ~RADEON_ACC_REQ_DFP1;
353962306a36Sopenharmony_ci		}
354062306a36Sopenharmony_ci	}
354162306a36Sopenharmony_ci	if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) &&
354262306a36Sopenharmony_ci	    (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) {
354362306a36Sopenharmony_ci		if (connected) {
354462306a36Sopenharmony_ci			DRM_DEBUG_KMS("DFP2 connected\n");
354562306a36Sopenharmony_ci			bios_4_scratch |= RADEON_DFP2_ATTACHED;
354662306a36Sopenharmony_ci			bios_5_scratch |= RADEON_DFP2_ON;
354762306a36Sopenharmony_ci			bios_5_scratch |= RADEON_ACC_REQ_DFP2;
354862306a36Sopenharmony_ci		} else {
354962306a36Sopenharmony_ci			DRM_DEBUG_KMS("DFP2 disconnected\n");
355062306a36Sopenharmony_ci			bios_4_scratch &= ~RADEON_DFP2_ATTACHED;
355162306a36Sopenharmony_ci			bios_5_scratch &= ~RADEON_DFP2_ON;
355262306a36Sopenharmony_ci			bios_5_scratch &= ~RADEON_ACC_REQ_DFP2;
355362306a36Sopenharmony_ci		}
355462306a36Sopenharmony_ci	}
355562306a36Sopenharmony_ci	WREG32(RADEON_BIOS_4_SCRATCH, bios_4_scratch);
355662306a36Sopenharmony_ci	WREG32(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
355762306a36Sopenharmony_ci}
355862306a36Sopenharmony_ci
355962306a36Sopenharmony_civoid
356062306a36Sopenharmony_ciradeon_combios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc)
356162306a36Sopenharmony_ci{
356262306a36Sopenharmony_ci	struct drm_device *dev = encoder->dev;
356362306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
356462306a36Sopenharmony_ci	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
356562306a36Sopenharmony_ci	uint32_t bios_5_scratch = RREG32(RADEON_BIOS_5_SCRATCH);
356662306a36Sopenharmony_ci
356762306a36Sopenharmony_ci	if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {
356862306a36Sopenharmony_ci		bios_5_scratch &= ~RADEON_TV1_CRTC_MASK;
356962306a36Sopenharmony_ci		bios_5_scratch |= (crtc << RADEON_TV1_CRTC_SHIFT);
357062306a36Sopenharmony_ci	}
357162306a36Sopenharmony_ci	if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) {
357262306a36Sopenharmony_ci		bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK;
357362306a36Sopenharmony_ci		bios_5_scratch |= (crtc << RADEON_CRT1_CRTC_SHIFT);
357462306a36Sopenharmony_ci	}
357562306a36Sopenharmony_ci	if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) {
357662306a36Sopenharmony_ci		bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK;
357762306a36Sopenharmony_ci		bios_5_scratch |= (crtc << RADEON_CRT2_CRTC_SHIFT);
357862306a36Sopenharmony_ci	}
357962306a36Sopenharmony_ci	if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {
358062306a36Sopenharmony_ci		bios_5_scratch &= ~RADEON_LCD1_CRTC_MASK;
358162306a36Sopenharmony_ci		bios_5_scratch |= (crtc << RADEON_LCD1_CRTC_SHIFT);
358262306a36Sopenharmony_ci	}
358362306a36Sopenharmony_ci	if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) {
358462306a36Sopenharmony_ci		bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK;
358562306a36Sopenharmony_ci		bios_5_scratch |= (crtc << RADEON_DFP1_CRTC_SHIFT);
358662306a36Sopenharmony_ci	}
358762306a36Sopenharmony_ci	if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) {
358862306a36Sopenharmony_ci		bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK;
358962306a36Sopenharmony_ci		bios_5_scratch |= (crtc << RADEON_DFP2_CRTC_SHIFT);
359062306a36Sopenharmony_ci	}
359162306a36Sopenharmony_ci	WREG32(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
359262306a36Sopenharmony_ci}
359362306a36Sopenharmony_ci
359462306a36Sopenharmony_civoid
359562306a36Sopenharmony_ciradeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on)
359662306a36Sopenharmony_ci{
359762306a36Sopenharmony_ci	struct drm_device *dev = encoder->dev;
359862306a36Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
359962306a36Sopenharmony_ci	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
360062306a36Sopenharmony_ci	uint32_t bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
360162306a36Sopenharmony_ci
360262306a36Sopenharmony_ci	if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) {
360362306a36Sopenharmony_ci		if (on)
360462306a36Sopenharmony_ci			bios_6_scratch |= RADEON_TV_DPMS_ON;
360562306a36Sopenharmony_ci		else
360662306a36Sopenharmony_ci			bios_6_scratch &= ~RADEON_TV_DPMS_ON;
360762306a36Sopenharmony_ci	}
360862306a36Sopenharmony_ci	if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
360962306a36Sopenharmony_ci		if (on)
361062306a36Sopenharmony_ci			bios_6_scratch |= RADEON_CRT_DPMS_ON;
361162306a36Sopenharmony_ci		else
361262306a36Sopenharmony_ci			bios_6_scratch &= ~RADEON_CRT_DPMS_ON;
361362306a36Sopenharmony_ci	}
361462306a36Sopenharmony_ci	if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
361562306a36Sopenharmony_ci		if (on)
361662306a36Sopenharmony_ci			bios_6_scratch |= RADEON_LCD_DPMS_ON;
361762306a36Sopenharmony_ci		else
361862306a36Sopenharmony_ci			bios_6_scratch &= ~RADEON_LCD_DPMS_ON;
361962306a36Sopenharmony_ci	}
362062306a36Sopenharmony_ci	if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
362162306a36Sopenharmony_ci		if (on)
362262306a36Sopenharmony_ci			bios_6_scratch |= RADEON_DFP_DPMS_ON;
362362306a36Sopenharmony_ci		else
362462306a36Sopenharmony_ci			bios_6_scratch &= ~RADEON_DFP_DPMS_ON;
362562306a36Sopenharmony_ci	}
362662306a36Sopenharmony_ci	WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
362762306a36Sopenharmony_ci}
3628