18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright 2004 ATI Technologies Inc., Markham, Ontario
38c2ecf20Sopenharmony_ci * Copyright 2007-8 Advanced Micro Devices, Inc.
48c2ecf20Sopenharmony_ci * Copyright 2008 Red Hat Inc.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
78c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
88c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation
98c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
108c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
118c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
148c2ecf20Sopenharmony_ci * all copies or substantial portions of the Software.
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
178c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
188c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
198c2ecf20Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
208c2ecf20Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
218c2ecf20Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
228c2ecf20Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
238c2ecf20Sopenharmony_ci *
248c2ecf20Sopenharmony_ci * Authors: Dave Airlie
258c2ecf20Sopenharmony_ci *          Alex Deucher
268c2ecf20Sopenharmony_ci */
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci#include <linux/pci.h>
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci#include <drm/drm_device.h>
318c2ecf20Sopenharmony_ci#include <drm/radeon_drm.h>
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci#include "radeon.h"
348c2ecf20Sopenharmony_ci#include "atom.h"
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_PMAC
378c2ecf20Sopenharmony_ci/* not sure which of these are needed */
388c2ecf20Sopenharmony_ci#include <asm/machdep.h>
398c2ecf20Sopenharmony_ci#include <asm/pmac_feature.h>
408c2ecf20Sopenharmony_ci#include <asm/prom.h>
418c2ecf20Sopenharmony_ci#endif /* CONFIG_PPC_PMAC */
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci/* from radeon_legacy_encoder.c */
448c2ecf20Sopenharmony_ciextern void
458c2ecf20Sopenharmony_ciradeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum,
468c2ecf20Sopenharmony_ci			  uint32_t supported_device);
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci/* old legacy ATI BIOS routines */
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci/* COMBIOS table offsets */
518c2ecf20Sopenharmony_cienum radeon_combios_table_offset {
528c2ecf20Sopenharmony_ci	/* absolute offset tables */
538c2ecf20Sopenharmony_ci	COMBIOS_ASIC_INIT_1_TABLE,
548c2ecf20Sopenharmony_ci	COMBIOS_BIOS_SUPPORT_TABLE,
558c2ecf20Sopenharmony_ci	COMBIOS_DAC_PROGRAMMING_TABLE,
568c2ecf20Sopenharmony_ci	COMBIOS_MAX_COLOR_DEPTH_TABLE,
578c2ecf20Sopenharmony_ci	COMBIOS_CRTC_INFO_TABLE,
588c2ecf20Sopenharmony_ci	COMBIOS_PLL_INFO_TABLE,
598c2ecf20Sopenharmony_ci	COMBIOS_TV_INFO_TABLE,
608c2ecf20Sopenharmony_ci	COMBIOS_DFP_INFO_TABLE,
618c2ecf20Sopenharmony_ci	COMBIOS_HW_CONFIG_INFO_TABLE,
628c2ecf20Sopenharmony_ci	COMBIOS_MULTIMEDIA_INFO_TABLE,
638c2ecf20Sopenharmony_ci	COMBIOS_TV_STD_PATCH_TABLE,
648c2ecf20Sopenharmony_ci	COMBIOS_LCD_INFO_TABLE,
658c2ecf20Sopenharmony_ci	COMBIOS_MOBILE_INFO_TABLE,
668c2ecf20Sopenharmony_ci	COMBIOS_PLL_INIT_TABLE,
678c2ecf20Sopenharmony_ci	COMBIOS_MEM_CONFIG_TABLE,
688c2ecf20Sopenharmony_ci	COMBIOS_SAVE_MASK_TABLE,
698c2ecf20Sopenharmony_ci	COMBIOS_HARDCODED_EDID_TABLE,
708c2ecf20Sopenharmony_ci	COMBIOS_ASIC_INIT_2_TABLE,
718c2ecf20Sopenharmony_ci	COMBIOS_CONNECTOR_INFO_TABLE,
728c2ecf20Sopenharmony_ci	COMBIOS_DYN_CLK_1_TABLE,
738c2ecf20Sopenharmony_ci	COMBIOS_RESERVED_MEM_TABLE,
748c2ecf20Sopenharmony_ci	COMBIOS_EXT_TMDS_INFO_TABLE,
758c2ecf20Sopenharmony_ci	COMBIOS_MEM_CLK_INFO_TABLE,
768c2ecf20Sopenharmony_ci	COMBIOS_EXT_DAC_INFO_TABLE,
778c2ecf20Sopenharmony_ci	COMBIOS_MISC_INFO_TABLE,
788c2ecf20Sopenharmony_ci	COMBIOS_CRT_INFO_TABLE,
798c2ecf20Sopenharmony_ci	COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE,
808c2ecf20Sopenharmony_ci	COMBIOS_COMPONENT_VIDEO_INFO_TABLE,
818c2ecf20Sopenharmony_ci	COMBIOS_FAN_SPEED_INFO_TABLE,
828c2ecf20Sopenharmony_ci	COMBIOS_OVERDRIVE_INFO_TABLE,
838c2ecf20Sopenharmony_ci	COMBIOS_OEM_INFO_TABLE,
848c2ecf20Sopenharmony_ci	COMBIOS_DYN_CLK_2_TABLE,
858c2ecf20Sopenharmony_ci	COMBIOS_POWER_CONNECTOR_INFO_TABLE,
868c2ecf20Sopenharmony_ci	COMBIOS_I2C_INFO_TABLE,
878c2ecf20Sopenharmony_ci	/* relative offset tables */
888c2ecf20Sopenharmony_ci	COMBIOS_ASIC_INIT_3_TABLE,	/* offset from misc info */
898c2ecf20Sopenharmony_ci	COMBIOS_ASIC_INIT_4_TABLE,	/* offset from misc info */
908c2ecf20Sopenharmony_ci	COMBIOS_DETECTED_MEM_TABLE,	/* offset from misc info */
918c2ecf20Sopenharmony_ci	COMBIOS_ASIC_INIT_5_TABLE,	/* offset from misc info */
928c2ecf20Sopenharmony_ci	COMBIOS_RAM_RESET_TABLE,	/* offset from mem config */
938c2ecf20Sopenharmony_ci	COMBIOS_POWERPLAY_INFO_TABLE,	/* offset from mobile info */
948c2ecf20Sopenharmony_ci	COMBIOS_GPIO_INFO_TABLE,	/* offset from mobile info */
958c2ecf20Sopenharmony_ci	COMBIOS_LCD_DDC_INFO_TABLE,	/* offset from mobile info */
968c2ecf20Sopenharmony_ci	COMBIOS_TMDS_POWER_TABLE,	/* offset from mobile info */
978c2ecf20Sopenharmony_ci	COMBIOS_TMDS_POWER_ON_TABLE,	/* offset from tmds power */
988c2ecf20Sopenharmony_ci	COMBIOS_TMDS_POWER_OFF_TABLE,	/* offset from tmds power */
998c2ecf20Sopenharmony_ci};
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_cienum radeon_combios_ddc {
1028c2ecf20Sopenharmony_ci	DDC_NONE_DETECTED,
1038c2ecf20Sopenharmony_ci	DDC_MONID,
1048c2ecf20Sopenharmony_ci	DDC_DVI,
1058c2ecf20Sopenharmony_ci	DDC_VGA,
1068c2ecf20Sopenharmony_ci	DDC_CRT2,
1078c2ecf20Sopenharmony_ci	DDC_LCD,
1088c2ecf20Sopenharmony_ci	DDC_GPIO,
1098c2ecf20Sopenharmony_ci};
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_cienum radeon_combios_connector {
1128c2ecf20Sopenharmony_ci	CONNECTOR_NONE_LEGACY,
1138c2ecf20Sopenharmony_ci	CONNECTOR_PROPRIETARY_LEGACY,
1148c2ecf20Sopenharmony_ci	CONNECTOR_CRT_LEGACY,
1158c2ecf20Sopenharmony_ci	CONNECTOR_DVI_I_LEGACY,
1168c2ecf20Sopenharmony_ci	CONNECTOR_DVI_D_LEGACY,
1178c2ecf20Sopenharmony_ci	CONNECTOR_CTV_LEGACY,
1188c2ecf20Sopenharmony_ci	CONNECTOR_STV_LEGACY,
1198c2ecf20Sopenharmony_ci	CONNECTOR_UNSUPPORTED_LEGACY
1208c2ecf20Sopenharmony_ci};
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_cistatic const int legacy_connector_convert[] = {
1238c2ecf20Sopenharmony_ci	DRM_MODE_CONNECTOR_Unknown,
1248c2ecf20Sopenharmony_ci	DRM_MODE_CONNECTOR_DVID,
1258c2ecf20Sopenharmony_ci	DRM_MODE_CONNECTOR_VGA,
1268c2ecf20Sopenharmony_ci	DRM_MODE_CONNECTOR_DVII,
1278c2ecf20Sopenharmony_ci	DRM_MODE_CONNECTOR_DVID,
1288c2ecf20Sopenharmony_ci	DRM_MODE_CONNECTOR_Composite,
1298c2ecf20Sopenharmony_ci	DRM_MODE_CONNECTOR_SVIDEO,
1308c2ecf20Sopenharmony_ci	DRM_MODE_CONNECTOR_Unknown,
1318c2ecf20Sopenharmony_ci};
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_cistatic uint16_t combios_get_table_offset(struct drm_device *dev,
1348c2ecf20Sopenharmony_ci					 enum radeon_combios_table_offset table)
1358c2ecf20Sopenharmony_ci{
1368c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
1378c2ecf20Sopenharmony_ci	int rev, size;
1388c2ecf20Sopenharmony_ci	uint16_t offset = 0, check_offset;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	if (!rdev->bios)
1418c2ecf20Sopenharmony_ci		return 0;
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	switch (table) {
1448c2ecf20Sopenharmony_ci		/* absolute offset tables */
1458c2ecf20Sopenharmony_ci	case COMBIOS_ASIC_INIT_1_TABLE:
1468c2ecf20Sopenharmony_ci		check_offset = 0xc;
1478c2ecf20Sopenharmony_ci		break;
1488c2ecf20Sopenharmony_ci	case COMBIOS_BIOS_SUPPORT_TABLE:
1498c2ecf20Sopenharmony_ci		check_offset = 0x14;
1508c2ecf20Sopenharmony_ci		break;
1518c2ecf20Sopenharmony_ci	case COMBIOS_DAC_PROGRAMMING_TABLE:
1528c2ecf20Sopenharmony_ci		check_offset = 0x2a;
1538c2ecf20Sopenharmony_ci		break;
1548c2ecf20Sopenharmony_ci	case COMBIOS_MAX_COLOR_DEPTH_TABLE:
1558c2ecf20Sopenharmony_ci		check_offset = 0x2c;
1568c2ecf20Sopenharmony_ci		break;
1578c2ecf20Sopenharmony_ci	case COMBIOS_CRTC_INFO_TABLE:
1588c2ecf20Sopenharmony_ci		check_offset = 0x2e;
1598c2ecf20Sopenharmony_ci		break;
1608c2ecf20Sopenharmony_ci	case COMBIOS_PLL_INFO_TABLE:
1618c2ecf20Sopenharmony_ci		check_offset = 0x30;
1628c2ecf20Sopenharmony_ci		break;
1638c2ecf20Sopenharmony_ci	case COMBIOS_TV_INFO_TABLE:
1648c2ecf20Sopenharmony_ci		check_offset = 0x32;
1658c2ecf20Sopenharmony_ci		break;
1668c2ecf20Sopenharmony_ci	case COMBIOS_DFP_INFO_TABLE:
1678c2ecf20Sopenharmony_ci		check_offset = 0x34;
1688c2ecf20Sopenharmony_ci		break;
1698c2ecf20Sopenharmony_ci	case COMBIOS_HW_CONFIG_INFO_TABLE:
1708c2ecf20Sopenharmony_ci		check_offset = 0x36;
1718c2ecf20Sopenharmony_ci		break;
1728c2ecf20Sopenharmony_ci	case COMBIOS_MULTIMEDIA_INFO_TABLE:
1738c2ecf20Sopenharmony_ci		check_offset = 0x38;
1748c2ecf20Sopenharmony_ci		break;
1758c2ecf20Sopenharmony_ci	case COMBIOS_TV_STD_PATCH_TABLE:
1768c2ecf20Sopenharmony_ci		check_offset = 0x3e;
1778c2ecf20Sopenharmony_ci		break;
1788c2ecf20Sopenharmony_ci	case COMBIOS_LCD_INFO_TABLE:
1798c2ecf20Sopenharmony_ci		check_offset = 0x40;
1808c2ecf20Sopenharmony_ci		break;
1818c2ecf20Sopenharmony_ci	case COMBIOS_MOBILE_INFO_TABLE:
1828c2ecf20Sopenharmony_ci		check_offset = 0x42;
1838c2ecf20Sopenharmony_ci		break;
1848c2ecf20Sopenharmony_ci	case COMBIOS_PLL_INIT_TABLE:
1858c2ecf20Sopenharmony_ci		check_offset = 0x46;
1868c2ecf20Sopenharmony_ci		break;
1878c2ecf20Sopenharmony_ci	case COMBIOS_MEM_CONFIG_TABLE:
1888c2ecf20Sopenharmony_ci		check_offset = 0x48;
1898c2ecf20Sopenharmony_ci		break;
1908c2ecf20Sopenharmony_ci	case COMBIOS_SAVE_MASK_TABLE:
1918c2ecf20Sopenharmony_ci		check_offset = 0x4a;
1928c2ecf20Sopenharmony_ci		break;
1938c2ecf20Sopenharmony_ci	case COMBIOS_HARDCODED_EDID_TABLE:
1948c2ecf20Sopenharmony_ci		check_offset = 0x4c;
1958c2ecf20Sopenharmony_ci		break;
1968c2ecf20Sopenharmony_ci	case COMBIOS_ASIC_INIT_2_TABLE:
1978c2ecf20Sopenharmony_ci		check_offset = 0x4e;
1988c2ecf20Sopenharmony_ci		break;
1998c2ecf20Sopenharmony_ci	case COMBIOS_CONNECTOR_INFO_TABLE:
2008c2ecf20Sopenharmony_ci		check_offset = 0x50;
2018c2ecf20Sopenharmony_ci		break;
2028c2ecf20Sopenharmony_ci	case COMBIOS_DYN_CLK_1_TABLE:
2038c2ecf20Sopenharmony_ci		check_offset = 0x52;
2048c2ecf20Sopenharmony_ci		break;
2058c2ecf20Sopenharmony_ci	case COMBIOS_RESERVED_MEM_TABLE:
2068c2ecf20Sopenharmony_ci		check_offset = 0x54;
2078c2ecf20Sopenharmony_ci		break;
2088c2ecf20Sopenharmony_ci	case COMBIOS_EXT_TMDS_INFO_TABLE:
2098c2ecf20Sopenharmony_ci		check_offset = 0x58;
2108c2ecf20Sopenharmony_ci		break;
2118c2ecf20Sopenharmony_ci	case COMBIOS_MEM_CLK_INFO_TABLE:
2128c2ecf20Sopenharmony_ci		check_offset = 0x5a;
2138c2ecf20Sopenharmony_ci		break;
2148c2ecf20Sopenharmony_ci	case COMBIOS_EXT_DAC_INFO_TABLE:
2158c2ecf20Sopenharmony_ci		check_offset = 0x5c;
2168c2ecf20Sopenharmony_ci		break;
2178c2ecf20Sopenharmony_ci	case COMBIOS_MISC_INFO_TABLE:
2188c2ecf20Sopenharmony_ci		check_offset = 0x5e;
2198c2ecf20Sopenharmony_ci		break;
2208c2ecf20Sopenharmony_ci	case COMBIOS_CRT_INFO_TABLE:
2218c2ecf20Sopenharmony_ci		check_offset = 0x60;
2228c2ecf20Sopenharmony_ci		break;
2238c2ecf20Sopenharmony_ci	case COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE:
2248c2ecf20Sopenharmony_ci		check_offset = 0x62;
2258c2ecf20Sopenharmony_ci		break;
2268c2ecf20Sopenharmony_ci	case COMBIOS_COMPONENT_VIDEO_INFO_TABLE:
2278c2ecf20Sopenharmony_ci		check_offset = 0x64;
2288c2ecf20Sopenharmony_ci		break;
2298c2ecf20Sopenharmony_ci	case COMBIOS_FAN_SPEED_INFO_TABLE:
2308c2ecf20Sopenharmony_ci		check_offset = 0x66;
2318c2ecf20Sopenharmony_ci		break;
2328c2ecf20Sopenharmony_ci	case COMBIOS_OVERDRIVE_INFO_TABLE:
2338c2ecf20Sopenharmony_ci		check_offset = 0x68;
2348c2ecf20Sopenharmony_ci		break;
2358c2ecf20Sopenharmony_ci	case COMBIOS_OEM_INFO_TABLE:
2368c2ecf20Sopenharmony_ci		check_offset = 0x6a;
2378c2ecf20Sopenharmony_ci		break;
2388c2ecf20Sopenharmony_ci	case COMBIOS_DYN_CLK_2_TABLE:
2398c2ecf20Sopenharmony_ci		check_offset = 0x6c;
2408c2ecf20Sopenharmony_ci		break;
2418c2ecf20Sopenharmony_ci	case COMBIOS_POWER_CONNECTOR_INFO_TABLE:
2428c2ecf20Sopenharmony_ci		check_offset = 0x6e;
2438c2ecf20Sopenharmony_ci		break;
2448c2ecf20Sopenharmony_ci	case COMBIOS_I2C_INFO_TABLE:
2458c2ecf20Sopenharmony_ci		check_offset = 0x70;
2468c2ecf20Sopenharmony_ci		break;
2478c2ecf20Sopenharmony_ci		/* relative offset tables */
2488c2ecf20Sopenharmony_ci	case COMBIOS_ASIC_INIT_3_TABLE:	/* offset from misc info */
2498c2ecf20Sopenharmony_ci		check_offset =
2508c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
2518c2ecf20Sopenharmony_ci		if (check_offset) {
2528c2ecf20Sopenharmony_ci			rev = RBIOS8(check_offset);
2538c2ecf20Sopenharmony_ci			if (rev > 0) {
2548c2ecf20Sopenharmony_ci				check_offset = RBIOS16(check_offset + 0x3);
2558c2ecf20Sopenharmony_ci				if (check_offset)
2568c2ecf20Sopenharmony_ci					offset = check_offset;
2578c2ecf20Sopenharmony_ci			}
2588c2ecf20Sopenharmony_ci		}
2598c2ecf20Sopenharmony_ci		break;
2608c2ecf20Sopenharmony_ci	case COMBIOS_ASIC_INIT_4_TABLE:	/* offset from misc info */
2618c2ecf20Sopenharmony_ci		check_offset =
2628c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
2638c2ecf20Sopenharmony_ci		if (check_offset) {
2648c2ecf20Sopenharmony_ci			rev = RBIOS8(check_offset);
2658c2ecf20Sopenharmony_ci			if (rev > 0) {
2668c2ecf20Sopenharmony_ci				check_offset = RBIOS16(check_offset + 0x5);
2678c2ecf20Sopenharmony_ci				if (check_offset)
2688c2ecf20Sopenharmony_ci					offset = check_offset;
2698c2ecf20Sopenharmony_ci			}
2708c2ecf20Sopenharmony_ci		}
2718c2ecf20Sopenharmony_ci		break;
2728c2ecf20Sopenharmony_ci	case COMBIOS_DETECTED_MEM_TABLE:	/* offset from misc info */
2738c2ecf20Sopenharmony_ci		check_offset =
2748c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
2758c2ecf20Sopenharmony_ci		if (check_offset) {
2768c2ecf20Sopenharmony_ci			rev = RBIOS8(check_offset);
2778c2ecf20Sopenharmony_ci			if (rev > 0) {
2788c2ecf20Sopenharmony_ci				check_offset = RBIOS16(check_offset + 0x7);
2798c2ecf20Sopenharmony_ci				if (check_offset)
2808c2ecf20Sopenharmony_ci					offset = check_offset;
2818c2ecf20Sopenharmony_ci			}
2828c2ecf20Sopenharmony_ci		}
2838c2ecf20Sopenharmony_ci		break;
2848c2ecf20Sopenharmony_ci	case COMBIOS_ASIC_INIT_5_TABLE:	/* offset from misc info */
2858c2ecf20Sopenharmony_ci		check_offset =
2868c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
2878c2ecf20Sopenharmony_ci		if (check_offset) {
2888c2ecf20Sopenharmony_ci			rev = RBIOS8(check_offset);
2898c2ecf20Sopenharmony_ci			if (rev == 2) {
2908c2ecf20Sopenharmony_ci				check_offset = RBIOS16(check_offset + 0x9);
2918c2ecf20Sopenharmony_ci				if (check_offset)
2928c2ecf20Sopenharmony_ci					offset = check_offset;
2938c2ecf20Sopenharmony_ci			}
2948c2ecf20Sopenharmony_ci		}
2958c2ecf20Sopenharmony_ci		break;
2968c2ecf20Sopenharmony_ci	case COMBIOS_RAM_RESET_TABLE:	/* offset from mem config */
2978c2ecf20Sopenharmony_ci		check_offset =
2988c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE);
2998c2ecf20Sopenharmony_ci		if (check_offset) {
3008c2ecf20Sopenharmony_ci			while (RBIOS8(check_offset++));
3018c2ecf20Sopenharmony_ci			check_offset += 2;
3028c2ecf20Sopenharmony_ci			if (check_offset)
3038c2ecf20Sopenharmony_ci				offset = check_offset;
3048c2ecf20Sopenharmony_ci		}
3058c2ecf20Sopenharmony_ci		break;
3068c2ecf20Sopenharmony_ci	case COMBIOS_POWERPLAY_INFO_TABLE:	/* offset from mobile info */
3078c2ecf20Sopenharmony_ci		check_offset =
3088c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
3098c2ecf20Sopenharmony_ci		if (check_offset) {
3108c2ecf20Sopenharmony_ci			check_offset = RBIOS16(check_offset + 0x11);
3118c2ecf20Sopenharmony_ci			if (check_offset)
3128c2ecf20Sopenharmony_ci				offset = check_offset;
3138c2ecf20Sopenharmony_ci		}
3148c2ecf20Sopenharmony_ci		break;
3158c2ecf20Sopenharmony_ci	case COMBIOS_GPIO_INFO_TABLE:	/* offset from mobile info */
3168c2ecf20Sopenharmony_ci		check_offset =
3178c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
3188c2ecf20Sopenharmony_ci		if (check_offset) {
3198c2ecf20Sopenharmony_ci			check_offset = RBIOS16(check_offset + 0x13);
3208c2ecf20Sopenharmony_ci			if (check_offset)
3218c2ecf20Sopenharmony_ci				offset = check_offset;
3228c2ecf20Sopenharmony_ci		}
3238c2ecf20Sopenharmony_ci		break;
3248c2ecf20Sopenharmony_ci	case COMBIOS_LCD_DDC_INFO_TABLE:	/* offset from mobile info */
3258c2ecf20Sopenharmony_ci		check_offset =
3268c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
3278c2ecf20Sopenharmony_ci		if (check_offset) {
3288c2ecf20Sopenharmony_ci			check_offset = RBIOS16(check_offset + 0x15);
3298c2ecf20Sopenharmony_ci			if (check_offset)
3308c2ecf20Sopenharmony_ci				offset = check_offset;
3318c2ecf20Sopenharmony_ci		}
3328c2ecf20Sopenharmony_ci		break;
3338c2ecf20Sopenharmony_ci	case COMBIOS_TMDS_POWER_TABLE:	/* offset from mobile info */
3348c2ecf20Sopenharmony_ci		check_offset =
3358c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
3368c2ecf20Sopenharmony_ci		if (check_offset) {
3378c2ecf20Sopenharmony_ci			check_offset = RBIOS16(check_offset + 0x17);
3388c2ecf20Sopenharmony_ci			if (check_offset)
3398c2ecf20Sopenharmony_ci				offset = check_offset;
3408c2ecf20Sopenharmony_ci		}
3418c2ecf20Sopenharmony_ci		break;
3428c2ecf20Sopenharmony_ci	case COMBIOS_TMDS_POWER_ON_TABLE:	/* offset from tmds power */
3438c2ecf20Sopenharmony_ci		check_offset =
3448c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE);
3458c2ecf20Sopenharmony_ci		if (check_offset) {
3468c2ecf20Sopenharmony_ci			check_offset = RBIOS16(check_offset + 0x2);
3478c2ecf20Sopenharmony_ci			if (check_offset)
3488c2ecf20Sopenharmony_ci				offset = check_offset;
3498c2ecf20Sopenharmony_ci		}
3508c2ecf20Sopenharmony_ci		break;
3518c2ecf20Sopenharmony_ci	case COMBIOS_TMDS_POWER_OFF_TABLE:	/* offset from tmds power */
3528c2ecf20Sopenharmony_ci		check_offset =
3538c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE);
3548c2ecf20Sopenharmony_ci		if (check_offset) {
3558c2ecf20Sopenharmony_ci			check_offset = RBIOS16(check_offset + 0x4);
3568c2ecf20Sopenharmony_ci			if (check_offset)
3578c2ecf20Sopenharmony_ci				offset = check_offset;
3588c2ecf20Sopenharmony_ci		}
3598c2ecf20Sopenharmony_ci		break;
3608c2ecf20Sopenharmony_ci	default:
3618c2ecf20Sopenharmony_ci		check_offset = 0;
3628c2ecf20Sopenharmony_ci		break;
3638c2ecf20Sopenharmony_ci	}
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ci	size = RBIOS8(rdev->bios_header_start + 0x6);
3668c2ecf20Sopenharmony_ci	/* check absolute offset tables */
3678c2ecf20Sopenharmony_ci	if (table < COMBIOS_ASIC_INIT_3_TABLE && check_offset && check_offset < size)
3688c2ecf20Sopenharmony_ci		offset = RBIOS16(rdev->bios_header_start + check_offset);
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ci	return offset;
3718c2ecf20Sopenharmony_ci}
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_cibool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
3748c2ecf20Sopenharmony_ci{
3758c2ecf20Sopenharmony_ci	int edid_info, size;
3768c2ecf20Sopenharmony_ci	struct edid *edid;
3778c2ecf20Sopenharmony_ci	unsigned char *raw;
3788c2ecf20Sopenharmony_ci	edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE);
3798c2ecf20Sopenharmony_ci	if (!edid_info)
3808c2ecf20Sopenharmony_ci		return false;
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_ci	raw = rdev->bios + edid_info;
3838c2ecf20Sopenharmony_ci	size = EDID_LENGTH * (raw[0x7e] + 1);
3848c2ecf20Sopenharmony_ci	edid = kmalloc(size, GFP_KERNEL);
3858c2ecf20Sopenharmony_ci	if (edid == NULL)
3868c2ecf20Sopenharmony_ci		return false;
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci	memcpy((unsigned char *)edid, raw, size);
3898c2ecf20Sopenharmony_ci
3908c2ecf20Sopenharmony_ci	if (!drm_edid_is_valid(edid)) {
3918c2ecf20Sopenharmony_ci		kfree(edid);
3928c2ecf20Sopenharmony_ci		return false;
3938c2ecf20Sopenharmony_ci	}
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_ci	rdev->mode_info.bios_hardcoded_edid = edid;
3968c2ecf20Sopenharmony_ci	rdev->mode_info.bios_hardcoded_edid_size = size;
3978c2ecf20Sopenharmony_ci	return true;
3988c2ecf20Sopenharmony_ci}
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_ci/* this is used for atom LCDs as well */
4018c2ecf20Sopenharmony_cistruct edid *
4028c2ecf20Sopenharmony_ciradeon_bios_get_hardcoded_edid(struct radeon_device *rdev)
4038c2ecf20Sopenharmony_ci{
4048c2ecf20Sopenharmony_ci	struct edid *edid;
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ci	if (rdev->mode_info.bios_hardcoded_edid) {
4078c2ecf20Sopenharmony_ci		edid = kmalloc(rdev->mode_info.bios_hardcoded_edid_size, GFP_KERNEL);
4088c2ecf20Sopenharmony_ci		if (edid) {
4098c2ecf20Sopenharmony_ci			memcpy((unsigned char *)edid,
4108c2ecf20Sopenharmony_ci			       (unsigned char *)rdev->mode_info.bios_hardcoded_edid,
4118c2ecf20Sopenharmony_ci			       rdev->mode_info.bios_hardcoded_edid_size);
4128c2ecf20Sopenharmony_ci			return edid;
4138c2ecf20Sopenharmony_ci		}
4148c2ecf20Sopenharmony_ci	}
4158c2ecf20Sopenharmony_ci	return NULL;
4168c2ecf20Sopenharmony_ci}
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_cistatic struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev,
4198c2ecf20Sopenharmony_ci						       enum radeon_combios_ddc ddc,
4208c2ecf20Sopenharmony_ci						       u32 clk_mask,
4218c2ecf20Sopenharmony_ci						       u32 data_mask)
4228c2ecf20Sopenharmony_ci{
4238c2ecf20Sopenharmony_ci	struct radeon_i2c_bus_rec i2c;
4248c2ecf20Sopenharmony_ci	int ddc_line = 0;
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_ci	/* ddc id            = mask reg
4278c2ecf20Sopenharmony_ci	 * DDC_NONE_DETECTED = none
4288c2ecf20Sopenharmony_ci	 * DDC_DVI           = RADEON_GPIO_DVI_DDC
4298c2ecf20Sopenharmony_ci	 * DDC_VGA           = RADEON_GPIO_VGA_DDC
4308c2ecf20Sopenharmony_ci	 * DDC_LCD           = RADEON_GPIOPAD_MASK
4318c2ecf20Sopenharmony_ci	 * DDC_GPIO          = RADEON_MDGPIO_MASK
4328c2ecf20Sopenharmony_ci	 * r1xx
4338c2ecf20Sopenharmony_ci	 * DDC_MONID         = RADEON_GPIO_MONID
4348c2ecf20Sopenharmony_ci	 * DDC_CRT2          = RADEON_GPIO_CRT2_DDC
4358c2ecf20Sopenharmony_ci	 * r200
4368c2ecf20Sopenharmony_ci	 * DDC_MONID         = RADEON_GPIO_MONID
4378c2ecf20Sopenharmony_ci	 * DDC_CRT2          = RADEON_GPIO_DVI_DDC
4388c2ecf20Sopenharmony_ci	 * r300/r350
4398c2ecf20Sopenharmony_ci	 * DDC_MONID         = RADEON_GPIO_DVI_DDC
4408c2ecf20Sopenharmony_ci	 * DDC_CRT2          = RADEON_GPIO_DVI_DDC
4418c2ecf20Sopenharmony_ci	 * rv2xx/rv3xx
4428c2ecf20Sopenharmony_ci	 * DDC_MONID         = RADEON_GPIO_MONID
4438c2ecf20Sopenharmony_ci	 * DDC_CRT2          = RADEON_GPIO_MONID
4448c2ecf20Sopenharmony_ci	 * rs3xx/rs4xx
4458c2ecf20Sopenharmony_ci	 * DDC_MONID         = RADEON_GPIOPAD_MASK
4468c2ecf20Sopenharmony_ci	 * DDC_CRT2          = RADEON_GPIO_MONID
4478c2ecf20Sopenharmony_ci	 */
4488c2ecf20Sopenharmony_ci	switch (ddc) {
4498c2ecf20Sopenharmony_ci	case DDC_NONE_DETECTED:
4508c2ecf20Sopenharmony_ci	default:
4518c2ecf20Sopenharmony_ci		ddc_line = 0;
4528c2ecf20Sopenharmony_ci		break;
4538c2ecf20Sopenharmony_ci	case DDC_DVI:
4548c2ecf20Sopenharmony_ci		ddc_line = RADEON_GPIO_DVI_DDC;
4558c2ecf20Sopenharmony_ci		break;
4568c2ecf20Sopenharmony_ci	case DDC_VGA:
4578c2ecf20Sopenharmony_ci		ddc_line = RADEON_GPIO_VGA_DDC;
4588c2ecf20Sopenharmony_ci		break;
4598c2ecf20Sopenharmony_ci	case DDC_LCD:
4608c2ecf20Sopenharmony_ci		ddc_line = RADEON_GPIOPAD_MASK;
4618c2ecf20Sopenharmony_ci		break;
4628c2ecf20Sopenharmony_ci	case DDC_GPIO:
4638c2ecf20Sopenharmony_ci		ddc_line = RADEON_MDGPIO_MASK;
4648c2ecf20Sopenharmony_ci		break;
4658c2ecf20Sopenharmony_ci	case DDC_MONID:
4668c2ecf20Sopenharmony_ci		if (rdev->family == CHIP_RS300 ||
4678c2ecf20Sopenharmony_ci		    rdev->family == CHIP_RS400 ||
4688c2ecf20Sopenharmony_ci		    rdev->family == CHIP_RS480)
4698c2ecf20Sopenharmony_ci			ddc_line = RADEON_GPIOPAD_MASK;
4708c2ecf20Sopenharmony_ci		else if (rdev->family == CHIP_R300 ||
4718c2ecf20Sopenharmony_ci			 rdev->family == CHIP_R350) {
4728c2ecf20Sopenharmony_ci			ddc_line = RADEON_GPIO_DVI_DDC;
4738c2ecf20Sopenharmony_ci			ddc = DDC_DVI;
4748c2ecf20Sopenharmony_ci		} else
4758c2ecf20Sopenharmony_ci			ddc_line = RADEON_GPIO_MONID;
4768c2ecf20Sopenharmony_ci		break;
4778c2ecf20Sopenharmony_ci	case DDC_CRT2:
4788c2ecf20Sopenharmony_ci		if (rdev->family == CHIP_R200 ||
4798c2ecf20Sopenharmony_ci		    rdev->family == CHIP_R300 ||
4808c2ecf20Sopenharmony_ci		    rdev->family == CHIP_R350) {
4818c2ecf20Sopenharmony_ci			ddc_line = RADEON_GPIO_DVI_DDC;
4828c2ecf20Sopenharmony_ci			ddc = DDC_DVI;
4838c2ecf20Sopenharmony_ci		} else if (rdev->family == CHIP_RS300 ||
4848c2ecf20Sopenharmony_ci			   rdev->family == CHIP_RS400 ||
4858c2ecf20Sopenharmony_ci			   rdev->family == CHIP_RS480)
4868c2ecf20Sopenharmony_ci			ddc_line = RADEON_GPIO_MONID;
4878c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_RV350) {
4888c2ecf20Sopenharmony_ci			ddc_line = RADEON_GPIO_MONID;
4898c2ecf20Sopenharmony_ci			ddc = DDC_MONID;
4908c2ecf20Sopenharmony_ci		} else
4918c2ecf20Sopenharmony_ci			ddc_line = RADEON_GPIO_CRT2_DDC;
4928c2ecf20Sopenharmony_ci		break;
4938c2ecf20Sopenharmony_ci	}
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_ci	if (ddc_line == RADEON_GPIOPAD_MASK) {
4968c2ecf20Sopenharmony_ci		i2c.mask_clk_reg = RADEON_GPIOPAD_MASK;
4978c2ecf20Sopenharmony_ci		i2c.mask_data_reg = RADEON_GPIOPAD_MASK;
4988c2ecf20Sopenharmony_ci		i2c.a_clk_reg = RADEON_GPIOPAD_A;
4998c2ecf20Sopenharmony_ci		i2c.a_data_reg = RADEON_GPIOPAD_A;
5008c2ecf20Sopenharmony_ci		i2c.en_clk_reg = RADEON_GPIOPAD_EN;
5018c2ecf20Sopenharmony_ci		i2c.en_data_reg = RADEON_GPIOPAD_EN;
5028c2ecf20Sopenharmony_ci		i2c.y_clk_reg = RADEON_GPIOPAD_Y;
5038c2ecf20Sopenharmony_ci		i2c.y_data_reg = RADEON_GPIOPAD_Y;
5048c2ecf20Sopenharmony_ci	} else if (ddc_line == RADEON_MDGPIO_MASK) {
5058c2ecf20Sopenharmony_ci		i2c.mask_clk_reg = RADEON_MDGPIO_MASK;
5068c2ecf20Sopenharmony_ci		i2c.mask_data_reg = RADEON_MDGPIO_MASK;
5078c2ecf20Sopenharmony_ci		i2c.a_clk_reg = RADEON_MDGPIO_A;
5088c2ecf20Sopenharmony_ci		i2c.a_data_reg = RADEON_MDGPIO_A;
5098c2ecf20Sopenharmony_ci		i2c.en_clk_reg = RADEON_MDGPIO_EN;
5108c2ecf20Sopenharmony_ci		i2c.en_data_reg = RADEON_MDGPIO_EN;
5118c2ecf20Sopenharmony_ci		i2c.y_clk_reg = RADEON_MDGPIO_Y;
5128c2ecf20Sopenharmony_ci		i2c.y_data_reg = RADEON_MDGPIO_Y;
5138c2ecf20Sopenharmony_ci	} else {
5148c2ecf20Sopenharmony_ci		i2c.mask_clk_reg = ddc_line;
5158c2ecf20Sopenharmony_ci		i2c.mask_data_reg = ddc_line;
5168c2ecf20Sopenharmony_ci		i2c.a_clk_reg = ddc_line;
5178c2ecf20Sopenharmony_ci		i2c.a_data_reg = ddc_line;
5188c2ecf20Sopenharmony_ci		i2c.en_clk_reg = ddc_line;
5198c2ecf20Sopenharmony_ci		i2c.en_data_reg = ddc_line;
5208c2ecf20Sopenharmony_ci		i2c.y_clk_reg = ddc_line;
5218c2ecf20Sopenharmony_ci		i2c.y_data_reg = ddc_line;
5228c2ecf20Sopenharmony_ci	}
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_ci	if (clk_mask && data_mask) {
5258c2ecf20Sopenharmony_ci		/* system specific masks */
5268c2ecf20Sopenharmony_ci		i2c.mask_clk_mask = clk_mask;
5278c2ecf20Sopenharmony_ci		i2c.mask_data_mask = data_mask;
5288c2ecf20Sopenharmony_ci		i2c.a_clk_mask = clk_mask;
5298c2ecf20Sopenharmony_ci		i2c.a_data_mask = data_mask;
5308c2ecf20Sopenharmony_ci		i2c.en_clk_mask = clk_mask;
5318c2ecf20Sopenharmony_ci		i2c.en_data_mask = data_mask;
5328c2ecf20Sopenharmony_ci		i2c.y_clk_mask = clk_mask;
5338c2ecf20Sopenharmony_ci		i2c.y_data_mask = data_mask;
5348c2ecf20Sopenharmony_ci	} else if ((ddc_line == RADEON_GPIOPAD_MASK) ||
5358c2ecf20Sopenharmony_ci		   (ddc_line == RADEON_MDGPIO_MASK)) {
5368c2ecf20Sopenharmony_ci		/* default gpiopad masks */
5378c2ecf20Sopenharmony_ci		i2c.mask_clk_mask = (0x20 << 8);
5388c2ecf20Sopenharmony_ci		i2c.mask_data_mask = 0x80;
5398c2ecf20Sopenharmony_ci		i2c.a_clk_mask = (0x20 << 8);
5408c2ecf20Sopenharmony_ci		i2c.a_data_mask = 0x80;
5418c2ecf20Sopenharmony_ci		i2c.en_clk_mask = (0x20 << 8);
5428c2ecf20Sopenharmony_ci		i2c.en_data_mask = 0x80;
5438c2ecf20Sopenharmony_ci		i2c.y_clk_mask = (0x20 << 8);
5448c2ecf20Sopenharmony_ci		i2c.y_data_mask = 0x80;
5458c2ecf20Sopenharmony_ci	} else {
5468c2ecf20Sopenharmony_ci		/* default masks for ddc pads */
5478c2ecf20Sopenharmony_ci		i2c.mask_clk_mask = RADEON_GPIO_MASK_1;
5488c2ecf20Sopenharmony_ci		i2c.mask_data_mask = RADEON_GPIO_MASK_0;
5498c2ecf20Sopenharmony_ci		i2c.a_clk_mask = RADEON_GPIO_A_1;
5508c2ecf20Sopenharmony_ci		i2c.a_data_mask = RADEON_GPIO_A_0;
5518c2ecf20Sopenharmony_ci		i2c.en_clk_mask = RADEON_GPIO_EN_1;
5528c2ecf20Sopenharmony_ci		i2c.en_data_mask = RADEON_GPIO_EN_0;
5538c2ecf20Sopenharmony_ci		i2c.y_clk_mask = RADEON_GPIO_Y_1;
5548c2ecf20Sopenharmony_ci		i2c.y_data_mask = RADEON_GPIO_Y_0;
5558c2ecf20Sopenharmony_ci	}
5568c2ecf20Sopenharmony_ci
5578c2ecf20Sopenharmony_ci	switch (rdev->family) {
5588c2ecf20Sopenharmony_ci	case CHIP_R100:
5598c2ecf20Sopenharmony_ci	case CHIP_RV100:
5608c2ecf20Sopenharmony_ci	case CHIP_RS100:
5618c2ecf20Sopenharmony_ci	case CHIP_RV200:
5628c2ecf20Sopenharmony_ci	case CHIP_RS200:
5638c2ecf20Sopenharmony_ci	case CHIP_RS300:
5648c2ecf20Sopenharmony_ci		switch (ddc_line) {
5658c2ecf20Sopenharmony_ci		case RADEON_GPIO_DVI_DDC:
5668c2ecf20Sopenharmony_ci			i2c.hw_capable = true;
5678c2ecf20Sopenharmony_ci			break;
5688c2ecf20Sopenharmony_ci		default:
5698c2ecf20Sopenharmony_ci			i2c.hw_capable = false;
5708c2ecf20Sopenharmony_ci			break;
5718c2ecf20Sopenharmony_ci		}
5728c2ecf20Sopenharmony_ci		break;
5738c2ecf20Sopenharmony_ci	case CHIP_R200:
5748c2ecf20Sopenharmony_ci		switch (ddc_line) {
5758c2ecf20Sopenharmony_ci		case RADEON_GPIO_DVI_DDC:
5768c2ecf20Sopenharmony_ci		case RADEON_GPIO_MONID:
5778c2ecf20Sopenharmony_ci			i2c.hw_capable = true;
5788c2ecf20Sopenharmony_ci			break;
5798c2ecf20Sopenharmony_ci		default:
5808c2ecf20Sopenharmony_ci			i2c.hw_capable = false;
5818c2ecf20Sopenharmony_ci			break;
5828c2ecf20Sopenharmony_ci		}
5838c2ecf20Sopenharmony_ci		break;
5848c2ecf20Sopenharmony_ci	case CHIP_RV250:
5858c2ecf20Sopenharmony_ci	case CHIP_RV280:
5868c2ecf20Sopenharmony_ci		switch (ddc_line) {
5878c2ecf20Sopenharmony_ci		case RADEON_GPIO_VGA_DDC:
5888c2ecf20Sopenharmony_ci		case RADEON_GPIO_DVI_DDC:
5898c2ecf20Sopenharmony_ci		case RADEON_GPIO_CRT2_DDC:
5908c2ecf20Sopenharmony_ci			i2c.hw_capable = true;
5918c2ecf20Sopenharmony_ci			break;
5928c2ecf20Sopenharmony_ci		default:
5938c2ecf20Sopenharmony_ci			i2c.hw_capable = false;
5948c2ecf20Sopenharmony_ci			break;
5958c2ecf20Sopenharmony_ci		}
5968c2ecf20Sopenharmony_ci		break;
5978c2ecf20Sopenharmony_ci	case CHIP_R300:
5988c2ecf20Sopenharmony_ci	case CHIP_R350:
5998c2ecf20Sopenharmony_ci		switch (ddc_line) {
6008c2ecf20Sopenharmony_ci		case RADEON_GPIO_VGA_DDC:
6018c2ecf20Sopenharmony_ci		case RADEON_GPIO_DVI_DDC:
6028c2ecf20Sopenharmony_ci			i2c.hw_capable = true;
6038c2ecf20Sopenharmony_ci			break;
6048c2ecf20Sopenharmony_ci		default:
6058c2ecf20Sopenharmony_ci			i2c.hw_capable = false;
6068c2ecf20Sopenharmony_ci			break;
6078c2ecf20Sopenharmony_ci		}
6088c2ecf20Sopenharmony_ci		break;
6098c2ecf20Sopenharmony_ci	case CHIP_RV350:
6108c2ecf20Sopenharmony_ci	case CHIP_RV380:
6118c2ecf20Sopenharmony_ci	case CHIP_RS400:
6128c2ecf20Sopenharmony_ci	case CHIP_RS480:
6138c2ecf20Sopenharmony_ci		switch (ddc_line) {
6148c2ecf20Sopenharmony_ci		case RADEON_GPIO_VGA_DDC:
6158c2ecf20Sopenharmony_ci		case RADEON_GPIO_DVI_DDC:
6168c2ecf20Sopenharmony_ci			i2c.hw_capable = true;
6178c2ecf20Sopenharmony_ci			break;
6188c2ecf20Sopenharmony_ci		case RADEON_GPIO_MONID:
6198c2ecf20Sopenharmony_ci			/* hw i2c on RADEON_GPIO_MONID doesn't seem to work
6208c2ecf20Sopenharmony_ci			 * reliably on some pre-r4xx hardware; not sure why.
6218c2ecf20Sopenharmony_ci			 */
6228c2ecf20Sopenharmony_ci			i2c.hw_capable = false;
6238c2ecf20Sopenharmony_ci			break;
6248c2ecf20Sopenharmony_ci		default:
6258c2ecf20Sopenharmony_ci			i2c.hw_capable = false;
6268c2ecf20Sopenharmony_ci			break;
6278c2ecf20Sopenharmony_ci		}
6288c2ecf20Sopenharmony_ci		break;
6298c2ecf20Sopenharmony_ci	default:
6308c2ecf20Sopenharmony_ci		i2c.hw_capable = false;
6318c2ecf20Sopenharmony_ci		break;
6328c2ecf20Sopenharmony_ci	}
6338c2ecf20Sopenharmony_ci	i2c.mm_i2c = false;
6348c2ecf20Sopenharmony_ci
6358c2ecf20Sopenharmony_ci	i2c.i2c_id = ddc;
6368c2ecf20Sopenharmony_ci	i2c.hpd = RADEON_HPD_NONE;
6378c2ecf20Sopenharmony_ci
6388c2ecf20Sopenharmony_ci	if (ddc_line)
6398c2ecf20Sopenharmony_ci		i2c.valid = true;
6408c2ecf20Sopenharmony_ci	else
6418c2ecf20Sopenharmony_ci		i2c.valid = false;
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_ci	return i2c;
6448c2ecf20Sopenharmony_ci}
6458c2ecf20Sopenharmony_ci
6468c2ecf20Sopenharmony_cistatic struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev)
6478c2ecf20Sopenharmony_ci{
6488c2ecf20Sopenharmony_ci	struct drm_device *dev = rdev->ddev;
6498c2ecf20Sopenharmony_ci	struct radeon_i2c_bus_rec i2c;
6508c2ecf20Sopenharmony_ci	u16 offset;
6518c2ecf20Sopenharmony_ci	u8 id, blocks, clk, data;
6528c2ecf20Sopenharmony_ci	int i;
6538c2ecf20Sopenharmony_ci
6548c2ecf20Sopenharmony_ci	i2c.valid = false;
6558c2ecf20Sopenharmony_ci
6568c2ecf20Sopenharmony_ci	offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE);
6578c2ecf20Sopenharmony_ci	if (offset) {
6588c2ecf20Sopenharmony_ci		blocks = RBIOS8(offset + 2);
6598c2ecf20Sopenharmony_ci		for (i = 0; i < blocks; i++) {
6608c2ecf20Sopenharmony_ci			id = RBIOS8(offset + 3 + (i * 5) + 0);
6618c2ecf20Sopenharmony_ci			if (id == 136) {
6628c2ecf20Sopenharmony_ci				clk = RBIOS8(offset + 3 + (i * 5) + 3);
6638c2ecf20Sopenharmony_ci				data = RBIOS8(offset + 3 + (i * 5) + 4);
6648c2ecf20Sopenharmony_ci				/* gpiopad */
6658c2ecf20Sopenharmony_ci				i2c = combios_setup_i2c_bus(rdev, DDC_MONID,
6668c2ecf20Sopenharmony_ci							    (1 << clk), (1 << data));
6678c2ecf20Sopenharmony_ci				break;
6688c2ecf20Sopenharmony_ci			}
6698c2ecf20Sopenharmony_ci		}
6708c2ecf20Sopenharmony_ci	}
6718c2ecf20Sopenharmony_ci	return i2c;
6728c2ecf20Sopenharmony_ci}
6738c2ecf20Sopenharmony_ci
6748c2ecf20Sopenharmony_civoid radeon_combios_i2c_init(struct radeon_device *rdev)
6758c2ecf20Sopenharmony_ci{
6768c2ecf20Sopenharmony_ci	struct drm_device *dev = rdev->ddev;
6778c2ecf20Sopenharmony_ci	struct radeon_i2c_bus_rec i2c;
6788c2ecf20Sopenharmony_ci
6798c2ecf20Sopenharmony_ci	/* actual hw pads
6808c2ecf20Sopenharmony_ci	 * r1xx/rs2xx/rs3xx
6818c2ecf20Sopenharmony_ci	 * 0x60, 0x64, 0x68, 0x6c, gpiopads, mm
6828c2ecf20Sopenharmony_ci	 * r200
6838c2ecf20Sopenharmony_ci	 * 0x60, 0x64, 0x68, mm
6848c2ecf20Sopenharmony_ci	 * r300/r350
6858c2ecf20Sopenharmony_ci	 * 0x60, 0x64, mm
6868c2ecf20Sopenharmony_ci	 * rv2xx/rv3xx/rs4xx
6878c2ecf20Sopenharmony_ci	 * 0x60, 0x64, 0x68, gpiopads, mm
6888c2ecf20Sopenharmony_ci	 */
6898c2ecf20Sopenharmony_ci
6908c2ecf20Sopenharmony_ci	/* 0x60 */
6918c2ecf20Sopenharmony_ci	i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
6928c2ecf20Sopenharmony_ci	rdev->i2c_bus[0] = radeon_i2c_create(dev, &i2c, "DVI_DDC");
6938c2ecf20Sopenharmony_ci	/* 0x64 */
6948c2ecf20Sopenharmony_ci	i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
6958c2ecf20Sopenharmony_ci	rdev->i2c_bus[1] = radeon_i2c_create(dev, &i2c, "VGA_DDC");
6968c2ecf20Sopenharmony_ci
6978c2ecf20Sopenharmony_ci	/* mm i2c */
6988c2ecf20Sopenharmony_ci	i2c.valid = true;
6998c2ecf20Sopenharmony_ci	i2c.hw_capable = true;
7008c2ecf20Sopenharmony_ci	i2c.mm_i2c = true;
7018c2ecf20Sopenharmony_ci	i2c.i2c_id = 0xa0;
7028c2ecf20Sopenharmony_ci	rdev->i2c_bus[2] = radeon_i2c_create(dev, &i2c, "MM_I2C");
7038c2ecf20Sopenharmony_ci
7048c2ecf20Sopenharmony_ci	if (rdev->family == CHIP_R300 ||
7058c2ecf20Sopenharmony_ci	    rdev->family == CHIP_R350) {
7068c2ecf20Sopenharmony_ci		/* only 2 sw i2c pads */
7078c2ecf20Sopenharmony_ci	} else if (rdev->family == CHIP_RS300 ||
7088c2ecf20Sopenharmony_ci		   rdev->family == CHIP_RS400 ||
7098c2ecf20Sopenharmony_ci		   rdev->family == CHIP_RS480) {
7108c2ecf20Sopenharmony_ci		/* 0x68 */
7118c2ecf20Sopenharmony_ci		i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
7128c2ecf20Sopenharmony_ci		rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
7138c2ecf20Sopenharmony_ci
7148c2ecf20Sopenharmony_ci		/* gpiopad */
7158c2ecf20Sopenharmony_ci		i2c = radeon_combios_get_i2c_info_from_table(rdev);
7168c2ecf20Sopenharmony_ci		if (i2c.valid)
7178c2ecf20Sopenharmony_ci			rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK");
7188c2ecf20Sopenharmony_ci	} else if ((rdev->family == CHIP_R200) ||
7198c2ecf20Sopenharmony_ci		   (rdev->family >= CHIP_R300)) {
7208c2ecf20Sopenharmony_ci		/* 0x68 */
7218c2ecf20Sopenharmony_ci		i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
7228c2ecf20Sopenharmony_ci		rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
7238c2ecf20Sopenharmony_ci	} else {
7248c2ecf20Sopenharmony_ci		/* 0x68 */
7258c2ecf20Sopenharmony_ci		i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
7268c2ecf20Sopenharmony_ci		rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
7278c2ecf20Sopenharmony_ci		/* 0x6c */
7288c2ecf20Sopenharmony_ci		i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
7298c2ecf20Sopenharmony_ci		rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "CRT2_DDC");
7308c2ecf20Sopenharmony_ci	}
7318c2ecf20Sopenharmony_ci}
7328c2ecf20Sopenharmony_ci
7338c2ecf20Sopenharmony_cibool radeon_combios_get_clock_info(struct drm_device *dev)
7348c2ecf20Sopenharmony_ci{
7358c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
7368c2ecf20Sopenharmony_ci	uint16_t pll_info;
7378c2ecf20Sopenharmony_ci	struct radeon_pll *p1pll = &rdev->clock.p1pll;
7388c2ecf20Sopenharmony_ci	struct radeon_pll *p2pll = &rdev->clock.p2pll;
7398c2ecf20Sopenharmony_ci	struct radeon_pll *spll = &rdev->clock.spll;
7408c2ecf20Sopenharmony_ci	struct radeon_pll *mpll = &rdev->clock.mpll;
7418c2ecf20Sopenharmony_ci	int8_t rev;
7428c2ecf20Sopenharmony_ci	uint16_t sclk, mclk;
7438c2ecf20Sopenharmony_ci
7448c2ecf20Sopenharmony_ci	pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE);
7458c2ecf20Sopenharmony_ci	if (pll_info) {
7468c2ecf20Sopenharmony_ci		rev = RBIOS8(pll_info);
7478c2ecf20Sopenharmony_ci
7488c2ecf20Sopenharmony_ci		/* pixel clocks */
7498c2ecf20Sopenharmony_ci		p1pll->reference_freq = RBIOS16(pll_info + 0xe);
7508c2ecf20Sopenharmony_ci		p1pll->reference_div = RBIOS16(pll_info + 0x10);
7518c2ecf20Sopenharmony_ci		p1pll->pll_out_min = RBIOS32(pll_info + 0x12);
7528c2ecf20Sopenharmony_ci		p1pll->pll_out_max = RBIOS32(pll_info + 0x16);
7538c2ecf20Sopenharmony_ci		p1pll->lcd_pll_out_min = p1pll->pll_out_min;
7548c2ecf20Sopenharmony_ci		p1pll->lcd_pll_out_max = p1pll->pll_out_max;
7558c2ecf20Sopenharmony_ci
7568c2ecf20Sopenharmony_ci		if (rev > 9) {
7578c2ecf20Sopenharmony_ci			p1pll->pll_in_min = RBIOS32(pll_info + 0x36);
7588c2ecf20Sopenharmony_ci			p1pll->pll_in_max = RBIOS32(pll_info + 0x3a);
7598c2ecf20Sopenharmony_ci		} else {
7608c2ecf20Sopenharmony_ci			p1pll->pll_in_min = 40;
7618c2ecf20Sopenharmony_ci			p1pll->pll_in_max = 500;
7628c2ecf20Sopenharmony_ci		}
7638c2ecf20Sopenharmony_ci		*p2pll = *p1pll;
7648c2ecf20Sopenharmony_ci
7658c2ecf20Sopenharmony_ci		/* system clock */
7668c2ecf20Sopenharmony_ci		spll->reference_freq = RBIOS16(pll_info + 0x1a);
7678c2ecf20Sopenharmony_ci		spll->reference_div = RBIOS16(pll_info + 0x1c);
7688c2ecf20Sopenharmony_ci		spll->pll_out_min = RBIOS32(pll_info + 0x1e);
7698c2ecf20Sopenharmony_ci		spll->pll_out_max = RBIOS32(pll_info + 0x22);
7708c2ecf20Sopenharmony_ci
7718c2ecf20Sopenharmony_ci		if (rev > 10) {
7728c2ecf20Sopenharmony_ci			spll->pll_in_min = RBIOS32(pll_info + 0x48);
7738c2ecf20Sopenharmony_ci			spll->pll_in_max = RBIOS32(pll_info + 0x4c);
7748c2ecf20Sopenharmony_ci		} else {
7758c2ecf20Sopenharmony_ci			/* ??? */
7768c2ecf20Sopenharmony_ci			spll->pll_in_min = 40;
7778c2ecf20Sopenharmony_ci			spll->pll_in_max = 500;
7788c2ecf20Sopenharmony_ci		}
7798c2ecf20Sopenharmony_ci
7808c2ecf20Sopenharmony_ci		/* memory clock */
7818c2ecf20Sopenharmony_ci		mpll->reference_freq = RBIOS16(pll_info + 0x26);
7828c2ecf20Sopenharmony_ci		mpll->reference_div = RBIOS16(pll_info + 0x28);
7838c2ecf20Sopenharmony_ci		mpll->pll_out_min = RBIOS32(pll_info + 0x2a);
7848c2ecf20Sopenharmony_ci		mpll->pll_out_max = RBIOS32(pll_info + 0x2e);
7858c2ecf20Sopenharmony_ci
7868c2ecf20Sopenharmony_ci		if (rev > 10) {
7878c2ecf20Sopenharmony_ci			mpll->pll_in_min = RBIOS32(pll_info + 0x5a);
7888c2ecf20Sopenharmony_ci			mpll->pll_in_max = RBIOS32(pll_info + 0x5e);
7898c2ecf20Sopenharmony_ci		} else {
7908c2ecf20Sopenharmony_ci			/* ??? */
7918c2ecf20Sopenharmony_ci			mpll->pll_in_min = 40;
7928c2ecf20Sopenharmony_ci			mpll->pll_in_max = 500;
7938c2ecf20Sopenharmony_ci		}
7948c2ecf20Sopenharmony_ci
7958c2ecf20Sopenharmony_ci		/* default sclk/mclk */
7968c2ecf20Sopenharmony_ci		sclk = RBIOS16(pll_info + 0xa);
7978c2ecf20Sopenharmony_ci		mclk = RBIOS16(pll_info + 0x8);
7988c2ecf20Sopenharmony_ci		if (sclk == 0)
7998c2ecf20Sopenharmony_ci			sclk = 200 * 100;
8008c2ecf20Sopenharmony_ci		if (mclk == 0)
8018c2ecf20Sopenharmony_ci			mclk = 200 * 100;
8028c2ecf20Sopenharmony_ci
8038c2ecf20Sopenharmony_ci		rdev->clock.default_sclk = sclk;
8048c2ecf20Sopenharmony_ci		rdev->clock.default_mclk = mclk;
8058c2ecf20Sopenharmony_ci
8068c2ecf20Sopenharmony_ci		if (RBIOS32(pll_info + 0x16))
8078c2ecf20Sopenharmony_ci			rdev->clock.max_pixel_clock = RBIOS32(pll_info + 0x16);
8088c2ecf20Sopenharmony_ci		else
8098c2ecf20Sopenharmony_ci			rdev->clock.max_pixel_clock = 35000; /* might need something asic specific */
8108c2ecf20Sopenharmony_ci
8118c2ecf20Sopenharmony_ci		return true;
8128c2ecf20Sopenharmony_ci	}
8138c2ecf20Sopenharmony_ci	return false;
8148c2ecf20Sopenharmony_ci}
8158c2ecf20Sopenharmony_ci
8168c2ecf20Sopenharmony_cibool radeon_combios_sideport_present(struct radeon_device *rdev)
8178c2ecf20Sopenharmony_ci{
8188c2ecf20Sopenharmony_ci	struct drm_device *dev = rdev->ddev;
8198c2ecf20Sopenharmony_ci	u16 igp_info;
8208c2ecf20Sopenharmony_ci
8218c2ecf20Sopenharmony_ci	/* sideport is AMD only */
8228c2ecf20Sopenharmony_ci	if (rdev->family == CHIP_RS400)
8238c2ecf20Sopenharmony_ci		return false;
8248c2ecf20Sopenharmony_ci
8258c2ecf20Sopenharmony_ci	igp_info = combios_get_table_offset(dev, COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE);
8268c2ecf20Sopenharmony_ci
8278c2ecf20Sopenharmony_ci	if (igp_info) {
8288c2ecf20Sopenharmony_ci		if (RBIOS16(igp_info + 0x4))
8298c2ecf20Sopenharmony_ci			return true;
8308c2ecf20Sopenharmony_ci	}
8318c2ecf20Sopenharmony_ci	return false;
8328c2ecf20Sopenharmony_ci}
8338c2ecf20Sopenharmony_ci
8348c2ecf20Sopenharmony_cistatic const uint32_t default_primarydac_adj[CHIP_LAST] = {
8358c2ecf20Sopenharmony_ci	0x00000808,		/* r100  */
8368c2ecf20Sopenharmony_ci	0x00000808,		/* rv100 */
8378c2ecf20Sopenharmony_ci	0x00000808,		/* rs100 */
8388c2ecf20Sopenharmony_ci	0x00000808,		/* rv200 */
8398c2ecf20Sopenharmony_ci	0x00000808,		/* rs200 */
8408c2ecf20Sopenharmony_ci	0x00000808,		/* r200  */
8418c2ecf20Sopenharmony_ci	0x00000808,		/* rv250 */
8428c2ecf20Sopenharmony_ci	0x00000000,		/* rs300 */
8438c2ecf20Sopenharmony_ci	0x00000808,		/* rv280 */
8448c2ecf20Sopenharmony_ci	0x00000808,		/* r300  */
8458c2ecf20Sopenharmony_ci	0x00000808,		/* r350  */
8468c2ecf20Sopenharmony_ci	0x00000808,		/* rv350 */
8478c2ecf20Sopenharmony_ci	0x00000808,		/* rv380 */
8488c2ecf20Sopenharmony_ci	0x00000808,		/* r420  */
8498c2ecf20Sopenharmony_ci	0x00000808,		/* r423  */
8508c2ecf20Sopenharmony_ci	0x00000808,		/* rv410 */
8518c2ecf20Sopenharmony_ci	0x00000000,		/* rs400 */
8528c2ecf20Sopenharmony_ci	0x00000000,		/* rs480 */
8538c2ecf20Sopenharmony_ci};
8548c2ecf20Sopenharmony_ci
8558c2ecf20Sopenharmony_cistatic void radeon_legacy_get_primary_dac_info_from_table(struct radeon_device *rdev,
8568c2ecf20Sopenharmony_ci							  struct radeon_encoder_primary_dac *p_dac)
8578c2ecf20Sopenharmony_ci{
8588c2ecf20Sopenharmony_ci	p_dac->ps2_pdac_adj = default_primarydac_adj[rdev->family];
8598c2ecf20Sopenharmony_ci	return;
8608c2ecf20Sopenharmony_ci}
8618c2ecf20Sopenharmony_ci
8628c2ecf20Sopenharmony_cistruct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct
8638c2ecf20Sopenharmony_ci								       radeon_encoder
8648c2ecf20Sopenharmony_ci								       *encoder)
8658c2ecf20Sopenharmony_ci{
8668c2ecf20Sopenharmony_ci	struct drm_device *dev = encoder->base.dev;
8678c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
8688c2ecf20Sopenharmony_ci	uint16_t dac_info;
8698c2ecf20Sopenharmony_ci	uint8_t rev, bg, dac;
8708c2ecf20Sopenharmony_ci	struct radeon_encoder_primary_dac *p_dac = NULL;
8718c2ecf20Sopenharmony_ci	int found = 0;
8728c2ecf20Sopenharmony_ci
8738c2ecf20Sopenharmony_ci	p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac),
8748c2ecf20Sopenharmony_ci			GFP_KERNEL);
8758c2ecf20Sopenharmony_ci
8768c2ecf20Sopenharmony_ci	if (!p_dac)
8778c2ecf20Sopenharmony_ci		return NULL;
8788c2ecf20Sopenharmony_ci
8798c2ecf20Sopenharmony_ci	/* check CRT table */
8808c2ecf20Sopenharmony_ci	dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
8818c2ecf20Sopenharmony_ci	if (dac_info) {
8828c2ecf20Sopenharmony_ci		rev = RBIOS8(dac_info) & 0x3;
8838c2ecf20Sopenharmony_ci		if (rev < 2) {
8848c2ecf20Sopenharmony_ci			bg = RBIOS8(dac_info + 0x2) & 0xf;
8858c2ecf20Sopenharmony_ci			dac = (RBIOS8(dac_info + 0x2) >> 4) & 0xf;
8868c2ecf20Sopenharmony_ci			p_dac->ps2_pdac_adj = (bg << 8) | (dac);
8878c2ecf20Sopenharmony_ci		} else {
8888c2ecf20Sopenharmony_ci			bg = RBIOS8(dac_info + 0x2) & 0xf;
8898c2ecf20Sopenharmony_ci			dac = RBIOS8(dac_info + 0x3) & 0xf;
8908c2ecf20Sopenharmony_ci			p_dac->ps2_pdac_adj = (bg << 8) | (dac);
8918c2ecf20Sopenharmony_ci		}
8928c2ecf20Sopenharmony_ci		/* if the values are zeros, use the table */
8938c2ecf20Sopenharmony_ci		if ((dac == 0) || (bg == 0))
8948c2ecf20Sopenharmony_ci			found = 0;
8958c2ecf20Sopenharmony_ci		else
8968c2ecf20Sopenharmony_ci			found = 1;
8978c2ecf20Sopenharmony_ci	}
8988c2ecf20Sopenharmony_ci
8998c2ecf20Sopenharmony_ci	/* quirks */
9008c2ecf20Sopenharmony_ci	/* Radeon 7000 (RV100) */
9018c2ecf20Sopenharmony_ci	if (((dev->pdev->device == 0x5159) &&
9028c2ecf20Sopenharmony_ci	    (dev->pdev->subsystem_vendor == 0x174B) &&
9038c2ecf20Sopenharmony_ci	    (dev->pdev->subsystem_device == 0x7c28)) ||
9048c2ecf20Sopenharmony_ci	/* Radeon 9100 (R200) */
9058c2ecf20Sopenharmony_ci	   ((dev->pdev->device == 0x514D) &&
9068c2ecf20Sopenharmony_ci	    (dev->pdev->subsystem_vendor == 0x174B) &&
9078c2ecf20Sopenharmony_ci	    (dev->pdev->subsystem_device == 0x7149))) {
9088c2ecf20Sopenharmony_ci		/* vbios value is bad, use the default */
9098c2ecf20Sopenharmony_ci		found = 0;
9108c2ecf20Sopenharmony_ci	}
9118c2ecf20Sopenharmony_ci
9128c2ecf20Sopenharmony_ci	if (!found) /* fallback to defaults */
9138c2ecf20Sopenharmony_ci		radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac);
9148c2ecf20Sopenharmony_ci
9158c2ecf20Sopenharmony_ci	return p_dac;
9168c2ecf20Sopenharmony_ci}
9178c2ecf20Sopenharmony_ci
9188c2ecf20Sopenharmony_cienum radeon_tv_std
9198c2ecf20Sopenharmony_ciradeon_combios_get_tv_info(struct radeon_device *rdev)
9208c2ecf20Sopenharmony_ci{
9218c2ecf20Sopenharmony_ci	struct drm_device *dev = rdev->ddev;
9228c2ecf20Sopenharmony_ci	uint16_t tv_info;
9238c2ecf20Sopenharmony_ci	enum radeon_tv_std tv_std = TV_STD_NTSC;
9248c2ecf20Sopenharmony_ci
9258c2ecf20Sopenharmony_ci	tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
9268c2ecf20Sopenharmony_ci	if (tv_info) {
9278c2ecf20Sopenharmony_ci		if (RBIOS8(tv_info + 6) == 'T') {
9288c2ecf20Sopenharmony_ci			switch (RBIOS8(tv_info + 7) & 0xf) {
9298c2ecf20Sopenharmony_ci			case 1:
9308c2ecf20Sopenharmony_ci				tv_std = TV_STD_NTSC;
9318c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS("Default TV standard: NTSC\n");
9328c2ecf20Sopenharmony_ci				break;
9338c2ecf20Sopenharmony_ci			case 2:
9348c2ecf20Sopenharmony_ci				tv_std = TV_STD_PAL;
9358c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS("Default TV standard: PAL\n");
9368c2ecf20Sopenharmony_ci				break;
9378c2ecf20Sopenharmony_ci			case 3:
9388c2ecf20Sopenharmony_ci				tv_std = TV_STD_PAL_M;
9398c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS("Default TV standard: PAL-M\n");
9408c2ecf20Sopenharmony_ci				break;
9418c2ecf20Sopenharmony_ci			case 4:
9428c2ecf20Sopenharmony_ci				tv_std = TV_STD_PAL_60;
9438c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS("Default TV standard: PAL-60\n");
9448c2ecf20Sopenharmony_ci				break;
9458c2ecf20Sopenharmony_ci			case 5:
9468c2ecf20Sopenharmony_ci				tv_std = TV_STD_NTSC_J;
9478c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS("Default TV standard: NTSC-J\n");
9488c2ecf20Sopenharmony_ci				break;
9498c2ecf20Sopenharmony_ci			case 6:
9508c2ecf20Sopenharmony_ci				tv_std = TV_STD_SCART_PAL;
9518c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS("Default TV standard: SCART-PAL\n");
9528c2ecf20Sopenharmony_ci				break;
9538c2ecf20Sopenharmony_ci			default:
9548c2ecf20Sopenharmony_ci				tv_std = TV_STD_NTSC;
9558c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS
9568c2ecf20Sopenharmony_ci				    ("Unknown TV standard; defaulting to NTSC\n");
9578c2ecf20Sopenharmony_ci				break;
9588c2ecf20Sopenharmony_ci			}
9598c2ecf20Sopenharmony_ci
9608c2ecf20Sopenharmony_ci			switch ((RBIOS8(tv_info + 9) >> 2) & 0x3) {
9618c2ecf20Sopenharmony_ci			case 0:
9628c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS("29.498928713 MHz TV ref clk\n");
9638c2ecf20Sopenharmony_ci				break;
9648c2ecf20Sopenharmony_ci			case 1:
9658c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS("28.636360000 MHz TV ref clk\n");
9668c2ecf20Sopenharmony_ci				break;
9678c2ecf20Sopenharmony_ci			case 2:
9688c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS("14.318180000 MHz TV ref clk\n");
9698c2ecf20Sopenharmony_ci				break;
9708c2ecf20Sopenharmony_ci			case 3:
9718c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS("27.000000000 MHz TV ref clk\n");
9728c2ecf20Sopenharmony_ci				break;
9738c2ecf20Sopenharmony_ci			default:
9748c2ecf20Sopenharmony_ci				break;
9758c2ecf20Sopenharmony_ci			}
9768c2ecf20Sopenharmony_ci		}
9778c2ecf20Sopenharmony_ci	}
9788c2ecf20Sopenharmony_ci	return tv_std;
9798c2ecf20Sopenharmony_ci}
9808c2ecf20Sopenharmony_ci
9818c2ecf20Sopenharmony_cistatic const uint32_t default_tvdac_adj[CHIP_LAST] = {
9828c2ecf20Sopenharmony_ci	0x00000000,		/* r100  */
9838c2ecf20Sopenharmony_ci	0x00280000,		/* rv100 */
9848c2ecf20Sopenharmony_ci	0x00000000,		/* rs100 */
9858c2ecf20Sopenharmony_ci	0x00880000,		/* rv200 */
9868c2ecf20Sopenharmony_ci	0x00000000,		/* rs200 */
9878c2ecf20Sopenharmony_ci	0x00000000,		/* r200  */
9888c2ecf20Sopenharmony_ci	0x00770000,		/* rv250 */
9898c2ecf20Sopenharmony_ci	0x00290000,		/* rs300 */
9908c2ecf20Sopenharmony_ci	0x00560000,		/* rv280 */
9918c2ecf20Sopenharmony_ci	0x00780000,		/* r300  */
9928c2ecf20Sopenharmony_ci	0x00770000,		/* r350  */
9938c2ecf20Sopenharmony_ci	0x00780000,		/* rv350 */
9948c2ecf20Sopenharmony_ci	0x00780000,		/* rv380 */
9958c2ecf20Sopenharmony_ci	0x01080000,		/* r420  */
9968c2ecf20Sopenharmony_ci	0x01080000,		/* r423  */
9978c2ecf20Sopenharmony_ci	0x01080000,		/* rv410 */
9988c2ecf20Sopenharmony_ci	0x00780000,		/* rs400 */
9998c2ecf20Sopenharmony_ci	0x00780000,		/* rs480 */
10008c2ecf20Sopenharmony_ci};
10018c2ecf20Sopenharmony_ci
10028c2ecf20Sopenharmony_cistatic void radeon_legacy_get_tv_dac_info_from_table(struct radeon_device *rdev,
10038c2ecf20Sopenharmony_ci						     struct radeon_encoder_tv_dac *tv_dac)
10048c2ecf20Sopenharmony_ci{
10058c2ecf20Sopenharmony_ci	tv_dac->ps2_tvdac_adj = default_tvdac_adj[rdev->family];
10068c2ecf20Sopenharmony_ci	if ((rdev->flags & RADEON_IS_MOBILITY) && (rdev->family == CHIP_RV250))
10078c2ecf20Sopenharmony_ci		tv_dac->ps2_tvdac_adj = 0x00880000;
10088c2ecf20Sopenharmony_ci	tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
10098c2ecf20Sopenharmony_ci	tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
10108c2ecf20Sopenharmony_ci	return;
10118c2ecf20Sopenharmony_ci}
10128c2ecf20Sopenharmony_ci
10138c2ecf20Sopenharmony_cistruct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
10148c2ecf20Sopenharmony_ci							     radeon_encoder
10158c2ecf20Sopenharmony_ci							     *encoder)
10168c2ecf20Sopenharmony_ci{
10178c2ecf20Sopenharmony_ci	struct drm_device *dev = encoder->base.dev;
10188c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
10198c2ecf20Sopenharmony_ci	uint16_t dac_info;
10208c2ecf20Sopenharmony_ci	uint8_t rev, bg, dac;
10218c2ecf20Sopenharmony_ci	struct radeon_encoder_tv_dac *tv_dac = NULL;
10228c2ecf20Sopenharmony_ci	int found = 0;
10238c2ecf20Sopenharmony_ci
10248c2ecf20Sopenharmony_ci	tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL);
10258c2ecf20Sopenharmony_ci	if (!tv_dac)
10268c2ecf20Sopenharmony_ci		return NULL;
10278c2ecf20Sopenharmony_ci
10288c2ecf20Sopenharmony_ci	/* first check TV table */
10298c2ecf20Sopenharmony_ci	dac_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
10308c2ecf20Sopenharmony_ci	if (dac_info) {
10318c2ecf20Sopenharmony_ci		rev = RBIOS8(dac_info + 0x3);
10328c2ecf20Sopenharmony_ci		if (rev > 4) {
10338c2ecf20Sopenharmony_ci			bg = RBIOS8(dac_info + 0xc) & 0xf;
10348c2ecf20Sopenharmony_ci			dac = RBIOS8(dac_info + 0xd) & 0xf;
10358c2ecf20Sopenharmony_ci			tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
10368c2ecf20Sopenharmony_ci
10378c2ecf20Sopenharmony_ci			bg = RBIOS8(dac_info + 0xe) & 0xf;
10388c2ecf20Sopenharmony_ci			dac = RBIOS8(dac_info + 0xf) & 0xf;
10398c2ecf20Sopenharmony_ci			tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20);
10408c2ecf20Sopenharmony_ci
10418c2ecf20Sopenharmony_ci			bg = RBIOS8(dac_info + 0x10) & 0xf;
10428c2ecf20Sopenharmony_ci			dac = RBIOS8(dac_info + 0x11) & 0xf;
10438c2ecf20Sopenharmony_ci			tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
10448c2ecf20Sopenharmony_ci			/* if the values are all zeros, use the table */
10458c2ecf20Sopenharmony_ci			if (tv_dac->ps2_tvdac_adj)
10468c2ecf20Sopenharmony_ci				found = 1;
10478c2ecf20Sopenharmony_ci		} else if (rev > 1) {
10488c2ecf20Sopenharmony_ci			bg = RBIOS8(dac_info + 0xc) & 0xf;
10498c2ecf20Sopenharmony_ci			dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf;
10508c2ecf20Sopenharmony_ci			tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
10518c2ecf20Sopenharmony_ci
10528c2ecf20Sopenharmony_ci			bg = RBIOS8(dac_info + 0xd) & 0xf;
10538c2ecf20Sopenharmony_ci			dac = (RBIOS8(dac_info + 0xd) >> 4) & 0xf;
10548c2ecf20Sopenharmony_ci			tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20);
10558c2ecf20Sopenharmony_ci
10568c2ecf20Sopenharmony_ci			bg = RBIOS8(dac_info + 0xe) & 0xf;
10578c2ecf20Sopenharmony_ci			dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf;
10588c2ecf20Sopenharmony_ci			tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
10598c2ecf20Sopenharmony_ci			/* if the values are all zeros, use the table */
10608c2ecf20Sopenharmony_ci			if (tv_dac->ps2_tvdac_adj)
10618c2ecf20Sopenharmony_ci				found = 1;
10628c2ecf20Sopenharmony_ci		}
10638c2ecf20Sopenharmony_ci		tv_dac->tv_std = radeon_combios_get_tv_info(rdev);
10648c2ecf20Sopenharmony_ci	}
10658c2ecf20Sopenharmony_ci	if (!found) {
10668c2ecf20Sopenharmony_ci		/* then check CRT table */
10678c2ecf20Sopenharmony_ci		dac_info =
10688c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
10698c2ecf20Sopenharmony_ci		if (dac_info) {
10708c2ecf20Sopenharmony_ci			rev = RBIOS8(dac_info) & 0x3;
10718c2ecf20Sopenharmony_ci			if (rev < 2) {
10728c2ecf20Sopenharmony_ci				bg = RBIOS8(dac_info + 0x3) & 0xf;
10738c2ecf20Sopenharmony_ci				dac = (RBIOS8(dac_info + 0x3) >> 4) & 0xf;
10748c2ecf20Sopenharmony_ci				tv_dac->ps2_tvdac_adj =
10758c2ecf20Sopenharmony_ci				    (bg << 16) | (dac << 20);
10768c2ecf20Sopenharmony_ci				tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
10778c2ecf20Sopenharmony_ci				tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
10788c2ecf20Sopenharmony_ci				/* if the values are all zeros, use the table */
10798c2ecf20Sopenharmony_ci				if (tv_dac->ps2_tvdac_adj)
10808c2ecf20Sopenharmony_ci					found = 1;
10818c2ecf20Sopenharmony_ci			} else {
10828c2ecf20Sopenharmony_ci				bg = RBIOS8(dac_info + 0x4) & 0xf;
10838c2ecf20Sopenharmony_ci				dac = RBIOS8(dac_info + 0x5) & 0xf;
10848c2ecf20Sopenharmony_ci				tv_dac->ps2_tvdac_adj =
10858c2ecf20Sopenharmony_ci				    (bg << 16) | (dac << 20);
10868c2ecf20Sopenharmony_ci				tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
10878c2ecf20Sopenharmony_ci				tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
10888c2ecf20Sopenharmony_ci				/* if the values are all zeros, use the table */
10898c2ecf20Sopenharmony_ci				if (tv_dac->ps2_tvdac_adj)
10908c2ecf20Sopenharmony_ci					found = 1;
10918c2ecf20Sopenharmony_ci			}
10928c2ecf20Sopenharmony_ci		} else {
10938c2ecf20Sopenharmony_ci			DRM_INFO("No TV DAC info found in BIOS\n");
10948c2ecf20Sopenharmony_ci		}
10958c2ecf20Sopenharmony_ci	}
10968c2ecf20Sopenharmony_ci
10978c2ecf20Sopenharmony_ci	if (!found) /* fallback to defaults */
10988c2ecf20Sopenharmony_ci		radeon_legacy_get_tv_dac_info_from_table(rdev, tv_dac);
10998c2ecf20Sopenharmony_ci
11008c2ecf20Sopenharmony_ci	return tv_dac;
11018c2ecf20Sopenharmony_ci}
11028c2ecf20Sopenharmony_ci
11038c2ecf20Sopenharmony_cistatic struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct
11048c2ecf20Sopenharmony_ci									 radeon_device
11058c2ecf20Sopenharmony_ci									 *rdev)
11068c2ecf20Sopenharmony_ci{
11078c2ecf20Sopenharmony_ci	struct radeon_encoder_lvds *lvds = NULL;
11088c2ecf20Sopenharmony_ci	uint32_t fp_vert_stretch, fp_horz_stretch;
11098c2ecf20Sopenharmony_ci	uint32_t ppll_div_sel, ppll_val;
11108c2ecf20Sopenharmony_ci	uint32_t lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL);
11118c2ecf20Sopenharmony_ci
11128c2ecf20Sopenharmony_ci	lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL);
11138c2ecf20Sopenharmony_ci
11148c2ecf20Sopenharmony_ci	if (!lvds)
11158c2ecf20Sopenharmony_ci		return NULL;
11168c2ecf20Sopenharmony_ci
11178c2ecf20Sopenharmony_ci	fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH);
11188c2ecf20Sopenharmony_ci	fp_horz_stretch = RREG32(RADEON_FP_HORZ_STRETCH);
11198c2ecf20Sopenharmony_ci
11208c2ecf20Sopenharmony_ci	/* These should be fail-safe defaults, fingers crossed */
11218c2ecf20Sopenharmony_ci	lvds->panel_pwr_delay = 200;
11228c2ecf20Sopenharmony_ci	lvds->panel_vcc_delay = 2000;
11238c2ecf20Sopenharmony_ci
11248c2ecf20Sopenharmony_ci	lvds->lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL);
11258c2ecf20Sopenharmony_ci	lvds->panel_digon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) & 0xf;
11268c2ecf20Sopenharmony_ci	lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf;
11278c2ecf20Sopenharmony_ci
11288c2ecf20Sopenharmony_ci	if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE)
11298c2ecf20Sopenharmony_ci		lvds->native_mode.vdisplay =
11308c2ecf20Sopenharmony_ci		    ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >>
11318c2ecf20Sopenharmony_ci		     RADEON_VERT_PANEL_SHIFT) + 1;
11328c2ecf20Sopenharmony_ci	else
11338c2ecf20Sopenharmony_ci		lvds->native_mode.vdisplay =
11348c2ecf20Sopenharmony_ci		    (RREG32(RADEON_CRTC_V_TOTAL_DISP) >> 16) + 1;
11358c2ecf20Sopenharmony_ci
11368c2ecf20Sopenharmony_ci	if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE)
11378c2ecf20Sopenharmony_ci		lvds->native_mode.hdisplay =
11388c2ecf20Sopenharmony_ci		    (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >>
11398c2ecf20Sopenharmony_ci		      RADEON_HORZ_PANEL_SHIFT) + 1) * 8;
11408c2ecf20Sopenharmony_ci	else
11418c2ecf20Sopenharmony_ci		lvds->native_mode.hdisplay =
11428c2ecf20Sopenharmony_ci		    ((RREG32(RADEON_CRTC_H_TOTAL_DISP) >> 16) + 1) * 8;
11438c2ecf20Sopenharmony_ci
11448c2ecf20Sopenharmony_ci	if ((lvds->native_mode.hdisplay < 640) ||
11458c2ecf20Sopenharmony_ci	    (lvds->native_mode.vdisplay < 480)) {
11468c2ecf20Sopenharmony_ci		lvds->native_mode.hdisplay = 640;
11478c2ecf20Sopenharmony_ci		lvds->native_mode.vdisplay = 480;
11488c2ecf20Sopenharmony_ci	}
11498c2ecf20Sopenharmony_ci
11508c2ecf20Sopenharmony_ci	ppll_div_sel = RREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
11518c2ecf20Sopenharmony_ci	ppll_val = RREG32_PLL(RADEON_PPLL_DIV_0 + ppll_div_sel);
11528c2ecf20Sopenharmony_ci	if ((ppll_val & 0x000707ff) == 0x1bb)
11538c2ecf20Sopenharmony_ci		lvds->use_bios_dividers = false;
11548c2ecf20Sopenharmony_ci	else {
11558c2ecf20Sopenharmony_ci		lvds->panel_ref_divider =
11568c2ecf20Sopenharmony_ci		    RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff;
11578c2ecf20Sopenharmony_ci		lvds->panel_post_divider = (ppll_val >> 16) & 0x7;
11588c2ecf20Sopenharmony_ci		lvds->panel_fb_divider = ppll_val & 0x7ff;
11598c2ecf20Sopenharmony_ci
11608c2ecf20Sopenharmony_ci		if ((lvds->panel_ref_divider != 0) &&
11618c2ecf20Sopenharmony_ci		    (lvds->panel_fb_divider > 3))
11628c2ecf20Sopenharmony_ci			lvds->use_bios_dividers = true;
11638c2ecf20Sopenharmony_ci	}
11648c2ecf20Sopenharmony_ci	lvds->panel_vcc_delay = 200;
11658c2ecf20Sopenharmony_ci
11668c2ecf20Sopenharmony_ci	DRM_INFO("Panel info derived from registers\n");
11678c2ecf20Sopenharmony_ci	DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay,
11688c2ecf20Sopenharmony_ci		 lvds->native_mode.vdisplay);
11698c2ecf20Sopenharmony_ci
11708c2ecf20Sopenharmony_ci	return lvds;
11718c2ecf20Sopenharmony_ci}
11728c2ecf20Sopenharmony_ci
11738c2ecf20Sopenharmony_cistruct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
11748c2ecf20Sopenharmony_ci							 *encoder)
11758c2ecf20Sopenharmony_ci{
11768c2ecf20Sopenharmony_ci	struct drm_device *dev = encoder->base.dev;
11778c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
11788c2ecf20Sopenharmony_ci	uint16_t lcd_info;
11798c2ecf20Sopenharmony_ci	uint32_t panel_setup;
11808c2ecf20Sopenharmony_ci	char stmp[30];
11818c2ecf20Sopenharmony_ci	int tmp, i;
11828c2ecf20Sopenharmony_ci	struct radeon_encoder_lvds *lvds = NULL;
11838c2ecf20Sopenharmony_ci
11848c2ecf20Sopenharmony_ci	lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
11858c2ecf20Sopenharmony_ci
11868c2ecf20Sopenharmony_ci	if (lcd_info) {
11878c2ecf20Sopenharmony_ci		lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL);
11888c2ecf20Sopenharmony_ci
11898c2ecf20Sopenharmony_ci		if (!lvds)
11908c2ecf20Sopenharmony_ci			return NULL;
11918c2ecf20Sopenharmony_ci
11928c2ecf20Sopenharmony_ci		for (i = 0; i < 24; i++)
11938c2ecf20Sopenharmony_ci			stmp[i] = RBIOS8(lcd_info + i + 1);
11948c2ecf20Sopenharmony_ci		stmp[24] = 0;
11958c2ecf20Sopenharmony_ci
11968c2ecf20Sopenharmony_ci		DRM_INFO("Panel ID String: %s\n", stmp);
11978c2ecf20Sopenharmony_ci
11988c2ecf20Sopenharmony_ci		lvds->native_mode.hdisplay = RBIOS16(lcd_info + 0x19);
11998c2ecf20Sopenharmony_ci		lvds->native_mode.vdisplay = RBIOS16(lcd_info + 0x1b);
12008c2ecf20Sopenharmony_ci
12018c2ecf20Sopenharmony_ci		DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay,
12028c2ecf20Sopenharmony_ci			 lvds->native_mode.vdisplay);
12038c2ecf20Sopenharmony_ci
12048c2ecf20Sopenharmony_ci		lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c);
12058c2ecf20Sopenharmony_ci		lvds->panel_vcc_delay = min_t(u16, lvds->panel_vcc_delay, 2000);
12068c2ecf20Sopenharmony_ci
12078c2ecf20Sopenharmony_ci		lvds->panel_pwr_delay = RBIOS8(lcd_info + 0x24);
12088c2ecf20Sopenharmony_ci		lvds->panel_digon_delay = RBIOS16(lcd_info + 0x38) & 0xf;
12098c2ecf20Sopenharmony_ci		lvds->panel_blon_delay = (RBIOS16(lcd_info + 0x38) >> 4) & 0xf;
12108c2ecf20Sopenharmony_ci
12118c2ecf20Sopenharmony_ci		lvds->panel_ref_divider = RBIOS16(lcd_info + 0x2e);
12128c2ecf20Sopenharmony_ci		lvds->panel_post_divider = RBIOS8(lcd_info + 0x30);
12138c2ecf20Sopenharmony_ci		lvds->panel_fb_divider = RBIOS16(lcd_info + 0x31);
12148c2ecf20Sopenharmony_ci		if ((lvds->panel_ref_divider != 0) &&
12158c2ecf20Sopenharmony_ci		    (lvds->panel_fb_divider > 3))
12168c2ecf20Sopenharmony_ci			lvds->use_bios_dividers = true;
12178c2ecf20Sopenharmony_ci
12188c2ecf20Sopenharmony_ci		panel_setup = RBIOS32(lcd_info + 0x39);
12198c2ecf20Sopenharmony_ci		lvds->lvds_gen_cntl = 0xff00;
12208c2ecf20Sopenharmony_ci		if (panel_setup & 0x1)
12218c2ecf20Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_PANEL_FORMAT;
12228c2ecf20Sopenharmony_ci
12238c2ecf20Sopenharmony_ci		if ((panel_setup >> 4) & 0x1)
12248c2ecf20Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_PANEL_TYPE;
12258c2ecf20Sopenharmony_ci
12268c2ecf20Sopenharmony_ci		switch ((panel_setup >> 8) & 0x7) {
12278c2ecf20Sopenharmony_ci		case 0:
12288c2ecf20Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_NO_FM;
12298c2ecf20Sopenharmony_ci			break;
12308c2ecf20Sopenharmony_ci		case 1:
12318c2ecf20Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_2_GREY;
12328c2ecf20Sopenharmony_ci			break;
12338c2ecf20Sopenharmony_ci		case 2:
12348c2ecf20Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_4_GREY;
12358c2ecf20Sopenharmony_ci			break;
12368c2ecf20Sopenharmony_ci		default:
12378c2ecf20Sopenharmony_ci			break;
12388c2ecf20Sopenharmony_ci		}
12398c2ecf20Sopenharmony_ci
12408c2ecf20Sopenharmony_ci		if ((panel_setup >> 16) & 0x1)
12418c2ecf20Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_FP_POL_LOW;
12428c2ecf20Sopenharmony_ci
12438c2ecf20Sopenharmony_ci		if ((panel_setup >> 17) & 0x1)
12448c2ecf20Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_LP_POL_LOW;
12458c2ecf20Sopenharmony_ci
12468c2ecf20Sopenharmony_ci		if ((panel_setup >> 18) & 0x1)
12478c2ecf20Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_DTM_POL_LOW;
12488c2ecf20Sopenharmony_ci
12498c2ecf20Sopenharmony_ci		if ((panel_setup >> 23) & 0x1)
12508c2ecf20Sopenharmony_ci			lvds->lvds_gen_cntl |= RADEON_LVDS_BL_CLK_SEL;
12518c2ecf20Sopenharmony_ci
12528c2ecf20Sopenharmony_ci		lvds->lvds_gen_cntl |= (panel_setup & 0xf0000000);
12538c2ecf20Sopenharmony_ci
12548c2ecf20Sopenharmony_ci		for (i = 0; i < 32; i++) {
12558c2ecf20Sopenharmony_ci			tmp = RBIOS16(lcd_info + 64 + i * 2);
12568c2ecf20Sopenharmony_ci			if (tmp == 0)
12578c2ecf20Sopenharmony_ci				break;
12588c2ecf20Sopenharmony_ci
12598c2ecf20Sopenharmony_ci			if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) &&
12608c2ecf20Sopenharmony_ci			    (RBIOS16(tmp + 2) == lvds->native_mode.vdisplay)) {
12618c2ecf20Sopenharmony_ci				u32 hss = (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - 1) * 8;
12628c2ecf20Sopenharmony_ci
12638c2ecf20Sopenharmony_ci				if (hss > lvds->native_mode.hdisplay)
12648c2ecf20Sopenharmony_ci					hss = (10 - 1) * 8;
12658c2ecf20Sopenharmony_ci
12668c2ecf20Sopenharmony_ci				lvds->native_mode.htotal = lvds->native_mode.hdisplay +
12678c2ecf20Sopenharmony_ci					(RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8;
12688c2ecf20Sopenharmony_ci				lvds->native_mode.hsync_start = lvds->native_mode.hdisplay +
12698c2ecf20Sopenharmony_ci					hss;
12708c2ecf20Sopenharmony_ci				lvds->native_mode.hsync_end = lvds->native_mode.hsync_start +
12718c2ecf20Sopenharmony_ci					(RBIOS8(tmp + 23) * 8);
12728c2ecf20Sopenharmony_ci
12738c2ecf20Sopenharmony_ci				lvds->native_mode.vtotal = lvds->native_mode.vdisplay +
12748c2ecf20Sopenharmony_ci					(RBIOS16(tmp + 24) - RBIOS16(tmp + 26));
12758c2ecf20Sopenharmony_ci				lvds->native_mode.vsync_start = lvds->native_mode.vdisplay +
12768c2ecf20Sopenharmony_ci					((RBIOS16(tmp + 28) & 0x7ff) - RBIOS16(tmp + 26));
12778c2ecf20Sopenharmony_ci				lvds->native_mode.vsync_end = lvds->native_mode.vsync_start +
12788c2ecf20Sopenharmony_ci					((RBIOS16(tmp + 28) & 0xf800) >> 11);
12798c2ecf20Sopenharmony_ci
12808c2ecf20Sopenharmony_ci				lvds->native_mode.clock = RBIOS16(tmp + 9) * 10;
12818c2ecf20Sopenharmony_ci				lvds->native_mode.flags = 0;
12828c2ecf20Sopenharmony_ci				/* set crtc values */
12838c2ecf20Sopenharmony_ci				drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);
12848c2ecf20Sopenharmony_ci
12858c2ecf20Sopenharmony_ci			}
12868c2ecf20Sopenharmony_ci		}
12878c2ecf20Sopenharmony_ci	} else {
12888c2ecf20Sopenharmony_ci		DRM_INFO("No panel info found in BIOS\n");
12898c2ecf20Sopenharmony_ci		lvds = radeon_legacy_get_lvds_info_from_regs(rdev);
12908c2ecf20Sopenharmony_ci	}
12918c2ecf20Sopenharmony_ci
12928c2ecf20Sopenharmony_ci	if (lvds)
12938c2ecf20Sopenharmony_ci		encoder->native_mode = lvds->native_mode;
12948c2ecf20Sopenharmony_ci	return lvds;
12958c2ecf20Sopenharmony_ci}
12968c2ecf20Sopenharmony_ci
12978c2ecf20Sopenharmony_cistatic const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = {
12988c2ecf20Sopenharmony_ci	{{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/* CHIP_R100  */
12998c2ecf20Sopenharmony_ci	{{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/* CHIP_RV100 */
13008c2ecf20Sopenharmony_ci	{{0, 0}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_RS100 */
13018c2ecf20Sopenharmony_ci	{{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/* CHIP_RV200 */
13028c2ecf20Sopenharmony_ci	{{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/* CHIP_RS200 */
13038c2ecf20Sopenharmony_ci	{{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/* CHIP_R200  */
13048c2ecf20Sopenharmony_ci	{{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}},	/* CHIP_RV250 */
13058c2ecf20Sopenharmony_ci	{{0, 0}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_RS300 */
13068c2ecf20Sopenharmony_ci	{{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}},	/* CHIP_RV280 */
13078c2ecf20Sopenharmony_ci	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_R300  */
13088c2ecf20Sopenharmony_ci	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_R350  */
13098c2ecf20Sopenharmony_ci	{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/* CHIP_RV350 */
13108c2ecf20Sopenharmony_ci	{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/* CHIP_RV380 */
13118c2ecf20Sopenharmony_ci	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_R420  */
13128c2ecf20Sopenharmony_ci	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_R423  */
13138c2ecf20Sopenharmony_ci	{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},	/* CHIP_RV410 */
13148c2ecf20Sopenharmony_ci	{ {0, 0}, {0, 0}, {0, 0}, {0, 0} },	/* CHIP_RS400 */
13158c2ecf20Sopenharmony_ci	{ {0, 0}, {0, 0}, {0, 0}, {0, 0} },	/* CHIP_RS480 */
13168c2ecf20Sopenharmony_ci};
13178c2ecf20Sopenharmony_ci
13188c2ecf20Sopenharmony_cibool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
13198c2ecf20Sopenharmony_ci					    struct radeon_encoder_int_tmds *tmds)
13208c2ecf20Sopenharmony_ci{
13218c2ecf20Sopenharmony_ci	struct drm_device *dev = encoder->base.dev;
13228c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
13238c2ecf20Sopenharmony_ci	int i;
13248c2ecf20Sopenharmony_ci
13258c2ecf20Sopenharmony_ci	for (i = 0; i < 4; i++) {
13268c2ecf20Sopenharmony_ci		tmds->tmds_pll[i].value =
13278c2ecf20Sopenharmony_ci			default_tmds_pll[rdev->family][i].value;
13288c2ecf20Sopenharmony_ci		tmds->tmds_pll[i].freq = default_tmds_pll[rdev->family][i].freq;
13298c2ecf20Sopenharmony_ci	}
13308c2ecf20Sopenharmony_ci
13318c2ecf20Sopenharmony_ci	return true;
13328c2ecf20Sopenharmony_ci}
13338c2ecf20Sopenharmony_ci
13348c2ecf20Sopenharmony_cibool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
13358c2ecf20Sopenharmony_ci					      struct radeon_encoder_int_tmds *tmds)
13368c2ecf20Sopenharmony_ci{
13378c2ecf20Sopenharmony_ci	struct drm_device *dev = encoder->base.dev;
13388c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
13398c2ecf20Sopenharmony_ci	uint16_t tmds_info;
13408c2ecf20Sopenharmony_ci	int i, n;
13418c2ecf20Sopenharmony_ci	uint8_t ver;
13428c2ecf20Sopenharmony_ci
13438c2ecf20Sopenharmony_ci	tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
13448c2ecf20Sopenharmony_ci
13458c2ecf20Sopenharmony_ci	if (tmds_info) {
13468c2ecf20Sopenharmony_ci		ver = RBIOS8(tmds_info);
13478c2ecf20Sopenharmony_ci		DRM_DEBUG_KMS("DFP table revision: %d\n", ver);
13488c2ecf20Sopenharmony_ci		if (ver == 3) {
13498c2ecf20Sopenharmony_ci			n = RBIOS8(tmds_info + 5) + 1;
13508c2ecf20Sopenharmony_ci			if (n > 4)
13518c2ecf20Sopenharmony_ci				n = 4;
13528c2ecf20Sopenharmony_ci			for (i = 0; i < n; i++) {
13538c2ecf20Sopenharmony_ci				tmds->tmds_pll[i].value =
13548c2ecf20Sopenharmony_ci				    RBIOS32(tmds_info + i * 10 + 0x08);
13558c2ecf20Sopenharmony_ci				tmds->tmds_pll[i].freq =
13568c2ecf20Sopenharmony_ci				    RBIOS16(tmds_info + i * 10 + 0x10);
13578c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n",
13588c2ecf20Sopenharmony_ci					  tmds->tmds_pll[i].freq,
13598c2ecf20Sopenharmony_ci					  tmds->tmds_pll[i].value);
13608c2ecf20Sopenharmony_ci			}
13618c2ecf20Sopenharmony_ci		} else if (ver == 4) {
13628c2ecf20Sopenharmony_ci			int stride = 0;
13638c2ecf20Sopenharmony_ci			n = RBIOS8(tmds_info + 5) + 1;
13648c2ecf20Sopenharmony_ci			if (n > 4)
13658c2ecf20Sopenharmony_ci				n = 4;
13668c2ecf20Sopenharmony_ci			for (i = 0; i < n; i++) {
13678c2ecf20Sopenharmony_ci				tmds->tmds_pll[i].value =
13688c2ecf20Sopenharmony_ci				    RBIOS32(tmds_info + stride + 0x08);
13698c2ecf20Sopenharmony_ci				tmds->tmds_pll[i].freq =
13708c2ecf20Sopenharmony_ci				    RBIOS16(tmds_info + stride + 0x10);
13718c2ecf20Sopenharmony_ci				if (i == 0)
13728c2ecf20Sopenharmony_ci					stride += 10;
13738c2ecf20Sopenharmony_ci				else
13748c2ecf20Sopenharmony_ci					stride += 6;
13758c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n",
13768c2ecf20Sopenharmony_ci					  tmds->tmds_pll[i].freq,
13778c2ecf20Sopenharmony_ci					  tmds->tmds_pll[i].value);
13788c2ecf20Sopenharmony_ci			}
13798c2ecf20Sopenharmony_ci		}
13808c2ecf20Sopenharmony_ci	} else {
13818c2ecf20Sopenharmony_ci		DRM_INFO("No TMDS info found in BIOS\n");
13828c2ecf20Sopenharmony_ci		return false;
13838c2ecf20Sopenharmony_ci	}
13848c2ecf20Sopenharmony_ci	return true;
13858c2ecf20Sopenharmony_ci}
13868c2ecf20Sopenharmony_ci
13878c2ecf20Sopenharmony_cibool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
13888c2ecf20Sopenharmony_ci						struct radeon_encoder_ext_tmds *tmds)
13898c2ecf20Sopenharmony_ci{
13908c2ecf20Sopenharmony_ci	struct drm_device *dev = encoder->base.dev;
13918c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
13928c2ecf20Sopenharmony_ci	struct radeon_i2c_bus_rec i2c_bus;
13938c2ecf20Sopenharmony_ci
13948c2ecf20Sopenharmony_ci	/* default for macs */
13958c2ecf20Sopenharmony_ci	i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
13968c2ecf20Sopenharmony_ci	tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
13978c2ecf20Sopenharmony_ci
13988c2ecf20Sopenharmony_ci	/* XXX some macs have duallink chips */
13998c2ecf20Sopenharmony_ci	switch (rdev->mode_info.connector_table) {
14008c2ecf20Sopenharmony_ci	case CT_POWERBOOK_EXTERNAL:
14018c2ecf20Sopenharmony_ci	case CT_MINI_EXTERNAL:
14028c2ecf20Sopenharmony_ci	default:
14038c2ecf20Sopenharmony_ci		tmds->dvo_chip = DVO_SIL164;
14048c2ecf20Sopenharmony_ci		tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
14058c2ecf20Sopenharmony_ci		break;
14068c2ecf20Sopenharmony_ci	}
14078c2ecf20Sopenharmony_ci
14088c2ecf20Sopenharmony_ci	return true;
14098c2ecf20Sopenharmony_ci}
14108c2ecf20Sopenharmony_ci
14118c2ecf20Sopenharmony_cibool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
14128c2ecf20Sopenharmony_ci						  struct radeon_encoder_ext_tmds *tmds)
14138c2ecf20Sopenharmony_ci{
14148c2ecf20Sopenharmony_ci	struct drm_device *dev = encoder->base.dev;
14158c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
14168c2ecf20Sopenharmony_ci	uint16_t offset;
14178c2ecf20Sopenharmony_ci	uint8_t ver;
14188c2ecf20Sopenharmony_ci	enum radeon_combios_ddc gpio;
14198c2ecf20Sopenharmony_ci	struct radeon_i2c_bus_rec i2c_bus;
14208c2ecf20Sopenharmony_ci
14218c2ecf20Sopenharmony_ci	tmds->i2c_bus = NULL;
14228c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP) {
14238c2ecf20Sopenharmony_ci		i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
14248c2ecf20Sopenharmony_ci		tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
14258c2ecf20Sopenharmony_ci		tmds->dvo_chip = DVO_SIL164;
14268c2ecf20Sopenharmony_ci		tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
14278c2ecf20Sopenharmony_ci	} else {
14288c2ecf20Sopenharmony_ci		offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
14298c2ecf20Sopenharmony_ci		if (offset) {
14308c2ecf20Sopenharmony_ci			ver = RBIOS8(offset);
14318c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("External TMDS Table revision: %d\n", ver);
14328c2ecf20Sopenharmony_ci			tmds->slave_addr = RBIOS8(offset + 4 + 2);
14338c2ecf20Sopenharmony_ci			tmds->slave_addr >>= 1; /* 7 bit addressing */
14348c2ecf20Sopenharmony_ci			gpio = RBIOS8(offset + 4 + 3);
14358c2ecf20Sopenharmony_ci			if (gpio == DDC_LCD) {
14368c2ecf20Sopenharmony_ci				/* MM i2c */
14378c2ecf20Sopenharmony_ci				i2c_bus.valid = true;
14388c2ecf20Sopenharmony_ci				i2c_bus.hw_capable = true;
14398c2ecf20Sopenharmony_ci				i2c_bus.mm_i2c = true;
14408c2ecf20Sopenharmony_ci				i2c_bus.i2c_id = 0xa0;
14418c2ecf20Sopenharmony_ci			} else
14428c2ecf20Sopenharmony_ci				i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0);
14438c2ecf20Sopenharmony_ci			tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
14448c2ecf20Sopenharmony_ci		}
14458c2ecf20Sopenharmony_ci	}
14468c2ecf20Sopenharmony_ci
14478c2ecf20Sopenharmony_ci	if (!tmds->i2c_bus) {
14488c2ecf20Sopenharmony_ci		DRM_INFO("No valid Ext TMDS info found in BIOS\n");
14498c2ecf20Sopenharmony_ci		return false;
14508c2ecf20Sopenharmony_ci	}
14518c2ecf20Sopenharmony_ci
14528c2ecf20Sopenharmony_ci	return true;
14538c2ecf20Sopenharmony_ci}
14548c2ecf20Sopenharmony_ci
14558c2ecf20Sopenharmony_cibool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
14568c2ecf20Sopenharmony_ci{
14578c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
14588c2ecf20Sopenharmony_ci	struct radeon_i2c_bus_rec ddc_i2c;
14598c2ecf20Sopenharmony_ci	struct radeon_hpd hpd;
14608c2ecf20Sopenharmony_ci
14618c2ecf20Sopenharmony_ci	rdev->mode_info.connector_table = radeon_connector_table;
14628c2ecf20Sopenharmony_ci	if (rdev->mode_info.connector_table == CT_NONE) {
14638c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_PMAC
14648c2ecf20Sopenharmony_ci		if (of_machine_is_compatible("PowerBook3,3")) {
14658c2ecf20Sopenharmony_ci			/* powerbook with VGA */
14668c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_POWERBOOK_VGA;
14678c2ecf20Sopenharmony_ci		} else if (of_machine_is_compatible("PowerBook3,4") ||
14688c2ecf20Sopenharmony_ci			   of_machine_is_compatible("PowerBook3,5")) {
14698c2ecf20Sopenharmony_ci			/* powerbook with internal tmds */
14708c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_POWERBOOK_INTERNAL;
14718c2ecf20Sopenharmony_ci		} else if (of_machine_is_compatible("PowerBook5,1") ||
14728c2ecf20Sopenharmony_ci			   of_machine_is_compatible("PowerBook5,2") ||
14738c2ecf20Sopenharmony_ci			   of_machine_is_compatible("PowerBook5,3") ||
14748c2ecf20Sopenharmony_ci			   of_machine_is_compatible("PowerBook5,4") ||
14758c2ecf20Sopenharmony_ci			   of_machine_is_compatible("PowerBook5,5")) {
14768c2ecf20Sopenharmony_ci			/* powerbook with external single link tmds (sil164) */
14778c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
14788c2ecf20Sopenharmony_ci		} else if (of_machine_is_compatible("PowerBook5,6")) {
14798c2ecf20Sopenharmony_ci			/* powerbook with external dual or single link tmds */
14808c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
14818c2ecf20Sopenharmony_ci		} else if (of_machine_is_compatible("PowerBook5,7") ||
14828c2ecf20Sopenharmony_ci			   of_machine_is_compatible("PowerBook5,8") ||
14838c2ecf20Sopenharmony_ci			   of_machine_is_compatible("PowerBook5,9")) {
14848c2ecf20Sopenharmony_ci			/* PowerBook6,2 ? */
14858c2ecf20Sopenharmony_ci			/* powerbook with external dual link tmds (sil1178?) */
14868c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL;
14878c2ecf20Sopenharmony_ci		} else if (of_machine_is_compatible("PowerBook4,1") ||
14888c2ecf20Sopenharmony_ci			   of_machine_is_compatible("PowerBook4,2") ||
14898c2ecf20Sopenharmony_ci			   of_machine_is_compatible("PowerBook4,3") ||
14908c2ecf20Sopenharmony_ci			   of_machine_is_compatible("PowerBook6,3") ||
14918c2ecf20Sopenharmony_ci			   of_machine_is_compatible("PowerBook6,5") ||
14928c2ecf20Sopenharmony_ci			   of_machine_is_compatible("PowerBook6,7")) {
14938c2ecf20Sopenharmony_ci			/* ibook */
14948c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_IBOOK;
14958c2ecf20Sopenharmony_ci		} else if (of_machine_is_compatible("PowerMac3,5")) {
14968c2ecf20Sopenharmony_ci			/* PowerMac G4 Silver radeon 7500 */
14978c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_MAC_G4_SILVER;
14988c2ecf20Sopenharmony_ci		} else if (of_machine_is_compatible("PowerMac4,4")) {
14998c2ecf20Sopenharmony_ci			/* emac */
15008c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_EMAC;
15018c2ecf20Sopenharmony_ci		} else if (of_machine_is_compatible("PowerMac10,1")) {
15028c2ecf20Sopenharmony_ci			/* mini with internal tmds */
15038c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_MINI_INTERNAL;
15048c2ecf20Sopenharmony_ci		} else if (of_machine_is_compatible("PowerMac10,2")) {
15058c2ecf20Sopenharmony_ci			/* mini with external tmds */
15068c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_MINI_EXTERNAL;
15078c2ecf20Sopenharmony_ci		} else if (of_machine_is_compatible("PowerMac12,1")) {
15088c2ecf20Sopenharmony_ci			/* PowerMac8,1 ? */
15098c2ecf20Sopenharmony_ci			/* imac g5 isight */
15108c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT;
15118c2ecf20Sopenharmony_ci		} else if ((rdev->pdev->device == 0x4a48) &&
15128c2ecf20Sopenharmony_ci			   (rdev->pdev->subsystem_vendor == 0x1002) &&
15138c2ecf20Sopenharmony_ci			   (rdev->pdev->subsystem_device == 0x4a48)) {
15148c2ecf20Sopenharmony_ci			/* Mac X800 */
15158c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_MAC_X800;
15168c2ecf20Sopenharmony_ci		} else if ((of_machine_is_compatible("PowerMac7,2") ||
15178c2ecf20Sopenharmony_ci			    of_machine_is_compatible("PowerMac7,3")) &&
15188c2ecf20Sopenharmony_ci			   (rdev->pdev->device == 0x4150) &&
15198c2ecf20Sopenharmony_ci			   (rdev->pdev->subsystem_vendor == 0x1002) &&
15208c2ecf20Sopenharmony_ci			   (rdev->pdev->subsystem_device == 0x4150)) {
15218c2ecf20Sopenharmony_ci			/* Mac G5 tower 9600 */
15228c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_MAC_G5_9600;
15238c2ecf20Sopenharmony_ci		} else if ((rdev->pdev->device == 0x4c66) &&
15248c2ecf20Sopenharmony_ci			   (rdev->pdev->subsystem_vendor == 0x1002) &&
15258c2ecf20Sopenharmony_ci			   (rdev->pdev->subsystem_device == 0x4c66)) {
15268c2ecf20Sopenharmony_ci			/* SAM440ep RV250 embedded board */
15278c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_SAM440EP;
15288c2ecf20Sopenharmony_ci		} else
15298c2ecf20Sopenharmony_ci#endif /* CONFIG_PPC_PMAC */
15308c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC64
15318c2ecf20Sopenharmony_ci		if (ASIC_IS_RN50(rdev))
15328c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_RN50_POWER;
15338c2ecf20Sopenharmony_ci		else
15348c2ecf20Sopenharmony_ci#endif
15358c2ecf20Sopenharmony_ci			rdev->mode_info.connector_table = CT_GENERIC;
15368c2ecf20Sopenharmony_ci	}
15378c2ecf20Sopenharmony_ci
15388c2ecf20Sopenharmony_ci	switch (rdev->mode_info.connector_table) {
15398c2ecf20Sopenharmony_ci	case CT_GENERIC:
15408c2ecf20Sopenharmony_ci		DRM_INFO("Connector Table: %d (generic)\n",
15418c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
15428c2ecf20Sopenharmony_ci		/* these are the most common settings */
15438c2ecf20Sopenharmony_ci		if (rdev->flags & RADEON_SINGLE_CRTC) {
15448c2ecf20Sopenharmony_ci			/* VGA - primary dac */
15458c2ecf20Sopenharmony_ci			ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
15468c2ecf20Sopenharmony_ci			hpd.hpd = RADEON_HPD_NONE;
15478c2ecf20Sopenharmony_ci			radeon_add_legacy_encoder(dev,
15488c2ecf20Sopenharmony_ci						  radeon_get_encoder_enum(dev,
15498c2ecf20Sopenharmony_ci									ATOM_DEVICE_CRT1_SUPPORT,
15508c2ecf20Sopenharmony_ci									1),
15518c2ecf20Sopenharmony_ci						  ATOM_DEVICE_CRT1_SUPPORT);
15528c2ecf20Sopenharmony_ci			radeon_add_legacy_connector(dev, 0,
15538c2ecf20Sopenharmony_ci						    ATOM_DEVICE_CRT1_SUPPORT,
15548c2ecf20Sopenharmony_ci						    DRM_MODE_CONNECTOR_VGA,
15558c2ecf20Sopenharmony_ci						    &ddc_i2c,
15568c2ecf20Sopenharmony_ci						    CONNECTOR_OBJECT_ID_VGA,
15578c2ecf20Sopenharmony_ci						    &hpd);
15588c2ecf20Sopenharmony_ci		} else if (rdev->flags & RADEON_IS_MOBILITY) {
15598c2ecf20Sopenharmony_ci			/* LVDS */
15608c2ecf20Sopenharmony_ci			ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0);
15618c2ecf20Sopenharmony_ci			hpd.hpd = RADEON_HPD_NONE;
15628c2ecf20Sopenharmony_ci			radeon_add_legacy_encoder(dev,
15638c2ecf20Sopenharmony_ci						  radeon_get_encoder_enum(dev,
15648c2ecf20Sopenharmony_ci									ATOM_DEVICE_LCD1_SUPPORT,
15658c2ecf20Sopenharmony_ci									0),
15668c2ecf20Sopenharmony_ci						  ATOM_DEVICE_LCD1_SUPPORT);
15678c2ecf20Sopenharmony_ci			radeon_add_legacy_connector(dev, 0,
15688c2ecf20Sopenharmony_ci						    ATOM_DEVICE_LCD1_SUPPORT,
15698c2ecf20Sopenharmony_ci						    DRM_MODE_CONNECTOR_LVDS,
15708c2ecf20Sopenharmony_ci						    &ddc_i2c,
15718c2ecf20Sopenharmony_ci						    CONNECTOR_OBJECT_ID_LVDS,
15728c2ecf20Sopenharmony_ci						    &hpd);
15738c2ecf20Sopenharmony_ci
15748c2ecf20Sopenharmony_ci			/* VGA - primary dac */
15758c2ecf20Sopenharmony_ci			ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
15768c2ecf20Sopenharmony_ci			hpd.hpd = RADEON_HPD_NONE;
15778c2ecf20Sopenharmony_ci			radeon_add_legacy_encoder(dev,
15788c2ecf20Sopenharmony_ci						  radeon_get_encoder_enum(dev,
15798c2ecf20Sopenharmony_ci									ATOM_DEVICE_CRT1_SUPPORT,
15808c2ecf20Sopenharmony_ci									1),
15818c2ecf20Sopenharmony_ci						  ATOM_DEVICE_CRT1_SUPPORT);
15828c2ecf20Sopenharmony_ci			radeon_add_legacy_connector(dev, 1,
15838c2ecf20Sopenharmony_ci						    ATOM_DEVICE_CRT1_SUPPORT,
15848c2ecf20Sopenharmony_ci						    DRM_MODE_CONNECTOR_VGA,
15858c2ecf20Sopenharmony_ci						    &ddc_i2c,
15868c2ecf20Sopenharmony_ci						    CONNECTOR_OBJECT_ID_VGA,
15878c2ecf20Sopenharmony_ci						    &hpd);
15888c2ecf20Sopenharmony_ci		} else {
15898c2ecf20Sopenharmony_ci			/* DVI-I - tv dac, int tmds */
15908c2ecf20Sopenharmony_ci			ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
15918c2ecf20Sopenharmony_ci			hpd.hpd = RADEON_HPD_1;
15928c2ecf20Sopenharmony_ci			radeon_add_legacy_encoder(dev,
15938c2ecf20Sopenharmony_ci						  radeon_get_encoder_enum(dev,
15948c2ecf20Sopenharmony_ci									ATOM_DEVICE_DFP1_SUPPORT,
15958c2ecf20Sopenharmony_ci									0),
15968c2ecf20Sopenharmony_ci						  ATOM_DEVICE_DFP1_SUPPORT);
15978c2ecf20Sopenharmony_ci			radeon_add_legacy_encoder(dev,
15988c2ecf20Sopenharmony_ci						  radeon_get_encoder_enum(dev,
15998c2ecf20Sopenharmony_ci									ATOM_DEVICE_CRT2_SUPPORT,
16008c2ecf20Sopenharmony_ci									2),
16018c2ecf20Sopenharmony_ci						  ATOM_DEVICE_CRT2_SUPPORT);
16028c2ecf20Sopenharmony_ci			radeon_add_legacy_connector(dev, 0,
16038c2ecf20Sopenharmony_ci						    ATOM_DEVICE_DFP1_SUPPORT |
16048c2ecf20Sopenharmony_ci						    ATOM_DEVICE_CRT2_SUPPORT,
16058c2ecf20Sopenharmony_ci						    DRM_MODE_CONNECTOR_DVII,
16068c2ecf20Sopenharmony_ci						    &ddc_i2c,
16078c2ecf20Sopenharmony_ci						    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
16088c2ecf20Sopenharmony_ci						    &hpd);
16098c2ecf20Sopenharmony_ci
16108c2ecf20Sopenharmony_ci			/* VGA - primary dac */
16118c2ecf20Sopenharmony_ci			ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
16128c2ecf20Sopenharmony_ci			hpd.hpd = RADEON_HPD_NONE;
16138c2ecf20Sopenharmony_ci			radeon_add_legacy_encoder(dev,
16148c2ecf20Sopenharmony_ci						  radeon_get_encoder_enum(dev,
16158c2ecf20Sopenharmony_ci									ATOM_DEVICE_CRT1_SUPPORT,
16168c2ecf20Sopenharmony_ci									1),
16178c2ecf20Sopenharmony_ci						  ATOM_DEVICE_CRT1_SUPPORT);
16188c2ecf20Sopenharmony_ci			radeon_add_legacy_connector(dev, 1,
16198c2ecf20Sopenharmony_ci						    ATOM_DEVICE_CRT1_SUPPORT,
16208c2ecf20Sopenharmony_ci						    DRM_MODE_CONNECTOR_VGA,
16218c2ecf20Sopenharmony_ci						    &ddc_i2c,
16228c2ecf20Sopenharmony_ci						    CONNECTOR_OBJECT_ID_VGA,
16238c2ecf20Sopenharmony_ci						    &hpd);
16248c2ecf20Sopenharmony_ci		}
16258c2ecf20Sopenharmony_ci
16268c2ecf20Sopenharmony_ci		if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) {
16278c2ecf20Sopenharmony_ci			/* TV - tv dac */
16288c2ecf20Sopenharmony_ci			ddc_i2c.valid = false;
16298c2ecf20Sopenharmony_ci			hpd.hpd = RADEON_HPD_NONE;
16308c2ecf20Sopenharmony_ci			radeon_add_legacy_encoder(dev,
16318c2ecf20Sopenharmony_ci						  radeon_get_encoder_enum(dev,
16328c2ecf20Sopenharmony_ci									ATOM_DEVICE_TV1_SUPPORT,
16338c2ecf20Sopenharmony_ci									2),
16348c2ecf20Sopenharmony_ci						  ATOM_DEVICE_TV1_SUPPORT);
16358c2ecf20Sopenharmony_ci			radeon_add_legacy_connector(dev, 2,
16368c2ecf20Sopenharmony_ci						    ATOM_DEVICE_TV1_SUPPORT,
16378c2ecf20Sopenharmony_ci						    DRM_MODE_CONNECTOR_SVIDEO,
16388c2ecf20Sopenharmony_ci						    &ddc_i2c,
16398c2ecf20Sopenharmony_ci						    CONNECTOR_OBJECT_ID_SVIDEO,
16408c2ecf20Sopenharmony_ci						    &hpd);
16418c2ecf20Sopenharmony_ci		}
16428c2ecf20Sopenharmony_ci		break;
16438c2ecf20Sopenharmony_ci	case CT_IBOOK:
16448c2ecf20Sopenharmony_ci		DRM_INFO("Connector Table: %d (ibook)\n",
16458c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
16468c2ecf20Sopenharmony_ci		/* LVDS */
16478c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
16488c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
16498c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
16508c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
16518c2ecf20Sopenharmony_ci								ATOM_DEVICE_LCD1_SUPPORT,
16528c2ecf20Sopenharmony_ci								0),
16538c2ecf20Sopenharmony_ci					  ATOM_DEVICE_LCD1_SUPPORT);
16548c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
16558c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
16568c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_LVDS,
16578c2ecf20Sopenharmony_ci					    &hpd);
16588c2ecf20Sopenharmony_ci		/* VGA - TV DAC */
16598c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
16608c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
16618c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
16628c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
16638c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
16648c2ecf20Sopenharmony_ci								2),
16658c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
16668c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
16678c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
16688c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
16698c2ecf20Sopenharmony_ci					    &hpd);
16708c2ecf20Sopenharmony_ci		/* TV - TV DAC */
16718c2ecf20Sopenharmony_ci		ddc_i2c.valid = false;
16728c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
16738c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
16748c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
16758c2ecf20Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
16768c2ecf20Sopenharmony_ci								2),
16778c2ecf20Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
16788c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
16798c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
16808c2ecf20Sopenharmony_ci					    &ddc_i2c,
16818c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
16828c2ecf20Sopenharmony_ci					    &hpd);
16838c2ecf20Sopenharmony_ci		break;
16848c2ecf20Sopenharmony_ci	case CT_POWERBOOK_EXTERNAL:
16858c2ecf20Sopenharmony_ci		DRM_INFO("Connector Table: %d (powerbook external tmds)\n",
16868c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
16878c2ecf20Sopenharmony_ci		/* LVDS */
16888c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
16898c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
16908c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
16918c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
16928c2ecf20Sopenharmony_ci								ATOM_DEVICE_LCD1_SUPPORT,
16938c2ecf20Sopenharmony_ci								0),
16948c2ecf20Sopenharmony_ci					  ATOM_DEVICE_LCD1_SUPPORT);
16958c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
16968c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
16978c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_LVDS,
16988c2ecf20Sopenharmony_ci					    &hpd);
16998c2ecf20Sopenharmony_ci		/* DVI-I - primary dac, ext tmds */
17008c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
17018c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_2; /* ??? */
17028c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
17038c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
17048c2ecf20Sopenharmony_ci								ATOM_DEVICE_DFP2_SUPPORT,
17058c2ecf20Sopenharmony_ci								0),
17068c2ecf20Sopenharmony_ci					  ATOM_DEVICE_DFP2_SUPPORT);
17078c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
17088c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
17098c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT1_SUPPORT,
17108c2ecf20Sopenharmony_ci								1),
17118c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
17128c2ecf20Sopenharmony_ci		/* XXX some are SL */
17138c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 1,
17148c2ecf20Sopenharmony_ci					    ATOM_DEVICE_DFP2_SUPPORT |
17158c2ecf20Sopenharmony_ci					    ATOM_DEVICE_CRT1_SUPPORT,
17168c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
17178c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
17188c2ecf20Sopenharmony_ci					    &hpd);
17198c2ecf20Sopenharmony_ci		/* TV - TV DAC */
17208c2ecf20Sopenharmony_ci		ddc_i2c.valid = false;
17218c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
17228c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
17238c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
17248c2ecf20Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
17258c2ecf20Sopenharmony_ci								2),
17268c2ecf20Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
17278c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
17288c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
17298c2ecf20Sopenharmony_ci					    &ddc_i2c,
17308c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
17318c2ecf20Sopenharmony_ci					    &hpd);
17328c2ecf20Sopenharmony_ci		break;
17338c2ecf20Sopenharmony_ci	case CT_POWERBOOK_INTERNAL:
17348c2ecf20Sopenharmony_ci		DRM_INFO("Connector Table: %d (powerbook internal tmds)\n",
17358c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
17368c2ecf20Sopenharmony_ci		/* LVDS */
17378c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
17388c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
17398c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
17408c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
17418c2ecf20Sopenharmony_ci								ATOM_DEVICE_LCD1_SUPPORT,
17428c2ecf20Sopenharmony_ci								0),
17438c2ecf20Sopenharmony_ci					  ATOM_DEVICE_LCD1_SUPPORT);
17448c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
17458c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
17468c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_LVDS,
17478c2ecf20Sopenharmony_ci					    &hpd);
17488c2ecf20Sopenharmony_ci		/* DVI-I - primary dac, int tmds */
17498c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
17508c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_1; /* ??? */
17518c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
17528c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
17538c2ecf20Sopenharmony_ci								ATOM_DEVICE_DFP1_SUPPORT,
17548c2ecf20Sopenharmony_ci								0),
17558c2ecf20Sopenharmony_ci					  ATOM_DEVICE_DFP1_SUPPORT);
17568c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
17578c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
17588c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT1_SUPPORT,
17598c2ecf20Sopenharmony_ci								1),
17608c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
17618c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 1,
17628c2ecf20Sopenharmony_ci					    ATOM_DEVICE_DFP1_SUPPORT |
17638c2ecf20Sopenharmony_ci					    ATOM_DEVICE_CRT1_SUPPORT,
17648c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
17658c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
17668c2ecf20Sopenharmony_ci					    &hpd);
17678c2ecf20Sopenharmony_ci		/* TV - TV DAC */
17688c2ecf20Sopenharmony_ci		ddc_i2c.valid = false;
17698c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
17708c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
17718c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
17728c2ecf20Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
17738c2ecf20Sopenharmony_ci								2),
17748c2ecf20Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
17758c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
17768c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
17778c2ecf20Sopenharmony_ci					    &ddc_i2c,
17788c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
17798c2ecf20Sopenharmony_ci					    &hpd);
17808c2ecf20Sopenharmony_ci		break;
17818c2ecf20Sopenharmony_ci	case CT_POWERBOOK_VGA:
17828c2ecf20Sopenharmony_ci		DRM_INFO("Connector Table: %d (powerbook vga)\n",
17838c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
17848c2ecf20Sopenharmony_ci		/* LVDS */
17858c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
17868c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
17878c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
17888c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
17898c2ecf20Sopenharmony_ci								ATOM_DEVICE_LCD1_SUPPORT,
17908c2ecf20Sopenharmony_ci								0),
17918c2ecf20Sopenharmony_ci					  ATOM_DEVICE_LCD1_SUPPORT);
17928c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
17938c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
17948c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_LVDS,
17958c2ecf20Sopenharmony_ci					    &hpd);
17968c2ecf20Sopenharmony_ci		/* VGA - primary dac */
17978c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
17988c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
17998c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
18008c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
18018c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT1_SUPPORT,
18028c2ecf20Sopenharmony_ci								1),
18038c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
18048c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
18058c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
18068c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
18078c2ecf20Sopenharmony_ci					    &hpd);
18088c2ecf20Sopenharmony_ci		/* TV - TV DAC */
18098c2ecf20Sopenharmony_ci		ddc_i2c.valid = false;
18108c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
18118c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
18128c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
18138c2ecf20Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
18148c2ecf20Sopenharmony_ci								2),
18158c2ecf20Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
18168c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
18178c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
18188c2ecf20Sopenharmony_ci					    &ddc_i2c,
18198c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
18208c2ecf20Sopenharmony_ci					    &hpd);
18218c2ecf20Sopenharmony_ci		break;
18228c2ecf20Sopenharmony_ci	case CT_MINI_EXTERNAL:
18238c2ecf20Sopenharmony_ci		DRM_INFO("Connector Table: %d (mini external tmds)\n",
18248c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
18258c2ecf20Sopenharmony_ci		/* DVI-I - tv dac, ext tmds */
18268c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
18278c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_2; /* ??? */
18288c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
18298c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
18308c2ecf20Sopenharmony_ci								ATOM_DEVICE_DFP2_SUPPORT,
18318c2ecf20Sopenharmony_ci								0),
18328c2ecf20Sopenharmony_ci					  ATOM_DEVICE_DFP2_SUPPORT);
18338c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
18348c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
18358c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
18368c2ecf20Sopenharmony_ci								2),
18378c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
18388c2ecf20Sopenharmony_ci		/* XXX are any DL? */
18398c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 0,
18408c2ecf20Sopenharmony_ci					    ATOM_DEVICE_DFP2_SUPPORT |
18418c2ecf20Sopenharmony_ci					    ATOM_DEVICE_CRT2_SUPPORT,
18428c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
18438c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
18448c2ecf20Sopenharmony_ci					    &hpd);
18458c2ecf20Sopenharmony_ci		/* TV - TV DAC */
18468c2ecf20Sopenharmony_ci		ddc_i2c.valid = false;
18478c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
18488c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
18498c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
18508c2ecf20Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
18518c2ecf20Sopenharmony_ci								2),
18528c2ecf20Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
18538c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
18548c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
18558c2ecf20Sopenharmony_ci					    &ddc_i2c,
18568c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
18578c2ecf20Sopenharmony_ci					    &hpd);
18588c2ecf20Sopenharmony_ci		break;
18598c2ecf20Sopenharmony_ci	case CT_MINI_INTERNAL:
18608c2ecf20Sopenharmony_ci		DRM_INFO("Connector Table: %d (mini internal tmds)\n",
18618c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
18628c2ecf20Sopenharmony_ci		/* DVI-I - tv dac, int tmds */
18638c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
18648c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_1; /* ??? */
18658c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
18668c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
18678c2ecf20Sopenharmony_ci								ATOM_DEVICE_DFP1_SUPPORT,
18688c2ecf20Sopenharmony_ci								0),
18698c2ecf20Sopenharmony_ci					  ATOM_DEVICE_DFP1_SUPPORT);
18708c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
18718c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
18728c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
18738c2ecf20Sopenharmony_ci								2),
18748c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
18758c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 0,
18768c2ecf20Sopenharmony_ci					    ATOM_DEVICE_DFP1_SUPPORT |
18778c2ecf20Sopenharmony_ci					    ATOM_DEVICE_CRT2_SUPPORT,
18788c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
18798c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
18808c2ecf20Sopenharmony_ci					    &hpd);
18818c2ecf20Sopenharmony_ci		/* TV - TV DAC */
18828c2ecf20Sopenharmony_ci		ddc_i2c.valid = false;
18838c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
18848c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
18858c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
18868c2ecf20Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
18878c2ecf20Sopenharmony_ci								2),
18888c2ecf20Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
18898c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT,
18908c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
18918c2ecf20Sopenharmony_ci					    &ddc_i2c,
18928c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
18938c2ecf20Sopenharmony_ci					    &hpd);
18948c2ecf20Sopenharmony_ci		break;
18958c2ecf20Sopenharmony_ci	case CT_IMAC_G5_ISIGHT:
18968c2ecf20Sopenharmony_ci		DRM_INFO("Connector Table: %d (imac g5 isight)\n",
18978c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
18988c2ecf20Sopenharmony_ci		/* DVI-D - int tmds */
18998c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
19008c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_1; /* ??? */
19018c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
19028c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
19038c2ecf20Sopenharmony_ci								ATOM_DEVICE_DFP1_SUPPORT,
19048c2ecf20Sopenharmony_ci								0),
19058c2ecf20Sopenharmony_ci					  ATOM_DEVICE_DFP1_SUPPORT);
19068c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT,
19078c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVID, &ddc_i2c,
19088c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
19098c2ecf20Sopenharmony_ci					    &hpd);
19108c2ecf20Sopenharmony_ci		/* VGA - tv dac */
19118c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
19128c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
19138c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
19148c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
19158c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
19168c2ecf20Sopenharmony_ci								2),
19178c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
19188c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
19198c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
19208c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
19218c2ecf20Sopenharmony_ci					    &hpd);
19228c2ecf20Sopenharmony_ci		/* TV - TV DAC */
19238c2ecf20Sopenharmony_ci		ddc_i2c.valid = false;
19248c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
19258c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
19268c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
19278c2ecf20Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
19288c2ecf20Sopenharmony_ci								2),
19298c2ecf20Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
19308c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
19318c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
19328c2ecf20Sopenharmony_ci					    &ddc_i2c,
19338c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
19348c2ecf20Sopenharmony_ci					    &hpd);
19358c2ecf20Sopenharmony_ci		break;
19368c2ecf20Sopenharmony_ci	case CT_EMAC:
19378c2ecf20Sopenharmony_ci		DRM_INFO("Connector Table: %d (emac)\n",
19388c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
19398c2ecf20Sopenharmony_ci		/* VGA - primary dac */
19408c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
19418c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
19428c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
19438c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
19448c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT1_SUPPORT,
19458c2ecf20Sopenharmony_ci								1),
19468c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
19478c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT,
19488c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
19498c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
19508c2ecf20Sopenharmony_ci					    &hpd);
19518c2ecf20Sopenharmony_ci		/* VGA - tv dac */
19528c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
19538c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
19548c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
19558c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
19568c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
19578c2ecf20Sopenharmony_ci								2),
19588c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
19598c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
19608c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
19618c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
19628c2ecf20Sopenharmony_ci					    &hpd);
19638c2ecf20Sopenharmony_ci		/* TV - TV DAC */
19648c2ecf20Sopenharmony_ci		ddc_i2c.valid = false;
19658c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
19668c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
19678c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
19688c2ecf20Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
19698c2ecf20Sopenharmony_ci								2),
19708c2ecf20Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
19718c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
19728c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
19738c2ecf20Sopenharmony_ci					    &ddc_i2c,
19748c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
19758c2ecf20Sopenharmony_ci					    &hpd);
19768c2ecf20Sopenharmony_ci		break;
19778c2ecf20Sopenharmony_ci	case CT_RN50_POWER:
19788c2ecf20Sopenharmony_ci		DRM_INFO("Connector Table: %d (rn50-power)\n",
19798c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
19808c2ecf20Sopenharmony_ci		/* VGA - primary dac */
19818c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
19828c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
19838c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
19848c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
19858c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT1_SUPPORT,
19868c2ecf20Sopenharmony_ci								1),
19878c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
19888c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT,
19898c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
19908c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
19918c2ecf20Sopenharmony_ci					    &hpd);
19928c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
19938c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
19948c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
19958c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
19968c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
19978c2ecf20Sopenharmony_ci								2),
19988c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
19998c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT,
20008c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
20018c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
20028c2ecf20Sopenharmony_ci					    &hpd);
20038c2ecf20Sopenharmony_ci		break;
20048c2ecf20Sopenharmony_ci	case CT_MAC_X800:
20058c2ecf20Sopenharmony_ci		DRM_INFO("Connector Table: %d (mac x800)\n",
20068c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
20078c2ecf20Sopenharmony_ci		/* DVI - primary dac, internal tmds */
20088c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
20098c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_1; /* ??? */
20108c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
20118c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
20128c2ecf20Sopenharmony_ci								  ATOM_DEVICE_DFP1_SUPPORT,
20138c2ecf20Sopenharmony_ci								  0),
20148c2ecf20Sopenharmony_ci					  ATOM_DEVICE_DFP1_SUPPORT);
20158c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
20168c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
20178c2ecf20Sopenharmony_ci								  ATOM_DEVICE_CRT1_SUPPORT,
20188c2ecf20Sopenharmony_ci								  1),
20198c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
20208c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 0,
20218c2ecf20Sopenharmony_ci					    ATOM_DEVICE_DFP1_SUPPORT |
20228c2ecf20Sopenharmony_ci					    ATOM_DEVICE_CRT1_SUPPORT,
20238c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
20248c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
20258c2ecf20Sopenharmony_ci					    &hpd);
20268c2ecf20Sopenharmony_ci		/* DVI - tv dac, dvo */
20278c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
20288c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_2; /* ??? */
20298c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
20308c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
20318c2ecf20Sopenharmony_ci								  ATOM_DEVICE_DFP2_SUPPORT,
20328c2ecf20Sopenharmony_ci								  0),
20338c2ecf20Sopenharmony_ci					  ATOM_DEVICE_DFP2_SUPPORT);
20348c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
20358c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
20368c2ecf20Sopenharmony_ci								  ATOM_DEVICE_CRT2_SUPPORT,
20378c2ecf20Sopenharmony_ci								  2),
20388c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
20398c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 1,
20408c2ecf20Sopenharmony_ci					    ATOM_DEVICE_DFP2_SUPPORT |
20418c2ecf20Sopenharmony_ci					    ATOM_DEVICE_CRT2_SUPPORT,
20428c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
20438c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
20448c2ecf20Sopenharmony_ci					    &hpd);
20458c2ecf20Sopenharmony_ci		break;
20468c2ecf20Sopenharmony_ci	case CT_MAC_G5_9600:
20478c2ecf20Sopenharmony_ci		DRM_INFO("Connector Table: %d (mac g5 9600)\n",
20488c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
20498c2ecf20Sopenharmony_ci		/* DVI - tv dac, dvo */
20508c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
20518c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_1; /* ??? */
20528c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
20538c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
20548c2ecf20Sopenharmony_ci								  ATOM_DEVICE_DFP2_SUPPORT,
20558c2ecf20Sopenharmony_ci								  0),
20568c2ecf20Sopenharmony_ci					  ATOM_DEVICE_DFP2_SUPPORT);
20578c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
20588c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
20598c2ecf20Sopenharmony_ci								  ATOM_DEVICE_CRT2_SUPPORT,
20608c2ecf20Sopenharmony_ci								  2),
20618c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
20628c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 0,
20638c2ecf20Sopenharmony_ci					    ATOM_DEVICE_DFP2_SUPPORT |
20648c2ecf20Sopenharmony_ci					    ATOM_DEVICE_CRT2_SUPPORT,
20658c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
20668c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
20678c2ecf20Sopenharmony_ci					    &hpd);
20688c2ecf20Sopenharmony_ci		/* ADC - primary dac, internal tmds */
20698c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
20708c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_2; /* ??? */
20718c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
20728c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
20738c2ecf20Sopenharmony_ci								  ATOM_DEVICE_DFP1_SUPPORT,
20748c2ecf20Sopenharmony_ci								  0),
20758c2ecf20Sopenharmony_ci					  ATOM_DEVICE_DFP1_SUPPORT);
20768c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
20778c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
20788c2ecf20Sopenharmony_ci								  ATOM_DEVICE_CRT1_SUPPORT,
20798c2ecf20Sopenharmony_ci								  1),
20808c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
20818c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 1,
20828c2ecf20Sopenharmony_ci					    ATOM_DEVICE_DFP1_SUPPORT |
20838c2ecf20Sopenharmony_ci					    ATOM_DEVICE_CRT1_SUPPORT,
20848c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
20858c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
20868c2ecf20Sopenharmony_ci					    &hpd);
20878c2ecf20Sopenharmony_ci		/* TV - TV DAC */
20888c2ecf20Sopenharmony_ci		ddc_i2c.valid = false;
20898c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
20908c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
20918c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
20928c2ecf20Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
20938c2ecf20Sopenharmony_ci								2),
20948c2ecf20Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
20958c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
20968c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
20978c2ecf20Sopenharmony_ci					    &ddc_i2c,
20988c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
20998c2ecf20Sopenharmony_ci					    &hpd);
21008c2ecf20Sopenharmony_ci		break;
21018c2ecf20Sopenharmony_ci	case CT_SAM440EP:
21028c2ecf20Sopenharmony_ci		DRM_INFO("Connector Table: %d (SAM440ep embedded board)\n",
21038c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
21048c2ecf20Sopenharmony_ci		/* LVDS */
21058c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0);
21068c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
21078c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
21088c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
21098c2ecf20Sopenharmony_ci								ATOM_DEVICE_LCD1_SUPPORT,
21108c2ecf20Sopenharmony_ci								0),
21118c2ecf20Sopenharmony_ci					  ATOM_DEVICE_LCD1_SUPPORT);
21128c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT,
21138c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_LVDS, &ddc_i2c,
21148c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_LVDS,
21158c2ecf20Sopenharmony_ci					    &hpd);
21168c2ecf20Sopenharmony_ci		/* DVI-I - secondary dac, int tmds */
21178c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
21188c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_1; /* ??? */
21198c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
21208c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
21218c2ecf20Sopenharmony_ci								ATOM_DEVICE_DFP1_SUPPORT,
21228c2ecf20Sopenharmony_ci								0),
21238c2ecf20Sopenharmony_ci					  ATOM_DEVICE_DFP1_SUPPORT);
21248c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
21258c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
21268c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
21278c2ecf20Sopenharmony_ci								2),
21288c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
21298c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 1,
21308c2ecf20Sopenharmony_ci					    ATOM_DEVICE_DFP1_SUPPORT |
21318c2ecf20Sopenharmony_ci					    ATOM_DEVICE_CRT2_SUPPORT,
21328c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
21338c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
21348c2ecf20Sopenharmony_ci					    &hpd);
21358c2ecf20Sopenharmony_ci		/* VGA - primary dac */
21368c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
21378c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
21388c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
21398c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
21408c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT1_SUPPORT,
21418c2ecf20Sopenharmony_ci								1),
21428c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
21438c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 2,
21448c2ecf20Sopenharmony_ci					    ATOM_DEVICE_CRT1_SUPPORT,
21458c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
21468c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
21478c2ecf20Sopenharmony_ci					    &hpd);
21488c2ecf20Sopenharmony_ci		/* TV - TV DAC */
21498c2ecf20Sopenharmony_ci		ddc_i2c.valid = false;
21508c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
21518c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
21528c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
21538c2ecf20Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
21548c2ecf20Sopenharmony_ci								2),
21558c2ecf20Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
21568c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 3, ATOM_DEVICE_TV1_SUPPORT,
21578c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
21588c2ecf20Sopenharmony_ci					    &ddc_i2c,
21598c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
21608c2ecf20Sopenharmony_ci					    &hpd);
21618c2ecf20Sopenharmony_ci		break;
21628c2ecf20Sopenharmony_ci	case CT_MAC_G4_SILVER:
21638c2ecf20Sopenharmony_ci		DRM_INFO("Connector Table: %d (mac g4 silver)\n",
21648c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
21658c2ecf20Sopenharmony_ci		/* DVI-I - tv dac, int tmds */
21668c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
21678c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_1; /* ??? */
21688c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
21698c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
21708c2ecf20Sopenharmony_ci								ATOM_DEVICE_DFP1_SUPPORT,
21718c2ecf20Sopenharmony_ci								0),
21728c2ecf20Sopenharmony_ci					  ATOM_DEVICE_DFP1_SUPPORT);
21738c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
21748c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
21758c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT2_SUPPORT,
21768c2ecf20Sopenharmony_ci								2),
21778c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT2_SUPPORT);
21788c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 0,
21798c2ecf20Sopenharmony_ci					    ATOM_DEVICE_DFP1_SUPPORT |
21808c2ecf20Sopenharmony_ci					    ATOM_DEVICE_CRT2_SUPPORT,
21818c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
21828c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
21838c2ecf20Sopenharmony_ci					    &hpd);
21848c2ecf20Sopenharmony_ci		/* VGA - primary dac */
21858c2ecf20Sopenharmony_ci		ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
21868c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
21878c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
21888c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
21898c2ecf20Sopenharmony_ci								ATOM_DEVICE_CRT1_SUPPORT,
21908c2ecf20Sopenharmony_ci								1),
21918c2ecf20Sopenharmony_ci					  ATOM_DEVICE_CRT1_SUPPORT);
21928c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
21938c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
21948c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_VGA,
21958c2ecf20Sopenharmony_ci					    &hpd);
21968c2ecf20Sopenharmony_ci		/* TV - TV DAC */
21978c2ecf20Sopenharmony_ci		ddc_i2c.valid = false;
21988c2ecf20Sopenharmony_ci		hpd.hpd = RADEON_HPD_NONE;
21998c2ecf20Sopenharmony_ci		radeon_add_legacy_encoder(dev,
22008c2ecf20Sopenharmony_ci					  radeon_get_encoder_enum(dev,
22018c2ecf20Sopenharmony_ci								ATOM_DEVICE_TV1_SUPPORT,
22028c2ecf20Sopenharmony_ci								2),
22038c2ecf20Sopenharmony_ci					  ATOM_DEVICE_TV1_SUPPORT);
22048c2ecf20Sopenharmony_ci		radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
22058c2ecf20Sopenharmony_ci					    DRM_MODE_CONNECTOR_SVIDEO,
22068c2ecf20Sopenharmony_ci					    &ddc_i2c,
22078c2ecf20Sopenharmony_ci					    CONNECTOR_OBJECT_ID_SVIDEO,
22088c2ecf20Sopenharmony_ci					    &hpd);
22098c2ecf20Sopenharmony_ci		break;
22108c2ecf20Sopenharmony_ci	default:
22118c2ecf20Sopenharmony_ci		DRM_INFO("Connector table: %d (invalid)\n",
22128c2ecf20Sopenharmony_ci			 rdev->mode_info.connector_table);
22138c2ecf20Sopenharmony_ci		return false;
22148c2ecf20Sopenharmony_ci	}
22158c2ecf20Sopenharmony_ci
22168c2ecf20Sopenharmony_ci	radeon_link_encoder_connector(dev);
22178c2ecf20Sopenharmony_ci
22188c2ecf20Sopenharmony_ci	return true;
22198c2ecf20Sopenharmony_ci}
22208c2ecf20Sopenharmony_ci
22218c2ecf20Sopenharmony_cistatic bool radeon_apply_legacy_quirks(struct drm_device *dev,
22228c2ecf20Sopenharmony_ci				       int bios_index,
22238c2ecf20Sopenharmony_ci				       enum radeon_combios_connector
22248c2ecf20Sopenharmony_ci				       *legacy_connector,
22258c2ecf20Sopenharmony_ci				       struct radeon_i2c_bus_rec *ddc_i2c,
22268c2ecf20Sopenharmony_ci				       struct radeon_hpd *hpd)
22278c2ecf20Sopenharmony_ci{
22288c2ecf20Sopenharmony_ci
22298c2ecf20Sopenharmony_ci	/* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
22308c2ecf20Sopenharmony_ci	   one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */
22318c2ecf20Sopenharmony_ci	if (dev->pdev->device == 0x515e &&
22328c2ecf20Sopenharmony_ci	    dev->pdev->subsystem_vendor == 0x1014) {
22338c2ecf20Sopenharmony_ci		if (*legacy_connector == CONNECTOR_CRT_LEGACY &&
22348c2ecf20Sopenharmony_ci		    ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
22358c2ecf20Sopenharmony_ci			return false;
22368c2ecf20Sopenharmony_ci	}
22378c2ecf20Sopenharmony_ci
22388c2ecf20Sopenharmony_ci	/* X300 card with extra non-existent DVI port */
22398c2ecf20Sopenharmony_ci	if (dev->pdev->device == 0x5B60 &&
22408c2ecf20Sopenharmony_ci	    dev->pdev->subsystem_vendor == 0x17af &&
22418c2ecf20Sopenharmony_ci	    dev->pdev->subsystem_device == 0x201e && bios_index == 2) {
22428c2ecf20Sopenharmony_ci		if (*legacy_connector == CONNECTOR_DVI_I_LEGACY)
22438c2ecf20Sopenharmony_ci			return false;
22448c2ecf20Sopenharmony_ci	}
22458c2ecf20Sopenharmony_ci
22468c2ecf20Sopenharmony_ci	return true;
22478c2ecf20Sopenharmony_ci}
22488c2ecf20Sopenharmony_ci
22498c2ecf20Sopenharmony_cistatic bool radeon_apply_legacy_tv_quirks(struct drm_device *dev)
22508c2ecf20Sopenharmony_ci{
22518c2ecf20Sopenharmony_ci	/* Acer 5102 has non-existent TV port */
22528c2ecf20Sopenharmony_ci	if (dev->pdev->device == 0x5975 &&
22538c2ecf20Sopenharmony_ci	    dev->pdev->subsystem_vendor == 0x1025 &&
22548c2ecf20Sopenharmony_ci	    dev->pdev->subsystem_device == 0x009f)
22558c2ecf20Sopenharmony_ci		return false;
22568c2ecf20Sopenharmony_ci
22578c2ecf20Sopenharmony_ci	/* HP dc5750 has non-existent TV port */
22588c2ecf20Sopenharmony_ci	if (dev->pdev->device == 0x5974 &&
22598c2ecf20Sopenharmony_ci	    dev->pdev->subsystem_vendor == 0x103c &&
22608c2ecf20Sopenharmony_ci	    dev->pdev->subsystem_device == 0x280a)
22618c2ecf20Sopenharmony_ci		return false;
22628c2ecf20Sopenharmony_ci
22638c2ecf20Sopenharmony_ci	/* MSI S270 has non-existent TV port */
22648c2ecf20Sopenharmony_ci	if (dev->pdev->device == 0x5955 &&
22658c2ecf20Sopenharmony_ci	    dev->pdev->subsystem_vendor == 0x1462 &&
22668c2ecf20Sopenharmony_ci	    dev->pdev->subsystem_device == 0x0131)
22678c2ecf20Sopenharmony_ci		return false;
22688c2ecf20Sopenharmony_ci
22698c2ecf20Sopenharmony_ci	return true;
22708c2ecf20Sopenharmony_ci}
22718c2ecf20Sopenharmony_ci
22728c2ecf20Sopenharmony_cistatic uint16_t combios_check_dl_dvi(struct drm_device *dev, int is_dvi_d)
22738c2ecf20Sopenharmony_ci{
22748c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
22758c2ecf20Sopenharmony_ci	uint32_t ext_tmds_info;
22768c2ecf20Sopenharmony_ci
22778c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP) {
22788c2ecf20Sopenharmony_ci		if (is_dvi_d)
22798c2ecf20Sopenharmony_ci			return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
22808c2ecf20Sopenharmony_ci		else
22818c2ecf20Sopenharmony_ci			return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
22828c2ecf20Sopenharmony_ci	}
22838c2ecf20Sopenharmony_ci	ext_tmds_info = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
22848c2ecf20Sopenharmony_ci	if (ext_tmds_info) {
22858c2ecf20Sopenharmony_ci		uint8_t rev = RBIOS8(ext_tmds_info);
22868c2ecf20Sopenharmony_ci		uint8_t flags = RBIOS8(ext_tmds_info + 4 + 5);
22878c2ecf20Sopenharmony_ci		if (rev >= 3) {
22888c2ecf20Sopenharmony_ci			if (is_dvi_d)
22898c2ecf20Sopenharmony_ci				return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
22908c2ecf20Sopenharmony_ci			else
22918c2ecf20Sopenharmony_ci				return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
22928c2ecf20Sopenharmony_ci		} else {
22938c2ecf20Sopenharmony_ci			if (flags & 1) {
22948c2ecf20Sopenharmony_ci				if (is_dvi_d)
22958c2ecf20Sopenharmony_ci					return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D;
22968c2ecf20Sopenharmony_ci				else
22978c2ecf20Sopenharmony_ci					return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I;
22988c2ecf20Sopenharmony_ci			}
22998c2ecf20Sopenharmony_ci		}
23008c2ecf20Sopenharmony_ci	}
23018c2ecf20Sopenharmony_ci	if (is_dvi_d)
23028c2ecf20Sopenharmony_ci		return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D;
23038c2ecf20Sopenharmony_ci	else
23048c2ecf20Sopenharmony_ci		return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
23058c2ecf20Sopenharmony_ci}
23068c2ecf20Sopenharmony_ci
23078c2ecf20Sopenharmony_cibool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
23088c2ecf20Sopenharmony_ci{
23098c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
23108c2ecf20Sopenharmony_ci	uint32_t conn_info, entry, devices;
23118c2ecf20Sopenharmony_ci	uint16_t tmp, connector_object_id;
23128c2ecf20Sopenharmony_ci	enum radeon_combios_ddc ddc_type;
23138c2ecf20Sopenharmony_ci	enum radeon_combios_connector connector;
23148c2ecf20Sopenharmony_ci	int i = 0;
23158c2ecf20Sopenharmony_ci	struct radeon_i2c_bus_rec ddc_i2c;
23168c2ecf20Sopenharmony_ci	struct radeon_hpd hpd;
23178c2ecf20Sopenharmony_ci
23188c2ecf20Sopenharmony_ci	conn_info = combios_get_table_offset(dev, COMBIOS_CONNECTOR_INFO_TABLE);
23198c2ecf20Sopenharmony_ci	if (conn_info) {
23208c2ecf20Sopenharmony_ci		for (i = 0; i < 4; i++) {
23218c2ecf20Sopenharmony_ci			entry = conn_info + 2 + i * 2;
23228c2ecf20Sopenharmony_ci
23238c2ecf20Sopenharmony_ci			if (!RBIOS16(entry))
23248c2ecf20Sopenharmony_ci				break;
23258c2ecf20Sopenharmony_ci
23268c2ecf20Sopenharmony_ci			tmp = RBIOS16(entry);
23278c2ecf20Sopenharmony_ci
23288c2ecf20Sopenharmony_ci			connector = (tmp >> 12) & 0xf;
23298c2ecf20Sopenharmony_ci
23308c2ecf20Sopenharmony_ci			ddc_type = (tmp >> 8) & 0xf;
23318c2ecf20Sopenharmony_ci			if (ddc_type == 5)
23328c2ecf20Sopenharmony_ci				ddc_i2c = radeon_combios_get_i2c_info_from_table(rdev);
23338c2ecf20Sopenharmony_ci			else
23348c2ecf20Sopenharmony_ci				ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0);
23358c2ecf20Sopenharmony_ci
23368c2ecf20Sopenharmony_ci			switch (connector) {
23378c2ecf20Sopenharmony_ci			case CONNECTOR_PROPRIETARY_LEGACY:
23388c2ecf20Sopenharmony_ci			case CONNECTOR_DVI_I_LEGACY:
23398c2ecf20Sopenharmony_ci			case CONNECTOR_DVI_D_LEGACY:
23408c2ecf20Sopenharmony_ci				if ((tmp >> 4) & 0x1)
23418c2ecf20Sopenharmony_ci					hpd.hpd = RADEON_HPD_2;
23428c2ecf20Sopenharmony_ci				else
23438c2ecf20Sopenharmony_ci					hpd.hpd = RADEON_HPD_1;
23448c2ecf20Sopenharmony_ci				break;
23458c2ecf20Sopenharmony_ci			default:
23468c2ecf20Sopenharmony_ci				hpd.hpd = RADEON_HPD_NONE;
23478c2ecf20Sopenharmony_ci				break;
23488c2ecf20Sopenharmony_ci			}
23498c2ecf20Sopenharmony_ci
23508c2ecf20Sopenharmony_ci			if (!radeon_apply_legacy_quirks(dev, i, &connector,
23518c2ecf20Sopenharmony_ci							&ddc_i2c, &hpd))
23528c2ecf20Sopenharmony_ci				continue;
23538c2ecf20Sopenharmony_ci
23548c2ecf20Sopenharmony_ci			switch (connector) {
23558c2ecf20Sopenharmony_ci			case CONNECTOR_PROPRIETARY_LEGACY:
23568c2ecf20Sopenharmony_ci				if ((tmp >> 4) & 0x1)
23578c2ecf20Sopenharmony_ci					devices = ATOM_DEVICE_DFP2_SUPPORT;
23588c2ecf20Sopenharmony_ci				else
23598c2ecf20Sopenharmony_ci					devices = ATOM_DEVICE_DFP1_SUPPORT;
23608c2ecf20Sopenharmony_ci				radeon_add_legacy_encoder(dev,
23618c2ecf20Sopenharmony_ci							  radeon_get_encoder_enum
23628c2ecf20Sopenharmony_ci							  (dev, devices, 0),
23638c2ecf20Sopenharmony_ci							  devices);
23648c2ecf20Sopenharmony_ci				radeon_add_legacy_connector(dev, i, devices,
23658c2ecf20Sopenharmony_ci							    legacy_connector_convert
23668c2ecf20Sopenharmony_ci							    [connector],
23678c2ecf20Sopenharmony_ci							    &ddc_i2c,
23688c2ecf20Sopenharmony_ci							    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D,
23698c2ecf20Sopenharmony_ci							    &hpd);
23708c2ecf20Sopenharmony_ci				break;
23718c2ecf20Sopenharmony_ci			case CONNECTOR_CRT_LEGACY:
23728c2ecf20Sopenharmony_ci				if (tmp & 0x1) {
23738c2ecf20Sopenharmony_ci					devices = ATOM_DEVICE_CRT2_SUPPORT;
23748c2ecf20Sopenharmony_ci					radeon_add_legacy_encoder(dev,
23758c2ecf20Sopenharmony_ci								  radeon_get_encoder_enum
23768c2ecf20Sopenharmony_ci								  (dev,
23778c2ecf20Sopenharmony_ci								   ATOM_DEVICE_CRT2_SUPPORT,
23788c2ecf20Sopenharmony_ci								   2),
23798c2ecf20Sopenharmony_ci								  ATOM_DEVICE_CRT2_SUPPORT);
23808c2ecf20Sopenharmony_ci				} else {
23818c2ecf20Sopenharmony_ci					devices = ATOM_DEVICE_CRT1_SUPPORT;
23828c2ecf20Sopenharmony_ci					radeon_add_legacy_encoder(dev,
23838c2ecf20Sopenharmony_ci								  radeon_get_encoder_enum
23848c2ecf20Sopenharmony_ci								  (dev,
23858c2ecf20Sopenharmony_ci								   ATOM_DEVICE_CRT1_SUPPORT,
23868c2ecf20Sopenharmony_ci								   1),
23878c2ecf20Sopenharmony_ci								  ATOM_DEVICE_CRT1_SUPPORT);
23888c2ecf20Sopenharmony_ci				}
23898c2ecf20Sopenharmony_ci				radeon_add_legacy_connector(dev,
23908c2ecf20Sopenharmony_ci							    i,
23918c2ecf20Sopenharmony_ci							    devices,
23928c2ecf20Sopenharmony_ci							    legacy_connector_convert
23938c2ecf20Sopenharmony_ci							    [connector],
23948c2ecf20Sopenharmony_ci							    &ddc_i2c,
23958c2ecf20Sopenharmony_ci							    CONNECTOR_OBJECT_ID_VGA,
23968c2ecf20Sopenharmony_ci							    &hpd);
23978c2ecf20Sopenharmony_ci				break;
23988c2ecf20Sopenharmony_ci			case CONNECTOR_DVI_I_LEGACY:
23998c2ecf20Sopenharmony_ci				devices = 0;
24008c2ecf20Sopenharmony_ci				if (tmp & 0x1) {
24018c2ecf20Sopenharmony_ci					devices |= ATOM_DEVICE_CRT2_SUPPORT;
24028c2ecf20Sopenharmony_ci					radeon_add_legacy_encoder(dev,
24038c2ecf20Sopenharmony_ci								  radeon_get_encoder_enum
24048c2ecf20Sopenharmony_ci								  (dev,
24058c2ecf20Sopenharmony_ci								   ATOM_DEVICE_CRT2_SUPPORT,
24068c2ecf20Sopenharmony_ci								   2),
24078c2ecf20Sopenharmony_ci								  ATOM_DEVICE_CRT2_SUPPORT);
24088c2ecf20Sopenharmony_ci				} else {
24098c2ecf20Sopenharmony_ci					devices |= ATOM_DEVICE_CRT1_SUPPORT;
24108c2ecf20Sopenharmony_ci					radeon_add_legacy_encoder(dev,
24118c2ecf20Sopenharmony_ci								  radeon_get_encoder_enum
24128c2ecf20Sopenharmony_ci								  (dev,
24138c2ecf20Sopenharmony_ci								   ATOM_DEVICE_CRT1_SUPPORT,
24148c2ecf20Sopenharmony_ci								   1),
24158c2ecf20Sopenharmony_ci								  ATOM_DEVICE_CRT1_SUPPORT);
24168c2ecf20Sopenharmony_ci				}
24178c2ecf20Sopenharmony_ci				/* RV100 board with external TDMS bit mis-set.
24188c2ecf20Sopenharmony_ci				 * Actually uses internal TMDS, clear the bit.
24198c2ecf20Sopenharmony_ci				 */
24208c2ecf20Sopenharmony_ci				if (dev->pdev->device == 0x5159 &&
24218c2ecf20Sopenharmony_ci				    dev->pdev->subsystem_vendor == 0x1014 &&
24228c2ecf20Sopenharmony_ci				    dev->pdev->subsystem_device == 0x029A) {
24238c2ecf20Sopenharmony_ci					tmp &= ~(1 << 4);
24248c2ecf20Sopenharmony_ci				}
24258c2ecf20Sopenharmony_ci				if ((tmp >> 4) & 0x1) {
24268c2ecf20Sopenharmony_ci					devices |= ATOM_DEVICE_DFP2_SUPPORT;
24278c2ecf20Sopenharmony_ci					radeon_add_legacy_encoder(dev,
24288c2ecf20Sopenharmony_ci								  radeon_get_encoder_enum
24298c2ecf20Sopenharmony_ci								  (dev,
24308c2ecf20Sopenharmony_ci								   ATOM_DEVICE_DFP2_SUPPORT,
24318c2ecf20Sopenharmony_ci								   0),
24328c2ecf20Sopenharmony_ci								  ATOM_DEVICE_DFP2_SUPPORT);
24338c2ecf20Sopenharmony_ci					connector_object_id = combios_check_dl_dvi(dev, 0);
24348c2ecf20Sopenharmony_ci				} else {
24358c2ecf20Sopenharmony_ci					devices |= ATOM_DEVICE_DFP1_SUPPORT;
24368c2ecf20Sopenharmony_ci					radeon_add_legacy_encoder(dev,
24378c2ecf20Sopenharmony_ci								  radeon_get_encoder_enum
24388c2ecf20Sopenharmony_ci								  (dev,
24398c2ecf20Sopenharmony_ci								   ATOM_DEVICE_DFP1_SUPPORT,
24408c2ecf20Sopenharmony_ci								   0),
24418c2ecf20Sopenharmony_ci								  ATOM_DEVICE_DFP1_SUPPORT);
24428c2ecf20Sopenharmony_ci					connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
24438c2ecf20Sopenharmony_ci				}
24448c2ecf20Sopenharmony_ci				radeon_add_legacy_connector(dev,
24458c2ecf20Sopenharmony_ci							    i,
24468c2ecf20Sopenharmony_ci							    devices,
24478c2ecf20Sopenharmony_ci							    legacy_connector_convert
24488c2ecf20Sopenharmony_ci							    [connector],
24498c2ecf20Sopenharmony_ci							    &ddc_i2c,
24508c2ecf20Sopenharmony_ci							    connector_object_id,
24518c2ecf20Sopenharmony_ci							    &hpd);
24528c2ecf20Sopenharmony_ci				break;
24538c2ecf20Sopenharmony_ci			case CONNECTOR_DVI_D_LEGACY:
24548c2ecf20Sopenharmony_ci				if ((tmp >> 4) & 0x1) {
24558c2ecf20Sopenharmony_ci					devices = ATOM_DEVICE_DFP2_SUPPORT;
24568c2ecf20Sopenharmony_ci					connector_object_id = combios_check_dl_dvi(dev, 1);
24578c2ecf20Sopenharmony_ci				} else {
24588c2ecf20Sopenharmony_ci					devices = ATOM_DEVICE_DFP1_SUPPORT;
24598c2ecf20Sopenharmony_ci					connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I;
24608c2ecf20Sopenharmony_ci				}
24618c2ecf20Sopenharmony_ci				radeon_add_legacy_encoder(dev,
24628c2ecf20Sopenharmony_ci							  radeon_get_encoder_enum
24638c2ecf20Sopenharmony_ci							  (dev, devices, 0),
24648c2ecf20Sopenharmony_ci							  devices);
24658c2ecf20Sopenharmony_ci				radeon_add_legacy_connector(dev, i, devices,
24668c2ecf20Sopenharmony_ci							    legacy_connector_convert
24678c2ecf20Sopenharmony_ci							    [connector],
24688c2ecf20Sopenharmony_ci							    &ddc_i2c,
24698c2ecf20Sopenharmony_ci							    connector_object_id,
24708c2ecf20Sopenharmony_ci							    &hpd);
24718c2ecf20Sopenharmony_ci				break;
24728c2ecf20Sopenharmony_ci			case CONNECTOR_CTV_LEGACY:
24738c2ecf20Sopenharmony_ci			case CONNECTOR_STV_LEGACY:
24748c2ecf20Sopenharmony_ci				radeon_add_legacy_encoder(dev,
24758c2ecf20Sopenharmony_ci							  radeon_get_encoder_enum
24768c2ecf20Sopenharmony_ci							  (dev,
24778c2ecf20Sopenharmony_ci							   ATOM_DEVICE_TV1_SUPPORT,
24788c2ecf20Sopenharmony_ci							   2),
24798c2ecf20Sopenharmony_ci							  ATOM_DEVICE_TV1_SUPPORT);
24808c2ecf20Sopenharmony_ci				radeon_add_legacy_connector(dev, i,
24818c2ecf20Sopenharmony_ci							    ATOM_DEVICE_TV1_SUPPORT,
24828c2ecf20Sopenharmony_ci							    legacy_connector_convert
24838c2ecf20Sopenharmony_ci							    [connector],
24848c2ecf20Sopenharmony_ci							    &ddc_i2c,
24858c2ecf20Sopenharmony_ci							    CONNECTOR_OBJECT_ID_SVIDEO,
24868c2ecf20Sopenharmony_ci							    &hpd);
24878c2ecf20Sopenharmony_ci				break;
24888c2ecf20Sopenharmony_ci			default:
24898c2ecf20Sopenharmony_ci				DRM_ERROR("Unknown connector type: %d\n",
24908c2ecf20Sopenharmony_ci					  connector);
24918c2ecf20Sopenharmony_ci				continue;
24928c2ecf20Sopenharmony_ci			}
24938c2ecf20Sopenharmony_ci
24948c2ecf20Sopenharmony_ci		}
24958c2ecf20Sopenharmony_ci	} else {
24968c2ecf20Sopenharmony_ci		uint16_t tmds_info =
24978c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
24988c2ecf20Sopenharmony_ci		if (tmds_info) {
24998c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n");
25008c2ecf20Sopenharmony_ci
25018c2ecf20Sopenharmony_ci			radeon_add_legacy_encoder(dev,
25028c2ecf20Sopenharmony_ci						  radeon_get_encoder_enum(dev,
25038c2ecf20Sopenharmony_ci									ATOM_DEVICE_CRT1_SUPPORT,
25048c2ecf20Sopenharmony_ci									1),
25058c2ecf20Sopenharmony_ci						  ATOM_DEVICE_CRT1_SUPPORT);
25068c2ecf20Sopenharmony_ci			radeon_add_legacy_encoder(dev,
25078c2ecf20Sopenharmony_ci						  radeon_get_encoder_enum(dev,
25088c2ecf20Sopenharmony_ci									ATOM_DEVICE_DFP1_SUPPORT,
25098c2ecf20Sopenharmony_ci									0),
25108c2ecf20Sopenharmony_ci						  ATOM_DEVICE_DFP1_SUPPORT);
25118c2ecf20Sopenharmony_ci
25128c2ecf20Sopenharmony_ci			ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
25138c2ecf20Sopenharmony_ci			hpd.hpd = RADEON_HPD_1;
25148c2ecf20Sopenharmony_ci			radeon_add_legacy_connector(dev,
25158c2ecf20Sopenharmony_ci						    0,
25168c2ecf20Sopenharmony_ci						    ATOM_DEVICE_CRT1_SUPPORT |
25178c2ecf20Sopenharmony_ci						    ATOM_DEVICE_DFP1_SUPPORT,
25188c2ecf20Sopenharmony_ci						    DRM_MODE_CONNECTOR_DVII,
25198c2ecf20Sopenharmony_ci						    &ddc_i2c,
25208c2ecf20Sopenharmony_ci						    CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
25218c2ecf20Sopenharmony_ci						    &hpd);
25228c2ecf20Sopenharmony_ci		} else {
25238c2ecf20Sopenharmony_ci			uint16_t crt_info =
25248c2ecf20Sopenharmony_ci				combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
25258c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n");
25268c2ecf20Sopenharmony_ci			if (crt_info) {
25278c2ecf20Sopenharmony_ci				radeon_add_legacy_encoder(dev,
25288c2ecf20Sopenharmony_ci							  radeon_get_encoder_enum(dev,
25298c2ecf20Sopenharmony_ci										ATOM_DEVICE_CRT1_SUPPORT,
25308c2ecf20Sopenharmony_ci										1),
25318c2ecf20Sopenharmony_ci							  ATOM_DEVICE_CRT1_SUPPORT);
25328c2ecf20Sopenharmony_ci				ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
25338c2ecf20Sopenharmony_ci				hpd.hpd = RADEON_HPD_NONE;
25348c2ecf20Sopenharmony_ci				radeon_add_legacy_connector(dev,
25358c2ecf20Sopenharmony_ci							    0,
25368c2ecf20Sopenharmony_ci							    ATOM_DEVICE_CRT1_SUPPORT,
25378c2ecf20Sopenharmony_ci							    DRM_MODE_CONNECTOR_VGA,
25388c2ecf20Sopenharmony_ci							    &ddc_i2c,
25398c2ecf20Sopenharmony_ci							    CONNECTOR_OBJECT_ID_VGA,
25408c2ecf20Sopenharmony_ci							    &hpd);
25418c2ecf20Sopenharmony_ci			} else {
25428c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS("No connector info found\n");
25438c2ecf20Sopenharmony_ci				return false;
25448c2ecf20Sopenharmony_ci			}
25458c2ecf20Sopenharmony_ci		}
25468c2ecf20Sopenharmony_ci	}
25478c2ecf20Sopenharmony_ci
25488c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_MOBILITY || rdev->flags & RADEON_IS_IGP) {
25498c2ecf20Sopenharmony_ci		uint16_t lcd_info =
25508c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
25518c2ecf20Sopenharmony_ci		if (lcd_info) {
25528c2ecf20Sopenharmony_ci			uint16_t lcd_ddc_info =
25538c2ecf20Sopenharmony_ci			    combios_get_table_offset(dev,
25548c2ecf20Sopenharmony_ci						     COMBIOS_LCD_DDC_INFO_TABLE);
25558c2ecf20Sopenharmony_ci
25568c2ecf20Sopenharmony_ci			radeon_add_legacy_encoder(dev,
25578c2ecf20Sopenharmony_ci						  radeon_get_encoder_enum(dev,
25588c2ecf20Sopenharmony_ci									ATOM_DEVICE_LCD1_SUPPORT,
25598c2ecf20Sopenharmony_ci									0),
25608c2ecf20Sopenharmony_ci						  ATOM_DEVICE_LCD1_SUPPORT);
25618c2ecf20Sopenharmony_ci
25628c2ecf20Sopenharmony_ci			if (lcd_ddc_info) {
25638c2ecf20Sopenharmony_ci				ddc_type = RBIOS8(lcd_ddc_info + 2);
25648c2ecf20Sopenharmony_ci				switch (ddc_type) {
25658c2ecf20Sopenharmony_ci				case DDC_LCD:
25668c2ecf20Sopenharmony_ci					ddc_i2c =
25678c2ecf20Sopenharmony_ci						combios_setup_i2c_bus(rdev,
25688c2ecf20Sopenharmony_ci								      DDC_LCD,
25698c2ecf20Sopenharmony_ci								      RBIOS32(lcd_ddc_info + 3),
25708c2ecf20Sopenharmony_ci								      RBIOS32(lcd_ddc_info + 7));
25718c2ecf20Sopenharmony_ci					radeon_i2c_add(rdev, &ddc_i2c, "LCD");
25728c2ecf20Sopenharmony_ci					break;
25738c2ecf20Sopenharmony_ci				case DDC_GPIO:
25748c2ecf20Sopenharmony_ci					ddc_i2c =
25758c2ecf20Sopenharmony_ci						combios_setup_i2c_bus(rdev,
25768c2ecf20Sopenharmony_ci								      DDC_GPIO,
25778c2ecf20Sopenharmony_ci								      RBIOS32(lcd_ddc_info + 3),
25788c2ecf20Sopenharmony_ci								      RBIOS32(lcd_ddc_info + 7));
25798c2ecf20Sopenharmony_ci					radeon_i2c_add(rdev, &ddc_i2c, "LCD");
25808c2ecf20Sopenharmony_ci					break;
25818c2ecf20Sopenharmony_ci				default:
25828c2ecf20Sopenharmony_ci					ddc_i2c =
25838c2ecf20Sopenharmony_ci						combios_setup_i2c_bus(rdev, ddc_type, 0, 0);
25848c2ecf20Sopenharmony_ci					break;
25858c2ecf20Sopenharmony_ci				}
25868c2ecf20Sopenharmony_ci				DRM_DEBUG_KMS("LCD DDC Info Table found!\n");
25878c2ecf20Sopenharmony_ci			} else
25888c2ecf20Sopenharmony_ci				ddc_i2c.valid = false;
25898c2ecf20Sopenharmony_ci
25908c2ecf20Sopenharmony_ci			hpd.hpd = RADEON_HPD_NONE;
25918c2ecf20Sopenharmony_ci			radeon_add_legacy_connector(dev,
25928c2ecf20Sopenharmony_ci						    5,
25938c2ecf20Sopenharmony_ci						    ATOM_DEVICE_LCD1_SUPPORT,
25948c2ecf20Sopenharmony_ci						    DRM_MODE_CONNECTOR_LVDS,
25958c2ecf20Sopenharmony_ci						    &ddc_i2c,
25968c2ecf20Sopenharmony_ci						    CONNECTOR_OBJECT_ID_LVDS,
25978c2ecf20Sopenharmony_ci						    &hpd);
25988c2ecf20Sopenharmony_ci		}
25998c2ecf20Sopenharmony_ci	}
26008c2ecf20Sopenharmony_ci
26018c2ecf20Sopenharmony_ci	/* check TV table */
26028c2ecf20Sopenharmony_ci	if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) {
26038c2ecf20Sopenharmony_ci		uint32_t tv_info =
26048c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
26058c2ecf20Sopenharmony_ci		if (tv_info) {
26068c2ecf20Sopenharmony_ci			if (RBIOS8(tv_info + 6) == 'T') {
26078c2ecf20Sopenharmony_ci				if (radeon_apply_legacy_tv_quirks(dev)) {
26088c2ecf20Sopenharmony_ci					hpd.hpd = RADEON_HPD_NONE;
26098c2ecf20Sopenharmony_ci					ddc_i2c.valid = false;
26108c2ecf20Sopenharmony_ci					radeon_add_legacy_encoder(dev,
26118c2ecf20Sopenharmony_ci								  radeon_get_encoder_enum
26128c2ecf20Sopenharmony_ci								  (dev,
26138c2ecf20Sopenharmony_ci								   ATOM_DEVICE_TV1_SUPPORT,
26148c2ecf20Sopenharmony_ci								   2),
26158c2ecf20Sopenharmony_ci								  ATOM_DEVICE_TV1_SUPPORT);
26168c2ecf20Sopenharmony_ci					radeon_add_legacy_connector(dev, 6,
26178c2ecf20Sopenharmony_ci								    ATOM_DEVICE_TV1_SUPPORT,
26188c2ecf20Sopenharmony_ci								    DRM_MODE_CONNECTOR_SVIDEO,
26198c2ecf20Sopenharmony_ci								    &ddc_i2c,
26208c2ecf20Sopenharmony_ci								    CONNECTOR_OBJECT_ID_SVIDEO,
26218c2ecf20Sopenharmony_ci								    &hpd);
26228c2ecf20Sopenharmony_ci				}
26238c2ecf20Sopenharmony_ci			}
26248c2ecf20Sopenharmony_ci		}
26258c2ecf20Sopenharmony_ci	}
26268c2ecf20Sopenharmony_ci
26278c2ecf20Sopenharmony_ci	radeon_link_encoder_connector(dev);
26288c2ecf20Sopenharmony_ci
26298c2ecf20Sopenharmony_ci	return true;
26308c2ecf20Sopenharmony_ci}
26318c2ecf20Sopenharmony_ci
26328c2ecf20Sopenharmony_cistatic const char *thermal_controller_names[] = {
26338c2ecf20Sopenharmony_ci	"NONE",
26348c2ecf20Sopenharmony_ci	"lm63",
26358c2ecf20Sopenharmony_ci	"adm1032",
26368c2ecf20Sopenharmony_ci};
26378c2ecf20Sopenharmony_ci
26388c2ecf20Sopenharmony_civoid radeon_combios_get_power_modes(struct radeon_device *rdev)
26398c2ecf20Sopenharmony_ci{
26408c2ecf20Sopenharmony_ci	struct drm_device *dev = rdev->ddev;
26418c2ecf20Sopenharmony_ci	u16 offset, misc, misc2 = 0;
26428c2ecf20Sopenharmony_ci	u8 rev, tmp;
26438c2ecf20Sopenharmony_ci	int state_index = 0;
26448c2ecf20Sopenharmony_ci	struct radeon_i2c_bus_rec i2c_bus;
26458c2ecf20Sopenharmony_ci
26468c2ecf20Sopenharmony_ci	rdev->pm.default_power_state_index = -1;
26478c2ecf20Sopenharmony_ci
26488c2ecf20Sopenharmony_ci	/* allocate 2 power states */
26498c2ecf20Sopenharmony_ci	rdev->pm.power_state = kcalloc(2, sizeof(struct radeon_power_state),
26508c2ecf20Sopenharmony_ci				       GFP_KERNEL);
26518c2ecf20Sopenharmony_ci	if (rdev->pm.power_state) {
26528c2ecf20Sopenharmony_ci		/* allocate 1 clock mode per state */
26538c2ecf20Sopenharmony_ci		rdev->pm.power_state[0].clock_info =
26548c2ecf20Sopenharmony_ci			kcalloc(1, sizeof(struct radeon_pm_clock_info),
26558c2ecf20Sopenharmony_ci				GFP_KERNEL);
26568c2ecf20Sopenharmony_ci		rdev->pm.power_state[1].clock_info =
26578c2ecf20Sopenharmony_ci			kcalloc(1, sizeof(struct radeon_pm_clock_info),
26588c2ecf20Sopenharmony_ci				GFP_KERNEL);
26598c2ecf20Sopenharmony_ci		if (!rdev->pm.power_state[0].clock_info ||
26608c2ecf20Sopenharmony_ci		    !rdev->pm.power_state[1].clock_info)
26618c2ecf20Sopenharmony_ci			goto pm_failed;
26628c2ecf20Sopenharmony_ci	} else
26638c2ecf20Sopenharmony_ci		goto pm_failed;
26648c2ecf20Sopenharmony_ci
26658c2ecf20Sopenharmony_ci	/* check for a thermal chip */
26668c2ecf20Sopenharmony_ci	offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE);
26678c2ecf20Sopenharmony_ci	if (offset) {
26688c2ecf20Sopenharmony_ci		u8 thermal_controller = 0, gpio = 0, i2c_addr = 0, clk_bit = 0, data_bit = 0;
26698c2ecf20Sopenharmony_ci
26708c2ecf20Sopenharmony_ci		rev = RBIOS8(offset);
26718c2ecf20Sopenharmony_ci
26728c2ecf20Sopenharmony_ci		if (rev == 0) {
26738c2ecf20Sopenharmony_ci			thermal_controller = RBIOS8(offset + 3);
26748c2ecf20Sopenharmony_ci			gpio = RBIOS8(offset + 4) & 0x3f;
26758c2ecf20Sopenharmony_ci			i2c_addr = RBIOS8(offset + 5);
26768c2ecf20Sopenharmony_ci		} else if (rev == 1) {
26778c2ecf20Sopenharmony_ci			thermal_controller = RBIOS8(offset + 4);
26788c2ecf20Sopenharmony_ci			gpio = RBIOS8(offset + 5) & 0x3f;
26798c2ecf20Sopenharmony_ci			i2c_addr = RBIOS8(offset + 6);
26808c2ecf20Sopenharmony_ci		} else if (rev == 2) {
26818c2ecf20Sopenharmony_ci			thermal_controller = RBIOS8(offset + 4);
26828c2ecf20Sopenharmony_ci			gpio = RBIOS8(offset + 5) & 0x3f;
26838c2ecf20Sopenharmony_ci			i2c_addr = RBIOS8(offset + 6);
26848c2ecf20Sopenharmony_ci			clk_bit = RBIOS8(offset + 0xa);
26858c2ecf20Sopenharmony_ci			data_bit = RBIOS8(offset + 0xb);
26868c2ecf20Sopenharmony_ci		}
26878c2ecf20Sopenharmony_ci		if ((thermal_controller > 0) && (thermal_controller < 3)) {
26888c2ecf20Sopenharmony_ci			DRM_INFO("Possible %s thermal controller at 0x%02x\n",
26898c2ecf20Sopenharmony_ci				 thermal_controller_names[thermal_controller],
26908c2ecf20Sopenharmony_ci				 i2c_addr >> 1);
26918c2ecf20Sopenharmony_ci			if (gpio == DDC_LCD) {
26928c2ecf20Sopenharmony_ci				/* MM i2c */
26938c2ecf20Sopenharmony_ci				i2c_bus.valid = true;
26948c2ecf20Sopenharmony_ci				i2c_bus.hw_capable = true;
26958c2ecf20Sopenharmony_ci				i2c_bus.mm_i2c = true;
26968c2ecf20Sopenharmony_ci				i2c_bus.i2c_id = 0xa0;
26978c2ecf20Sopenharmony_ci			} else if (gpio == DDC_GPIO)
26988c2ecf20Sopenharmony_ci				i2c_bus = combios_setup_i2c_bus(rdev, gpio, 1 << clk_bit, 1 << data_bit);
26998c2ecf20Sopenharmony_ci			else
27008c2ecf20Sopenharmony_ci				i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0);
27018c2ecf20Sopenharmony_ci			rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
27028c2ecf20Sopenharmony_ci			if (rdev->pm.i2c_bus) {
27038c2ecf20Sopenharmony_ci				struct i2c_board_info info = { };
27048c2ecf20Sopenharmony_ci				const char *name = thermal_controller_names[thermal_controller];
27058c2ecf20Sopenharmony_ci				info.addr = i2c_addr >> 1;
27068c2ecf20Sopenharmony_ci				strlcpy(info.type, name, sizeof(info.type));
27078c2ecf20Sopenharmony_ci				i2c_new_client_device(&rdev->pm.i2c_bus->adapter, &info);
27088c2ecf20Sopenharmony_ci			}
27098c2ecf20Sopenharmony_ci		}
27108c2ecf20Sopenharmony_ci	} else {
27118c2ecf20Sopenharmony_ci		/* boards with a thermal chip, but no overdrive table */
27128c2ecf20Sopenharmony_ci
27138c2ecf20Sopenharmony_ci		/* Asus 9600xt has an f75375 on the monid bus */
27148c2ecf20Sopenharmony_ci		if ((dev->pdev->device == 0x4152) &&
27158c2ecf20Sopenharmony_ci		    (dev->pdev->subsystem_vendor == 0x1043) &&
27168c2ecf20Sopenharmony_ci		    (dev->pdev->subsystem_device == 0xc002)) {
27178c2ecf20Sopenharmony_ci			i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
27188c2ecf20Sopenharmony_ci			rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
27198c2ecf20Sopenharmony_ci			if (rdev->pm.i2c_bus) {
27208c2ecf20Sopenharmony_ci				struct i2c_board_info info = { };
27218c2ecf20Sopenharmony_ci				const char *name = "f75375";
27228c2ecf20Sopenharmony_ci				info.addr = 0x28;
27238c2ecf20Sopenharmony_ci				strlcpy(info.type, name, sizeof(info.type));
27248c2ecf20Sopenharmony_ci				i2c_new_client_device(&rdev->pm.i2c_bus->adapter, &info);
27258c2ecf20Sopenharmony_ci				DRM_INFO("Possible %s thermal controller at 0x%02x\n",
27268c2ecf20Sopenharmony_ci					 name, info.addr);
27278c2ecf20Sopenharmony_ci			}
27288c2ecf20Sopenharmony_ci		}
27298c2ecf20Sopenharmony_ci	}
27308c2ecf20Sopenharmony_ci
27318c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_MOBILITY) {
27328c2ecf20Sopenharmony_ci		offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE);
27338c2ecf20Sopenharmony_ci		if (offset) {
27348c2ecf20Sopenharmony_ci			rev = RBIOS8(offset);
27358c2ecf20Sopenharmony_ci			/* power mode 0 tends to be the only valid one */
27368c2ecf20Sopenharmony_ci			rdev->pm.power_state[state_index].num_clock_modes = 1;
27378c2ecf20Sopenharmony_ci			rdev->pm.power_state[state_index].clock_info[0].mclk = RBIOS32(offset + 0x5 + 0x2);
27388c2ecf20Sopenharmony_ci			rdev->pm.power_state[state_index].clock_info[0].sclk = RBIOS32(offset + 0x5 + 0x6);
27398c2ecf20Sopenharmony_ci			if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) ||
27408c2ecf20Sopenharmony_ci			    (rdev->pm.power_state[state_index].clock_info[0].sclk == 0))
27418c2ecf20Sopenharmony_ci				goto default_mode;
27428c2ecf20Sopenharmony_ci			rdev->pm.power_state[state_index].type =
27438c2ecf20Sopenharmony_ci				POWER_STATE_TYPE_BATTERY;
27448c2ecf20Sopenharmony_ci			misc = RBIOS16(offset + 0x5 + 0x0);
27458c2ecf20Sopenharmony_ci			if (rev > 4)
27468c2ecf20Sopenharmony_ci				misc2 = RBIOS16(offset + 0x5 + 0xe);
27478c2ecf20Sopenharmony_ci			rdev->pm.power_state[state_index].misc = misc;
27488c2ecf20Sopenharmony_ci			rdev->pm.power_state[state_index].misc2 = misc2;
27498c2ecf20Sopenharmony_ci			if (misc & 0x4) {
27508c2ecf20Sopenharmony_ci				rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO;
27518c2ecf20Sopenharmony_ci				if (misc & 0x8)
27528c2ecf20Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
27538c2ecf20Sopenharmony_ci						true;
27548c2ecf20Sopenharmony_ci				else
27558c2ecf20Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.active_high =
27568c2ecf20Sopenharmony_ci						false;
27578c2ecf20Sopenharmony_ci				rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = true;
27588c2ecf20Sopenharmony_ci				if (rev < 6) {
27598c2ecf20Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg =
27608c2ecf20Sopenharmony_ci						RBIOS16(offset + 0x5 + 0xb) * 4;
27618c2ecf20Sopenharmony_ci					tmp = RBIOS8(offset + 0x5 + 0xd);
27628c2ecf20Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp);
27638c2ecf20Sopenharmony_ci				} else {
27648c2ecf20Sopenharmony_ci					u8 entries = RBIOS8(offset + 0x5 + 0xb);
27658c2ecf20Sopenharmony_ci					u16 voltage_table_offset = RBIOS16(offset + 0x5 + 0xc);
27668c2ecf20Sopenharmony_ci					if (entries && voltage_table_offset) {
27678c2ecf20Sopenharmony_ci						rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg =
27688c2ecf20Sopenharmony_ci							RBIOS16(voltage_table_offset) * 4;
27698c2ecf20Sopenharmony_ci						tmp = RBIOS8(voltage_table_offset + 0x2);
27708c2ecf20Sopenharmony_ci						rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp);
27718c2ecf20Sopenharmony_ci					} else
27728c2ecf20Sopenharmony_ci						rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = false;
27738c2ecf20Sopenharmony_ci				}
27748c2ecf20Sopenharmony_ci				switch ((misc2 & 0x700) >> 8) {
27758c2ecf20Sopenharmony_ci				case 0:
27768c2ecf20Sopenharmony_ci				default:
27778c2ecf20Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 0;
27788c2ecf20Sopenharmony_ci					break;
27798c2ecf20Sopenharmony_ci				case 1:
27808c2ecf20Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 33;
27818c2ecf20Sopenharmony_ci					break;
27828c2ecf20Sopenharmony_ci				case 2:
27838c2ecf20Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 66;
27848c2ecf20Sopenharmony_ci					break;
27858c2ecf20Sopenharmony_ci				case 3:
27868c2ecf20Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 99;
27878c2ecf20Sopenharmony_ci					break;
27888c2ecf20Sopenharmony_ci				case 4:
27898c2ecf20Sopenharmony_ci					rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 132;
27908c2ecf20Sopenharmony_ci					break;
27918c2ecf20Sopenharmony_ci				}
27928c2ecf20Sopenharmony_ci			} else
27938c2ecf20Sopenharmony_ci				rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
27948c2ecf20Sopenharmony_ci			if (rev > 6)
27958c2ecf20Sopenharmony_ci				rdev->pm.power_state[state_index].pcie_lanes =
27968c2ecf20Sopenharmony_ci					RBIOS8(offset + 0x5 + 0x10);
27978c2ecf20Sopenharmony_ci			rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
27988c2ecf20Sopenharmony_ci			state_index++;
27998c2ecf20Sopenharmony_ci		} else {
28008c2ecf20Sopenharmony_ci			/* XXX figure out some good default low power mode for mobility cards w/out power tables */
28018c2ecf20Sopenharmony_ci		}
28028c2ecf20Sopenharmony_ci	} else {
28038c2ecf20Sopenharmony_ci		/* XXX figure out some good default low power mode for desktop cards */
28048c2ecf20Sopenharmony_ci	}
28058c2ecf20Sopenharmony_ci
28068c2ecf20Sopenharmony_cidefault_mode:
28078c2ecf20Sopenharmony_ci	/* add the default mode */
28088c2ecf20Sopenharmony_ci	rdev->pm.power_state[state_index].type =
28098c2ecf20Sopenharmony_ci		POWER_STATE_TYPE_DEFAULT;
28108c2ecf20Sopenharmony_ci	rdev->pm.power_state[state_index].num_clock_modes = 1;
28118c2ecf20Sopenharmony_ci	rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
28128c2ecf20Sopenharmony_ci	rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
28138c2ecf20Sopenharmony_ci	rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0];
28148c2ecf20Sopenharmony_ci	if ((state_index > 0) &&
28158c2ecf20Sopenharmony_ci	    (rdev->pm.power_state[0].clock_info[0].voltage.type == VOLTAGE_GPIO))
28168c2ecf20Sopenharmony_ci		rdev->pm.power_state[state_index].clock_info[0].voltage =
28178c2ecf20Sopenharmony_ci			rdev->pm.power_state[0].clock_info[0].voltage;
28188c2ecf20Sopenharmony_ci	else
28198c2ecf20Sopenharmony_ci		rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
28208c2ecf20Sopenharmony_ci	rdev->pm.power_state[state_index].pcie_lanes = 16;
28218c2ecf20Sopenharmony_ci	rdev->pm.power_state[state_index].flags = 0;
28228c2ecf20Sopenharmony_ci	rdev->pm.default_power_state_index = state_index;
28238c2ecf20Sopenharmony_ci	rdev->pm.num_power_states = state_index + 1;
28248c2ecf20Sopenharmony_ci
28258c2ecf20Sopenharmony_ci	rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
28268c2ecf20Sopenharmony_ci	rdev->pm.current_clock_mode_index = 0;
28278c2ecf20Sopenharmony_ci	return;
28288c2ecf20Sopenharmony_ci
28298c2ecf20Sopenharmony_cipm_failed:
28308c2ecf20Sopenharmony_ci	rdev->pm.default_power_state_index = state_index;
28318c2ecf20Sopenharmony_ci	rdev->pm.num_power_states = 0;
28328c2ecf20Sopenharmony_ci
28338c2ecf20Sopenharmony_ci	rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
28348c2ecf20Sopenharmony_ci	rdev->pm.current_clock_mode_index = 0;
28358c2ecf20Sopenharmony_ci}
28368c2ecf20Sopenharmony_ci
28378c2ecf20Sopenharmony_civoid radeon_external_tmds_setup(struct drm_encoder *encoder)
28388c2ecf20Sopenharmony_ci{
28398c2ecf20Sopenharmony_ci	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
28408c2ecf20Sopenharmony_ci	struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
28418c2ecf20Sopenharmony_ci
28428c2ecf20Sopenharmony_ci	if (!tmds)
28438c2ecf20Sopenharmony_ci		return;
28448c2ecf20Sopenharmony_ci
28458c2ecf20Sopenharmony_ci	switch (tmds->dvo_chip) {
28468c2ecf20Sopenharmony_ci	case DVO_SIL164:
28478c2ecf20Sopenharmony_ci		/* sil 164 */
28488c2ecf20Sopenharmony_ci		radeon_i2c_put_byte(tmds->i2c_bus,
28498c2ecf20Sopenharmony_ci				    tmds->slave_addr,
28508c2ecf20Sopenharmony_ci				    0x08, 0x30);
28518c2ecf20Sopenharmony_ci		radeon_i2c_put_byte(tmds->i2c_bus,
28528c2ecf20Sopenharmony_ci				       tmds->slave_addr,
28538c2ecf20Sopenharmony_ci				       0x09, 0x00);
28548c2ecf20Sopenharmony_ci		radeon_i2c_put_byte(tmds->i2c_bus,
28558c2ecf20Sopenharmony_ci				    tmds->slave_addr,
28568c2ecf20Sopenharmony_ci				    0x0a, 0x90);
28578c2ecf20Sopenharmony_ci		radeon_i2c_put_byte(tmds->i2c_bus,
28588c2ecf20Sopenharmony_ci				    tmds->slave_addr,
28598c2ecf20Sopenharmony_ci				    0x0c, 0x89);
28608c2ecf20Sopenharmony_ci		radeon_i2c_put_byte(tmds->i2c_bus,
28618c2ecf20Sopenharmony_ci				       tmds->slave_addr,
28628c2ecf20Sopenharmony_ci				       0x08, 0x3b);
28638c2ecf20Sopenharmony_ci		break;
28648c2ecf20Sopenharmony_ci	case DVO_SIL1178:
28658c2ecf20Sopenharmony_ci		/* sil 1178 - untested */
28668c2ecf20Sopenharmony_ci		/*
28678c2ecf20Sopenharmony_ci		 * 0x0f, 0x44
28688c2ecf20Sopenharmony_ci		 * 0x0f, 0x4c
28698c2ecf20Sopenharmony_ci		 * 0x0e, 0x01
28708c2ecf20Sopenharmony_ci		 * 0x0a, 0x80
28718c2ecf20Sopenharmony_ci		 * 0x09, 0x30
28728c2ecf20Sopenharmony_ci		 * 0x0c, 0xc9
28738c2ecf20Sopenharmony_ci		 * 0x0d, 0x70
28748c2ecf20Sopenharmony_ci		 * 0x08, 0x32
28758c2ecf20Sopenharmony_ci		 * 0x08, 0x33
28768c2ecf20Sopenharmony_ci		 */
28778c2ecf20Sopenharmony_ci		break;
28788c2ecf20Sopenharmony_ci	default:
28798c2ecf20Sopenharmony_ci		break;
28808c2ecf20Sopenharmony_ci	}
28818c2ecf20Sopenharmony_ci
28828c2ecf20Sopenharmony_ci}
28838c2ecf20Sopenharmony_ci
28848c2ecf20Sopenharmony_cibool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
28858c2ecf20Sopenharmony_ci{
28868c2ecf20Sopenharmony_ci	struct drm_device *dev = encoder->dev;
28878c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
28888c2ecf20Sopenharmony_ci	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
28898c2ecf20Sopenharmony_ci	uint16_t offset;
28908c2ecf20Sopenharmony_ci	uint8_t blocks, slave_addr, rev;
28918c2ecf20Sopenharmony_ci	uint32_t index, id;
28928c2ecf20Sopenharmony_ci	uint32_t reg, val, and_mask, or_mask;
28938c2ecf20Sopenharmony_ci	struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
28948c2ecf20Sopenharmony_ci
28958c2ecf20Sopenharmony_ci	if (!tmds)
28968c2ecf20Sopenharmony_ci		return false;
28978c2ecf20Sopenharmony_ci
28988c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP) {
28998c2ecf20Sopenharmony_ci		offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_ON_TABLE);
29008c2ecf20Sopenharmony_ci		rev = RBIOS8(offset);
29018c2ecf20Sopenharmony_ci		if (offset) {
29028c2ecf20Sopenharmony_ci			rev = RBIOS8(offset);
29038c2ecf20Sopenharmony_ci			if (rev > 1) {
29048c2ecf20Sopenharmony_ci				blocks = RBIOS8(offset + 3);
29058c2ecf20Sopenharmony_ci				index = offset + 4;
29068c2ecf20Sopenharmony_ci				while (blocks > 0) {
29078c2ecf20Sopenharmony_ci					id = RBIOS16(index);
29088c2ecf20Sopenharmony_ci					index += 2;
29098c2ecf20Sopenharmony_ci					switch (id >> 13) {
29108c2ecf20Sopenharmony_ci					case 0:
29118c2ecf20Sopenharmony_ci						reg = (id & 0x1fff) * 4;
29128c2ecf20Sopenharmony_ci						val = RBIOS32(index);
29138c2ecf20Sopenharmony_ci						index += 4;
29148c2ecf20Sopenharmony_ci						WREG32(reg, val);
29158c2ecf20Sopenharmony_ci						break;
29168c2ecf20Sopenharmony_ci					case 2:
29178c2ecf20Sopenharmony_ci						reg = (id & 0x1fff) * 4;
29188c2ecf20Sopenharmony_ci						and_mask = RBIOS32(index);
29198c2ecf20Sopenharmony_ci						index += 4;
29208c2ecf20Sopenharmony_ci						or_mask = RBIOS32(index);
29218c2ecf20Sopenharmony_ci						index += 4;
29228c2ecf20Sopenharmony_ci						val = RREG32(reg);
29238c2ecf20Sopenharmony_ci						val = (val & and_mask) | or_mask;
29248c2ecf20Sopenharmony_ci						WREG32(reg, val);
29258c2ecf20Sopenharmony_ci						break;
29268c2ecf20Sopenharmony_ci					case 3:
29278c2ecf20Sopenharmony_ci						val = RBIOS16(index);
29288c2ecf20Sopenharmony_ci						index += 2;
29298c2ecf20Sopenharmony_ci						udelay(val);
29308c2ecf20Sopenharmony_ci						break;
29318c2ecf20Sopenharmony_ci					case 4:
29328c2ecf20Sopenharmony_ci						val = RBIOS16(index);
29338c2ecf20Sopenharmony_ci						index += 2;
29348c2ecf20Sopenharmony_ci						mdelay(val);
29358c2ecf20Sopenharmony_ci						break;
29368c2ecf20Sopenharmony_ci					case 6:
29378c2ecf20Sopenharmony_ci						slave_addr = id & 0xff;
29388c2ecf20Sopenharmony_ci						slave_addr >>= 1; /* 7 bit addressing */
29398c2ecf20Sopenharmony_ci						index++;
29408c2ecf20Sopenharmony_ci						reg = RBIOS8(index);
29418c2ecf20Sopenharmony_ci						index++;
29428c2ecf20Sopenharmony_ci						val = RBIOS8(index);
29438c2ecf20Sopenharmony_ci						index++;
29448c2ecf20Sopenharmony_ci						radeon_i2c_put_byte(tmds->i2c_bus,
29458c2ecf20Sopenharmony_ci								    slave_addr,
29468c2ecf20Sopenharmony_ci								    reg, val);
29478c2ecf20Sopenharmony_ci						break;
29488c2ecf20Sopenharmony_ci					default:
29498c2ecf20Sopenharmony_ci						DRM_ERROR("Unknown id %d\n", id >> 13);
29508c2ecf20Sopenharmony_ci						break;
29518c2ecf20Sopenharmony_ci					}
29528c2ecf20Sopenharmony_ci					blocks--;
29538c2ecf20Sopenharmony_ci				}
29548c2ecf20Sopenharmony_ci				return true;
29558c2ecf20Sopenharmony_ci			}
29568c2ecf20Sopenharmony_ci		}
29578c2ecf20Sopenharmony_ci	} else {
29588c2ecf20Sopenharmony_ci		offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
29598c2ecf20Sopenharmony_ci		if (offset) {
29608c2ecf20Sopenharmony_ci			index = offset + 10;
29618c2ecf20Sopenharmony_ci			id = RBIOS16(index);
29628c2ecf20Sopenharmony_ci			while (id != 0xffff) {
29638c2ecf20Sopenharmony_ci				index += 2;
29648c2ecf20Sopenharmony_ci				switch (id >> 13) {
29658c2ecf20Sopenharmony_ci				case 0:
29668c2ecf20Sopenharmony_ci					reg = (id & 0x1fff) * 4;
29678c2ecf20Sopenharmony_ci					val = RBIOS32(index);
29688c2ecf20Sopenharmony_ci					WREG32(reg, val);
29698c2ecf20Sopenharmony_ci					break;
29708c2ecf20Sopenharmony_ci				case 2:
29718c2ecf20Sopenharmony_ci					reg = (id & 0x1fff) * 4;
29728c2ecf20Sopenharmony_ci					and_mask = RBIOS32(index);
29738c2ecf20Sopenharmony_ci					index += 4;
29748c2ecf20Sopenharmony_ci					or_mask = RBIOS32(index);
29758c2ecf20Sopenharmony_ci					index += 4;
29768c2ecf20Sopenharmony_ci					val = RREG32(reg);
29778c2ecf20Sopenharmony_ci					val = (val & and_mask) | or_mask;
29788c2ecf20Sopenharmony_ci					WREG32(reg, val);
29798c2ecf20Sopenharmony_ci					break;
29808c2ecf20Sopenharmony_ci				case 4:
29818c2ecf20Sopenharmony_ci					val = RBIOS16(index);
29828c2ecf20Sopenharmony_ci					index += 2;
29838c2ecf20Sopenharmony_ci					udelay(val);
29848c2ecf20Sopenharmony_ci					break;
29858c2ecf20Sopenharmony_ci				case 5:
29868c2ecf20Sopenharmony_ci					reg = id & 0x1fff;
29878c2ecf20Sopenharmony_ci					and_mask = RBIOS32(index);
29888c2ecf20Sopenharmony_ci					index += 4;
29898c2ecf20Sopenharmony_ci					or_mask = RBIOS32(index);
29908c2ecf20Sopenharmony_ci					index += 4;
29918c2ecf20Sopenharmony_ci					val = RREG32_PLL(reg);
29928c2ecf20Sopenharmony_ci					val = (val & and_mask) | or_mask;
29938c2ecf20Sopenharmony_ci					WREG32_PLL(reg, val);
29948c2ecf20Sopenharmony_ci					break;
29958c2ecf20Sopenharmony_ci				case 6:
29968c2ecf20Sopenharmony_ci					reg = id & 0x1fff;
29978c2ecf20Sopenharmony_ci					val = RBIOS8(index);
29988c2ecf20Sopenharmony_ci					index += 1;
29998c2ecf20Sopenharmony_ci					radeon_i2c_put_byte(tmds->i2c_bus,
30008c2ecf20Sopenharmony_ci							    tmds->slave_addr,
30018c2ecf20Sopenharmony_ci							    reg, val);
30028c2ecf20Sopenharmony_ci					break;
30038c2ecf20Sopenharmony_ci				default:
30048c2ecf20Sopenharmony_ci					DRM_ERROR("Unknown id %d\n", id >> 13);
30058c2ecf20Sopenharmony_ci					break;
30068c2ecf20Sopenharmony_ci				}
30078c2ecf20Sopenharmony_ci				id = RBIOS16(index);
30088c2ecf20Sopenharmony_ci			}
30098c2ecf20Sopenharmony_ci			return true;
30108c2ecf20Sopenharmony_ci		}
30118c2ecf20Sopenharmony_ci	}
30128c2ecf20Sopenharmony_ci	return false;
30138c2ecf20Sopenharmony_ci}
30148c2ecf20Sopenharmony_ci
30158c2ecf20Sopenharmony_cistatic void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset)
30168c2ecf20Sopenharmony_ci{
30178c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
30188c2ecf20Sopenharmony_ci
30198c2ecf20Sopenharmony_ci	if (offset) {
30208c2ecf20Sopenharmony_ci		while (RBIOS16(offset)) {
30218c2ecf20Sopenharmony_ci			uint16_t cmd = ((RBIOS16(offset) & 0xe000) >> 13);
30228c2ecf20Sopenharmony_ci			uint32_t addr = (RBIOS16(offset) & 0x1fff);
30238c2ecf20Sopenharmony_ci			uint32_t val, and_mask, or_mask;
30248c2ecf20Sopenharmony_ci			uint32_t tmp;
30258c2ecf20Sopenharmony_ci
30268c2ecf20Sopenharmony_ci			offset += 2;
30278c2ecf20Sopenharmony_ci			switch (cmd) {
30288c2ecf20Sopenharmony_ci			case 0:
30298c2ecf20Sopenharmony_ci				val = RBIOS32(offset);
30308c2ecf20Sopenharmony_ci				offset += 4;
30318c2ecf20Sopenharmony_ci				WREG32(addr, val);
30328c2ecf20Sopenharmony_ci				break;
30338c2ecf20Sopenharmony_ci			case 1:
30348c2ecf20Sopenharmony_ci				val = RBIOS32(offset);
30358c2ecf20Sopenharmony_ci				offset += 4;
30368c2ecf20Sopenharmony_ci				WREG32(addr, val);
30378c2ecf20Sopenharmony_ci				break;
30388c2ecf20Sopenharmony_ci			case 2:
30398c2ecf20Sopenharmony_ci				and_mask = RBIOS32(offset);
30408c2ecf20Sopenharmony_ci				offset += 4;
30418c2ecf20Sopenharmony_ci				or_mask = RBIOS32(offset);
30428c2ecf20Sopenharmony_ci				offset += 4;
30438c2ecf20Sopenharmony_ci				tmp = RREG32(addr);
30448c2ecf20Sopenharmony_ci				tmp &= and_mask;
30458c2ecf20Sopenharmony_ci				tmp |= or_mask;
30468c2ecf20Sopenharmony_ci				WREG32(addr, tmp);
30478c2ecf20Sopenharmony_ci				break;
30488c2ecf20Sopenharmony_ci			case 3:
30498c2ecf20Sopenharmony_ci				and_mask = RBIOS32(offset);
30508c2ecf20Sopenharmony_ci				offset += 4;
30518c2ecf20Sopenharmony_ci				or_mask = RBIOS32(offset);
30528c2ecf20Sopenharmony_ci				offset += 4;
30538c2ecf20Sopenharmony_ci				tmp = RREG32(addr);
30548c2ecf20Sopenharmony_ci				tmp &= and_mask;
30558c2ecf20Sopenharmony_ci				tmp |= or_mask;
30568c2ecf20Sopenharmony_ci				WREG32(addr, tmp);
30578c2ecf20Sopenharmony_ci				break;
30588c2ecf20Sopenharmony_ci			case 4:
30598c2ecf20Sopenharmony_ci				val = RBIOS16(offset);
30608c2ecf20Sopenharmony_ci				offset += 2;
30618c2ecf20Sopenharmony_ci				udelay(val);
30628c2ecf20Sopenharmony_ci				break;
30638c2ecf20Sopenharmony_ci			case 5:
30648c2ecf20Sopenharmony_ci				val = RBIOS16(offset);
30658c2ecf20Sopenharmony_ci				offset += 2;
30668c2ecf20Sopenharmony_ci				switch (addr) {
30678c2ecf20Sopenharmony_ci				case 8:
30688c2ecf20Sopenharmony_ci					while (val--) {
30698c2ecf20Sopenharmony_ci						if (!
30708c2ecf20Sopenharmony_ci						    (RREG32_PLL
30718c2ecf20Sopenharmony_ci						     (RADEON_CLK_PWRMGT_CNTL) &
30728c2ecf20Sopenharmony_ci						     RADEON_MC_BUSY))
30738c2ecf20Sopenharmony_ci							break;
30748c2ecf20Sopenharmony_ci					}
30758c2ecf20Sopenharmony_ci					break;
30768c2ecf20Sopenharmony_ci				case 9:
30778c2ecf20Sopenharmony_ci					while (val--) {
30788c2ecf20Sopenharmony_ci						if ((RREG32(RADEON_MC_STATUS) &
30798c2ecf20Sopenharmony_ci						     RADEON_MC_IDLE))
30808c2ecf20Sopenharmony_ci							break;
30818c2ecf20Sopenharmony_ci					}
30828c2ecf20Sopenharmony_ci					break;
30838c2ecf20Sopenharmony_ci				default:
30848c2ecf20Sopenharmony_ci					break;
30858c2ecf20Sopenharmony_ci				}
30868c2ecf20Sopenharmony_ci				break;
30878c2ecf20Sopenharmony_ci			default:
30888c2ecf20Sopenharmony_ci				break;
30898c2ecf20Sopenharmony_ci			}
30908c2ecf20Sopenharmony_ci		}
30918c2ecf20Sopenharmony_ci	}
30928c2ecf20Sopenharmony_ci}
30938c2ecf20Sopenharmony_ci
30948c2ecf20Sopenharmony_cistatic void combios_parse_pll_table(struct drm_device *dev, uint16_t offset)
30958c2ecf20Sopenharmony_ci{
30968c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
30978c2ecf20Sopenharmony_ci
30988c2ecf20Sopenharmony_ci	if (offset) {
30998c2ecf20Sopenharmony_ci		while (RBIOS8(offset)) {
31008c2ecf20Sopenharmony_ci			uint8_t cmd = ((RBIOS8(offset) & 0xc0) >> 6);
31018c2ecf20Sopenharmony_ci			uint8_t addr = (RBIOS8(offset) & 0x3f);
31028c2ecf20Sopenharmony_ci			uint32_t val, shift, tmp;
31038c2ecf20Sopenharmony_ci			uint32_t and_mask, or_mask;
31048c2ecf20Sopenharmony_ci
31058c2ecf20Sopenharmony_ci			offset++;
31068c2ecf20Sopenharmony_ci			switch (cmd) {
31078c2ecf20Sopenharmony_ci			case 0:
31088c2ecf20Sopenharmony_ci				val = RBIOS32(offset);
31098c2ecf20Sopenharmony_ci				offset += 4;
31108c2ecf20Sopenharmony_ci				WREG32_PLL(addr, val);
31118c2ecf20Sopenharmony_ci				break;
31128c2ecf20Sopenharmony_ci			case 1:
31138c2ecf20Sopenharmony_ci				shift = RBIOS8(offset) * 8;
31148c2ecf20Sopenharmony_ci				offset++;
31158c2ecf20Sopenharmony_ci				and_mask = RBIOS8(offset) << shift;
31168c2ecf20Sopenharmony_ci				and_mask |= ~(0xff << shift);
31178c2ecf20Sopenharmony_ci				offset++;
31188c2ecf20Sopenharmony_ci				or_mask = RBIOS8(offset) << shift;
31198c2ecf20Sopenharmony_ci				offset++;
31208c2ecf20Sopenharmony_ci				tmp = RREG32_PLL(addr);
31218c2ecf20Sopenharmony_ci				tmp &= and_mask;
31228c2ecf20Sopenharmony_ci				tmp |= or_mask;
31238c2ecf20Sopenharmony_ci				WREG32_PLL(addr, tmp);
31248c2ecf20Sopenharmony_ci				break;
31258c2ecf20Sopenharmony_ci			case 2:
31268c2ecf20Sopenharmony_ci			case 3:
31278c2ecf20Sopenharmony_ci				tmp = 1000;
31288c2ecf20Sopenharmony_ci				switch (addr) {
31298c2ecf20Sopenharmony_ci				case 1:
31308c2ecf20Sopenharmony_ci					udelay(150);
31318c2ecf20Sopenharmony_ci					break;
31328c2ecf20Sopenharmony_ci				case 2:
31338c2ecf20Sopenharmony_ci					mdelay(1);
31348c2ecf20Sopenharmony_ci					break;
31358c2ecf20Sopenharmony_ci				case 3:
31368c2ecf20Sopenharmony_ci					while (tmp--) {
31378c2ecf20Sopenharmony_ci						if (!
31388c2ecf20Sopenharmony_ci						    (RREG32_PLL
31398c2ecf20Sopenharmony_ci						     (RADEON_CLK_PWRMGT_CNTL) &
31408c2ecf20Sopenharmony_ci						     RADEON_MC_BUSY))
31418c2ecf20Sopenharmony_ci							break;
31428c2ecf20Sopenharmony_ci					}
31438c2ecf20Sopenharmony_ci					break;
31448c2ecf20Sopenharmony_ci				case 4:
31458c2ecf20Sopenharmony_ci					while (tmp--) {
31468c2ecf20Sopenharmony_ci						if (RREG32_PLL
31478c2ecf20Sopenharmony_ci						    (RADEON_CLK_PWRMGT_CNTL) &
31488c2ecf20Sopenharmony_ci						    RADEON_DLL_READY)
31498c2ecf20Sopenharmony_ci							break;
31508c2ecf20Sopenharmony_ci					}
31518c2ecf20Sopenharmony_ci					break;
31528c2ecf20Sopenharmony_ci				case 5:
31538c2ecf20Sopenharmony_ci					tmp =
31548c2ecf20Sopenharmony_ci					    RREG32_PLL(RADEON_CLK_PWRMGT_CNTL);
31558c2ecf20Sopenharmony_ci					if (tmp & RADEON_CG_NO1_DEBUG_0) {
31568c2ecf20Sopenharmony_ci#if 0
31578c2ecf20Sopenharmony_ci						uint32_t mclk_cntl =
31588c2ecf20Sopenharmony_ci						    RREG32_PLL
31598c2ecf20Sopenharmony_ci						    (RADEON_MCLK_CNTL);
31608c2ecf20Sopenharmony_ci						mclk_cntl &= 0xffff0000;
31618c2ecf20Sopenharmony_ci						/*mclk_cntl |= 0x00001111;*//* ??? */
31628c2ecf20Sopenharmony_ci						WREG32_PLL(RADEON_MCLK_CNTL,
31638c2ecf20Sopenharmony_ci							   mclk_cntl);
31648c2ecf20Sopenharmony_ci						mdelay(10);
31658c2ecf20Sopenharmony_ci#endif
31668c2ecf20Sopenharmony_ci						WREG32_PLL
31678c2ecf20Sopenharmony_ci						    (RADEON_CLK_PWRMGT_CNTL,
31688c2ecf20Sopenharmony_ci						     tmp &
31698c2ecf20Sopenharmony_ci						     ~RADEON_CG_NO1_DEBUG_0);
31708c2ecf20Sopenharmony_ci						mdelay(10);
31718c2ecf20Sopenharmony_ci					}
31728c2ecf20Sopenharmony_ci					break;
31738c2ecf20Sopenharmony_ci				default:
31748c2ecf20Sopenharmony_ci					break;
31758c2ecf20Sopenharmony_ci				}
31768c2ecf20Sopenharmony_ci				break;
31778c2ecf20Sopenharmony_ci			default:
31788c2ecf20Sopenharmony_ci				break;
31798c2ecf20Sopenharmony_ci			}
31808c2ecf20Sopenharmony_ci		}
31818c2ecf20Sopenharmony_ci	}
31828c2ecf20Sopenharmony_ci}
31838c2ecf20Sopenharmony_ci
31848c2ecf20Sopenharmony_cistatic void combios_parse_ram_reset_table(struct drm_device *dev,
31858c2ecf20Sopenharmony_ci					  uint16_t offset)
31868c2ecf20Sopenharmony_ci{
31878c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
31888c2ecf20Sopenharmony_ci	uint32_t tmp;
31898c2ecf20Sopenharmony_ci
31908c2ecf20Sopenharmony_ci	if (offset) {
31918c2ecf20Sopenharmony_ci		uint8_t val = RBIOS8(offset);
31928c2ecf20Sopenharmony_ci		while (val != 0xff) {
31938c2ecf20Sopenharmony_ci			offset++;
31948c2ecf20Sopenharmony_ci
31958c2ecf20Sopenharmony_ci			if (val == 0x0f) {
31968c2ecf20Sopenharmony_ci				uint32_t channel_complete_mask;
31978c2ecf20Sopenharmony_ci
31988c2ecf20Sopenharmony_ci				if (ASIC_IS_R300(rdev))
31998c2ecf20Sopenharmony_ci					channel_complete_mask =
32008c2ecf20Sopenharmony_ci					    R300_MEM_PWRUP_COMPLETE;
32018c2ecf20Sopenharmony_ci				else
32028c2ecf20Sopenharmony_ci					channel_complete_mask =
32038c2ecf20Sopenharmony_ci					    RADEON_MEM_PWRUP_COMPLETE;
32048c2ecf20Sopenharmony_ci				tmp = 20000;
32058c2ecf20Sopenharmony_ci				while (tmp--) {
32068c2ecf20Sopenharmony_ci					if ((RREG32(RADEON_MEM_STR_CNTL) &
32078c2ecf20Sopenharmony_ci					     channel_complete_mask) ==
32088c2ecf20Sopenharmony_ci					    channel_complete_mask)
32098c2ecf20Sopenharmony_ci						break;
32108c2ecf20Sopenharmony_ci				}
32118c2ecf20Sopenharmony_ci			} else {
32128c2ecf20Sopenharmony_ci				uint32_t or_mask = RBIOS16(offset);
32138c2ecf20Sopenharmony_ci				offset += 2;
32148c2ecf20Sopenharmony_ci
32158c2ecf20Sopenharmony_ci				tmp = RREG32(RADEON_MEM_SDRAM_MODE_REG);
32168c2ecf20Sopenharmony_ci				tmp &= RADEON_SDRAM_MODE_MASK;
32178c2ecf20Sopenharmony_ci				tmp |= or_mask;
32188c2ecf20Sopenharmony_ci				WREG32(RADEON_MEM_SDRAM_MODE_REG, tmp);
32198c2ecf20Sopenharmony_ci
32208c2ecf20Sopenharmony_ci				or_mask = val << 24;
32218c2ecf20Sopenharmony_ci				tmp = RREG32(RADEON_MEM_SDRAM_MODE_REG);
32228c2ecf20Sopenharmony_ci				tmp &= RADEON_B3MEM_RESET_MASK;
32238c2ecf20Sopenharmony_ci				tmp |= or_mask;
32248c2ecf20Sopenharmony_ci				WREG32(RADEON_MEM_SDRAM_MODE_REG, tmp);
32258c2ecf20Sopenharmony_ci			}
32268c2ecf20Sopenharmony_ci			val = RBIOS8(offset);
32278c2ecf20Sopenharmony_ci		}
32288c2ecf20Sopenharmony_ci	}
32298c2ecf20Sopenharmony_ci}
32308c2ecf20Sopenharmony_ci
32318c2ecf20Sopenharmony_cistatic uint32_t combios_detect_ram(struct drm_device *dev, int ram,
32328c2ecf20Sopenharmony_ci				   int mem_addr_mapping)
32338c2ecf20Sopenharmony_ci{
32348c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
32358c2ecf20Sopenharmony_ci	uint32_t mem_cntl;
32368c2ecf20Sopenharmony_ci	uint32_t mem_size;
32378c2ecf20Sopenharmony_ci	uint32_t addr = 0;
32388c2ecf20Sopenharmony_ci
32398c2ecf20Sopenharmony_ci	mem_cntl = RREG32(RADEON_MEM_CNTL);
32408c2ecf20Sopenharmony_ci	if (mem_cntl & RV100_HALF_MODE)
32418c2ecf20Sopenharmony_ci		ram /= 2;
32428c2ecf20Sopenharmony_ci	mem_size = ram;
32438c2ecf20Sopenharmony_ci	mem_cntl &= ~(0xff << 8);
32448c2ecf20Sopenharmony_ci	mem_cntl |= (mem_addr_mapping & 0xff) << 8;
32458c2ecf20Sopenharmony_ci	WREG32(RADEON_MEM_CNTL, mem_cntl);
32468c2ecf20Sopenharmony_ci	RREG32(RADEON_MEM_CNTL);
32478c2ecf20Sopenharmony_ci
32488c2ecf20Sopenharmony_ci	/* sdram reset ? */
32498c2ecf20Sopenharmony_ci
32508c2ecf20Sopenharmony_ci	/* something like this????  */
32518c2ecf20Sopenharmony_ci	while (ram--) {
32528c2ecf20Sopenharmony_ci		addr = ram * 1024 * 1024;
32538c2ecf20Sopenharmony_ci		/* write to each page */
32548c2ecf20Sopenharmony_ci		WREG32_IDX((addr) | RADEON_MM_APER, 0xdeadbeef);
32558c2ecf20Sopenharmony_ci		/* read back and verify */
32568c2ecf20Sopenharmony_ci		if (RREG32_IDX((addr) | RADEON_MM_APER) != 0xdeadbeef)
32578c2ecf20Sopenharmony_ci			return 0;
32588c2ecf20Sopenharmony_ci	}
32598c2ecf20Sopenharmony_ci
32608c2ecf20Sopenharmony_ci	return mem_size;
32618c2ecf20Sopenharmony_ci}
32628c2ecf20Sopenharmony_ci
32638c2ecf20Sopenharmony_cistatic void combios_write_ram_size(struct drm_device *dev)
32648c2ecf20Sopenharmony_ci{
32658c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
32668c2ecf20Sopenharmony_ci	uint8_t rev;
32678c2ecf20Sopenharmony_ci	uint16_t offset;
32688c2ecf20Sopenharmony_ci	uint32_t mem_size = 0;
32698c2ecf20Sopenharmony_ci	uint32_t mem_cntl = 0;
32708c2ecf20Sopenharmony_ci
32718c2ecf20Sopenharmony_ci	/* should do something smarter here I guess... */
32728c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP)
32738c2ecf20Sopenharmony_ci		return;
32748c2ecf20Sopenharmony_ci
32758c2ecf20Sopenharmony_ci	/* first check detected mem table */
32768c2ecf20Sopenharmony_ci	offset = combios_get_table_offset(dev, COMBIOS_DETECTED_MEM_TABLE);
32778c2ecf20Sopenharmony_ci	if (offset) {
32788c2ecf20Sopenharmony_ci		rev = RBIOS8(offset);
32798c2ecf20Sopenharmony_ci		if (rev < 3) {
32808c2ecf20Sopenharmony_ci			mem_cntl = RBIOS32(offset + 1);
32818c2ecf20Sopenharmony_ci			mem_size = RBIOS16(offset + 5);
32828c2ecf20Sopenharmony_ci			if ((rdev->family < CHIP_R200) &&
32838c2ecf20Sopenharmony_ci			    !ASIC_IS_RN50(rdev))
32848c2ecf20Sopenharmony_ci				WREG32(RADEON_MEM_CNTL, mem_cntl);
32858c2ecf20Sopenharmony_ci		}
32868c2ecf20Sopenharmony_ci	}
32878c2ecf20Sopenharmony_ci
32888c2ecf20Sopenharmony_ci	if (!mem_size) {
32898c2ecf20Sopenharmony_ci		offset =
32908c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE);
32918c2ecf20Sopenharmony_ci		if (offset) {
32928c2ecf20Sopenharmony_ci			rev = RBIOS8(offset - 1);
32938c2ecf20Sopenharmony_ci			if (rev < 1) {
32948c2ecf20Sopenharmony_ci				if ((rdev->family < CHIP_R200)
32958c2ecf20Sopenharmony_ci				    && !ASIC_IS_RN50(rdev)) {
32968c2ecf20Sopenharmony_ci					int ram = 0;
32978c2ecf20Sopenharmony_ci					int mem_addr_mapping = 0;
32988c2ecf20Sopenharmony_ci
32998c2ecf20Sopenharmony_ci					while (RBIOS8(offset)) {
33008c2ecf20Sopenharmony_ci						ram = RBIOS8(offset);
33018c2ecf20Sopenharmony_ci						mem_addr_mapping =
33028c2ecf20Sopenharmony_ci						    RBIOS8(offset + 1);
33038c2ecf20Sopenharmony_ci						if (mem_addr_mapping != 0x25)
33048c2ecf20Sopenharmony_ci							ram *= 2;
33058c2ecf20Sopenharmony_ci						mem_size =
33068c2ecf20Sopenharmony_ci						    combios_detect_ram(dev, ram,
33078c2ecf20Sopenharmony_ci								       mem_addr_mapping);
33088c2ecf20Sopenharmony_ci						if (mem_size)
33098c2ecf20Sopenharmony_ci							break;
33108c2ecf20Sopenharmony_ci						offset += 2;
33118c2ecf20Sopenharmony_ci					}
33128c2ecf20Sopenharmony_ci				} else
33138c2ecf20Sopenharmony_ci					mem_size = RBIOS8(offset);
33148c2ecf20Sopenharmony_ci			} else {
33158c2ecf20Sopenharmony_ci				mem_size = RBIOS8(offset);
33168c2ecf20Sopenharmony_ci				mem_size *= 2;	/* convert to MB */
33178c2ecf20Sopenharmony_ci			}
33188c2ecf20Sopenharmony_ci		}
33198c2ecf20Sopenharmony_ci	}
33208c2ecf20Sopenharmony_ci
33218c2ecf20Sopenharmony_ci	mem_size *= (1024 * 1024);	/* convert to bytes */
33228c2ecf20Sopenharmony_ci	WREG32(RADEON_CONFIG_MEMSIZE, mem_size);
33238c2ecf20Sopenharmony_ci}
33248c2ecf20Sopenharmony_ci
33258c2ecf20Sopenharmony_civoid radeon_combios_asic_init(struct drm_device *dev)
33268c2ecf20Sopenharmony_ci{
33278c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
33288c2ecf20Sopenharmony_ci	uint16_t table;
33298c2ecf20Sopenharmony_ci
33308c2ecf20Sopenharmony_ci	/* port hardcoded mac stuff from radeonfb */
33318c2ecf20Sopenharmony_ci	if (rdev->bios == NULL)
33328c2ecf20Sopenharmony_ci		return;
33338c2ecf20Sopenharmony_ci
33348c2ecf20Sopenharmony_ci	/* ASIC INIT 1 */
33358c2ecf20Sopenharmony_ci	table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_1_TABLE);
33368c2ecf20Sopenharmony_ci	if (table)
33378c2ecf20Sopenharmony_ci		combios_parse_mmio_table(dev, table);
33388c2ecf20Sopenharmony_ci
33398c2ecf20Sopenharmony_ci	/* PLL INIT */
33408c2ecf20Sopenharmony_ci	table = combios_get_table_offset(dev, COMBIOS_PLL_INIT_TABLE);
33418c2ecf20Sopenharmony_ci	if (table)
33428c2ecf20Sopenharmony_ci		combios_parse_pll_table(dev, table);
33438c2ecf20Sopenharmony_ci
33448c2ecf20Sopenharmony_ci	/* ASIC INIT 2 */
33458c2ecf20Sopenharmony_ci	table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_2_TABLE);
33468c2ecf20Sopenharmony_ci	if (table)
33478c2ecf20Sopenharmony_ci		combios_parse_mmio_table(dev, table);
33488c2ecf20Sopenharmony_ci
33498c2ecf20Sopenharmony_ci	if (!(rdev->flags & RADEON_IS_IGP)) {
33508c2ecf20Sopenharmony_ci		/* ASIC INIT 4 */
33518c2ecf20Sopenharmony_ci		table =
33528c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_ASIC_INIT_4_TABLE);
33538c2ecf20Sopenharmony_ci		if (table)
33548c2ecf20Sopenharmony_ci			combios_parse_mmio_table(dev, table);
33558c2ecf20Sopenharmony_ci
33568c2ecf20Sopenharmony_ci		/* RAM RESET */
33578c2ecf20Sopenharmony_ci		table = combios_get_table_offset(dev, COMBIOS_RAM_RESET_TABLE);
33588c2ecf20Sopenharmony_ci		if (table)
33598c2ecf20Sopenharmony_ci			combios_parse_ram_reset_table(dev, table);
33608c2ecf20Sopenharmony_ci
33618c2ecf20Sopenharmony_ci		/* ASIC INIT 3 */
33628c2ecf20Sopenharmony_ci		table =
33638c2ecf20Sopenharmony_ci		    combios_get_table_offset(dev, COMBIOS_ASIC_INIT_3_TABLE);
33648c2ecf20Sopenharmony_ci		if (table)
33658c2ecf20Sopenharmony_ci			combios_parse_mmio_table(dev, table);
33668c2ecf20Sopenharmony_ci
33678c2ecf20Sopenharmony_ci		/* write CONFIG_MEMSIZE */
33688c2ecf20Sopenharmony_ci		combios_write_ram_size(dev);
33698c2ecf20Sopenharmony_ci	}
33708c2ecf20Sopenharmony_ci
33718c2ecf20Sopenharmony_ci	/* quirk for rs4xx HP nx6125 laptop to make it resume
33728c2ecf20Sopenharmony_ci	 * - it hangs on resume inside the dynclk 1 table.
33738c2ecf20Sopenharmony_ci	 */
33748c2ecf20Sopenharmony_ci	if (rdev->family == CHIP_RS480 &&
33758c2ecf20Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x103c &&
33768c2ecf20Sopenharmony_ci	    rdev->pdev->subsystem_device == 0x308b)
33778c2ecf20Sopenharmony_ci		return;
33788c2ecf20Sopenharmony_ci
33798c2ecf20Sopenharmony_ci	/* quirk for rs4xx HP dv5000 laptop to make it resume
33808c2ecf20Sopenharmony_ci	 * - it hangs on resume inside the dynclk 1 table.
33818c2ecf20Sopenharmony_ci	 */
33828c2ecf20Sopenharmony_ci	if (rdev->family == CHIP_RS480 &&
33838c2ecf20Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x103c &&
33848c2ecf20Sopenharmony_ci	    rdev->pdev->subsystem_device == 0x30a4)
33858c2ecf20Sopenharmony_ci		return;
33868c2ecf20Sopenharmony_ci
33878c2ecf20Sopenharmony_ci	/* quirk for rs4xx Compaq Presario V5245EU laptop to make it resume
33888c2ecf20Sopenharmony_ci	 * - it hangs on resume inside the dynclk 1 table.
33898c2ecf20Sopenharmony_ci	 */
33908c2ecf20Sopenharmony_ci	if (rdev->family == CHIP_RS480 &&
33918c2ecf20Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x103c &&
33928c2ecf20Sopenharmony_ci	    rdev->pdev->subsystem_device == 0x30ae)
33938c2ecf20Sopenharmony_ci		return;
33948c2ecf20Sopenharmony_ci
33958c2ecf20Sopenharmony_ci	/* quirk for rs4xx HP Compaq dc5750 Small Form Factor to make it resume
33968c2ecf20Sopenharmony_ci	 * - it hangs on resume inside the dynclk 1 table.
33978c2ecf20Sopenharmony_ci	 */
33988c2ecf20Sopenharmony_ci	if (rdev->family == CHIP_RS480 &&
33998c2ecf20Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x103c &&
34008c2ecf20Sopenharmony_ci	    rdev->pdev->subsystem_device == 0x280a)
34018c2ecf20Sopenharmony_ci		return;
34028c2ecf20Sopenharmony_ci	/* quirk for rs4xx Toshiba Sattellite L20-183 latop to make it resume
34038c2ecf20Sopenharmony_ci	 * - it hangs on resume inside the dynclk 1 table.
34048c2ecf20Sopenharmony_ci	 */
34058c2ecf20Sopenharmony_ci	if (rdev->family == CHIP_RS400 &&
34068c2ecf20Sopenharmony_ci	    rdev->pdev->subsystem_vendor == 0x1179 &&
34078c2ecf20Sopenharmony_ci	    rdev->pdev->subsystem_device == 0xff31)
34088c2ecf20Sopenharmony_ci	        return;
34098c2ecf20Sopenharmony_ci
34108c2ecf20Sopenharmony_ci	/* DYN CLK 1 */
34118c2ecf20Sopenharmony_ci	table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE);
34128c2ecf20Sopenharmony_ci	if (table)
34138c2ecf20Sopenharmony_ci		combios_parse_pll_table(dev, table);
34148c2ecf20Sopenharmony_ci
34158c2ecf20Sopenharmony_ci}
34168c2ecf20Sopenharmony_ci
34178c2ecf20Sopenharmony_civoid radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev)
34188c2ecf20Sopenharmony_ci{
34198c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
34208c2ecf20Sopenharmony_ci	uint32_t bios_0_scratch, bios_6_scratch, bios_7_scratch;
34218c2ecf20Sopenharmony_ci
34228c2ecf20Sopenharmony_ci	bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);
34238c2ecf20Sopenharmony_ci	bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
34248c2ecf20Sopenharmony_ci	bios_7_scratch = RREG32(RADEON_BIOS_7_SCRATCH);
34258c2ecf20Sopenharmony_ci
34268c2ecf20Sopenharmony_ci	/* let the bios control the backlight */
34278c2ecf20Sopenharmony_ci	bios_0_scratch &= ~RADEON_DRIVER_BRIGHTNESS_EN;
34288c2ecf20Sopenharmony_ci
34298c2ecf20Sopenharmony_ci	/* tell the bios not to handle mode switching */
34308c2ecf20Sopenharmony_ci	bios_6_scratch |= (RADEON_DISPLAY_SWITCHING_DIS |
34318c2ecf20Sopenharmony_ci			   RADEON_ACC_MODE_CHANGE);
34328c2ecf20Sopenharmony_ci
34338c2ecf20Sopenharmony_ci	/* tell the bios a driver is loaded */
34348c2ecf20Sopenharmony_ci	bios_7_scratch |= RADEON_DRV_LOADED;
34358c2ecf20Sopenharmony_ci
34368c2ecf20Sopenharmony_ci	WREG32(RADEON_BIOS_0_SCRATCH, bios_0_scratch);
34378c2ecf20Sopenharmony_ci	WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
34388c2ecf20Sopenharmony_ci	WREG32(RADEON_BIOS_7_SCRATCH, bios_7_scratch);
34398c2ecf20Sopenharmony_ci}
34408c2ecf20Sopenharmony_ci
34418c2ecf20Sopenharmony_civoid radeon_combios_output_lock(struct drm_encoder *encoder, bool lock)
34428c2ecf20Sopenharmony_ci{
34438c2ecf20Sopenharmony_ci	struct drm_device *dev = encoder->dev;
34448c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
34458c2ecf20Sopenharmony_ci	uint32_t bios_6_scratch;
34468c2ecf20Sopenharmony_ci
34478c2ecf20Sopenharmony_ci	bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
34488c2ecf20Sopenharmony_ci
34498c2ecf20Sopenharmony_ci	if (lock)
34508c2ecf20Sopenharmony_ci		bios_6_scratch |= RADEON_DRIVER_CRITICAL;
34518c2ecf20Sopenharmony_ci	else
34528c2ecf20Sopenharmony_ci		bios_6_scratch &= ~RADEON_DRIVER_CRITICAL;
34538c2ecf20Sopenharmony_ci
34548c2ecf20Sopenharmony_ci	WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
34558c2ecf20Sopenharmony_ci}
34568c2ecf20Sopenharmony_ci
34578c2ecf20Sopenharmony_civoid
34588c2ecf20Sopenharmony_ciradeon_combios_connected_scratch_regs(struct drm_connector *connector,
34598c2ecf20Sopenharmony_ci				      struct drm_encoder *encoder,
34608c2ecf20Sopenharmony_ci				      bool connected)
34618c2ecf20Sopenharmony_ci{
34628c2ecf20Sopenharmony_ci	struct drm_device *dev = connector->dev;
34638c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
34648c2ecf20Sopenharmony_ci	struct radeon_connector *radeon_connector =
34658c2ecf20Sopenharmony_ci	    to_radeon_connector(connector);
34668c2ecf20Sopenharmony_ci	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
34678c2ecf20Sopenharmony_ci	uint32_t bios_4_scratch = RREG32(RADEON_BIOS_4_SCRATCH);
34688c2ecf20Sopenharmony_ci	uint32_t bios_5_scratch = RREG32(RADEON_BIOS_5_SCRATCH);
34698c2ecf20Sopenharmony_ci
34708c2ecf20Sopenharmony_ci	if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) &&
34718c2ecf20Sopenharmony_ci	    (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) {
34728c2ecf20Sopenharmony_ci		if (connected) {
34738c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("TV1 connected\n");
34748c2ecf20Sopenharmony_ci			/* fix me */
34758c2ecf20Sopenharmony_ci			bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO;
34768c2ecf20Sopenharmony_ci			/*save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP; */
34778c2ecf20Sopenharmony_ci			bios_5_scratch |= RADEON_TV1_ON;
34788c2ecf20Sopenharmony_ci			bios_5_scratch |= RADEON_ACC_REQ_TV1;
34798c2ecf20Sopenharmony_ci		} else {
34808c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("TV1 disconnected\n");
34818c2ecf20Sopenharmony_ci			bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK;
34828c2ecf20Sopenharmony_ci			bios_5_scratch &= ~RADEON_TV1_ON;
34838c2ecf20Sopenharmony_ci			bios_5_scratch &= ~RADEON_ACC_REQ_TV1;
34848c2ecf20Sopenharmony_ci		}
34858c2ecf20Sopenharmony_ci	}
34868c2ecf20Sopenharmony_ci	if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) &&
34878c2ecf20Sopenharmony_ci	    (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) {
34888c2ecf20Sopenharmony_ci		if (connected) {
34898c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("LCD1 connected\n");
34908c2ecf20Sopenharmony_ci			bios_4_scratch |= RADEON_LCD1_ATTACHED;
34918c2ecf20Sopenharmony_ci			bios_5_scratch |= RADEON_LCD1_ON;
34928c2ecf20Sopenharmony_ci			bios_5_scratch |= RADEON_ACC_REQ_LCD1;
34938c2ecf20Sopenharmony_ci		} else {
34948c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("LCD1 disconnected\n");
34958c2ecf20Sopenharmony_ci			bios_4_scratch &= ~RADEON_LCD1_ATTACHED;
34968c2ecf20Sopenharmony_ci			bios_5_scratch &= ~RADEON_LCD1_ON;
34978c2ecf20Sopenharmony_ci			bios_5_scratch &= ~RADEON_ACC_REQ_LCD1;
34988c2ecf20Sopenharmony_ci		}
34998c2ecf20Sopenharmony_ci	}
35008c2ecf20Sopenharmony_ci	if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) &&
35018c2ecf20Sopenharmony_ci	    (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) {
35028c2ecf20Sopenharmony_ci		if (connected) {
35038c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("CRT1 connected\n");
35048c2ecf20Sopenharmony_ci			bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR;
35058c2ecf20Sopenharmony_ci			bios_5_scratch |= RADEON_CRT1_ON;
35068c2ecf20Sopenharmony_ci			bios_5_scratch |= RADEON_ACC_REQ_CRT1;
35078c2ecf20Sopenharmony_ci		} else {
35088c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("CRT1 disconnected\n");
35098c2ecf20Sopenharmony_ci			bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK;
35108c2ecf20Sopenharmony_ci			bios_5_scratch &= ~RADEON_CRT1_ON;
35118c2ecf20Sopenharmony_ci			bios_5_scratch &= ~RADEON_ACC_REQ_CRT1;
35128c2ecf20Sopenharmony_ci		}
35138c2ecf20Sopenharmony_ci	}
35148c2ecf20Sopenharmony_ci	if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) &&
35158c2ecf20Sopenharmony_ci	    (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) {
35168c2ecf20Sopenharmony_ci		if (connected) {
35178c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("CRT2 connected\n");
35188c2ecf20Sopenharmony_ci			bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR;
35198c2ecf20Sopenharmony_ci			bios_5_scratch |= RADEON_CRT2_ON;
35208c2ecf20Sopenharmony_ci			bios_5_scratch |= RADEON_ACC_REQ_CRT2;
35218c2ecf20Sopenharmony_ci		} else {
35228c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("CRT2 disconnected\n");
35238c2ecf20Sopenharmony_ci			bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK;
35248c2ecf20Sopenharmony_ci			bios_5_scratch &= ~RADEON_CRT2_ON;
35258c2ecf20Sopenharmony_ci			bios_5_scratch &= ~RADEON_ACC_REQ_CRT2;
35268c2ecf20Sopenharmony_ci		}
35278c2ecf20Sopenharmony_ci	}
35288c2ecf20Sopenharmony_ci	if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) &&
35298c2ecf20Sopenharmony_ci	    (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) {
35308c2ecf20Sopenharmony_ci		if (connected) {
35318c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("DFP1 connected\n");
35328c2ecf20Sopenharmony_ci			bios_4_scratch |= RADEON_DFP1_ATTACHED;
35338c2ecf20Sopenharmony_ci			bios_5_scratch |= RADEON_DFP1_ON;
35348c2ecf20Sopenharmony_ci			bios_5_scratch |= RADEON_ACC_REQ_DFP1;
35358c2ecf20Sopenharmony_ci		} else {
35368c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("DFP1 disconnected\n");
35378c2ecf20Sopenharmony_ci			bios_4_scratch &= ~RADEON_DFP1_ATTACHED;
35388c2ecf20Sopenharmony_ci			bios_5_scratch &= ~RADEON_DFP1_ON;
35398c2ecf20Sopenharmony_ci			bios_5_scratch &= ~RADEON_ACC_REQ_DFP1;
35408c2ecf20Sopenharmony_ci		}
35418c2ecf20Sopenharmony_ci	}
35428c2ecf20Sopenharmony_ci	if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) &&
35438c2ecf20Sopenharmony_ci	    (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) {
35448c2ecf20Sopenharmony_ci		if (connected) {
35458c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("DFP2 connected\n");
35468c2ecf20Sopenharmony_ci			bios_4_scratch |= RADEON_DFP2_ATTACHED;
35478c2ecf20Sopenharmony_ci			bios_5_scratch |= RADEON_DFP2_ON;
35488c2ecf20Sopenharmony_ci			bios_5_scratch |= RADEON_ACC_REQ_DFP2;
35498c2ecf20Sopenharmony_ci		} else {
35508c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("DFP2 disconnected\n");
35518c2ecf20Sopenharmony_ci			bios_4_scratch &= ~RADEON_DFP2_ATTACHED;
35528c2ecf20Sopenharmony_ci			bios_5_scratch &= ~RADEON_DFP2_ON;
35538c2ecf20Sopenharmony_ci			bios_5_scratch &= ~RADEON_ACC_REQ_DFP2;
35548c2ecf20Sopenharmony_ci		}
35558c2ecf20Sopenharmony_ci	}
35568c2ecf20Sopenharmony_ci	WREG32(RADEON_BIOS_4_SCRATCH, bios_4_scratch);
35578c2ecf20Sopenharmony_ci	WREG32(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
35588c2ecf20Sopenharmony_ci}
35598c2ecf20Sopenharmony_ci
35608c2ecf20Sopenharmony_civoid
35618c2ecf20Sopenharmony_ciradeon_combios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc)
35628c2ecf20Sopenharmony_ci{
35638c2ecf20Sopenharmony_ci	struct drm_device *dev = encoder->dev;
35648c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
35658c2ecf20Sopenharmony_ci	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
35668c2ecf20Sopenharmony_ci	uint32_t bios_5_scratch = RREG32(RADEON_BIOS_5_SCRATCH);
35678c2ecf20Sopenharmony_ci
35688c2ecf20Sopenharmony_ci	if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {
35698c2ecf20Sopenharmony_ci		bios_5_scratch &= ~RADEON_TV1_CRTC_MASK;
35708c2ecf20Sopenharmony_ci		bios_5_scratch |= (crtc << RADEON_TV1_CRTC_SHIFT);
35718c2ecf20Sopenharmony_ci	}
35728c2ecf20Sopenharmony_ci	if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) {
35738c2ecf20Sopenharmony_ci		bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK;
35748c2ecf20Sopenharmony_ci		bios_5_scratch |= (crtc << RADEON_CRT1_CRTC_SHIFT);
35758c2ecf20Sopenharmony_ci	}
35768c2ecf20Sopenharmony_ci	if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) {
35778c2ecf20Sopenharmony_ci		bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK;
35788c2ecf20Sopenharmony_ci		bios_5_scratch |= (crtc << RADEON_CRT2_CRTC_SHIFT);
35798c2ecf20Sopenharmony_ci	}
35808c2ecf20Sopenharmony_ci	if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) {
35818c2ecf20Sopenharmony_ci		bios_5_scratch &= ~RADEON_LCD1_CRTC_MASK;
35828c2ecf20Sopenharmony_ci		bios_5_scratch |= (crtc << RADEON_LCD1_CRTC_SHIFT);
35838c2ecf20Sopenharmony_ci	}
35848c2ecf20Sopenharmony_ci	if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) {
35858c2ecf20Sopenharmony_ci		bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK;
35868c2ecf20Sopenharmony_ci		bios_5_scratch |= (crtc << RADEON_DFP1_CRTC_SHIFT);
35878c2ecf20Sopenharmony_ci	}
35888c2ecf20Sopenharmony_ci	if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) {
35898c2ecf20Sopenharmony_ci		bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK;
35908c2ecf20Sopenharmony_ci		bios_5_scratch |= (crtc << RADEON_DFP2_CRTC_SHIFT);
35918c2ecf20Sopenharmony_ci	}
35928c2ecf20Sopenharmony_ci	WREG32(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
35938c2ecf20Sopenharmony_ci}
35948c2ecf20Sopenharmony_ci
35958c2ecf20Sopenharmony_civoid
35968c2ecf20Sopenharmony_ciradeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on)
35978c2ecf20Sopenharmony_ci{
35988c2ecf20Sopenharmony_ci	struct drm_device *dev = encoder->dev;
35998c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
36008c2ecf20Sopenharmony_ci	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
36018c2ecf20Sopenharmony_ci	uint32_t bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
36028c2ecf20Sopenharmony_ci
36038c2ecf20Sopenharmony_ci	if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) {
36048c2ecf20Sopenharmony_ci		if (on)
36058c2ecf20Sopenharmony_ci			bios_6_scratch |= RADEON_TV_DPMS_ON;
36068c2ecf20Sopenharmony_ci		else
36078c2ecf20Sopenharmony_ci			bios_6_scratch &= ~RADEON_TV_DPMS_ON;
36088c2ecf20Sopenharmony_ci	}
36098c2ecf20Sopenharmony_ci	if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
36108c2ecf20Sopenharmony_ci		if (on)
36118c2ecf20Sopenharmony_ci			bios_6_scratch |= RADEON_CRT_DPMS_ON;
36128c2ecf20Sopenharmony_ci		else
36138c2ecf20Sopenharmony_ci			bios_6_scratch &= ~RADEON_CRT_DPMS_ON;
36148c2ecf20Sopenharmony_ci	}
36158c2ecf20Sopenharmony_ci	if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
36168c2ecf20Sopenharmony_ci		if (on)
36178c2ecf20Sopenharmony_ci			bios_6_scratch |= RADEON_LCD_DPMS_ON;
36188c2ecf20Sopenharmony_ci		else
36198c2ecf20Sopenharmony_ci			bios_6_scratch &= ~RADEON_LCD_DPMS_ON;
36208c2ecf20Sopenharmony_ci	}
36218c2ecf20Sopenharmony_ci	if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
36228c2ecf20Sopenharmony_ci		if (on)
36238c2ecf20Sopenharmony_ci			bios_6_scratch |= RADEON_DFP_DPMS_ON;
36248c2ecf20Sopenharmony_ci		else
36258c2ecf20Sopenharmony_ci			bios_6_scratch &= ~RADEON_DFP_DPMS_ON;
36268c2ecf20Sopenharmony_ci	}
36278c2ecf20Sopenharmony_ci	WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
36288c2ecf20Sopenharmony_ci}
3629