Line data Source code
1 : /*
2 : * Copyright 2007-8 Advanced Micro Devices, Inc.
3 : * Copyright 2008 Red Hat Inc.
4 : *
5 : * Permission is hereby granted, free of charge, to any person obtaining a
6 : * copy of this software and associated documentation files (the "Software"),
7 : * to deal in the Software without restriction, including without limitation
8 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 : * and/or sell copies of the Software, and to permit persons to whom the
10 : * Software is furnished to do so, subject to the following conditions:
11 : *
12 : * The above copyright notice and this permission notice shall be included in
13 : * all copies or substantial portions of the Software.
14 : *
15 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 : * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 : * 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 OR
21 : * OTHER DEALINGS IN THE SOFTWARE.
22 : *
23 : * Authors: Dave Airlie
24 : * Alex Deucher
25 : * Jerome Glisse
26 : */
27 : #include <dev/pci/drm/drmP.h>
28 : #include <dev/pci/drm/radeon_drm.h>
29 : #include "radeon.h"
30 :
31 : #include "atom.h"
32 : #include "atom-bits.h"
33 : #include <dev/pci/drm/drm_dp_helper.h>
34 :
35 : /* move these to drm_dp_helper.c/h */
36 : #define DP_LINK_CONFIGURATION_SIZE 9
37 : #define DP_DPCD_SIZE DP_RECEIVER_CAP_SIZE
38 :
39 : #ifdef DRMDEBUG
40 : static char *voltage_names[] = {
41 : "0.4V", "0.6V", "0.8V", "1.2V"
42 : };
43 : static char *pre_emph_names[] = {
44 : "0dB", "3.5dB", "6dB", "9.5dB"
45 : };
46 : #endif
47 :
48 : /***** radeon AUX functions *****/
49 :
50 : /* Atom needs data in little endian format so swap as appropriate when copying
51 : * data to or from atom. Note that atom operates on dw units.
52 : *
53 : * Use to_le=true when sending data to atom and provide at least
54 : * ALIGN(num_bytes,4) bytes in the dst buffer.
55 : *
56 : * Use to_le=false when receiving data from atom and provide ALIGN(num_bytes,4)
57 : * byes in the src buffer.
58 : */
59 0 : void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le)
60 : {
61 : #ifdef __BIG_ENDIAN
62 : u32 src_tmp[5], dst_tmp[5];
63 : int i;
64 : u8 align_num_bytes = roundup2(num_bytes, 4);
65 :
66 : if (to_le) {
67 : memcpy(src_tmp, src, num_bytes);
68 : for (i = 0; i < align_num_bytes / 4; i++)
69 : dst_tmp[i] = cpu_to_le32(src_tmp[i]);
70 : memcpy(dst, dst_tmp, align_num_bytes);
71 : } else {
72 : memcpy(src_tmp, src, align_num_bytes);
73 : for (i = 0; i < align_num_bytes / 4; i++)
74 : dst_tmp[i] = le32_to_cpu(src_tmp[i]);
75 : memcpy(dst, dst_tmp, num_bytes);
76 : }
77 : #else
78 0 : memcpy(dst, src, num_bytes);
79 : #endif
80 0 : }
81 :
82 : union aux_channel_transaction {
83 : PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1;
84 : PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2;
85 : };
86 :
87 0 : static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
88 : u8 *send, int send_bytes,
89 : u8 *recv, int recv_size,
90 : u8 delay, u8 *ack)
91 : {
92 0 : struct drm_device *dev = chan->dev;
93 0 : struct radeon_device *rdev = dev->dev_private;
94 0 : union aux_channel_transaction args;
95 : int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
96 : unsigned char *base;
97 : int recv_bytes;
98 : int r = 0;
99 :
100 0 : memset(&args, 0, sizeof(args));
101 :
102 0 : mutex_lock(&chan->mutex);
103 0 : mutex_lock(&rdev->mode_info.atom_context->scratch_mutex);
104 :
105 0 : base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1);
106 :
107 0 : radeon_atom_copy_swap(base, send, send_bytes, true);
108 :
109 0 : args.v1.lpAuxRequest = cpu_to_le16((u16)(0 + 4));
110 0 : args.v1.lpDataOut = cpu_to_le16((u16)(16 + 4));
111 0 : args.v1.ucDataOutLen = 0;
112 0 : args.v1.ucChannelID = chan->rec.i2c_id;
113 0 : args.v1.ucDelay = delay / 10;
114 0 : if (ASIC_IS_DCE4(rdev))
115 0 : args.v2.ucHPD_ID = chan->rec.hpd;
116 :
117 0 : atom_execute_table_scratch_unlocked(rdev->mode_info.atom_context, index, (uint32_t *)&args);
118 :
119 0 : *ack = args.v1.ucReplyStatus;
120 :
121 : /* timeout */
122 0 : if (args.v1.ucReplyStatus == 1) {
123 : DRM_DEBUG_KMS("dp_aux_ch timeout\n");
124 : r = -ETIMEDOUT;
125 0 : goto done;
126 : }
127 :
128 : /* flags not zero */
129 0 : if (args.v1.ucReplyStatus == 2) {
130 : DRM_DEBUG_KMS("dp_aux_ch flags not zero\n");
131 : r = -EIO;
132 0 : goto done;
133 : }
134 :
135 : /* error */
136 0 : if (args.v1.ucReplyStatus == 3) {
137 : DRM_DEBUG_KMS("dp_aux_ch error\n");
138 : r = -EIO;
139 0 : goto done;
140 : }
141 :
142 0 : recv_bytes = args.v1.ucDataOutLen;
143 0 : if (recv_bytes > recv_size)
144 0 : recv_bytes = recv_size;
145 :
146 0 : if (recv && recv_size)
147 0 : radeon_atom_copy_swap(recv, base + 16, recv_bytes, false);
148 :
149 0 : r = recv_bytes;
150 : done:
151 0 : mutex_unlock(&rdev->mode_info.atom_context->scratch_mutex);
152 0 : mutex_unlock(&chan->mutex);
153 :
154 0 : return r;
155 0 : }
156 :
157 : #define BARE_ADDRESS_SIZE 3
158 : #define HEADER_SIZE (BARE_ADDRESS_SIZE + 1)
159 :
160 : static ssize_t
161 0 : radeon_dp_aux_transfer_atom(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
162 : {
163 : struct radeon_i2c_chan *chan =
164 0 : container_of(aux, struct radeon_i2c_chan, aux);
165 : int ret;
166 0 : u8 tx_buf[20];
167 : size_t tx_size;
168 0 : u8 ack, delay = 0;
169 :
170 0 : if (WARN_ON(msg->size > 16))
171 0 : return -E2BIG;
172 :
173 0 : tx_buf[0] = msg->address & 0xff;
174 0 : tx_buf[1] = (msg->address >> 8) & 0xff;
175 0 : tx_buf[2] = (msg->request << 4) |
176 0 : ((msg->address >> 16) & 0xf);
177 0 : tx_buf[3] = msg->size ? (msg->size - 1) : 0;
178 :
179 0 : switch (msg->request & ~DP_AUX_I2C_MOT) {
180 : case DP_AUX_NATIVE_WRITE:
181 : case DP_AUX_I2C_WRITE:
182 : case DP_AUX_I2C_WRITE_STATUS_UPDATE:
183 : /* The atom implementation only supports writes with a max payload of
184 : * 12 bytes since it uses 4 bits for the total count (header + payload)
185 : * in the parameter space. The atom interface supports 16 byte
186 : * payloads for reads. The hw itself supports up to 16 bytes of payload.
187 : */
188 0 : if (WARN_ON_ONCE(msg->size > 12))
189 0 : return -E2BIG;
190 : /* tx_size needs to be 4 even for bare address packets since the atom
191 : * table needs the info in tx_buf[3].
192 : */
193 0 : tx_size = HEADER_SIZE + msg->size;
194 0 : if (msg->size == 0)
195 0 : tx_buf[3] |= BARE_ADDRESS_SIZE << 4;
196 : else
197 0 : tx_buf[3] |= tx_size << 4;
198 0 : memcpy(tx_buf + HEADER_SIZE, msg->buffer, msg->size);
199 0 : ret = radeon_process_aux_ch(chan,
200 0 : tx_buf, tx_size, NULL, 0, delay, &ack);
201 0 : if (ret >= 0)
202 : /* Return payload size. */
203 0 : ret = msg->size;
204 : break;
205 : case DP_AUX_NATIVE_READ:
206 : case DP_AUX_I2C_READ:
207 : /* tx_size needs to be 4 even for bare address packets since the atom
208 : * table needs the info in tx_buf[3].
209 : */
210 : tx_size = HEADER_SIZE;
211 0 : if (msg->size == 0)
212 0 : tx_buf[3] |= BARE_ADDRESS_SIZE << 4;
213 : else
214 0 : tx_buf[3] |= tx_size << 4;
215 0 : ret = radeon_process_aux_ch(chan,
216 0 : tx_buf, tx_size, msg->buffer, msg->size, delay, &ack);
217 0 : break;
218 : default:
219 : ret = -EINVAL;
220 0 : break;
221 : }
222 :
223 0 : if (ret >= 0)
224 0 : msg->reply = ack >> 4;
225 :
226 0 : return ret;
227 0 : }
228 :
229 0 : void radeon_dp_aux_init(struct radeon_connector *radeon_connector)
230 : {
231 0 : struct drm_device *dev = radeon_connector->base.dev;
232 0 : struct radeon_device *rdev = dev->dev_private;
233 : int ret;
234 :
235 0 : radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd;
236 0 : radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev;
237 0 : if (ASIC_IS_DCE5(rdev)) {
238 0 : if (radeon_auxch)
239 0 : radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_native;
240 : else
241 0 : radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_atom;
242 : } else {
243 0 : radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer_atom;
244 : }
245 :
246 0 : ret = drm_dp_aux_register(&radeon_connector->ddc_bus->aux);
247 0 : if (!ret)
248 0 : radeon_connector->ddc_bus->has_aux = true;
249 :
250 0 : WARN(ret, "drm_dp_aux_register() failed with error %d\n", ret);
251 0 : }
252 :
253 : /***** general DP utility functions *****/
254 :
255 : #define DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_LEVEL_3
256 : #define DP_PRE_EMPHASIS_MAX DP_TRAIN_PRE_EMPH_LEVEL_3
257 :
258 0 : static void dp_get_adjust_train(const u8 link_status[DP_LINK_STATUS_SIZE],
259 : int lane_count,
260 : u8 train_set[4])
261 : {
262 : u8 v = 0;
263 : u8 p = 0;
264 : int lane;
265 :
266 0 : for (lane = 0; lane < lane_count; lane++) {
267 0 : u8 this_v = drm_dp_get_adjust_request_voltage(link_status, lane);
268 0 : u8 this_p = drm_dp_get_adjust_request_pre_emphasis(link_status, lane);
269 :
270 : DRM_DEBUG_KMS("requested signal parameters: lane %d voltage %s pre_emph %s\n",
271 : lane,
272 : voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
273 : pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
274 :
275 0 : if (this_v > v)
276 0 : v = this_v;
277 0 : if (this_p > p)
278 0 : p = this_p;
279 : }
280 :
281 0 : if (v >= DP_VOLTAGE_MAX)
282 0 : v |= DP_TRAIN_MAX_SWING_REACHED;
283 :
284 0 : if (p >= DP_PRE_EMPHASIS_MAX)
285 0 : p |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
286 :
287 : DRM_DEBUG_KMS("using signal parameters: voltage %s pre_emph %s\n",
288 : voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
289 : pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
290 :
291 0 : for (lane = 0; lane < 4; lane++)
292 0 : train_set[lane] = v | p;
293 0 : }
294 :
295 : /* convert bits per color to bits per pixel */
296 : /* get bpc from the EDID */
297 0 : static int convert_bpc_to_bpp(int bpc)
298 : {
299 0 : if (bpc == 0)
300 0 : return 24;
301 : else
302 0 : return bpc * 3;
303 0 : }
304 :
305 : /***** radeon specific DP functions *****/
306 :
307 0 : int radeon_dp_get_dp_link_config(struct drm_connector *connector,
308 : const u8 dpcd[DP_DPCD_SIZE],
309 : unsigned pix_clock,
310 : unsigned *dp_lanes, unsigned *dp_rate)
311 : {
312 0 : int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
313 : static const unsigned link_rates[3] = { 162000, 270000, 540000 };
314 0 : unsigned max_link_rate = drm_dp_max_link_rate(dpcd);
315 0 : unsigned max_lane_num = drm_dp_max_lane_count(dpcd);
316 : unsigned lane_num, i, max_pix_clock;
317 :
318 0 : if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
319 : ENCODER_OBJECT_ID_NUTMEG) {
320 0 : for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
321 0 : max_pix_clock = (lane_num * 270000 * 8) / bpp;
322 0 : if (max_pix_clock >= pix_clock) {
323 0 : *dp_lanes = lane_num;
324 0 : *dp_rate = 270000;
325 0 : return 0;
326 : }
327 : }
328 : } else {
329 0 : for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) {
330 0 : for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
331 0 : max_pix_clock = (lane_num * link_rates[i] * 8) / bpp;
332 0 : if (max_pix_clock >= pix_clock) {
333 0 : *dp_lanes = lane_num;
334 0 : *dp_rate = link_rates[i];
335 0 : return 0;
336 : }
337 : }
338 : }
339 : }
340 :
341 0 : return -EINVAL;
342 0 : }
343 :
344 0 : static u8 radeon_dp_encoder_service(struct radeon_device *rdev,
345 : int action, int dp_clock,
346 : u8 ucconfig, u8 lane_num)
347 : {
348 0 : DP_ENCODER_SERVICE_PARAMETERS args;
349 : int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
350 :
351 0 : memset(&args, 0, sizeof(args));
352 0 : args.ucLinkClock = dp_clock / 10;
353 0 : args.ucConfig = ucconfig;
354 0 : args.ucAction = action;
355 0 : args.ucLaneNum = lane_num;
356 0 : args.ucStatus = 0;
357 :
358 0 : atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
359 0 : return args.ucStatus;
360 0 : }
361 :
362 0 : u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector)
363 : {
364 0 : struct drm_device *dev = radeon_connector->base.dev;
365 0 : struct radeon_device *rdev = dev->dev_private;
366 :
367 0 : return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0,
368 0 : radeon_connector->ddc_bus->rec.i2c_id, 0);
369 : }
370 :
371 0 : static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
372 : {
373 0 : struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
374 0 : u8 buf[3];
375 :
376 0 : if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
377 0 : return;
378 :
379 0 : if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3) == 3)
380 : DRM_DEBUG_KMS("Sink OUI: %02x%02x%02x\n",
381 : buf[0], buf[1], buf[2]);
382 :
383 0 : if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3) == 3)
384 : DRM_DEBUG_KMS("Branch OUI: %02x%02x%02x\n",
385 : buf[0], buf[1], buf[2]);
386 0 : }
387 :
388 0 : bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
389 : {
390 0 : struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
391 0 : u8 msg[DP_DPCD_SIZE];
392 : int ret, i;
393 :
394 0 : for (i = 0; i < 7; i++) {
395 0 : ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg,
396 : DP_DPCD_SIZE);
397 0 : if (ret == DP_DPCD_SIZE) {
398 0 : memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
399 :
400 : DRM_DEBUG_KMS("DPCD: %*ph\n", (int)sizeof(dig_connector->dpcd),
401 : dig_connector->dpcd);
402 :
403 0 : radeon_dp_probe_oui(radeon_connector);
404 :
405 0 : return true;
406 : }
407 : }
408 0 : dig_connector->dpcd[0] = 0;
409 0 : return false;
410 0 : }
411 :
412 0 : int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
413 : struct drm_connector *connector)
414 : {
415 0 : struct drm_device *dev = encoder->dev;
416 0 : struct radeon_device *rdev = dev->dev_private;
417 0 : struct radeon_connector *radeon_connector = to_radeon_connector(connector);
418 : struct radeon_connector_atom_dig *dig_connector;
419 : int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
420 0 : u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector);
421 0 : u8 tmp;
422 :
423 0 : if (!ASIC_IS_DCE4(rdev))
424 0 : return panel_mode;
425 :
426 0 : if (!radeon_connector->con_priv)
427 0 : return panel_mode;
428 :
429 : dig_connector = radeon_connector->con_priv;
430 :
431 0 : if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
432 : /* DP bridge chips */
433 0 : if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
434 0 : DP_EDP_CONFIGURATION_CAP, &tmp) == 1) {
435 0 : if (tmp & 1)
436 0 : panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
437 0 : else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) ||
438 0 : (dp_bridge == ENCODER_OBJECT_ID_TRAVIS))
439 0 : panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
440 : else
441 : panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
442 : }
443 0 : } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
444 : /* eDP */
445 0 : if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
446 0 : DP_EDP_CONFIGURATION_CAP, &tmp) == 1) {
447 0 : if (tmp & 1)
448 0 : panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
449 : }
450 : }
451 :
452 0 : return panel_mode;
453 0 : }
454 :
455 0 : void radeon_dp_set_link_config(struct drm_connector *connector,
456 : const struct drm_display_mode *mode)
457 : {
458 0 : struct radeon_connector *radeon_connector = to_radeon_connector(connector);
459 : struct radeon_connector_atom_dig *dig_connector;
460 : int ret;
461 :
462 0 : if (!radeon_connector->con_priv)
463 0 : return;
464 0 : dig_connector = radeon_connector->con_priv;
465 :
466 0 : if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
467 0 : (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
468 0 : ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd,
469 0 : mode->clock,
470 0 : &dig_connector->dp_lane_count,
471 0 : &dig_connector->dp_clock);
472 0 : if (ret) {
473 0 : dig_connector->dp_clock = 0;
474 0 : dig_connector->dp_lane_count = 0;
475 0 : }
476 : }
477 0 : }
478 :
479 0 : int radeon_dp_mode_valid_helper(struct drm_connector *connector,
480 : struct drm_display_mode *mode)
481 : {
482 0 : struct radeon_connector *radeon_connector = to_radeon_connector(connector);
483 : struct radeon_connector_atom_dig *dig_connector;
484 0 : unsigned dp_clock, dp_lanes;
485 : int ret;
486 :
487 0 : if ((mode->clock > 340000) &&
488 0 : (!radeon_connector_is_dp12_capable(connector)))
489 0 : return MODE_CLOCK_HIGH;
490 :
491 0 : if (!radeon_connector->con_priv)
492 0 : return MODE_CLOCK_HIGH;
493 0 : dig_connector = radeon_connector->con_priv;
494 :
495 0 : ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd,
496 0 : mode->clock,
497 : &dp_lanes,
498 : &dp_clock);
499 0 : if (ret)
500 0 : return MODE_CLOCK_HIGH;
501 :
502 0 : if ((dp_clock == 540000) &&
503 0 : (!radeon_connector_is_dp12_capable(connector)))
504 0 : return MODE_CLOCK_HIGH;
505 :
506 0 : return MODE_OK;
507 0 : }
508 :
509 0 : bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
510 : {
511 0 : u8 link_status[DP_LINK_STATUS_SIZE];
512 0 : struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
513 :
514 0 : if (drm_dp_dpcd_read_link_status(&radeon_connector->ddc_bus->aux, link_status)
515 0 : <= 0)
516 0 : return false;
517 0 : if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count))
518 0 : return false;
519 0 : return true;
520 0 : }
521 :
522 0 : void radeon_dp_set_rx_power_state(struct drm_connector *connector,
523 : u8 power_state)
524 : {
525 0 : struct radeon_connector *radeon_connector = to_radeon_connector(connector);
526 : struct radeon_connector_atom_dig *dig_connector;
527 :
528 0 : if (!radeon_connector->con_priv)
529 0 : return;
530 :
531 0 : dig_connector = radeon_connector->con_priv;
532 :
533 : /* power up/down the sink */
534 0 : if (dig_connector->dpcd[0] >= 0x11) {
535 0 : drm_dp_dpcd_writeb(&radeon_connector->ddc_bus->aux,
536 : DP_SET_POWER, power_state);
537 0 : usleep_range(1000, 2000);
538 0 : }
539 0 : }
540 :
541 :
542 : struct radeon_dp_link_train_info {
543 : struct radeon_device *rdev;
544 : struct drm_encoder *encoder;
545 : struct drm_connector *connector;
546 : int enc_id;
547 : int dp_clock;
548 : int dp_lane_count;
549 : bool tp3_supported;
550 : u8 dpcd[DP_RECEIVER_CAP_SIZE];
551 : u8 train_set[4];
552 : u8 link_status[DP_LINK_STATUS_SIZE];
553 : u8 tries;
554 : bool use_dpencoder;
555 : struct drm_dp_aux *aux;
556 : };
557 :
558 0 : static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info)
559 : {
560 : /* set the initial vs/emph on the source */
561 0 : atombios_dig_transmitter_setup(dp_info->encoder,
562 : ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH,
563 0 : 0, dp_info->train_set[0]); /* sets all lanes at once */
564 :
565 : /* set the vs/emph on the sink */
566 0 : drm_dp_dpcd_write(dp_info->aux, DP_TRAINING_LANE0_SET,
567 0 : dp_info->train_set, dp_info->dp_lane_count);
568 0 : }
569 :
570 0 : static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp)
571 : {
572 : int rtp = 0;
573 :
574 : /* set training pattern on the source */
575 0 : if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) {
576 0 : switch (tp) {
577 : case DP_TRAINING_PATTERN_1:
578 : rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1;
579 0 : break;
580 : case DP_TRAINING_PATTERN_2:
581 : rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2;
582 0 : break;
583 : case DP_TRAINING_PATTERN_3:
584 : rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN3;
585 0 : break;
586 : }
587 0 : atombios_dig_encoder_setup(dp_info->encoder, rtp, 0);
588 0 : } else {
589 0 : switch (tp) {
590 : case DP_TRAINING_PATTERN_1:
591 : rtp = 0;
592 0 : break;
593 : case DP_TRAINING_PATTERN_2:
594 : rtp = 1;
595 0 : break;
596 : }
597 0 : radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
598 0 : dp_info->dp_clock, dp_info->enc_id, rtp);
599 : }
600 :
601 : /* enable training pattern on the sink */
602 0 : drm_dp_dpcd_writeb(dp_info->aux, DP_TRAINING_PATTERN_SET, tp);
603 0 : }
604 :
605 0 : static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info)
606 : {
607 0 : struct radeon_encoder *radeon_encoder = to_radeon_encoder(dp_info->encoder);
608 0 : struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
609 : u8 tmp;
610 :
611 : /* power up the sink */
612 0 : radeon_dp_set_rx_power_state(dp_info->connector, DP_SET_POWER_D0);
613 :
614 : /* possibly enable downspread on the sink */
615 0 : if (dp_info->dpcd[3] & 0x1)
616 0 : drm_dp_dpcd_writeb(dp_info->aux,
617 : DP_DOWNSPREAD_CTRL, DP_SPREAD_AMP_0_5);
618 : else
619 0 : drm_dp_dpcd_writeb(dp_info->aux,
620 : DP_DOWNSPREAD_CTRL, 0);
621 :
622 0 : if (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)
623 0 : drm_dp_dpcd_writeb(dp_info->aux, DP_EDP_CONFIGURATION_SET, 1);
624 :
625 : /* set the lane count on the sink */
626 0 : tmp = dp_info->dp_lane_count;
627 0 : if (drm_dp_enhanced_frame_cap(dp_info->dpcd))
628 0 : tmp |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
629 0 : drm_dp_dpcd_writeb(dp_info->aux, DP_LANE_COUNT_SET, tmp);
630 :
631 : /* set the link rate on the sink */
632 0 : tmp = drm_dp_link_rate_to_bw_code(dp_info->dp_clock);
633 0 : drm_dp_dpcd_writeb(dp_info->aux, DP_LINK_BW_SET, tmp);
634 :
635 : /* start training on the source */
636 0 : if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder)
637 0 : atombios_dig_encoder_setup(dp_info->encoder,
638 : ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0);
639 : else
640 0 : radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_START,
641 0 : dp_info->dp_clock, dp_info->enc_id, 0);
642 :
643 : /* disable the training pattern on the sink */
644 0 : drm_dp_dpcd_writeb(dp_info->aux,
645 : DP_TRAINING_PATTERN_SET,
646 : DP_TRAINING_PATTERN_DISABLE);
647 :
648 0 : return 0;
649 : }
650 :
651 0 : static int radeon_dp_link_train_finish(struct radeon_dp_link_train_info *dp_info)
652 : {
653 0 : udelay(400);
654 :
655 : /* disable the training pattern on the sink */
656 0 : drm_dp_dpcd_writeb(dp_info->aux,
657 : DP_TRAINING_PATTERN_SET,
658 : DP_TRAINING_PATTERN_DISABLE);
659 :
660 : /* disable the training pattern on the source */
661 0 : if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder)
662 0 : atombios_dig_encoder_setup(dp_info->encoder,
663 : ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0);
664 : else
665 0 : radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
666 0 : dp_info->dp_clock, dp_info->enc_id, 0);
667 :
668 0 : return 0;
669 : }
670 :
671 0 : static int radeon_dp_link_train_cr(struct radeon_dp_link_train_info *dp_info)
672 : {
673 : bool clock_recovery;
674 : u8 voltage;
675 : int i;
676 :
677 0 : radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_1);
678 0 : memset(dp_info->train_set, 0, 4);
679 0 : radeon_dp_update_vs_emph(dp_info);
680 :
681 0 : udelay(400);
682 :
683 : /* clock recovery loop */
684 : clock_recovery = false;
685 0 : dp_info->tries = 0;
686 : voltage = 0xff;
687 0 : while (1) {
688 0 : drm_dp_link_train_clock_recovery_delay(dp_info->dpcd);
689 :
690 0 : if (drm_dp_dpcd_read_link_status(dp_info->aux,
691 0 : dp_info->link_status) <= 0) {
692 0 : DRM_ERROR("displayport link status failed\n");
693 0 : break;
694 : }
695 :
696 0 : if (drm_dp_clock_recovery_ok(dp_info->link_status, dp_info->dp_lane_count)) {
697 : clock_recovery = true;
698 0 : break;
699 : }
700 :
701 0 : for (i = 0; i < dp_info->dp_lane_count; i++) {
702 0 : if ((dp_info->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
703 : break;
704 : }
705 0 : if (i == dp_info->dp_lane_count) {
706 0 : DRM_ERROR("clock recovery reached max voltage\n");
707 0 : break;
708 : }
709 :
710 0 : if ((dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
711 0 : ++dp_info->tries;
712 0 : if (dp_info->tries == 5) {
713 0 : DRM_ERROR("clock recovery tried 5 times\n");
714 0 : break;
715 : }
716 : } else
717 0 : dp_info->tries = 0;
718 :
719 0 : voltage = dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
720 :
721 : /* Compute new train_set as requested by sink */
722 0 : dp_get_adjust_train(dp_info->link_status, dp_info->dp_lane_count, dp_info->train_set);
723 :
724 0 : radeon_dp_update_vs_emph(dp_info);
725 : }
726 0 : if (!clock_recovery) {
727 0 : DRM_ERROR("clock recovery failed\n");
728 0 : return -1;
729 : } else {
730 : DRM_DEBUG_KMS("clock recovery at voltage %d pre-emphasis %d\n",
731 : dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
732 : (dp_info->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >>
733 : DP_TRAIN_PRE_EMPHASIS_SHIFT);
734 0 : return 0;
735 : }
736 0 : }
737 :
738 0 : static int radeon_dp_link_train_ce(struct radeon_dp_link_train_info *dp_info)
739 : {
740 : bool channel_eq;
741 :
742 0 : if (dp_info->tp3_supported)
743 0 : radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_3);
744 : else
745 0 : radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_2);
746 :
747 : /* channel equalization loop */
748 0 : dp_info->tries = 0;
749 : channel_eq = false;
750 0 : while (1) {
751 0 : drm_dp_link_train_channel_eq_delay(dp_info->dpcd);
752 :
753 0 : if (drm_dp_dpcd_read_link_status(dp_info->aux,
754 0 : dp_info->link_status) <= 0) {
755 0 : DRM_ERROR("displayport link status failed\n");
756 0 : break;
757 : }
758 :
759 0 : if (drm_dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) {
760 : channel_eq = true;
761 0 : break;
762 : }
763 :
764 : /* Try 5 times */
765 0 : if (dp_info->tries > 5) {
766 0 : DRM_ERROR("channel eq failed: 5 tries\n");
767 0 : break;
768 : }
769 :
770 : /* Compute new train_set as requested by sink */
771 0 : dp_get_adjust_train(dp_info->link_status, dp_info->dp_lane_count, dp_info->train_set);
772 :
773 0 : radeon_dp_update_vs_emph(dp_info);
774 0 : dp_info->tries++;
775 : }
776 :
777 0 : if (!channel_eq) {
778 0 : DRM_ERROR("channel eq failed\n");
779 0 : return -1;
780 : } else {
781 : DRM_DEBUG_KMS("channel eq at voltage %d pre-emphasis %d\n",
782 : dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
783 : (dp_info->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK)
784 : >> DP_TRAIN_PRE_EMPHASIS_SHIFT);
785 0 : return 0;
786 : }
787 0 : }
788 :
789 0 : void radeon_dp_link_train(struct drm_encoder *encoder,
790 : struct drm_connector *connector)
791 : {
792 0 : struct drm_device *dev = encoder->dev;
793 0 : struct radeon_device *rdev = dev->dev_private;
794 0 : struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
795 : struct radeon_encoder_atom_dig *dig;
796 : struct radeon_connector *radeon_connector;
797 : struct radeon_connector_atom_dig *dig_connector;
798 0 : struct radeon_dp_link_train_info dp_info;
799 : int index;
800 0 : u8 tmp, frev, crev;
801 :
802 0 : if (!radeon_encoder->enc_priv)
803 0 : return;
804 0 : dig = radeon_encoder->enc_priv;
805 :
806 0 : radeon_connector = to_radeon_connector(connector);
807 0 : if (!radeon_connector->con_priv)
808 0 : return;
809 0 : dig_connector = radeon_connector->con_priv;
810 :
811 0 : if ((dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT) &&
812 0 : (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_eDP))
813 0 : return;
814 :
815 : /* DPEncoderService newer than 1.1 can't program properly the
816 : * training pattern. When facing such version use the
817 : * DIGXEncoderControl (X== 1 | 2)
818 : */
819 0 : dp_info.use_dpencoder = true;
820 : index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
821 0 : if (atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) {
822 0 : if (crev > 1) {
823 0 : dp_info.use_dpencoder = false;
824 0 : }
825 : }
826 :
827 0 : dp_info.enc_id = 0;
828 0 : if (dig->dig_encoder)
829 0 : dp_info.enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
830 : else
831 0 : dp_info.enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER;
832 0 : if (dig->linkb)
833 0 : dp_info.enc_id |= ATOM_DP_CONFIG_LINK_B;
834 : else
835 : dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;
836 :
837 0 : if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp)
838 0 : == 1) {
839 0 : if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
840 0 : dp_info.tp3_supported = true;
841 : else
842 0 : dp_info.tp3_supported = false;
843 : } else {
844 0 : dp_info.tp3_supported = false;
845 : }
846 :
847 0 : memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE);
848 0 : dp_info.rdev = rdev;
849 0 : dp_info.encoder = encoder;
850 0 : dp_info.connector = connector;
851 0 : dp_info.dp_lane_count = dig_connector->dp_lane_count;
852 0 : dp_info.dp_clock = dig_connector->dp_clock;
853 0 : dp_info.aux = &radeon_connector->ddc_bus->aux;
854 :
855 0 : if (radeon_dp_link_train_init(&dp_info))
856 : goto done;
857 0 : if (radeon_dp_link_train_cr(&dp_info))
858 : goto done;
859 0 : if (radeon_dp_link_train_ce(&dp_info))
860 0 : goto done;
861 : done:
862 0 : if (radeon_dp_link_train_finish(&dp_info))
863 0 : return;
864 0 : }
|