brintos

brintos / linux-shallow public Read only

0
0
Text · 69.0 KiB · a51f341 Raw
2127 lines · c
1/*2 * Copyright 2007-11 Advanced Micro Devices, Inc.3 * Copyright 2008 Red Hat Inc.4 *5 * Permission is hereby granted, free of charge, to any person obtaining a6 * copy of this software and associated documentation files (the "Software"),7 * to deal in the Software without restriction, including without limitation8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,9 * and/or sell copies of the Software, and to permit persons to whom the10 * Software is furnished to do so, subject to the following conditions:11 *12 * The above copyright notice and this permission notice shall be included in13 * all copies or substantial portions of the Software.14 *15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR21 * OTHER DEALINGS IN THE SOFTWARE.22 *23 * Authors: Dave Airlie24 *          Alex Deucher25 */26 27#include <linux/pci.h>28 29#include <acpi/video.h>30 31#include <drm/drm_edid.h>32#include <drm/amdgpu_drm.h>33#include "amdgpu.h"34#include "amdgpu_connectors.h"35#include "amdgpu_display.h"36#include "atom.h"37#include "atombios_encoders.h"38#include "atombios_dp.h"39#include <linux/backlight.h>40#include "bif/bif_4_1_d.h"41 42u843amdgpu_atombios_encoder_get_backlight_level_from_reg(struct amdgpu_device *adev)44{45	u8 backlight_level;46	u32 bios_2_scratch;47 48	bios_2_scratch = RREG32(mmBIOS_SCRATCH_2);49 50	backlight_level = ((bios_2_scratch & ATOM_S2_CURRENT_BL_LEVEL_MASK) >>51			   ATOM_S2_CURRENT_BL_LEVEL_SHIFT);52 53	return backlight_level;54}55 56void57amdgpu_atombios_encoder_set_backlight_level_to_reg(struct amdgpu_device *adev,58					    u8 backlight_level)59{60	u32 bios_2_scratch;61 62	bios_2_scratch = RREG32(mmBIOS_SCRATCH_2);63 64	bios_2_scratch &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK;65	bios_2_scratch |= ((backlight_level << ATOM_S2_CURRENT_BL_LEVEL_SHIFT) &66			   ATOM_S2_CURRENT_BL_LEVEL_MASK);67 68	WREG32(mmBIOS_SCRATCH_2, bios_2_scratch);69}70 71u872amdgpu_atombios_encoder_get_backlight_level(struct amdgpu_encoder *amdgpu_encoder)73{74	struct drm_device *dev = amdgpu_encoder->base.dev;75	struct amdgpu_device *adev = drm_to_adev(dev);76 77	if (!(adev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))78		return 0;79 80	return amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);81}82 83void84amdgpu_atombios_encoder_set_backlight_level(struct amdgpu_encoder *amdgpu_encoder,85				     u8 level)86{87	struct drm_encoder *encoder = &amdgpu_encoder->base;88	struct drm_device *dev = amdgpu_encoder->base.dev;89	struct amdgpu_device *adev = drm_to_adev(dev);90	struct amdgpu_encoder_atom_dig *dig;91 92	if (!(adev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))93		return;94 95	if ((amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&96	    amdgpu_encoder->enc_priv) {97		dig = amdgpu_encoder->enc_priv;98		dig->backlight_level = level;99		amdgpu_atombios_encoder_set_backlight_level_to_reg(adev, dig->backlight_level);100 101		switch (amdgpu_encoder->encoder_id) {102		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:103		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:104		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:105		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:106		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:107			if (dig->backlight_level == 0)108				amdgpu_atombios_encoder_setup_dig_transmitter(encoder,109								       ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);110			else {111				amdgpu_atombios_encoder_setup_dig_transmitter(encoder,112								       ATOM_TRANSMITTER_ACTION_BL_BRIGHTNESS_CONTROL, 0, 0);113				amdgpu_atombios_encoder_setup_dig_transmitter(encoder,114								       ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);115			}116			break;117		default:118			break;119		}120	}121}122 123static u8 amdgpu_atombios_encoder_backlight_level(struct backlight_device *bd)124{125	u8 level;126 127	/* Convert brightness to hardware level */128	if (bd->props.brightness < 0)129		level = 0;130	else if (bd->props.brightness > AMDGPU_MAX_BL_LEVEL)131		level = AMDGPU_MAX_BL_LEVEL;132	else133		level = bd->props.brightness;134 135	return level;136}137 138static int amdgpu_atombios_encoder_update_backlight_status(struct backlight_device *bd)139{140	struct amdgpu_backlight_privdata *pdata = bl_get_data(bd);141	struct amdgpu_encoder *amdgpu_encoder = pdata->encoder;142 143	amdgpu_atombios_encoder_set_backlight_level(amdgpu_encoder,144					     amdgpu_atombios_encoder_backlight_level(bd));145 146	return 0;147}148 149static int150amdgpu_atombios_encoder_get_backlight_brightness(struct backlight_device *bd)151{152	struct amdgpu_backlight_privdata *pdata = bl_get_data(bd);153	struct amdgpu_encoder *amdgpu_encoder = pdata->encoder;154	struct drm_device *dev = amdgpu_encoder->base.dev;155	struct amdgpu_device *adev = drm_to_adev(dev);156 157	return amdgpu_atombios_encoder_get_backlight_level_from_reg(adev);158}159 160static const struct backlight_ops amdgpu_atombios_encoder_backlight_ops = {161	.get_brightness = amdgpu_atombios_encoder_get_backlight_brightness,162	.update_status	= amdgpu_atombios_encoder_update_backlight_status,163};164 165void amdgpu_atombios_encoder_init_backlight(struct amdgpu_encoder *amdgpu_encoder,166				     struct drm_connector *drm_connector)167{168	struct drm_device *dev = amdgpu_encoder->base.dev;169	struct amdgpu_device *adev = drm_to_adev(dev);170	struct backlight_device *bd;171	struct backlight_properties props;172	struct amdgpu_backlight_privdata *pdata;173	struct amdgpu_encoder_atom_dig *dig;174	char bl_name[16];175 176	/* Mac laptops with multiple GPUs use the gmux driver for backlight177	 * so don't register a backlight device178	 */179	if ((adev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) &&180	    (adev->pdev->device == 0x6741))181		return;182 183	if (!amdgpu_encoder->enc_priv)184		return;185 186	if (!(adev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))187		goto register_acpi_backlight;188 189	if (!acpi_video_backlight_use_native()) {190		drm_info(dev, "Skipping amdgpu atom DIG backlight registration\n");191		goto register_acpi_backlight;192	}193 194	pdata = kmalloc(sizeof(struct amdgpu_backlight_privdata), GFP_KERNEL);195	if (!pdata) {196		DRM_ERROR("Memory allocation failed\n");197		goto error;198	}199 200	memset(&props, 0, sizeof(props));201	props.max_brightness = AMDGPU_MAX_BL_LEVEL;202	props.type = BACKLIGHT_RAW;203	snprintf(bl_name, sizeof(bl_name),204		 "amdgpu_bl%d", dev->primary->index);205	bd = backlight_device_register(bl_name, drm_connector->kdev,206				       pdata, &amdgpu_atombios_encoder_backlight_ops, &props);207	if (IS_ERR(bd)) {208		DRM_ERROR("Backlight registration failed\n");209		goto error;210	}211 212	pdata->encoder = amdgpu_encoder;213 214	dig = amdgpu_encoder->enc_priv;215	dig->bl_dev = bd;216 217	bd->props.brightness = amdgpu_atombios_encoder_get_backlight_brightness(bd);218	bd->props.power = BACKLIGHT_POWER_ON;219	backlight_update_status(bd);220 221	DRM_INFO("amdgpu atom DIG backlight initialized\n");222 223	return;224 225error:226	kfree(pdata);227	return;228 229register_acpi_backlight:230	/* Try registering an ACPI video backlight device instead. */231	acpi_video_register_backlight();232}233 234void235amdgpu_atombios_encoder_fini_backlight(struct amdgpu_encoder *amdgpu_encoder)236{237	struct drm_device *dev = amdgpu_encoder->base.dev;238	struct amdgpu_device *adev = drm_to_adev(dev);239	struct backlight_device *bd = NULL;240	struct amdgpu_encoder_atom_dig *dig;241 242	if (!amdgpu_encoder->enc_priv)243		return;244 245	if (!(adev->mode_info.firmware_flags & ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))246		return;247 248	dig = amdgpu_encoder->enc_priv;249	bd = dig->bl_dev;250	dig->bl_dev = NULL;251 252	if (bd) {253		struct amdgpu_legacy_backlight_privdata *pdata;254 255		pdata = bl_get_data(bd);256		backlight_device_unregister(bd);257		kfree(pdata);258 259		DRM_INFO("amdgpu atom LVDS backlight unloaded\n");260	}261}262 263bool amdgpu_atombios_encoder_is_digital(struct drm_encoder *encoder)264{265	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);266	switch (amdgpu_encoder->encoder_id) {267	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:268	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:269	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:270	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:271	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:272		return true;273	default:274		return false;275	}276}277 278bool amdgpu_atombios_encoder_mode_fixup(struct drm_encoder *encoder,279				 const struct drm_display_mode *mode,280				 struct drm_display_mode *adjusted_mode)281{282	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);283 284	/* set the active encoder to connector routing */285	amdgpu_encoder_set_active_device(encoder);286	drm_mode_set_crtcinfo(adjusted_mode, 0);287 288	/* hw bug */289	if ((mode->flags & DRM_MODE_FLAG_INTERLACE)290	    && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))291		adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;292 293	/* vertical FP must be at least 1 */294	if (mode->crtc_vsync_start == mode->crtc_vdisplay)295		adjusted_mode->crtc_vsync_start++;296 297	/* get the native mode for scaling */298	if (amdgpu_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))299		amdgpu_panel_mode_fixup(encoder, adjusted_mode);300	else if (amdgpu_encoder->rmx_type != RMX_OFF)301		amdgpu_panel_mode_fixup(encoder, adjusted_mode);302 303	if ((amdgpu_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) ||304	    (amdgpu_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {305		struct drm_connector *connector = amdgpu_get_connector_for_encoder(encoder);306		amdgpu_atombios_dp_set_link_config(connector, adjusted_mode);307	}308 309	return true;310}311 312static void313amdgpu_atombios_encoder_setup_dac(struct drm_encoder *encoder, int action)314{315	struct drm_device *dev = encoder->dev;316	struct amdgpu_device *adev = drm_to_adev(dev);317	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);318	DAC_ENCODER_CONTROL_PS_ALLOCATION args;319	int index = 0;320 321	memset(&args, 0, sizeof(args));322 323	switch (amdgpu_encoder->encoder_id) {324	case ENCODER_OBJECT_ID_INTERNAL_DAC1:325	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:326		index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);327		break;328	case ENCODER_OBJECT_ID_INTERNAL_DAC2:329	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:330		index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);331		break;332	}333 334	args.ucAction = action;335	args.ucDacStandard = ATOM_DAC1_PS2;336	args.usPixelClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);337 338	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));339 340}341 342static u8 amdgpu_atombios_encoder_get_bpc(struct drm_encoder *encoder)343{344	int bpc = 8;345 346	if (encoder->crtc) {347		struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(encoder->crtc);348		bpc = amdgpu_crtc->bpc;349	}350 351	switch (bpc) {352	case 0:353		return PANEL_BPC_UNDEFINE;354	case 6:355		return PANEL_6BIT_PER_COLOR;356	case 8:357	default:358		return PANEL_8BIT_PER_COLOR;359	case 10:360		return PANEL_10BIT_PER_COLOR;361	case 12:362		return PANEL_12BIT_PER_COLOR;363	case 16:364		return PANEL_16BIT_PER_COLOR;365	}366}367 368union dvo_encoder_control {369	ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds;370	DVO_ENCODER_CONTROL_PS_ALLOCATION dvo;371	DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3;372	DVO_ENCODER_CONTROL_PS_ALLOCATION_V1_4 dvo_v4;373};374 375static void376amdgpu_atombios_encoder_setup_dvo(struct drm_encoder *encoder, int action)377{378	struct drm_device *dev = encoder->dev;379	struct amdgpu_device *adev = drm_to_adev(dev);380	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);381	union dvo_encoder_control args;382	int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);383	uint8_t frev, crev;384 385	memset(&args, 0, sizeof(args));386 387	if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))388		return;389 390	switch (frev) {391	case 1:392		switch (crev) {393		case 1:394			/* R4xx, R5xx */395			args.ext_tmds.sXTmdsEncoder.ucEnable = action;396 397			if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))398				args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL;399 400			args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB;401			break;402		case 2:403			/* RS600/690/740 */404			args.dvo.sDVOEncoder.ucAction = action;405			args.dvo.sDVOEncoder.usPixelClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);406			/* DFP1, CRT1, TV1 depending on the type of port */407			args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX;408 409			if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))410				args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL;411			break;412		case 3:413			/* R6xx */414			args.dvo_v3.ucAction = action;415			args.dvo_v3.usPixelClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);416			args.dvo_v3.ucDVOConfig = 0; /* XXX */417			break;418		case 4:419			/* DCE8 */420			args.dvo_v4.ucAction = action;421			args.dvo_v4.usPixelClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);422			args.dvo_v4.ucDVOConfig = 0; /* XXX */423			args.dvo_v4.ucBitPerColor = amdgpu_atombios_encoder_get_bpc(encoder);424			break;425		default:426			DRM_ERROR("Unknown table version %d, %d\n", frev, crev);427			break;428		}429		break;430	default:431		DRM_ERROR("Unknown table version %d, %d\n", frev, crev);432		break;433	}434 435	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));436}437 438int amdgpu_atombios_encoder_get_encoder_mode(struct drm_encoder *encoder)439{440	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);441	struct drm_connector *connector;442	struct amdgpu_connector *amdgpu_connector;443	struct amdgpu_connector_atom_dig *dig_connector;444 445	/* dp bridges are always DP */446	if (amdgpu_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)447		return ATOM_ENCODER_MODE_DP;448 449	/* DVO is always DVO */450	if ((amdgpu_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DVO1) ||451	    (amdgpu_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1))452		return ATOM_ENCODER_MODE_DVO;453 454	connector = amdgpu_get_connector_for_encoder(encoder);455	/* if we don't have an active device yet, just use one of456	 * the connectors tied to the encoder.457	 */458	if (!connector)459		connector = amdgpu_get_connector_for_encoder_init(encoder);460	amdgpu_connector = to_amdgpu_connector(connector);461 462	switch (connector->connector_type) {463	case DRM_MODE_CONNECTOR_DVII:464	case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */465		if (amdgpu_audio != 0) {466			if (amdgpu_connector->use_digital &&467			    (amdgpu_connector->audio == AMDGPU_AUDIO_ENABLE))468				return ATOM_ENCODER_MODE_HDMI;469			else if (connector->display_info.is_hdmi &&470				 (amdgpu_connector->audio == AMDGPU_AUDIO_AUTO))471				return ATOM_ENCODER_MODE_HDMI;472			else if (amdgpu_connector->use_digital)473				return ATOM_ENCODER_MODE_DVI;474			else475				return ATOM_ENCODER_MODE_CRT;476		} else if (amdgpu_connector->use_digital) {477			return ATOM_ENCODER_MODE_DVI;478		} else {479			return ATOM_ENCODER_MODE_CRT;480		}481		break;482	case DRM_MODE_CONNECTOR_DVID:483	case DRM_MODE_CONNECTOR_HDMIA:484	default:485		if (amdgpu_audio != 0) {486			if (amdgpu_connector->audio == AMDGPU_AUDIO_ENABLE)487				return ATOM_ENCODER_MODE_HDMI;488			else if (connector->display_info.is_hdmi &&489				 (amdgpu_connector->audio == AMDGPU_AUDIO_AUTO))490				return ATOM_ENCODER_MODE_HDMI;491			else492				return ATOM_ENCODER_MODE_DVI;493		} else {494			return ATOM_ENCODER_MODE_DVI;495		}496	case DRM_MODE_CONNECTOR_LVDS:497		return ATOM_ENCODER_MODE_LVDS;498	case DRM_MODE_CONNECTOR_DisplayPort:499		dig_connector = amdgpu_connector->con_priv;500		if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||501		    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {502			return ATOM_ENCODER_MODE_DP;503		} else if (amdgpu_audio != 0) {504			if (amdgpu_connector->audio == AMDGPU_AUDIO_ENABLE)505				return ATOM_ENCODER_MODE_HDMI;506			else if (connector->display_info.is_hdmi &&507				 (amdgpu_connector->audio == AMDGPU_AUDIO_AUTO))508				return ATOM_ENCODER_MODE_HDMI;509			else510				return ATOM_ENCODER_MODE_DVI;511		} else {512			return ATOM_ENCODER_MODE_DVI;513		}514	case DRM_MODE_CONNECTOR_eDP:515		return ATOM_ENCODER_MODE_DP;516	case DRM_MODE_CONNECTOR_DVIA:517	case DRM_MODE_CONNECTOR_VGA:518		return ATOM_ENCODER_MODE_CRT;519	case DRM_MODE_CONNECTOR_Composite:520	case DRM_MODE_CONNECTOR_SVIDEO:521	case DRM_MODE_CONNECTOR_9PinDIN:522		/* fix me */523		return ATOM_ENCODER_MODE_TV;524	}525}526 527/*528 * DIG Encoder/Transmitter Setup529 *530 * DCE 6.0531 * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B).532 * Supports up to 6 digital outputs533 * - 6 DIG encoder blocks.534 * - DIG to PHY mapping is hardcoded535 * DIG1 drives UNIPHY0 link A, A+B536 * DIG2 drives UNIPHY0 link B537 * DIG3 drives UNIPHY1 link A, A+B538 * DIG4 drives UNIPHY1 link B539 * DIG5 drives UNIPHY2 link A, A+B540 * DIG6 drives UNIPHY2 link B541 *542 * Routing543 * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)544 * Examples:545 * crtc0 -> dig2 -> LVTMA   links A+B -> TMDS/HDMI546 * crtc1 -> dig1 -> UNIPHY0 link  B   -> DP547 * crtc0 -> dig1 -> UNIPHY2 link  A   -> LVDS548 * crtc1 -> dig2 -> UNIPHY1 link  B+A -> TMDS/HDMI549 */550 551union dig_encoder_control {552	DIG_ENCODER_CONTROL_PS_ALLOCATION v1;553	DIG_ENCODER_CONTROL_PARAMETERS_V2 v2;554	DIG_ENCODER_CONTROL_PARAMETERS_V3 v3;555	DIG_ENCODER_CONTROL_PARAMETERS_V4 v4;556	DIG_ENCODER_CONTROL_PARAMETERS_V5 v5;557};558 559void560amdgpu_atombios_encoder_setup_dig_encoder(struct drm_encoder *encoder,561				   int action, int panel_mode)562{563	struct drm_device *dev = encoder->dev;564	struct amdgpu_device *adev = drm_to_adev(dev);565	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);566	struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;567	struct drm_connector *connector = amdgpu_get_connector_for_encoder(encoder);568	union dig_encoder_control args;569	int index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl);570	uint8_t frev, crev;571	int dp_clock = 0;572	int dp_lane_count = 0;573	int hpd_id = AMDGPU_HPD_NONE;574 575	if (connector) {576		struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);577		struct amdgpu_connector_atom_dig *dig_connector =578			amdgpu_connector->con_priv;579 580		dp_clock = dig_connector->dp_clock;581		dp_lane_count = dig_connector->dp_lane_count;582		hpd_id = amdgpu_connector->hpd.hpd;583	}584 585	/* no dig encoder assigned */586	if (dig->dig_encoder == -1)587		return;588 589	memset(&args, 0, sizeof(args));590 591	if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))592		return;593 594	switch (frev) {595	case 1:596		switch (crev) {597		case 1:598			args.v1.ucAction = action;599			args.v1.usPixelClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);600			if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)601				args.v3.ucPanelMode = panel_mode;602			else603				args.v1.ucEncoderMode = amdgpu_atombios_encoder_get_encoder_mode(encoder);604 605			if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))606				args.v1.ucLaneNum = dp_lane_count;607			else if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))608				args.v1.ucLaneNum = 8;609			else610				args.v1.ucLaneNum = 4;611 612			if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000))613				args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;614			switch (amdgpu_encoder->encoder_id) {615			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:616				args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;617				break;618			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:619			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:620				args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;621				break;622			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:623				args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;624				break;625			}626			if (dig->linkb)627				args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;628			else629				args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;630			break;631		case 2:632		case 3:633			args.v3.ucAction = action;634			args.v3.usPixelClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);635			if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)636				args.v3.ucPanelMode = panel_mode;637			else638				args.v3.ucEncoderMode = amdgpu_atombios_encoder_get_encoder_mode(encoder);639 640			if (ENCODER_MODE_IS_DP(args.v3.ucEncoderMode))641				args.v3.ucLaneNum = dp_lane_count;642			else if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))643				args.v3.ucLaneNum = 8;644			else645				args.v3.ucLaneNum = 4;646 647			if (ENCODER_MODE_IS_DP(args.v3.ucEncoderMode) && (dp_clock == 270000))648				args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;649			args.v3.acConfig.ucDigSel = dig->dig_encoder;650			args.v3.ucBitPerColor = amdgpu_atombios_encoder_get_bpc(encoder);651			break;652		case 4:653			args.v4.ucAction = action;654			args.v4.usPixelClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);655			if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)656				args.v4.ucPanelMode = panel_mode;657			else658				args.v4.ucEncoderMode = amdgpu_atombios_encoder_get_encoder_mode(encoder);659 660			if (ENCODER_MODE_IS_DP(args.v4.ucEncoderMode))661				args.v4.ucLaneNum = dp_lane_count;662			else if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))663				args.v4.ucLaneNum = 8;664			else665				args.v4.ucLaneNum = 4;666 667			if (ENCODER_MODE_IS_DP(args.v4.ucEncoderMode)) {668				if (dp_clock == 540000)669					args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ;670				else if (dp_clock == 324000)671					args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_3_24GHZ;672				else if (dp_clock == 270000)673					args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ;674				else675					args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_1_62GHZ;676			}677			args.v4.acConfig.ucDigSel = dig->dig_encoder;678			args.v4.ucBitPerColor = amdgpu_atombios_encoder_get_bpc(encoder);679			if (hpd_id == AMDGPU_HPD_NONE)680				args.v4.ucHPD_ID = 0;681			else682				args.v4.ucHPD_ID = hpd_id + 1;683			break;684		case 5:685			switch (action) {686			case ATOM_ENCODER_CMD_SETUP_PANEL_MODE:687				args.v5.asDPPanelModeParam.ucAction = action;688				args.v5.asDPPanelModeParam.ucPanelMode = panel_mode;689				args.v5.asDPPanelModeParam.ucDigId = dig->dig_encoder;690				break;691			case ATOM_ENCODER_CMD_STREAM_SETUP:692				args.v5.asStreamParam.ucAction = action;693				args.v5.asStreamParam.ucDigId = dig->dig_encoder;694				args.v5.asStreamParam.ucDigMode =695					amdgpu_atombios_encoder_get_encoder_mode(encoder);696				if (ENCODER_MODE_IS_DP(args.v5.asStreamParam.ucDigMode))697					args.v5.asStreamParam.ucLaneNum = dp_lane_count;698				else if (amdgpu_dig_monitor_is_duallink(encoder,699									amdgpu_encoder->pixel_clock))700					args.v5.asStreamParam.ucLaneNum = 8;701				else702					args.v5.asStreamParam.ucLaneNum = 4;703				args.v5.asStreamParam.ulPixelClock =704					cpu_to_le32(amdgpu_encoder->pixel_clock / 10);705				args.v5.asStreamParam.ucBitPerColor =706					amdgpu_atombios_encoder_get_bpc(encoder);707				args.v5.asStreamParam.ucLinkRateIn270Mhz = dp_clock / 27000;708				break;709			case ATOM_ENCODER_CMD_DP_LINK_TRAINING_START:710			case ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1:711			case ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2:712			case ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN3:713			case ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN4:714			case ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE:715			case ATOM_ENCODER_CMD_DP_VIDEO_OFF:716			case ATOM_ENCODER_CMD_DP_VIDEO_ON:717				args.v5.asCmdParam.ucAction = action;718				args.v5.asCmdParam.ucDigId = dig->dig_encoder;719				break;720			default:721				DRM_ERROR("Unsupported action 0x%x\n", action);722				break;723			}724			break;725		default:726			DRM_ERROR("Unknown table version %d, %d\n", frev, crev);727			break;728		}729		break;730	default:731		DRM_ERROR("Unknown table version %d, %d\n", frev, crev);732		break;733	}734 735	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));736 737}738 739union dig_transmitter_control {740	DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1;741	DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;742	DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3;743	DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4;744	DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 v5;745	DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_6 v6;746};747 748void749amdgpu_atombios_encoder_setup_dig_transmitter(struct drm_encoder *encoder, int action,750					      uint8_t lane_num, uint8_t lane_set)751{752	struct drm_device *dev = encoder->dev;753	struct amdgpu_device *adev = drm_to_adev(dev);754	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);755	struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;756	struct drm_connector *connector;757	union dig_transmitter_control args;758	int index = 0;759	uint8_t frev, crev;760	bool is_dp = false;761	int pll_id = 0;762	int dp_clock = 0;763	int dp_lane_count = 0;764	int connector_object_id = 0;765	int dig_encoder = dig->dig_encoder;766	int hpd_id = AMDGPU_HPD_NONE;767 768	if (action == ATOM_TRANSMITTER_ACTION_INIT) {769		connector = amdgpu_get_connector_for_encoder_init(encoder);770		/* just needed to avoid bailing in the encoder check.  the encoder771		 * isn't used for init772		 */773		dig_encoder = 0;774	} else775		connector = amdgpu_get_connector_for_encoder(encoder);776 777	if (connector) {778		struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);779		struct amdgpu_connector_atom_dig *dig_connector =780			amdgpu_connector->con_priv;781 782		hpd_id = amdgpu_connector->hpd.hpd;783		dp_clock = dig_connector->dp_clock;784		dp_lane_count = dig_connector->dp_lane_count;785		connector_object_id =786			(amdgpu_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;787	}788 789	if (encoder->crtc) {790		struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(encoder->crtc);791		pll_id = amdgpu_crtc->pll_id;792	}793 794	/* no dig encoder assigned */795	if (dig_encoder == -1)796		return;797 798	if (ENCODER_MODE_IS_DP(amdgpu_atombios_encoder_get_encoder_mode(encoder)))799		is_dp = true;800 801	memset(&args, 0, sizeof(args));802 803	switch (amdgpu_encoder->encoder_id) {804	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:805		index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);806		break;807	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:808	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:809	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:810	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:811		index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);812		break;813	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:814		index = GetIndexIntoMasterTable(COMMAND, LVTMATransmitterControl);815		break;816	}817 818	if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))819		return;820 821	switch (frev) {822	case 1:823		switch (crev) {824		case 1:825			args.v1.ucAction = action;826			if (action == ATOM_TRANSMITTER_ACTION_INIT) {827				args.v1.usInitInfo = cpu_to_le16(connector_object_id);828			} else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {829				args.v1.asMode.ucLaneSel = lane_num;830				args.v1.asMode.ucLaneSet = lane_set;831			} else {832				if (is_dp)833					args.v1.usPixelClock = cpu_to_le16(dp_clock / 10);834				else if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))835					args.v1.usPixelClock = cpu_to_le16((amdgpu_encoder->pixel_clock / 2) / 10);836				else837					args.v1.usPixelClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);838			}839 840			args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;841 842			if (dig_encoder)843				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;844			else845				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;846 847			if (dig->linkb)848				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;849			else850				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;851 852			if (is_dp)853				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;854			else if (amdgpu_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {855				if (dig->coherent_mode)856					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;857				if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))858					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;859			}860			break;861		case 2:862			args.v2.ucAction = action;863			if (action == ATOM_TRANSMITTER_ACTION_INIT) {864				args.v2.usInitInfo = cpu_to_le16(connector_object_id);865			} else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {866				args.v2.asMode.ucLaneSel = lane_num;867				args.v2.asMode.ucLaneSet = lane_set;868			} else {869				if (is_dp)870					args.v2.usPixelClock = cpu_to_le16(dp_clock / 10);871				else if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))872					args.v2.usPixelClock = cpu_to_le16((amdgpu_encoder->pixel_clock / 2) / 10);873				else874					args.v2.usPixelClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);875			}876 877			args.v2.acConfig.ucEncoderSel = dig_encoder;878			if (dig->linkb)879				args.v2.acConfig.ucLinkSel = 1;880 881			switch (amdgpu_encoder->encoder_id) {882			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:883				args.v2.acConfig.ucTransmitterSel = 0;884				break;885			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:886				args.v2.acConfig.ucTransmitterSel = 1;887				break;888			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:889				args.v2.acConfig.ucTransmitterSel = 2;890				break;891			}892 893			if (is_dp) {894				args.v2.acConfig.fCoherentMode = 1;895				args.v2.acConfig.fDPConnector = 1;896			} else if (amdgpu_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {897				if (dig->coherent_mode)898					args.v2.acConfig.fCoherentMode = 1;899				if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))900					args.v2.acConfig.fDualLinkConnector = 1;901			}902			break;903		case 3:904			args.v3.ucAction = action;905			if (action == ATOM_TRANSMITTER_ACTION_INIT) {906				args.v3.usInitInfo = cpu_to_le16(connector_object_id);907			} else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {908				args.v3.asMode.ucLaneSel = lane_num;909				args.v3.asMode.ucLaneSet = lane_set;910			} else {911				if (is_dp)912					args.v3.usPixelClock = cpu_to_le16(dp_clock / 10);913				else if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))914					args.v3.usPixelClock = cpu_to_le16((amdgpu_encoder->pixel_clock / 2) / 10);915				else916					args.v3.usPixelClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);917			}918 919			if (is_dp)920				args.v3.ucLaneNum = dp_lane_count;921			else if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))922				args.v3.ucLaneNum = 8;923			else924				args.v3.ucLaneNum = 4;925 926			if (dig->linkb)927				args.v3.acConfig.ucLinkSel = 1;928			if (dig_encoder & 1)929				args.v3.acConfig.ucEncoderSel = 1;930 931			/* Select the PLL for the PHY932			 * DP PHY should be clocked from external src if there is933			 * one.934			 */935			/* On DCE4, if there is an external clock, it generates the DP ref clock */936			if (is_dp && adev->clock.dp_extclk)937				args.v3.acConfig.ucRefClkSource = 2; /* external src */938			else939				args.v3.acConfig.ucRefClkSource = pll_id;940 941			switch (amdgpu_encoder->encoder_id) {942			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:943				args.v3.acConfig.ucTransmitterSel = 0;944				break;945			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:946				args.v3.acConfig.ucTransmitterSel = 1;947				break;948			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:949				args.v3.acConfig.ucTransmitterSel = 2;950				break;951			}952 953			if (is_dp)954				args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */955			else if (amdgpu_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {956				if (dig->coherent_mode)957					args.v3.acConfig.fCoherentMode = 1;958				if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))959					args.v3.acConfig.fDualLinkConnector = 1;960			}961			break;962		case 4:963			args.v4.ucAction = action;964			if (action == ATOM_TRANSMITTER_ACTION_INIT) {965				args.v4.usInitInfo = cpu_to_le16(connector_object_id);966			} else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {967				args.v4.asMode.ucLaneSel = lane_num;968				args.v4.asMode.ucLaneSet = lane_set;969			} else {970				if (is_dp)971					args.v4.usPixelClock = cpu_to_le16(dp_clock / 10);972				else if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))973					args.v4.usPixelClock = cpu_to_le16((amdgpu_encoder->pixel_clock / 2) / 10);974				else975					args.v4.usPixelClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);976			}977 978			if (is_dp)979				args.v4.ucLaneNum = dp_lane_count;980			else if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))981				args.v4.ucLaneNum = 8;982			else983				args.v4.ucLaneNum = 4;984 985			if (dig->linkb)986				args.v4.acConfig.ucLinkSel = 1;987			if (dig_encoder & 1)988				args.v4.acConfig.ucEncoderSel = 1;989 990			/* Select the PLL for the PHY991			 * DP PHY should be clocked from external src if there is992			 * one.993			 */994			/* On DCE5 DCPLL usually generates the DP ref clock */995			if (is_dp) {996				if (adev->clock.dp_extclk)997					args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_EXTCLK;998				else999					args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_DCPLL;1000			} else1001				args.v4.acConfig.ucRefClkSource = pll_id;1002 1003			switch (amdgpu_encoder->encoder_id) {1004			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:1005				args.v4.acConfig.ucTransmitterSel = 0;1006				break;1007			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:1008				args.v4.acConfig.ucTransmitterSel = 1;1009				break;1010			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:1011				args.v4.acConfig.ucTransmitterSel = 2;1012				break;1013			}1014 1015			if (is_dp)1016				args.v4.acConfig.fCoherentMode = 1; /* DP requires coherent */1017			else if (amdgpu_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {1018				if (dig->coherent_mode)1019					args.v4.acConfig.fCoherentMode = 1;1020				if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))1021					args.v4.acConfig.fDualLinkConnector = 1;1022			}1023			break;1024		case 5:1025			args.v5.ucAction = action;1026			if (is_dp)1027				args.v5.usSymClock = cpu_to_le16(dp_clock / 10);1028			else1029				args.v5.usSymClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);1030 1031			switch (amdgpu_encoder->encoder_id) {1032			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:1033				if (dig->linkb)1034					args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYB;1035				else1036					args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYA;1037				break;1038			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:1039				if (dig->linkb)1040					args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYD;1041				else1042					args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYC;1043				break;1044			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:1045				if (dig->linkb)1046					args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYF;1047				else1048					args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYE;1049				break;1050			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:1051				args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYG;1052				break;1053			}1054			if (is_dp)1055				args.v5.ucLaneNum = dp_lane_count;1056			else if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))1057				args.v5.ucLaneNum = 8;1058			else1059				args.v5.ucLaneNum = 4;1060			args.v5.ucConnObjId = connector_object_id;1061			args.v5.ucDigMode = amdgpu_atombios_encoder_get_encoder_mode(encoder);1062 1063			if (is_dp && adev->clock.dp_extclk)1064				args.v5.asConfig.ucPhyClkSrcId = ENCODER_REFCLK_SRC_EXTCLK;1065			else1066				args.v5.asConfig.ucPhyClkSrcId = pll_id;1067 1068			if (is_dp)1069				args.v5.asConfig.ucCoherentMode = 1; /* DP requires coherent */1070			else if (amdgpu_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {1071				if (dig->coherent_mode)1072					args.v5.asConfig.ucCoherentMode = 1;1073			}1074			if (hpd_id == AMDGPU_HPD_NONE)1075				args.v5.asConfig.ucHPDSel = 0;1076			else1077				args.v5.asConfig.ucHPDSel = hpd_id + 1;1078			args.v5.ucDigEncoderSel = 1 << dig_encoder;1079			args.v5.ucDPLaneSet = lane_set;1080			break;1081		case 6:1082			args.v6.ucAction = action;1083			if (is_dp)1084				args.v6.ulSymClock = cpu_to_le32(dp_clock / 10);1085			else1086				args.v6.ulSymClock = cpu_to_le32(amdgpu_encoder->pixel_clock / 10);1087 1088			switch (amdgpu_encoder->encoder_id) {1089			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:1090				if (dig->linkb)1091					args.v6.ucPhyId = ATOM_PHY_ID_UNIPHYB;1092				else1093					args.v6.ucPhyId = ATOM_PHY_ID_UNIPHYA;1094				break;1095			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:1096				if (dig->linkb)1097					args.v6.ucPhyId = ATOM_PHY_ID_UNIPHYD;1098				else1099					args.v6.ucPhyId = ATOM_PHY_ID_UNIPHYC;1100				break;1101			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:1102				if (dig->linkb)1103					args.v6.ucPhyId = ATOM_PHY_ID_UNIPHYF;1104				else1105					args.v6.ucPhyId = ATOM_PHY_ID_UNIPHYE;1106				break;1107			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:1108				args.v6.ucPhyId = ATOM_PHY_ID_UNIPHYG;1109				break;1110			}1111			if (is_dp)1112				args.v6.ucLaneNum = dp_lane_count;1113			else if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))1114				args.v6.ucLaneNum = 8;1115			else1116				args.v6.ucLaneNum = 4;1117			args.v6.ucConnObjId = connector_object_id;1118			if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH)1119				args.v6.ucDPLaneSet = lane_set;1120			else1121				args.v6.ucDigMode = amdgpu_atombios_encoder_get_encoder_mode(encoder);1122 1123			if (hpd_id == AMDGPU_HPD_NONE)1124				args.v6.ucHPDSel = 0;1125			else1126				args.v6.ucHPDSel = hpd_id + 1;1127			args.v6.ucDigEncoderSel = 1 << dig_encoder;1128			break;1129		default:1130			DRM_ERROR("Unknown table version %d, %d\n", frev, crev);1131			break;1132		}1133		break;1134	default:1135		DRM_ERROR("Unknown table version %d, %d\n", frev, crev);1136		break;1137	}1138 1139	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1140}1141 1142bool1143amdgpu_atombios_encoder_set_edp_panel_power(struct drm_connector *connector,1144				     int action)1145{1146	struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1147	struct drm_device *dev = amdgpu_connector->base.dev;1148	struct amdgpu_device *adev = drm_to_adev(dev);1149	union dig_transmitter_control args;1150	int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);1151	uint8_t frev, crev;1152 1153	if (connector->connector_type != DRM_MODE_CONNECTOR_eDP)1154		goto done;1155 1156	if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) &&1157	    (action != ATOM_TRANSMITTER_ACTION_POWER_OFF))1158		goto done;1159 1160	if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))1161		goto done;1162 1163	memset(&args, 0, sizeof(args));1164 1165	args.v1.ucAction = action;1166 1167	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1168 1169	/* wait for the panel to power up */1170	if (action == ATOM_TRANSMITTER_ACTION_POWER_ON) {1171		int i;1172 1173		for (i = 0; i < 300; i++) {1174			if (amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd))1175				return true;1176			mdelay(1);1177		}1178		return false;1179	}1180done:1181	return true;1182}1183 1184union external_encoder_control {1185	EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1;1186	EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3;1187};1188 1189static void1190amdgpu_atombios_encoder_setup_external_encoder(struct drm_encoder *encoder,1191					struct drm_encoder *ext_encoder,1192					int action)1193{1194	struct drm_device *dev = encoder->dev;1195	struct amdgpu_device *adev = drm_to_adev(dev);1196	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);1197	struct amdgpu_encoder *ext_amdgpu_encoder = to_amdgpu_encoder(ext_encoder);1198	union external_encoder_control args;1199	struct drm_connector *connector;1200	int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);1201	u8 frev, crev;1202	int dp_clock = 0;1203	int dp_lane_count = 0;1204	int connector_object_id = 0;1205	u32 ext_enum = (ext_amdgpu_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;1206 1207	if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT)1208		connector = amdgpu_get_connector_for_encoder_init(encoder);1209	else1210		connector = amdgpu_get_connector_for_encoder(encoder);1211 1212	if (connector) {1213		struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1214		struct amdgpu_connector_atom_dig *dig_connector =1215			amdgpu_connector->con_priv;1216 1217		dp_clock = dig_connector->dp_clock;1218		dp_lane_count = dig_connector->dp_lane_count;1219		connector_object_id =1220			(amdgpu_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;1221	}1222 1223	memset(&args, 0, sizeof(args));1224 1225	if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))1226		return;1227 1228	switch (frev) {1229	case 1:1230		/* no params on frev 1 */1231		break;1232	case 2:1233		switch (crev) {1234		case 1:1235		case 2:1236			args.v1.sDigEncoder.ucAction = action;1237			args.v1.sDigEncoder.usPixelClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);1238			args.v1.sDigEncoder.ucEncoderMode =1239				amdgpu_atombios_encoder_get_encoder_mode(encoder);1240 1241			if (ENCODER_MODE_IS_DP(args.v1.sDigEncoder.ucEncoderMode)) {1242				if (dp_clock == 270000)1243					args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;1244				args.v1.sDigEncoder.ucLaneNum = dp_lane_count;1245			} else if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))1246				args.v1.sDigEncoder.ucLaneNum = 8;1247			else1248				args.v1.sDigEncoder.ucLaneNum = 4;1249			break;1250		case 3:1251			args.v3.sExtEncoder.ucAction = action;1252			if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT)1253				args.v3.sExtEncoder.usConnectorId = cpu_to_le16(connector_object_id);1254			else1255				args.v3.sExtEncoder.usPixelClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);1256			args.v3.sExtEncoder.ucEncoderMode =1257				amdgpu_atombios_encoder_get_encoder_mode(encoder);1258 1259			if (ENCODER_MODE_IS_DP(args.v3.sExtEncoder.ucEncoderMode)) {1260				if (dp_clock == 270000)1261					args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;1262				else if (dp_clock == 540000)1263					args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ;1264				args.v3.sExtEncoder.ucLaneNum = dp_lane_count;1265			} else if (amdgpu_dig_monitor_is_duallink(encoder, amdgpu_encoder->pixel_clock))1266				args.v3.sExtEncoder.ucLaneNum = 8;1267			else1268				args.v3.sExtEncoder.ucLaneNum = 4;1269			switch (ext_enum) {1270			case GRAPH_OBJECT_ENUM_ID1:1271				args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1;1272				break;1273			case GRAPH_OBJECT_ENUM_ID2:1274				args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2;1275				break;1276			case GRAPH_OBJECT_ENUM_ID3:1277				args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3;1278				break;1279			}1280			args.v3.sExtEncoder.ucBitPerColor = amdgpu_atombios_encoder_get_bpc(encoder);1281			break;1282		default:1283			DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);1284			return;1285		}1286		break;1287	default:1288		DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);1289		return;1290	}1291	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1292}1293 1294static void1295amdgpu_atombios_encoder_setup_dig(struct drm_encoder *encoder, int action)1296{1297	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);1298	struct drm_encoder *ext_encoder = amdgpu_get_external_encoder(encoder);1299	struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;1300	struct drm_connector *connector = amdgpu_get_connector_for_encoder(encoder);1301	struct amdgpu_connector *amdgpu_connector = NULL;1302	struct amdgpu_connector_atom_dig *amdgpu_dig_connector = NULL;1303 1304	if (connector) {1305		amdgpu_connector = to_amdgpu_connector(connector);1306		amdgpu_dig_connector = amdgpu_connector->con_priv;1307	}1308 1309	if (action == ATOM_ENABLE) {1310		if (!connector)1311			dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;1312		else1313			dig->panel_mode = amdgpu_atombios_dp_get_panel_mode(encoder, connector);1314 1315		/* setup and enable the encoder */1316		amdgpu_atombios_encoder_setup_dig_encoder(encoder, ATOM_ENCODER_CMD_SETUP, 0);1317		amdgpu_atombios_encoder_setup_dig_encoder(encoder,1318						   ATOM_ENCODER_CMD_SETUP_PANEL_MODE,1319						   dig->panel_mode);1320		if (ext_encoder)1321			amdgpu_atombios_encoder_setup_external_encoder(encoder, ext_encoder,1322								EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);1323		if (ENCODER_MODE_IS_DP(amdgpu_atombios_encoder_get_encoder_mode(encoder)) &&1324		    connector) {1325			if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {1326				amdgpu_atombios_encoder_set_edp_panel_power(connector,1327								     ATOM_TRANSMITTER_ACTION_POWER_ON);1328				amdgpu_dig_connector->edp_on = true;1329			}1330		}1331		/* enable the transmitter */1332		amdgpu_atombios_encoder_setup_dig_transmitter(encoder,1333						       ATOM_TRANSMITTER_ACTION_ENABLE,1334						       0, 0);1335		if (ENCODER_MODE_IS_DP(amdgpu_atombios_encoder_get_encoder_mode(encoder)) &&1336		    connector) {1337			/* DP_SET_POWER_D0 is set in amdgpu_atombios_dp_link_train */1338			amdgpu_atombios_dp_link_train(encoder, connector);1339			amdgpu_atombios_encoder_setup_dig_encoder(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);1340		}1341		if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))1342			amdgpu_atombios_encoder_set_backlight_level(amdgpu_encoder, dig->backlight_level);1343		if (ext_encoder)1344			amdgpu_atombios_encoder_setup_external_encoder(encoder, ext_encoder, ATOM_ENABLE);1345	} else {1346		if (ENCODER_MODE_IS_DP(amdgpu_atombios_encoder_get_encoder_mode(encoder)) &&1347		    connector)1348			amdgpu_atombios_encoder_setup_dig_encoder(encoder,1349							   ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);1350		if (ext_encoder)1351			amdgpu_atombios_encoder_setup_external_encoder(encoder, ext_encoder, ATOM_DISABLE);1352		if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))1353			amdgpu_atombios_encoder_setup_dig_transmitter(encoder,1354							       ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);1355 1356		if (ENCODER_MODE_IS_DP(amdgpu_atombios_encoder_get_encoder_mode(encoder)) &&1357		    connector)1358			amdgpu_atombios_dp_set_rx_power_state(connector, DP_SET_POWER_D3);1359		/* disable the transmitter */1360		amdgpu_atombios_encoder_setup_dig_transmitter(encoder,1361						       ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);1362		if (ENCODER_MODE_IS_DP(amdgpu_atombios_encoder_get_encoder_mode(encoder)) &&1363		    connector) {1364			if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {1365				amdgpu_atombios_encoder_set_edp_panel_power(connector,1366								     ATOM_TRANSMITTER_ACTION_POWER_OFF);1367				amdgpu_dig_connector->edp_on = false;1368			}1369		}1370	}1371}1372 1373void1374amdgpu_atombios_encoder_dpms(struct drm_encoder *encoder, int mode)1375{1376	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);1377 1378	DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n",1379		  amdgpu_encoder->encoder_id, mode, amdgpu_encoder->devices,1380		  amdgpu_encoder->active_device);1381	switch (amdgpu_encoder->encoder_id) {1382	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:1383	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:1384	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:1385	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:1386		switch (mode) {1387		case DRM_MODE_DPMS_ON:1388			amdgpu_atombios_encoder_setup_dig(encoder, ATOM_ENABLE);1389			break;1390		case DRM_MODE_DPMS_STANDBY:1391		case DRM_MODE_DPMS_SUSPEND:1392		case DRM_MODE_DPMS_OFF:1393			amdgpu_atombios_encoder_setup_dig(encoder, ATOM_DISABLE);1394			break;1395		}1396		break;1397	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:1398		switch (mode) {1399		case DRM_MODE_DPMS_ON:1400			amdgpu_atombios_encoder_setup_dvo(encoder, ATOM_ENABLE);1401			break;1402		case DRM_MODE_DPMS_STANDBY:1403		case DRM_MODE_DPMS_SUSPEND:1404		case DRM_MODE_DPMS_OFF:1405			amdgpu_atombios_encoder_setup_dvo(encoder, ATOM_DISABLE);1406			break;1407		}1408		break;1409	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:1410		switch (mode) {1411		case DRM_MODE_DPMS_ON:1412			amdgpu_atombios_encoder_setup_dac(encoder, ATOM_ENABLE);1413			break;1414		case DRM_MODE_DPMS_STANDBY:1415		case DRM_MODE_DPMS_SUSPEND:1416		case DRM_MODE_DPMS_OFF:1417			amdgpu_atombios_encoder_setup_dac(encoder, ATOM_DISABLE);1418			break;1419		}1420		break;1421	default:1422		return;1423	}1424}1425 1426union crtc_source_param {1427	SELECT_CRTC_SOURCE_PS_ALLOCATION v1;1428	SELECT_CRTC_SOURCE_PARAMETERS_V2 v2;1429	SELECT_CRTC_SOURCE_PARAMETERS_V3 v3;1430};1431 1432void1433amdgpu_atombios_encoder_set_crtc_source(struct drm_encoder *encoder)1434{1435	struct drm_device *dev = encoder->dev;1436	struct amdgpu_device *adev = drm_to_adev(dev);1437	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);1438	struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(encoder->crtc);1439	union crtc_source_param args;1440	int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);1441	uint8_t frev, crev;1442	struct amdgpu_encoder_atom_dig *dig;1443 1444	memset(&args, 0, sizeof(args));1445 1446	if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))1447		return;1448 1449	switch (frev) {1450	case 1:1451		switch (crev) {1452		case 1:1453		default:1454			args.v1.ucCRTC = amdgpu_crtc->crtc_id;1455			switch (amdgpu_encoder->encoder_id) {1456			case ENCODER_OBJECT_ID_INTERNAL_TMDS1:1457			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:1458				args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX;1459				break;1460			case ENCODER_OBJECT_ID_INTERNAL_LVDS:1461			case ENCODER_OBJECT_ID_INTERNAL_LVTM1:1462				if (amdgpu_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT)1463					args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX;1464				else1465					args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX;1466				break;1467			case ENCODER_OBJECT_ID_INTERNAL_DVO1:1468			case ENCODER_OBJECT_ID_INTERNAL_DDI:1469			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:1470				args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX;1471				break;1472			case ENCODER_OBJECT_ID_INTERNAL_DAC1:1473			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:1474				if (amdgpu_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))1475					args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;1476				else if (amdgpu_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))1477					args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;1478				else1479					args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX;1480				break;1481			case ENCODER_OBJECT_ID_INTERNAL_DAC2:1482			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:1483				if (amdgpu_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))1484					args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;1485				else if (amdgpu_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))1486					args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;1487				else1488					args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX;1489				break;1490			}1491			break;1492		case 2:1493			args.v2.ucCRTC = amdgpu_crtc->crtc_id;1494			if (amdgpu_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE) {1495				struct drm_connector *connector = amdgpu_get_connector_for_encoder(encoder);1496 1497				if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)1498					args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;1499				else if (connector->connector_type == DRM_MODE_CONNECTOR_VGA)1500					args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;1501				else1502					args.v2.ucEncodeMode = amdgpu_atombios_encoder_get_encoder_mode(encoder);1503			} else if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {1504				args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;1505			} else {1506				args.v2.ucEncodeMode = amdgpu_atombios_encoder_get_encoder_mode(encoder);1507			}1508			switch (amdgpu_encoder->encoder_id) {1509			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:1510			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:1511			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:1512			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:1513			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:1514				dig = amdgpu_encoder->enc_priv;1515				switch (dig->dig_encoder) {1516				case 0:1517					args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;1518					break;1519				case 1:1520					args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;1521					break;1522				case 2:1523					args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID;1524					break;1525				case 3:1526					args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID;1527					break;1528				case 4:1529					args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID;1530					break;1531				case 5:1532					args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID;1533					break;1534				case 6:1535					args.v2.ucEncoderID = ASIC_INT_DIG7_ENCODER_ID;1536					break;1537				}1538				break;1539			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:1540				args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;1541				break;1542			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:1543				if (amdgpu_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))1544					args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;1545				else if (amdgpu_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))1546					args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;1547				else1548					args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;1549				break;1550			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:1551				if (amdgpu_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))1552					args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;1553				else if (amdgpu_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))1554					args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;1555				else1556					args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;1557				break;1558			}1559			break;1560		case 3:1561			args.v3.ucCRTC = amdgpu_crtc->crtc_id;1562			if (amdgpu_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE) {1563				struct drm_connector *connector = amdgpu_get_connector_for_encoder(encoder);1564 1565				if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)1566					args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;1567				else if (connector->connector_type == DRM_MODE_CONNECTOR_VGA)1568					args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;1569				else1570					args.v2.ucEncodeMode = amdgpu_atombios_encoder_get_encoder_mode(encoder);1571			} else if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {1572				args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;1573			} else {1574				args.v2.ucEncodeMode = amdgpu_atombios_encoder_get_encoder_mode(encoder);1575			}1576			args.v3.ucDstBpc = amdgpu_atombios_encoder_get_bpc(encoder);1577			switch (amdgpu_encoder->encoder_id) {1578			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:1579			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:1580			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:1581			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:1582			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:1583				dig = amdgpu_encoder->enc_priv;1584				switch (dig->dig_encoder) {1585				case 0:1586					args.v3.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;1587					break;1588				case 1:1589					args.v3.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;1590					break;1591				case 2:1592					args.v3.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID;1593					break;1594				case 3:1595					args.v3.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID;1596					break;1597				case 4:1598					args.v3.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID;1599					break;1600				case 5:1601					args.v3.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID;1602					break;1603				case 6:1604					args.v3.ucEncoderID = ASIC_INT_DIG7_ENCODER_ID;1605					break;1606				}1607				break;1608			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:1609				args.v3.ucEncoderID = ASIC_INT_DVO_ENCODER_ID;1610				break;1611			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:1612				if (amdgpu_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))1613					args.v3.ucEncoderID = ASIC_INT_TV_ENCODER_ID;1614				else if (amdgpu_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))1615					args.v3.ucEncoderID = ASIC_INT_TV_ENCODER_ID;1616				else1617					args.v3.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;1618				break;1619			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:1620				if (amdgpu_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))1621					args.v3.ucEncoderID = ASIC_INT_TV_ENCODER_ID;1622				else if (amdgpu_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))1623					args.v3.ucEncoderID = ASIC_INT_TV_ENCODER_ID;1624				else1625					args.v3.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;1626				break;1627			}1628			break;1629		}1630		break;1631	default:1632		DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);1633		return;1634	}1635 1636	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1637}1638 1639/* This only needs to be called once at startup */1640void1641amdgpu_atombios_encoder_init_dig(struct amdgpu_device *adev)1642{1643	struct drm_device *dev = adev_to_drm(adev);1644	struct drm_encoder *encoder;1645 1646	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {1647		struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);1648		struct drm_encoder *ext_encoder = amdgpu_get_external_encoder(encoder);1649 1650		switch (amdgpu_encoder->encoder_id) {1651		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:1652		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:1653		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:1654		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:1655			amdgpu_atombios_encoder_setup_dig_transmitter(encoder, ATOM_TRANSMITTER_ACTION_INIT,1656							       0, 0);1657			break;1658		}1659 1660		if (ext_encoder)1661			amdgpu_atombios_encoder_setup_external_encoder(encoder, ext_encoder,1662								EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT);1663	}1664}1665 1666static bool1667amdgpu_atombios_encoder_dac_load_detect(struct drm_encoder *encoder,1668				 struct drm_connector *connector)1669{1670	struct drm_device *dev = encoder->dev;1671	struct amdgpu_device *adev = drm_to_adev(dev);1672	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);1673	struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1674 1675	if (amdgpu_encoder->devices & (ATOM_DEVICE_TV_SUPPORT |1676				       ATOM_DEVICE_CV_SUPPORT |1677				       ATOM_DEVICE_CRT_SUPPORT)) {1678		DAC_LOAD_DETECTION_PS_ALLOCATION args;1679		int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);1680		uint8_t frev, crev;1681 1682		memset(&args, 0, sizeof(args));1683 1684		if (!amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, index, &frev, &crev))1685			return false;1686 1687		args.sDacload.ucMisc = 0;1688 1689		if ((amdgpu_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) ||1690		    (amdgpu_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1))1691			args.sDacload.ucDacType = ATOM_DAC_A;1692		else1693			args.sDacload.ucDacType = ATOM_DAC_B;1694 1695		if (amdgpu_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)1696			args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT);1697		else if (amdgpu_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)1698			args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT);1699		else if (amdgpu_connector->devices & ATOM_DEVICE_CV_SUPPORT) {1700			args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT);1701			if (crev >= 3)1702				args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;1703		} else if (amdgpu_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {1704			args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT);1705			if (crev >= 3)1706				args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;1707		}1708 1709		amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));1710 1711		return true;1712	} else1713		return false;1714}1715 1716enum drm_connector_status1717amdgpu_atombios_encoder_dac_detect(struct drm_encoder *encoder,1718			    struct drm_connector *connector)1719{1720	struct drm_device *dev = encoder->dev;1721	struct amdgpu_device *adev = drm_to_adev(dev);1722	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);1723	struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1724	uint32_t bios_0_scratch;1725 1726	if (!amdgpu_atombios_encoder_dac_load_detect(encoder, connector)) {1727		DRM_DEBUG_KMS("detect returned false \n");1728		return connector_status_unknown;1729	}1730 1731	bios_0_scratch = RREG32(mmBIOS_SCRATCH_0);1732 1733	DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, amdgpu_encoder->devices);1734	if (amdgpu_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) {1735		if (bios_0_scratch & ATOM_S0_CRT1_MASK)1736			return connector_status_connected;1737	}1738	if (amdgpu_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) {1739		if (bios_0_scratch & ATOM_S0_CRT2_MASK)1740			return connector_status_connected;1741	}1742	if (amdgpu_connector->devices & ATOM_DEVICE_CV_SUPPORT) {1743		if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))1744			return connector_status_connected;1745	}1746	if (amdgpu_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {1747		if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))1748			return connector_status_connected; /* CTV */1749		else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))1750			return connector_status_connected; /* STV */1751	}1752	return connector_status_disconnected;1753}1754 1755enum drm_connector_status1756amdgpu_atombios_encoder_dig_detect(struct drm_encoder *encoder,1757			    struct drm_connector *connector)1758{1759	struct drm_device *dev = encoder->dev;1760	struct amdgpu_device *adev = drm_to_adev(dev);1761	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);1762	struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1763	struct drm_encoder *ext_encoder = amdgpu_get_external_encoder(encoder);1764	u32 bios_0_scratch;1765 1766	if (!ext_encoder)1767		return connector_status_unknown;1768 1769	if ((amdgpu_connector->devices & ATOM_DEVICE_CRT_SUPPORT) == 0)1770		return connector_status_unknown;1771 1772	/* load detect on the dp bridge */1773	amdgpu_atombios_encoder_setup_external_encoder(encoder, ext_encoder,1774						EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION);1775 1776	bios_0_scratch = RREG32(mmBIOS_SCRATCH_0);1777 1778	DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, amdgpu_encoder->devices);1779	if (amdgpu_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) {1780		if (bios_0_scratch & ATOM_S0_CRT1_MASK)1781			return connector_status_connected;1782	}1783	if (amdgpu_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) {1784		if (bios_0_scratch & ATOM_S0_CRT2_MASK)1785			return connector_status_connected;1786	}1787	if (amdgpu_connector->devices & ATOM_DEVICE_CV_SUPPORT) {1788		if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))1789			return connector_status_connected;1790	}1791	if (amdgpu_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {1792		if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))1793			return connector_status_connected; /* CTV */1794		else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))1795			return connector_status_connected; /* STV */1796	}1797	return connector_status_disconnected;1798}1799 1800void1801amdgpu_atombios_encoder_setup_ext_encoder_ddc(struct drm_encoder *encoder)1802{1803	struct drm_encoder *ext_encoder = amdgpu_get_external_encoder(encoder);1804 1805	if (ext_encoder)1806		/* ddc_setup on the dp bridge */1807		amdgpu_atombios_encoder_setup_external_encoder(encoder, ext_encoder,1808							EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP);1809 1810}1811 1812void1813amdgpu_atombios_encoder_set_bios_scratch_regs(struct drm_connector *connector,1814				       struct drm_encoder *encoder,1815				       bool connected)1816{1817	struct drm_device *dev = connector->dev;1818	struct amdgpu_device *adev = drm_to_adev(dev);1819	struct amdgpu_connector *amdgpu_connector =1820	    to_amdgpu_connector(connector);1821	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);1822	uint32_t bios_0_scratch, bios_3_scratch, bios_6_scratch;1823 1824	bios_0_scratch = RREG32(mmBIOS_SCRATCH_0);1825	bios_3_scratch = RREG32(mmBIOS_SCRATCH_3);1826	bios_6_scratch = RREG32(mmBIOS_SCRATCH_6);1827 1828	if ((amdgpu_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) &&1829	    (amdgpu_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) {1830		if (connected) {1831			DRM_DEBUG_KMS("LCD1 connected\n");1832			bios_0_scratch |= ATOM_S0_LCD1;1833			bios_3_scratch |= ATOM_S3_LCD1_ACTIVE;1834			bios_6_scratch |= ATOM_S6_ACC_REQ_LCD1;1835		} else {1836			DRM_DEBUG_KMS("LCD1 disconnected\n");1837			bios_0_scratch &= ~ATOM_S0_LCD1;1838			bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE;1839			bios_6_scratch &= ~ATOM_S6_ACC_REQ_LCD1;1840		}1841	}1842	if ((amdgpu_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) &&1843	    (amdgpu_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) {1844		if (connected) {1845			DRM_DEBUG_KMS("CRT1 connected\n");1846			bios_0_scratch |= ATOM_S0_CRT1_COLOR;1847			bios_3_scratch |= ATOM_S3_CRT1_ACTIVE;1848			bios_6_scratch |= ATOM_S6_ACC_REQ_CRT1;1849		} else {1850			DRM_DEBUG_KMS("CRT1 disconnected\n");1851			bios_0_scratch &= ~ATOM_S0_CRT1_MASK;1852			bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE;1853			bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT1;1854		}1855	}1856	if ((amdgpu_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) &&1857	    (amdgpu_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) {1858		if (connected) {1859			DRM_DEBUG_KMS("CRT2 connected\n");1860			bios_0_scratch |= ATOM_S0_CRT2_COLOR;1861			bios_3_scratch |= ATOM_S3_CRT2_ACTIVE;1862			bios_6_scratch |= ATOM_S6_ACC_REQ_CRT2;1863		} else {1864			DRM_DEBUG_KMS("CRT2 disconnected\n");1865			bios_0_scratch &= ~ATOM_S0_CRT2_MASK;1866			bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE;1867			bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT2;1868		}1869	}1870	if ((amdgpu_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) &&1871	    (amdgpu_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) {1872		if (connected) {1873			DRM_DEBUG_KMS("DFP1 connected\n");1874			bios_0_scratch |= ATOM_S0_DFP1;1875			bios_3_scratch |= ATOM_S3_DFP1_ACTIVE;1876			bios_6_scratch |= ATOM_S6_ACC_REQ_DFP1;1877		} else {1878			DRM_DEBUG_KMS("DFP1 disconnected\n");1879			bios_0_scratch &= ~ATOM_S0_DFP1;1880			bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE;1881			bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP1;1882		}1883	}1884	if ((amdgpu_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) &&1885	    (amdgpu_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) {1886		if (connected) {1887			DRM_DEBUG_KMS("DFP2 connected\n");1888			bios_0_scratch |= ATOM_S0_DFP2;1889			bios_3_scratch |= ATOM_S3_DFP2_ACTIVE;1890			bios_6_scratch |= ATOM_S6_ACC_REQ_DFP2;1891		} else {1892			DRM_DEBUG_KMS("DFP2 disconnected\n");1893			bios_0_scratch &= ~ATOM_S0_DFP2;1894			bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE;1895			bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP2;1896		}1897	}1898	if ((amdgpu_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) &&1899	    (amdgpu_connector->devices & ATOM_DEVICE_DFP3_SUPPORT)) {1900		if (connected) {1901			DRM_DEBUG_KMS("DFP3 connected\n");1902			bios_0_scratch |= ATOM_S0_DFP3;1903			bios_3_scratch |= ATOM_S3_DFP3_ACTIVE;1904			bios_6_scratch |= ATOM_S6_ACC_REQ_DFP3;1905		} else {1906			DRM_DEBUG_KMS("DFP3 disconnected\n");1907			bios_0_scratch &= ~ATOM_S0_DFP3;1908			bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE;1909			bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP3;1910		}1911	}1912	if ((amdgpu_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) &&1913	    (amdgpu_connector->devices & ATOM_DEVICE_DFP4_SUPPORT)) {1914		if (connected) {1915			DRM_DEBUG_KMS("DFP4 connected\n");1916			bios_0_scratch |= ATOM_S0_DFP4;1917			bios_3_scratch |= ATOM_S3_DFP4_ACTIVE;1918			bios_6_scratch |= ATOM_S6_ACC_REQ_DFP4;1919		} else {1920			DRM_DEBUG_KMS("DFP4 disconnected\n");1921			bios_0_scratch &= ~ATOM_S0_DFP4;1922			bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE;1923			bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP4;1924		}1925	}1926	if ((amdgpu_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) &&1927	    (amdgpu_connector->devices & ATOM_DEVICE_DFP5_SUPPORT)) {1928		if (connected) {1929			DRM_DEBUG_KMS("DFP5 connected\n");1930			bios_0_scratch |= ATOM_S0_DFP5;1931			bios_3_scratch |= ATOM_S3_DFP5_ACTIVE;1932			bios_6_scratch |= ATOM_S6_ACC_REQ_DFP5;1933		} else {1934			DRM_DEBUG_KMS("DFP5 disconnected\n");1935			bios_0_scratch &= ~ATOM_S0_DFP5;1936			bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE;1937			bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5;1938		}1939	}1940	if ((amdgpu_encoder->devices & ATOM_DEVICE_DFP6_SUPPORT) &&1941	    (amdgpu_connector->devices & ATOM_DEVICE_DFP6_SUPPORT)) {1942		if (connected) {1943			DRM_DEBUG_KMS("DFP6 connected\n");1944			bios_0_scratch |= ATOM_S0_DFP6;1945			bios_3_scratch |= ATOM_S3_DFP6_ACTIVE;1946			bios_6_scratch |= ATOM_S6_ACC_REQ_DFP6;1947		} else {1948			DRM_DEBUG_KMS("DFP6 disconnected\n");1949			bios_0_scratch &= ~ATOM_S0_DFP6;1950			bios_3_scratch &= ~ATOM_S3_DFP6_ACTIVE;1951			bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP6;1952		}1953	}1954 1955	WREG32(mmBIOS_SCRATCH_0, bios_0_scratch);1956	WREG32(mmBIOS_SCRATCH_3, bios_3_scratch);1957	WREG32(mmBIOS_SCRATCH_6, bios_6_scratch);1958}1959 1960union lvds_info {1961	struct _ATOM_LVDS_INFO info;1962	struct _ATOM_LVDS_INFO_V12 info_12;1963};1964 1965struct amdgpu_encoder_atom_dig *1966amdgpu_atombios_encoder_get_lcd_info(struct amdgpu_encoder *encoder)1967{1968	struct drm_device *dev = encoder->base.dev;1969	struct amdgpu_device *adev = drm_to_adev(dev);1970	struct amdgpu_mode_info *mode_info = &adev->mode_info;1971	int index = GetIndexIntoMasterTable(DATA, LVDS_Info);1972	uint16_t data_offset, misc;1973	union lvds_info *lvds_info;1974	uint8_t frev, crev;1975	struct amdgpu_encoder_atom_dig *lvds = NULL;1976	int encoder_enum = (encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;1977 1978	if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,1979				   &frev, &crev, &data_offset)) {1980		lvds_info =1981			(union lvds_info *)(mode_info->atom_context->bios + data_offset);1982		lvds =1983		    kzalloc(sizeof(struct amdgpu_encoder_atom_dig), GFP_KERNEL);1984 1985		if (!lvds)1986			return NULL;1987 1988		lvds->native_mode.clock =1989		    le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10;1990		lvds->native_mode.hdisplay =1991		    le16_to_cpu(lvds_info->info.sLCDTiming.usHActive);1992		lvds->native_mode.vdisplay =1993		    le16_to_cpu(lvds_info->info.sLCDTiming.usVActive);1994		lvds->native_mode.htotal = lvds->native_mode.hdisplay +1995			le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);1996		lvds->native_mode.hsync_start = lvds->native_mode.hdisplay +1997			le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);1998		lvds->native_mode.hsync_end = lvds->native_mode.hsync_start +1999			le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);2000		lvds->native_mode.vtotal = lvds->native_mode.vdisplay +2001			le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time);2002		lvds->native_mode.vsync_start = lvds->native_mode.vdisplay +2003			le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset);2004		lvds->native_mode.vsync_end = lvds->native_mode.vsync_start +2005			le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);2006		lvds->panel_pwr_delay =2007		    le16_to_cpu(lvds_info->info.usOffDelayInMs);2008		lvds->lcd_misc = lvds_info->info.ucLVDS_Misc;2009 2010		misc = le16_to_cpu(lvds_info->info.sLCDTiming.susModeMiscInfo.usAccess);2011		if (misc & ATOM_VSYNC_POLARITY)2012			lvds->native_mode.flags |= DRM_MODE_FLAG_NVSYNC;2013		if (misc & ATOM_HSYNC_POLARITY)2014			lvds->native_mode.flags |= DRM_MODE_FLAG_NHSYNC;2015		if (misc & ATOM_COMPOSITESYNC)2016			lvds->native_mode.flags |= DRM_MODE_FLAG_CSYNC;2017		if (misc & ATOM_INTERLACE)2018			lvds->native_mode.flags |= DRM_MODE_FLAG_INTERLACE;2019		if (misc & ATOM_DOUBLE_CLOCK_MODE)2020			lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN;2021 2022		lvds->native_mode.width_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageHSize);2023		lvds->native_mode.height_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageVSize);2024 2025		/* set crtc values */2026		drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V);2027 2028		lvds->lcd_ss_id = lvds_info->info.ucSS_Id;2029 2030		encoder->native_mode = lvds->native_mode;2031 2032		if (encoder_enum == 2)2033			lvds->linkb = true;2034		else2035			lvds->linkb = false;2036 2037		/* parse the lcd record table */2038		if (le16_to_cpu(lvds_info->info.usModePatchTableOffset)) {2039			ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record;2040			ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record;2041			bool bad_record = false;2042			u8 *record;2043 2044			if ((frev == 1) && (crev < 2))2045				/* absolute */2046				record = (u8 *)(mode_info->atom_context->bios +2047						le16_to_cpu(lvds_info->info.usModePatchTableOffset));2048			else2049				/* relative */2050				record = (u8 *)(mode_info->atom_context->bios +2051						data_offset +2052						le16_to_cpu(lvds_info->info.usModePatchTableOffset));2053			while (*record != ATOM_RECORD_END_TYPE) {2054				switch (*record) {2055				case LCD_MODE_PATCH_RECORD_MODE_TYPE:2056					record += sizeof(ATOM_PATCH_RECORD_MODE);2057					break;2058				case LCD_RTS_RECORD_TYPE:2059					record += sizeof(ATOM_LCD_RTS_RECORD);2060					break;2061				case LCD_CAP_RECORD_TYPE:2062					record += sizeof(ATOM_LCD_MODE_CONTROL_CAP);2063					break;2064				case LCD_FAKE_EDID_PATCH_RECORD_TYPE:2065					fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;2066					if (fake_edid_record->ucFakeEDIDLength) {2067						const struct drm_edid *edid;2068						int edid_size;2069 2070						if (fake_edid_record->ucFakeEDIDLength == 128)2071							edid_size = fake_edid_record->ucFakeEDIDLength;2072						else2073							edid_size = fake_edid_record->ucFakeEDIDLength * 128;2074						edid = drm_edid_alloc(fake_edid_record->ucFakeEDIDString, edid_size);2075						if (drm_edid_valid(edid))2076							adev->mode_info.bios_hardcoded_edid = edid;2077						else2078							drm_edid_free(edid);2079						record += struct_size(fake_edid_record,2080								      ucFakeEDIDString,2081								      edid_size);2082					} else {2083						/* empty fake edid record must be 3 bytes long */2084						record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;2085					}2086					break;2087				case LCD_PANEL_RESOLUTION_RECORD_TYPE:2088					panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;2089					lvds->native_mode.width_mm = panel_res_record->usHSize;2090					lvds->native_mode.height_mm = panel_res_record->usVSize;2091					record += sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD);2092					break;2093				default:2094					DRM_ERROR("Bad LCD record %d\n", *record);2095					bad_record = true;2096					break;2097				}2098				if (bad_record)2099					break;2100			}2101		}2102	}2103	return lvds;2104}2105 2106struct amdgpu_encoder_atom_dig *2107amdgpu_atombios_encoder_get_dig_info(struct amdgpu_encoder *amdgpu_encoder)2108{2109	int encoder_enum = (amdgpu_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;2110	struct amdgpu_encoder_atom_dig *dig = kzalloc(sizeof(struct amdgpu_encoder_atom_dig), GFP_KERNEL);2111 2112	if (!dig)2113		return NULL;2114 2115	/* coherent mode by default */2116	dig->coherent_mode = true;2117	dig->dig_encoder = -1;2118 2119	if (encoder_enum == 2)2120		dig->linkb = true;2121	else2122		dig->linkb = false;2123 2124	return dig;2125}2126 2127