Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2007-8 Advanced Micro Devices, Inc.
0003  * Copyright 2008 Red Hat Inc.
0004  *
0005  * Permission is hereby granted, free of charge, to any person obtaining a
0006  * copy of this software and associated documentation files (the "Software"),
0007  * to deal in the Software without restriction, including without limitation
0008  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0009  * and/or sell copies of the Software, and to permit persons to whom the
0010  * Software is furnished to do so, subject to the following conditions:
0011  *
0012  * The above copyright notice and this permission notice shall be included in
0013  * all copies or substantial portions of the Software.
0014  *
0015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0018  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0019  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0020  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0021  * OTHER DEALINGS IN THE SOFTWARE.
0022  *
0023  * Authors: Dave Airlie
0024  *          Alex Deucher
0025  *          Jerome Glisse
0026  */
0027 
0028 #include <drm/radeon_drm.h>
0029 #include "radeon.h"
0030 
0031 #include "atom.h"
0032 #include "atom-bits.h"
0033 #include <drm/display/drm_dp_helper.h>
0034 
0035 /* move these to drm_dp_helper.c/h */
0036 #define DP_LINK_CONFIGURATION_SIZE 9
0037 #define DP_DPCD_SIZE DP_RECEIVER_CAP_SIZE
0038 
0039 static char *voltage_names[] = {
0040     "0.4V", "0.6V", "0.8V", "1.2V"
0041 };
0042 static char *pre_emph_names[] = {
0043     "0dB", "3.5dB", "6dB", "9.5dB"
0044 };
0045 
0046 /***** radeon AUX functions *****/
0047 
0048 /* Atom needs data in little endian format so swap as appropriate when copying
0049  * data to or from atom. Note that atom operates on dw units.
0050  *
0051  * Use to_le=true when sending data to atom and provide at least
0052  * ALIGN(num_bytes,4) bytes in the dst buffer.
0053  *
0054  * Use to_le=false when receiving data from atom and provide ALIGN(num_bytes,4)
0055  * byes in the src buffer.
0056  */
0057 void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le)
0058 {
0059 #ifdef __BIG_ENDIAN
0060     u32 src_tmp[5], dst_tmp[5];
0061     int i;
0062     u8 align_num_bytes = ALIGN(num_bytes, 4);
0063 
0064     if (to_le) {
0065         memcpy(src_tmp, src, num_bytes);
0066         for (i = 0; i < align_num_bytes / 4; i++)
0067             dst_tmp[i] = cpu_to_le32(src_tmp[i]);
0068         memcpy(dst, dst_tmp, align_num_bytes);
0069     } else {
0070         memcpy(src_tmp, src, align_num_bytes);
0071         for (i = 0; i < align_num_bytes / 4; i++)
0072             dst_tmp[i] = le32_to_cpu(src_tmp[i]);
0073         memcpy(dst, dst_tmp, num_bytes);
0074     }
0075 #else
0076     memcpy(dst, src, num_bytes);
0077 #endif
0078 }
0079 
0080 union aux_channel_transaction {
0081     PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1;
0082     PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2;
0083 };
0084 
0085 static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
0086                  u8 *send, int send_bytes,
0087                  u8 *recv, int recv_size,
0088                  u8 delay, u8 *ack)
0089 {
0090     struct drm_device *dev = chan->dev;
0091     struct radeon_device *rdev = dev->dev_private;
0092     union aux_channel_transaction args;
0093     int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
0094     unsigned char *base;
0095     int recv_bytes;
0096     int r = 0;
0097 
0098     memset(&args, 0, sizeof(args));
0099 
0100     mutex_lock(&chan->mutex);
0101     mutex_lock(&rdev->mode_info.atom_context->scratch_mutex);
0102 
0103     base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1);
0104 
0105     radeon_atom_copy_swap(base, send, send_bytes, true);
0106 
0107     args.v1.lpAuxRequest = cpu_to_le16((u16)(0 + 4));
0108     args.v1.lpDataOut = cpu_to_le16((u16)(16 + 4));
0109     args.v1.ucDataOutLen = 0;
0110     args.v1.ucChannelID = chan->rec.i2c_id;
0111     args.v1.ucDelay = delay / 10;
0112     if (ASIC_IS_DCE4(rdev))
0113         args.v2.ucHPD_ID = chan->rec.hpd;
0114 
0115     atom_execute_table_scratch_unlocked(rdev->mode_info.atom_context, index, (uint32_t *)&args);
0116 
0117     *ack = args.v1.ucReplyStatus;
0118 
0119     /* timeout */
0120     if (args.v1.ucReplyStatus == 1) {
0121         DRM_DEBUG_KMS("dp_aux_ch timeout\n");
0122         r = -ETIMEDOUT;
0123         goto done;
0124     }
0125 
0126     /* flags not zero */
0127     if (args.v1.ucReplyStatus == 2) {
0128         DRM_DEBUG_KMS("dp_aux_ch flags not zero\n");
0129         r = -EIO;
0130         goto done;
0131     }
0132 
0133     /* error */
0134     if (args.v1.ucReplyStatus == 3) {
0135         DRM_DEBUG_KMS("dp_aux_ch error\n");
0136         r = -EIO;
0137         goto done;
0138     }
0139 
0140     recv_bytes = args.v1.ucDataOutLen;
0141     if (recv_bytes > recv_size)
0142         recv_bytes = recv_size;
0143 
0144     if (recv && recv_size)
0145         radeon_atom_copy_swap(recv, base + 16, recv_bytes, false);
0146 
0147     r = recv_bytes;
0148 done:
0149     mutex_unlock(&rdev->mode_info.atom_context->scratch_mutex);
0150     mutex_unlock(&chan->mutex);
0151 
0152     return r;
0153 }
0154 
0155 #define BARE_ADDRESS_SIZE 3
0156 #define HEADER_SIZE (BARE_ADDRESS_SIZE + 1)
0157 
0158 static ssize_t
0159 radeon_dp_aux_transfer_atom(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
0160 {
0161     struct radeon_i2c_chan *chan =
0162         container_of(aux, struct radeon_i2c_chan, aux);
0163     int ret;
0164     u8 tx_buf[20];
0165     size_t tx_size;
0166     u8 ack, delay = 0;
0167 
0168     if (WARN_ON(msg->size > 16))
0169         return -E2BIG;
0170 
0171     tx_buf[0] = msg->address & 0xff;
0172     tx_buf[1] = (msg->address >> 8) & 0xff;
0173     tx_buf[2] = (msg->request << 4) |
0174         ((msg->address >> 16) & 0xf);
0175     tx_buf[3] = msg->size ? (msg->size - 1) : 0;
0176 
0177     switch (msg->request & ~DP_AUX_I2C_MOT) {
0178     case DP_AUX_NATIVE_WRITE:
0179     case DP_AUX_I2C_WRITE:
0180     case DP_AUX_I2C_WRITE_STATUS_UPDATE:
0181         /* The atom implementation only supports writes with a max payload of
0182          * 12 bytes since it uses 4 bits for the total count (header + payload)
0183          * in the parameter space.  The atom interface supports 16 byte
0184          * payloads for reads. The hw itself supports up to 16 bytes of payload.
0185          */
0186         if (WARN_ON_ONCE(msg->size > 12))
0187             return -E2BIG;
0188         /* tx_size needs to be 4 even for bare address packets since the atom
0189          * table needs the info in tx_buf[3].
0190          */
0191         tx_size = HEADER_SIZE + msg->size;
0192         if (msg->size == 0)
0193             tx_buf[3] |= BARE_ADDRESS_SIZE << 4;
0194         else
0195             tx_buf[3] |= tx_size << 4;
0196         memcpy(tx_buf + HEADER_SIZE, msg->buffer, msg->size);
0197         ret = radeon_process_aux_ch(chan,
0198                         tx_buf, tx_size, NULL, 0, delay, &ack);
0199         if (ret >= 0)
0200             /* Return payload size. */
0201             ret = msg->size;
0202         break;
0203     case DP_AUX_NATIVE_READ:
0204     case DP_AUX_I2C_READ:
0205         /* tx_size needs to be 4 even for bare address packets since the atom
0206          * table needs the info in tx_buf[3].
0207          */
0208         tx_size = HEADER_SIZE;
0209         if (msg->size == 0)
0210             tx_buf[3] |= BARE_ADDRESS_SIZE << 4;
0211         else
0212             tx_buf[3] |= tx_size << 4;
0213         ret = radeon_process_aux_ch(chan,
0214                         tx_buf, tx_size, msg->buffer, msg->size, delay, &ack);
0215         break;
0216     default:
0217         ret = -EINVAL;
0218         break;
0219     }
0220 
0221     if (ret >= 0)
0222         msg->reply = ack >> 4;
0223 
0224     return ret;
0225 }
0226 
0227 void radeon_dp_aux_init(struct radeon_connector *radeon_connector)
0228 {
0229     struct drm_device *dev = radeon_connector->base.dev;
0230     struct radeon_device *rdev = dev->dev_private;
0231     int ret;
0232 
0233     radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd;
0234     radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev;
0235     radeon_connector->ddc_bus->aux.drm_dev = radeon_connector->base.dev;
0236     if (ASIC_IS_DCE5(rdev)) {
0237         if (radeon_auxch)
0238             radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_native;
0239         else
0240             radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_atom;
0241     } else {
0242         radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_atom;
0243     }
0244 
0245     ret = drm_dp_aux_register(&radeon_connector->ddc_bus->aux);
0246     if (!ret)
0247         radeon_connector->ddc_bus->has_aux = true;
0248 
0249     WARN(ret, "drm_dp_aux_register() failed with error %d\n", ret);
0250 }
0251 
0252 /***** general DP utility functions *****/
0253 
0254 #define DP_VOLTAGE_MAX         DP_TRAIN_VOLTAGE_SWING_LEVEL_3
0255 #define DP_PRE_EMPHASIS_MAX    DP_TRAIN_PRE_EMPH_LEVEL_3
0256 
0257 static void dp_get_adjust_train(const u8 link_status[DP_LINK_STATUS_SIZE],
0258                 int lane_count,
0259                 u8 train_set[4])
0260 {
0261     u8 v = 0;
0262     u8 p = 0;
0263     int lane;
0264 
0265     for (lane = 0; lane < lane_count; lane++) {
0266         u8 this_v = drm_dp_get_adjust_request_voltage(link_status, lane);
0267         u8 this_p = drm_dp_get_adjust_request_pre_emphasis(link_status, lane);
0268 
0269         DRM_DEBUG_KMS("requested signal parameters: lane %d voltage %s pre_emph %s\n",
0270               lane,
0271               voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
0272               pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
0273 
0274         if (this_v > v)
0275             v = this_v;
0276         if (this_p > p)
0277             p = this_p;
0278     }
0279 
0280     if (v >= DP_VOLTAGE_MAX)
0281         v |= DP_TRAIN_MAX_SWING_REACHED;
0282 
0283     if (p >= DP_PRE_EMPHASIS_MAX)
0284         p |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
0285 
0286     DRM_DEBUG_KMS("using signal parameters: voltage %s pre_emph %s\n",
0287           voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
0288           pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
0289 
0290     for (lane = 0; lane < 4; lane++)
0291         train_set[lane] = v | p;
0292 }
0293 
0294 /* convert bits per color to bits per pixel */
0295 /* get bpc from the EDID */
0296 static int convert_bpc_to_bpp(int bpc)
0297 {
0298     if (bpc == 0)
0299         return 24;
0300     else
0301         return bpc * 3;
0302 }
0303 
0304 /***** radeon specific DP functions *****/
0305 
0306 static int radeon_dp_get_dp_link_config(struct drm_connector *connector,
0307                     const u8 dpcd[DP_DPCD_SIZE],
0308                     unsigned pix_clock,
0309                     unsigned *dp_lanes, unsigned *dp_rate)
0310 {
0311     int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
0312     static const unsigned link_rates[3] = { 162000, 270000, 540000 };
0313     unsigned max_link_rate = drm_dp_max_link_rate(dpcd);
0314     unsigned max_lane_num = drm_dp_max_lane_count(dpcd);
0315     unsigned lane_num, i, max_pix_clock;
0316 
0317     if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
0318         ENCODER_OBJECT_ID_NUTMEG) {
0319         for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
0320             max_pix_clock = (lane_num * 270000 * 8) / bpp;
0321             if (max_pix_clock >= pix_clock) {
0322                 *dp_lanes = lane_num;
0323                 *dp_rate = 270000;
0324                 return 0;
0325             }
0326         }
0327     } else {
0328         for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) {
0329             for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
0330                 max_pix_clock = (lane_num * link_rates[i] * 8) / bpp;
0331                 if (max_pix_clock >= pix_clock) {
0332                     *dp_lanes = lane_num;
0333                     *dp_rate = link_rates[i];
0334                     return 0;
0335                 }
0336             }
0337         }
0338     }
0339 
0340     return -EINVAL;
0341 }
0342 
0343 static u8 radeon_dp_encoder_service(struct radeon_device *rdev,
0344                     int action, int dp_clock,
0345                     u8 ucconfig, u8 lane_num)
0346 {
0347     DP_ENCODER_SERVICE_PARAMETERS args;
0348     int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
0349 
0350     memset(&args, 0, sizeof(args));
0351     args.ucLinkClock = dp_clock / 10;
0352     args.ucConfig = ucconfig;
0353     args.ucAction = action;
0354     args.ucLaneNum = lane_num;
0355     args.ucStatus = 0;
0356 
0357     atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
0358     return args.ucStatus;
0359 }
0360 
0361 u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector)
0362 {
0363     struct drm_device *dev = radeon_connector->base.dev;
0364     struct radeon_device *rdev = dev->dev_private;
0365 
0366     return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0,
0367                      radeon_connector->ddc_bus->rec.i2c_id, 0);
0368 }
0369 
0370 static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
0371 {
0372     struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
0373     u8 buf[3];
0374 
0375     if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
0376         return;
0377 
0378     if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3) == 3)
0379         DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
0380                   buf[0], buf[1], buf[2]);
0381 
0382     if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3) == 3)
0383         DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
0384                   buf[0], buf[1], buf[2]);
0385 }
0386 
0387 bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
0388 {
0389     struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
0390     u8 msg[DP_DPCD_SIZE];
0391     int ret;
0392 
0393     ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg,
0394                    DP_DPCD_SIZE);
0395     if (ret == DP_DPCD_SIZE) {
0396         memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
0397 
0398         DRM_DEBUG_KMS("DPCD: %*ph\n", (int)sizeof(dig_connector->dpcd),
0399                   dig_connector->dpcd);
0400 
0401         radeon_dp_probe_oui(radeon_connector);
0402 
0403         return true;
0404     }
0405 
0406     dig_connector->dpcd[0] = 0;
0407     return false;
0408 }
0409 
0410 int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
0411                  struct drm_connector *connector)
0412 {
0413     struct drm_device *dev = encoder->dev;
0414     struct radeon_device *rdev = dev->dev_private;
0415     struct radeon_connector *radeon_connector = to_radeon_connector(connector);
0416     int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
0417     u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector);
0418     u8 tmp;
0419 
0420     if (!ASIC_IS_DCE4(rdev))
0421         return panel_mode;
0422 
0423     if (!radeon_connector->con_priv)
0424         return panel_mode;
0425 
0426     if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
0427         /* DP bridge chips */
0428         if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
0429                       DP_EDP_CONFIGURATION_CAP, &tmp) == 1) {
0430             if (tmp & 1)
0431                 panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
0432             else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) ||
0433                  (dp_bridge == ENCODER_OBJECT_ID_TRAVIS))
0434                 panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
0435             else
0436                 panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
0437         }
0438     } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
0439         /* eDP */
0440         if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
0441                       DP_EDP_CONFIGURATION_CAP, &tmp) == 1) {
0442             if (tmp & 1)
0443                 panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
0444         }
0445     }
0446 
0447     return panel_mode;
0448 }
0449 
0450 void radeon_dp_set_link_config(struct drm_connector *connector,
0451                    const struct drm_display_mode *mode)
0452 {
0453     struct radeon_connector *radeon_connector = to_radeon_connector(connector);
0454     struct radeon_connector_atom_dig *dig_connector;
0455     int ret;
0456 
0457     if (!radeon_connector->con_priv)
0458         return;
0459     dig_connector = radeon_connector->con_priv;
0460 
0461     if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
0462         (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
0463         ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd,
0464                            mode->clock,
0465                            &dig_connector->dp_lane_count,
0466                            &dig_connector->dp_clock);
0467         if (ret) {
0468             dig_connector->dp_clock = 0;
0469             dig_connector->dp_lane_count = 0;
0470         }
0471     }
0472 }
0473 
0474 int radeon_dp_mode_valid_helper(struct drm_connector *connector,
0475                 struct drm_display_mode *mode)
0476 {
0477     struct radeon_connector *radeon_connector = to_radeon_connector(connector);
0478     struct radeon_connector_atom_dig *dig_connector;
0479     unsigned dp_clock, dp_lanes;
0480     int ret;
0481 
0482     if ((mode->clock > 340000) &&
0483         (!radeon_connector_is_dp12_capable(connector)))
0484         return MODE_CLOCK_HIGH;
0485 
0486     if (!radeon_connector->con_priv)
0487         return MODE_CLOCK_HIGH;
0488     dig_connector = radeon_connector->con_priv;
0489 
0490     ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd,
0491                        mode->clock,
0492                        &dp_lanes,
0493                        &dp_clock);
0494     if (ret)
0495         return MODE_CLOCK_HIGH;
0496 
0497     if ((dp_clock == 540000) &&
0498         (!radeon_connector_is_dp12_capable(connector)))
0499         return MODE_CLOCK_HIGH;
0500 
0501     return MODE_OK;
0502 }
0503 
0504 bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
0505 {
0506     u8 link_status[DP_LINK_STATUS_SIZE];
0507     struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
0508 
0509     if (drm_dp_dpcd_read_link_status(&radeon_connector->ddc_bus->aux, link_status)
0510         <= 0)
0511         return false;
0512     if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count))
0513         return false;
0514     return true;
0515 }
0516 
0517 void radeon_dp_set_rx_power_state(struct drm_connector *connector,
0518                   u8 power_state)
0519 {
0520     struct radeon_connector *radeon_connector = to_radeon_connector(connector);
0521     struct radeon_connector_atom_dig *dig_connector;
0522 
0523     if (!radeon_connector->con_priv)
0524         return;
0525 
0526     dig_connector = radeon_connector->con_priv;
0527 
0528     /* power up/down the sink */
0529     if (dig_connector->dpcd[0] >= 0x11) {
0530         drm_dp_dpcd_writeb(&radeon_connector->ddc_bus->aux,
0531                    DP_SET_POWER, power_state);
0532         usleep_range(1000, 2000);
0533     }
0534 }
0535 
0536 
0537 struct radeon_dp_link_train_info {
0538     struct radeon_device *rdev;
0539     struct drm_encoder *encoder;
0540     struct drm_connector *connector;
0541     int enc_id;
0542     int dp_clock;
0543     int dp_lane_count;
0544     bool tp3_supported;
0545     u8 dpcd[DP_RECEIVER_CAP_SIZE];
0546     u8 train_set[4];
0547     u8 link_status[DP_LINK_STATUS_SIZE];
0548     u8 tries;
0549     bool use_dpencoder;
0550     struct drm_dp_aux *aux;
0551 };
0552 
0553 static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info)
0554 {
0555     /* set the initial vs/emph on the source */
0556     atombios_dig_transmitter_setup(dp_info->encoder,
0557                        ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH,
0558                        0, dp_info->train_set[0]); /* sets all lanes at once */
0559 
0560     /* set the vs/emph on the sink */
0561     drm_dp_dpcd_write(dp_info->aux, DP_TRAINING_LANE0_SET,
0562               dp_info->train_set, dp_info->dp_lane_count);
0563 }
0564 
0565 static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp)
0566 {
0567     int rtp = 0;
0568 
0569     /* set training pattern on the source */
0570     if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) {
0571         switch (tp) {
0572         case DP_TRAINING_PATTERN_1:
0573             rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1;
0574             break;
0575         case DP_TRAINING_PATTERN_2:
0576             rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2;
0577             break;
0578         case DP_TRAINING_PATTERN_3:
0579             rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN3;
0580             break;
0581         }
0582         atombios_dig_encoder_setup(dp_info->encoder, rtp, 0);
0583     } else {
0584         switch (tp) {
0585         case DP_TRAINING_PATTERN_1:
0586             rtp = 0;
0587             break;
0588         case DP_TRAINING_PATTERN_2:
0589             rtp = 1;
0590             break;
0591         }
0592         radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
0593                       dp_info->dp_clock, dp_info->enc_id, rtp);
0594     }
0595 
0596     /* enable training pattern on the sink */
0597     drm_dp_dpcd_writeb(dp_info->aux, DP_TRAINING_PATTERN_SET, tp);
0598 }
0599 
0600 static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info)
0601 {
0602     struct radeon_encoder *radeon_encoder = to_radeon_encoder(dp_info->encoder);
0603     struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
0604     u8 tmp;
0605 
0606     /* power up the sink */
0607     radeon_dp_set_rx_power_state(dp_info->connector, DP_SET_POWER_D0);
0608 
0609     /* possibly enable downspread on the sink */
0610     if (dp_info->dpcd[3] & 0x1)
0611         drm_dp_dpcd_writeb(dp_info->aux,
0612                    DP_DOWNSPREAD_CTRL, DP_SPREAD_AMP_0_5);
0613     else
0614         drm_dp_dpcd_writeb(dp_info->aux,
0615                    DP_DOWNSPREAD_CTRL, 0);
0616 
0617     if (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)
0618         drm_dp_dpcd_writeb(dp_info->aux, DP_EDP_CONFIGURATION_SET, 1);
0619 
0620     /* set the lane count on the sink */
0621     tmp = dp_info->dp_lane_count;
0622     if (drm_dp_enhanced_frame_cap(dp_info->dpcd))
0623         tmp |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
0624     drm_dp_dpcd_writeb(dp_info->aux, DP_LANE_COUNT_SET, tmp);
0625 
0626     /* set the link rate on the sink */
0627     tmp = drm_dp_link_rate_to_bw_code(dp_info->dp_clock);
0628     drm_dp_dpcd_writeb(dp_info->aux, DP_LINK_BW_SET, tmp);
0629 
0630     /* start training on the source */
0631     if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder)
0632         atombios_dig_encoder_setup(dp_info->encoder,
0633                        ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0);
0634     else
0635         radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_START,
0636                       dp_info->dp_clock, dp_info->enc_id, 0);
0637 
0638     /* disable the training pattern on the sink */
0639     drm_dp_dpcd_writeb(dp_info->aux,
0640                DP_TRAINING_PATTERN_SET,
0641                DP_TRAINING_PATTERN_DISABLE);
0642 
0643     return 0;
0644 }
0645 
0646 static int radeon_dp_link_train_finish(struct radeon_dp_link_train_info *dp_info)
0647 {
0648     udelay(400);
0649 
0650     /* disable the training pattern on the sink */
0651     drm_dp_dpcd_writeb(dp_info->aux,
0652                DP_TRAINING_PATTERN_SET,
0653                DP_TRAINING_PATTERN_DISABLE);
0654 
0655     /* disable the training pattern on the source */
0656     if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder)
0657         atombios_dig_encoder_setup(dp_info->encoder,
0658                        ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0);
0659     else
0660         radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
0661                       dp_info->dp_clock, dp_info->enc_id, 0);
0662 
0663     return 0;
0664 }
0665 
0666 static int radeon_dp_link_train_cr(struct radeon_dp_link_train_info *dp_info)
0667 {
0668     bool clock_recovery;
0669     u8 voltage;
0670     int i;
0671 
0672     radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_1);
0673     memset(dp_info->train_set, 0, 4);
0674     radeon_dp_update_vs_emph(dp_info);
0675 
0676     udelay(400);
0677 
0678     /* clock recovery loop */
0679     clock_recovery = false;
0680     dp_info->tries = 0;
0681     voltage = 0xff;
0682     while (1) {
0683         drm_dp_link_train_clock_recovery_delay(dp_info->aux, dp_info->dpcd);
0684 
0685         if (drm_dp_dpcd_read_link_status(dp_info->aux,
0686                          dp_info->link_status) <= 0) {
0687             DRM_ERROR("displayport link status failed\n");
0688             break;
0689         }
0690 
0691         if (drm_dp_clock_recovery_ok(dp_info->link_status, dp_info->dp_lane_count)) {
0692             clock_recovery = true;
0693             break;
0694         }
0695 
0696         for (i = 0; i < dp_info->dp_lane_count; i++) {
0697             if ((dp_info->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
0698                 break;
0699         }
0700         if (i == dp_info->dp_lane_count) {
0701             DRM_ERROR("clock recovery reached max voltage\n");
0702             break;
0703         }
0704 
0705         if ((dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
0706             ++dp_info->tries;
0707             if (dp_info->tries == 5) {
0708                 DRM_ERROR("clock recovery tried 5 times\n");
0709                 break;
0710             }
0711         } else
0712             dp_info->tries = 0;
0713 
0714         voltage = dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
0715 
0716         /* Compute new train_set as requested by sink */
0717         dp_get_adjust_train(dp_info->link_status, dp_info->dp_lane_count, dp_info->train_set);
0718 
0719         radeon_dp_update_vs_emph(dp_info);
0720     }
0721     if (!clock_recovery) {
0722         DRM_ERROR("clock recovery failed\n");
0723         return -1;
0724     } else {
0725         DRM_DEBUG_KMS("clock recovery at voltage %d pre-emphasis %d\n",
0726               dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
0727               (dp_info->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >>
0728               DP_TRAIN_PRE_EMPHASIS_SHIFT);
0729         return 0;
0730     }
0731 }
0732 
0733 static int radeon_dp_link_train_ce(struct radeon_dp_link_train_info *dp_info)
0734 {
0735     bool channel_eq;
0736 
0737     if (dp_info->tp3_supported)
0738         radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_3);
0739     else
0740         radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_2);
0741 
0742     /* channel equalization loop */
0743     dp_info->tries = 0;
0744     channel_eq = false;
0745     while (1) {
0746         drm_dp_link_train_channel_eq_delay(dp_info->aux, dp_info->dpcd);
0747 
0748         if (drm_dp_dpcd_read_link_status(dp_info->aux,
0749                          dp_info->link_status) <= 0) {
0750             DRM_ERROR("displayport link status failed\n");
0751             break;
0752         }
0753 
0754         if (drm_dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) {
0755             channel_eq = true;
0756             break;
0757         }
0758 
0759         /* Try 5 times */
0760         if (dp_info->tries > 5) {
0761             DRM_ERROR("channel eq failed: 5 tries\n");
0762             break;
0763         }
0764 
0765         /* Compute new train_set as requested by sink */
0766         dp_get_adjust_train(dp_info->link_status, dp_info->dp_lane_count, dp_info->train_set);
0767 
0768         radeon_dp_update_vs_emph(dp_info);
0769         dp_info->tries++;
0770     }
0771 
0772     if (!channel_eq) {
0773         DRM_ERROR("channel eq failed\n");
0774         return -1;
0775     } else {
0776         DRM_DEBUG_KMS("channel eq at voltage %d pre-emphasis %d\n",
0777               dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
0778               (dp_info->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK)
0779               >> DP_TRAIN_PRE_EMPHASIS_SHIFT);
0780         return 0;
0781     }
0782 }
0783 
0784 void radeon_dp_link_train(struct drm_encoder *encoder,
0785               struct drm_connector *connector)
0786 {
0787     struct drm_device *dev = encoder->dev;
0788     struct radeon_device *rdev = dev->dev_private;
0789     struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
0790     struct radeon_encoder_atom_dig *dig;
0791     struct radeon_connector *radeon_connector;
0792     struct radeon_connector_atom_dig *dig_connector;
0793     struct radeon_dp_link_train_info dp_info;
0794     int index;
0795     u8 tmp, frev, crev;
0796 
0797     if (!radeon_encoder->enc_priv)
0798         return;
0799     dig = radeon_encoder->enc_priv;
0800 
0801     radeon_connector = to_radeon_connector(connector);
0802     if (!radeon_connector->con_priv)
0803         return;
0804     dig_connector = radeon_connector->con_priv;
0805 
0806     if ((dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT) &&
0807         (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_eDP))
0808         return;
0809 
0810     /* DPEncoderService newer than 1.1 can't program properly the
0811      * training pattern. When facing such version use the
0812      * DIGXEncoderControl (X== 1 | 2)
0813      */
0814     dp_info.use_dpencoder = true;
0815     index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
0816     if (atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) {
0817         if (crev > 1)
0818             dp_info.use_dpencoder = false;
0819     }
0820 
0821     dp_info.enc_id = 0;
0822     if (dig->dig_encoder)
0823         dp_info.enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
0824     else
0825         dp_info.enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER;
0826     if (dig->linkb)
0827         dp_info.enc_id |= ATOM_DP_CONFIG_LINK_B;
0828     else
0829         dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;
0830 
0831     if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp)
0832         == 1) {
0833         if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
0834             dp_info.tp3_supported = true;
0835         else
0836             dp_info.tp3_supported = false;
0837     } else {
0838         dp_info.tp3_supported = false;
0839     }
0840 
0841     memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE);
0842     dp_info.rdev = rdev;
0843     dp_info.encoder = encoder;
0844     dp_info.connector = connector;
0845     dp_info.dp_lane_count = dig_connector->dp_lane_count;
0846     dp_info.dp_clock = dig_connector->dp_clock;
0847     dp_info.aux = &radeon_connector->ddc_bus->aux;
0848 
0849     if (radeon_dp_link_train_init(&dp_info))
0850         goto done;
0851     if (radeon_dp_link_train_cr(&dp_info))
0852         goto done;
0853     if (radeon_dp_link_train_ce(&dp_info))
0854         goto done;
0855 done:
0856     if (radeon_dp_link_train_finish(&dp_info))
0857         return;
0858 }