From 1ee116cdbe51e956c67051175a6f2e82fa14a1a1 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 1 Feb 2010 19:18:04 -0500 Subject: [PATCH] drm/radeon/kms/evergreen: add support for digital outputs This adds modesetting for digital outputs using the atom DIG encoder and transmitter tables. Analog outputs are already supported by the existing code. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_dp.c | 62 ++++++--- drivers/gpu/drm/radeon/radeon_atombios.c | 12 ++- drivers/gpu/drm/radeon/radeon_combios.c | 1 + drivers/gpu/drm/radeon/radeon_encoders.c | 227 +++++++++++++++++++++++------- drivers/gpu/drm/radeon/radeon_mode.h | 3 + 5 files changed, 229 insertions(+), 76 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 7106011..0b6f2ce 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -321,6 +321,10 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], train_set[lane] = v | p; } +union aux_channel_transaction { + PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1; + PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2; +}; /* radeon aux chan functions */ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, @@ -329,7 +333,7 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, { struct drm_device *dev = chan->dev; struct radeon_device *rdev = dev->dev_private; - PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args; + union aux_channel_transaction args; int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); unsigned char *base; @@ -339,29 +343,31 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, memcpy(base, req_bytes, num_bytes); - args.lpAuxRequest = 0; - args.lpDataOut = 16; - args.ucDataOutLen = 0; - args.ucChannelID = chan->rec.i2c_id; - args.ucDelay = delay / 10; + args.v1.lpAuxRequest = 0; + args.v1.lpDataOut = 16; + args.v1.ucDataOutLen = 0; + args.v1.ucChannelID = chan->rec.i2c_id; + args.v1.ucDelay = delay / 10; + if (ASIC_IS_DCE4(rdev)) + args.v2.ucHPD_ID = chan->rec.hpd_id; atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - if (args.ucReplyStatus) { + if (args.v1.ucReplyStatus) { DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x\n", req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], - chan->rec.i2c_id, args.ucReplyStatus); + chan->rec.i2c_id, args.v1.ucReplyStatus); return false; } - if (args.ucDataOutLen && read_byte && read_buf_len) { - if (read_buf_len < args.ucDataOutLen) { + if (args.v1.ucDataOutLen && read_byte && read_buf_len) { + if (read_buf_len < args.v1.ucDataOutLen) { DRM_ERROR("Buffer to small for return answer %d %d\n", - read_buf_len, args.ucDataOutLen); + read_buf_len, args.v1.ucDataOutLen); return false; } { - int len = min(read_buf_len, args.ucDataOutLen); + int len = min(read_buf_len, args.v1.ucDataOutLen); memcpy(read_byte, base + 16, len); } } @@ -622,12 +628,19 @@ void dp_link_train(struct drm_encoder *encoder, dp_set_link_bw_lanes(radeon_connector, link_configuration); /* disable downspread on the sink */ dp_set_downspread(radeon_connector, 0); - /* start training on the source */ - radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START, - dig_connector->dp_clock, enc_id, 0); - /* set training pattern 1 on the source */ - radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, - dig_connector->dp_clock, enc_id, 0); + if (ASIC_IS_DCE4(rdev)) { + /* start training on the source */ + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START); + /* set training pattern 1 on the source */ + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1); + } else { + /* start training on the source */ + radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START, + dig_connector->dp_clock, enc_id, 0); + /* set training pattern 1 on the source */ + radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, + dig_connector->dp_clock, enc_id, 0); + } /* set initial vs/emph */ memset(train_set, 0, 4); @@ -687,8 +700,11 @@ void dp_link_train(struct drm_encoder *encoder, /* set training pattern 2 on the sink */ dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2); /* set training pattern 2 on the source */ - radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, - dig_connector->dp_clock, enc_id, 1); + if (ASIC_IS_DCE4(rdev)) + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2); + else + radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, + dig_connector->dp_clock, enc_id, 1); /* channel equalization loop */ tries = 0; @@ -725,7 +741,11 @@ void dp_link_train(struct drm_encoder *encoder, >> DP_TRAIN_PRE_EMPHASIS_SHIFT); /* disable the training pattern on the sink */ - dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE); + if (ASIC_IS_DCE4(rdev)) + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE); + else + radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, + dig_connector->dp_clock, enc_id, 0); radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, dig_connector->dp_clock, enc_id, 0); diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index d33fb41..a151f91 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -159,8 +159,15 @@ static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device struct radeon_gpio_rec *gpio) { struct radeon_hpd hpd; + u32 reg; + + if (ASIC_IS_DCE4(rdev)) + reg = EVERGREEN_DC_GPIO_HPD_A; + else + reg = AVIVO_DC_GPIO_HPD_A; + hpd.gpio = *gpio; - if (gpio->reg == AVIVO_DC_GPIO_HPD_A) { + if (gpio->reg == reg) { switch(gpio->mask) { case (1 << 0): hpd.hpd = RADEON_HPD_1; @@ -556,6 +563,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) ddc_bus.valid = false; } + /* needed for aux chan transactions */ + ddc_bus.hpd_id = hpd.hpd ? (hpd.hpd - 1) : 0; + conn_id = le16_to_cpu(path->usConnObjectId); if (!radeon_atom_apply_quirks diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 579c892..24a485a 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -507,6 +507,7 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde } i2c.mm_i2c = false; i2c.i2c_id = 0; + i2c.hpd_id = 0; if (ddc_line) i2c.valid = true; diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 0e3e9b3..835e936 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -53,7 +53,7 @@ static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) /* DVO requires 2x ppll clocks depending on tmds chip */ if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) return index_mask; - + count = -1; list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) { struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder); @@ -668,6 +668,19 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) * - 2 DIG encoder blocks. * DIG1/2 can drive UNIPHY0/1/2 link A or link B * + * DCE 4.0 + * - 3 DIG transmitter blocks UNPHY0/1/2 (links A and B). + * Supports up to 6 digital outputs + * - 6 DIG encoder blocks. + * - DIG to PHY mapping: + * XXX - verify + * DIG1 drives UNIPHY0 link A, A+B + * DIG2 drives UNIPHY0 link B, B+A + * DIG3 drives UNIPHY1 link A, A+B + * DIG4 drives UNIPHY1 link B, B+A + * DIG5 drives UNIPHY2 link A, A+B + * DIG6 drives UNIPHY2 link B, B+A + * * Routing * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) * Examples: @@ -676,7 +689,14 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI */ -static void + +union dig_encoder_control { + DIG_ENCODER_CONTROL_PS_ALLOCATION v1; + DIG_ENCODER_CONTROL_PARAMETERS_V2 v2; + DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; +}; + +void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) { struct drm_device *dev = encoder->dev; @@ -685,7 +705,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; struct radeon_connector_atom_dig *dig_connector = radeon_get_atom_connector_priv_from_encoder(encoder); - DIG_ENCODER_CONTROL_PS_ALLOCATION args; + union dig_encoder_control args; int index = 0, num = 0; uint8_t frev, crev; @@ -694,56 +714,53 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) memset(&args, 0, sizeof(args)); - if (dig->dig_encoder) - index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); - else - index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); + if (ASIC_IS_DCE4(rdev)) + index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl); + else { + if (dig->dig_encoder) + index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); + else + index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); + } num = dig->dig_encoder + 1; atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); - args.ucAction = action; - args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); + args.v1.ucAction = action; + args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); + args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); - if (ASIC_IS_DCE32(rdev)) { + if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { + if (dig_connector->dp_clock == 270000) + args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; + args.v1.ucLaneNum = dig_connector->dp_lane_count; + } else if (radeon_encoder->pixel_clock > 165000) + args.v1.ucLaneNum = 8; + else + args.v1.ucLaneNum = 4; + + if (ASIC_IS_DCE4(rdev)) { + args.v3.acConfig.ucDigSel = dig->dig_encoder; + args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; + } else { switch (radeon_encoder->encoder_id) { case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; + args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; break; case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; break; case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; - break; - } - } else { - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1; - break; - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2; + args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; break; } + if (dig_connector->linkb) + args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; + else + args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; } - args.ucEncoderMode = atombios_get_encoder_mode(encoder); - - if (args.ucEncoderMode == ATOM_ENCODER_MODE_DP) { - if (dig_connector->dp_clock == 270000) - args.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; - args.ucLaneNum = dig_connector->dp_lane_count; - } else if (radeon_encoder->pixel_clock > 165000) - args.ucLaneNum = 8; - else - args.ucLaneNum = 4; - - if (dig_connector->linkb) - args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; - else - args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } @@ -751,6 +768,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) union dig_transmitter_control { DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; + DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; }; void @@ -780,7 +798,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t memset(&args, 0, sizeof(args)); - if (ASIC_IS_DCE32(rdev)) + if (ASIC_IS_DCE32(rdev) || ASIC_IS_DCE4(rdev)) index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); else { switch (radeon_encoder->encoder_id) { @@ -810,7 +828,48 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t else args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); } - if (ASIC_IS_DCE32(rdev)) { + if (ASIC_IS_DCE4(rdev)) { + if (is_dp) + args.v3.ucLaneNum = dig_connector->dp_lane_count; + else if (radeon_encoder->pixel_clock > 165000) + args.v3.ucLaneNum = 8; + else + args.v3.ucLaneNum = 4; + + /*if (dig->dig_encoder) + args.v3.acConfig.ucEncoderSel = 1;*/ + + if (dig_connector->linkb) + args.v3.acConfig.ucLinkSel = 1; + + /* Select the PLL + * needed for non-DP digital outputs + * XXX: only 2 PLLs. need to allocate PLLs as needed + */ + args.v3.acConfig.ucRefClkSource = dig->dig_encoder ? 1 : 0; + + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: + args.v3.acConfig.ucTransmitterSel = 0; + num = 0; + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + args.v3.acConfig.ucTransmitterSel = 1; + num = 1; + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + args.v3.acConfig.ucTransmitterSel = 2; + num = 2; + break; + } + + if (is_dp) + args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */ + else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { + if (dig->coherent_mode) + args.v3.acConfig.fCoherentMode = 1; + } + } else if (ASIC_IS_DCE32(rdev)) { if (dig->dig_encoder == 1) args.v2.acConfig.ucEncoderSel = 1; if (dig_connector->linkb) @@ -838,7 +897,6 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t args.v2.acConfig.fCoherentMode = 1; } } else { - args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; if (dig->dig_encoder) @@ -1096,10 +1154,26 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: dig = radeon_encoder->enc_priv; - if (dig->dig_encoder) - args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; - else + switch (dig->dig_encoder) { + case 0: args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; + break; + case 1: + args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; + break; + case 2: + args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID; + break; + case 3: + args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID; + break; + case 4: + args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID; + break; + case 5: + args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID; + break; + } break; case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; @@ -1156,6 +1230,7 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder, } /* set scaler clears this on some chips */ + /* XXX check DCE4 */ if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) { if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, @@ -1172,6 +1247,37 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) struct drm_encoder *test_encoder; struct radeon_encoder_atom_dig *dig; uint32_t dig_enc_in_use = 0; + + /* The DIG to PHY routing isn't exactly clear yet + * I would be simpler to just use crtc_id like DCE3.2 + * and we might be able to. + */ + if (ASIC_IS_DCE4(rdev)) { + struct radeon_connector_atom_dig *dig_connector = + radeon_get_atom_connector_priv_from_encoder(encoder); + + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: + if (dig_connector->linkb) + return 1; + else + return 0; + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + if (dig_connector->linkb) + return 3; + else + return 2; + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + if (dig_connector->linkb) + return 5; + else + return 4; + break; + } + } + /* on DCE32 and encoder can driver any block so just crtc id */ if (ASIC_IS_DCE32(rdev)) { return radeon_crtc->crtc_id; @@ -1243,15 +1349,26 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - /* disable the encoder and transmitter */ - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); - atombios_dig_encoder_setup(encoder, ATOM_DISABLE); - - /* setup and enable the encoder and transmitter */ - atombios_dig_encoder_setup(encoder, ATOM_ENABLE); - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); + if (ASIC_IS_DCE4(rdev)) { + /* disable the transmitter */ + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); + /* setup and enable the encoder */ + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP); + + /* init and enable the transmitter */ + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); + } else { + /* disable the encoder and transmitter */ + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); + atombios_dig_encoder_setup(encoder, ATOM_DISABLE); + + /* setup and enable the encoder and transmitter */ + atombios_dig_encoder_setup(encoder, ATOM_ENABLE); + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); + } break; case ENCODER_OBJECT_ID_INTERNAL_DDI: atombios_ddia_setup(encoder, ATOM_ENABLE); @@ -1271,7 +1388,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, } atombios_apply_encoder_quirks(encoder, adjusted_mode); - r600_hdmi_setmode(encoder, adjusted_mode); + /* XXX */ + if (!ASIC_IS_DCE4(rdev)) + r600_hdmi_setmode(encoder, adjusted_mode); } static bool diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 410cb94..a63782f 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -83,6 +83,8 @@ struct radeon_i2c_bus_rec { bool valid; /* id used by atom */ uint8_t i2c_id; + /* id used by atom */ + uint8_t hpd_id; /* can be used with hw i2c engine */ bool hw_capable; /* uses multi-media i2c engine */ @@ -408,6 +410,7 @@ extern void dp_link_train(struct drm_encoder *encoder, struct drm_connector *connector); extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); +extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action); extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set); -- 1.5.6.3