1 /* 2 * Copyright 2009 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: Ben Skeggs 23 */ 24 25 #include <drm/drmP.h> 26 #include <drm/drm_dp_helper.h> 27 28 #include "nouveau_drm.h" 29 #include "nouveau_connector.h" 30 #include "nouveau_encoder.h" 31 #include "nouveau_crtc.h" 32 33 #include <subdev/gpio.h> 34 #include <subdev/i2c.h> 35 36 u8 * 37 nouveau_dp_bios_data(struct drm_device *dev, struct dcb_output *dcb, u8 **entry) 38 { 39 struct nouveau_drm *drm = nouveau_drm(dev); 40 struct bit_entry d; 41 u8 *table; 42 int i; 43 44 if (bit_table(dev, 'd', &d)) { 45 NV_ERROR(drm, "BIT 'd' table not found\n"); 46 return NULL; 47 } 48 49 if (d.version != 1) { 50 NV_ERROR(drm, "BIT 'd' table version %d unknown\n", d.version); 51 return NULL; 52 } 53 54 table = ROMPTR(dev, d.data[0]); 55 if (!table) { 56 NV_ERROR(drm, "displayport table pointer invalid\n"); 57 return NULL; 58 } 59 60 switch (table[0]) { 61 case 0x20: 62 case 0x21: 63 case 0x30: 64 case 0x40: 65 break; 66 default: 67 NV_ERROR(drm, "displayport table 0x%02x unknown\n", table[0]); 68 return NULL; 69 } 70 71 for (i = 0; i < table[3]; i++) { 72 *entry = ROMPTR(dev, table[table[1] + (i * table[2])]); 73 if (*entry && bios_encoder_match(dcb, ROM32((*entry)[0]))) 74 return table; 75 } 76 77 NV_ERROR(drm, "displayport encoder table not found\n"); 78 return NULL; 79 } 80 81 /****************************************************************************** 82 * link training 83 *****************************************************************************/ 84 struct dp_state { 85 struct nouveau_i2c_port *auxch; 86 struct dp_train_func *func; 87 struct dcb_output *dcb; 88 int crtc; 89 u8 *dpcd; 90 int link_nr; 91 u32 link_bw; 92 u8 stat[6]; 93 u8 conf[4]; 94 }; 95 96 static void 97 dp_set_link_config(struct drm_device *dev, struct dp_state *dp) 98 { 99 struct nouveau_drm *drm = nouveau_drm(dev); 100 u8 sink[2]; 101 102 NV_DEBUG(drm, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw); 103 104 /* set desired link configuration on the source */ 105 dp->func->link_set(dev, dp->dcb, dp->crtc, dp->link_nr, dp->link_bw, 106 dp->dpcd[2] & DP_ENHANCED_FRAME_CAP); 107 108 /* inform the sink of the new configuration */ 109 sink[0] = dp->link_bw / 27000; 110 sink[1] = dp->link_nr; 111 if (dp->dpcd[2] & DP_ENHANCED_FRAME_CAP) 112 sink[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; 113 114 nv_wraux(dp->auxch, DP_LINK_BW_SET, sink, 2); 115 } 116 117 static void 118 dp_set_training_pattern(struct drm_device *dev, struct dp_state *dp, u8 pattern) 119 { 120 struct nouveau_drm *drm = nouveau_drm(dev); 121 u8 sink_tp; 122 123 NV_DEBUG(drm, "training pattern %d\n", pattern); 124 125 dp->func->train_set(dev, dp->dcb, pattern); 126 127 nv_rdaux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1); 128 sink_tp &= ~DP_TRAINING_PATTERN_MASK; 129 sink_tp |= pattern; 130 nv_wraux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1); 131 } 132 133 static int 134 dp_link_train_commit(struct drm_device *dev, struct dp_state *dp) 135 { 136 struct nouveau_drm *drm = nouveau_drm(dev); 137 int i; 138 139 for (i = 0; i < dp->link_nr; i++) { 140 u8 lane = (dp->stat[4 + (i >> 1)] >> ((i & 1) * 4)) & 0xf; 141 u8 lpre = (lane & 0x0c) >> 2; 142 u8 lvsw = (lane & 0x03) >> 0; 143 144 dp->conf[i] = (lpre << 3) | lvsw; 145 if (lvsw == DP_TRAIN_VOLTAGE_SWING_1200) 146 dp->conf[i] |= DP_TRAIN_MAX_SWING_REACHED; 147 if ((lpre << 3) == DP_TRAIN_PRE_EMPHASIS_9_5) 148 dp->conf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; 149 150 NV_DEBUG(drm, "config lane %d %02x\n", i, dp->conf[i]); 151 dp->func->train_adj(dev, dp->dcb, i, lvsw, lpre); 152 } 153 154 return nv_wraux(dp->auxch, DP_TRAINING_LANE0_SET, dp->conf, 4); 155 } 156 157 static int 158 dp_link_train_update(struct drm_device *dev, struct dp_state *dp, u32 delay) 159 { 160 struct nouveau_drm *drm = nouveau_drm(dev); 161 int ret; 162 163 udelay(delay); 164 165 ret = nv_rdaux(dp->auxch, DP_LANE0_1_STATUS, dp->stat, 6); 166 if (ret) 167 return ret; 168 169 NV_DEBUG(drm, "status %*ph\n", 6, dp->stat); 170 return 0; 171 } 172 173 static int 174 dp_link_train_cr(struct drm_device *dev, struct dp_state *dp) 175 { 176 bool cr_done = false, abort = false; 177 int voltage = dp->conf[0] & DP_TRAIN_VOLTAGE_SWING_MASK; 178 int tries = 0, i; 179 180 dp_set_training_pattern(dev, dp, DP_TRAINING_PATTERN_1); 181 182 do { 183 if (dp_link_train_commit(dev, dp) || 184 dp_link_train_update(dev, dp, 100)) 185 break; 186 187 cr_done = true; 188 for (i = 0; i < dp->link_nr; i++) { 189 u8 lane = (dp->stat[i >> 1] >> ((i & 1) * 4)) & 0xf; 190 if (!(lane & DP_LANE_CR_DONE)) { 191 cr_done = false; 192 if (dp->conf[i] & DP_TRAIN_MAX_SWING_REACHED) 193 abort = true; 194 break; 195 } 196 } 197 198 if ((dp->conf[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) { 199 voltage = dp->conf[0] & DP_TRAIN_VOLTAGE_SWING_MASK; 200 tries = 0; 201 } 202 } while (!cr_done && !abort && ++tries < 5); 203 204 return cr_done ? 0 : -1; 205 } 206 207 static int 208 dp_link_train_eq(struct drm_device *dev, struct dp_state *dp) 209 { 210 bool eq_done, cr_done = true; 211 int tries = 0, i; 212 213 dp_set_training_pattern(dev, dp, DP_TRAINING_PATTERN_2); 214 215 do { 216 if (dp_link_train_update(dev, dp, 400)) 217 break; 218 219 eq_done = !!(dp->stat[2] & DP_INTERLANE_ALIGN_DONE); 220 for (i = 0; i < dp->link_nr && eq_done; i++) { 221 u8 lane = (dp->stat[i >> 1] >> ((i & 1) * 4)) & 0xf; 222 if (!(lane & DP_LANE_CR_DONE)) 223 cr_done = false; 224 if (!(lane & DP_LANE_CHANNEL_EQ_DONE) || 225 !(lane & DP_LANE_SYMBOL_LOCKED)) 226 eq_done = false; 227 } 228 229 if (dp_link_train_commit(dev, dp)) 230 break; 231 } while (!eq_done && cr_done && ++tries <= 5); 232 233 return eq_done ? 0 : -1; 234 } 235 236 static void 237 dp_set_downspread(struct drm_device *dev, struct dp_state *dp, bool enable) 238 { 239 u16 script = 0x0000; 240 u8 *entry, *table = nouveau_dp_bios_data(dev, dp->dcb, &entry); 241 if (table) { 242 if (table[0] >= 0x20 && table[0] <= 0x30) { 243 if (enable) script = ROM16(entry[12]); 244 else script = ROM16(entry[14]); 245 } else 246 if (table[0] == 0x40) { 247 if (enable) script = ROM16(entry[11]); 248 else script = ROM16(entry[13]); 249 } 250 } 251 252 nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); 253 } 254 255 static void 256 dp_link_train_init(struct drm_device *dev, struct dp_state *dp) 257 { 258 u16 script = 0x0000; 259 u8 *entry, *table = nouveau_dp_bios_data(dev, dp->dcb, &entry); 260 if (table) { 261 if (table[0] >= 0x20 && table[0] <= 0x30) 262 script = ROM16(entry[6]); 263 else 264 if (table[0] == 0x40) 265 script = ROM16(entry[5]); 266 } 267 268 nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); 269 } 270 271 static void 272 dp_link_train_fini(struct drm_device *dev, struct dp_state *dp) 273 { 274 u16 script = 0x0000; 275 u8 *entry, *table = nouveau_dp_bios_data(dev, dp->dcb, &entry); 276 if (table) { 277 if (table[0] >= 0x20 && table[0] <= 0x30) 278 script = ROM16(entry[8]); 279 else 280 if (table[0] == 0x40) 281 script = ROM16(entry[7]); 282 } 283 284 nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); 285 } 286 287 static bool 288 nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate, 289 struct dp_train_func *func) 290 { 291 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 292 struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); 293 struct nouveau_connector *nv_connector = 294 nouveau_encoder_connector_get(nv_encoder); 295 struct drm_device *dev = encoder->dev; 296 struct nouveau_drm *drm = nouveau_drm(dev); 297 struct nouveau_i2c *i2c = nouveau_i2c(drm->device); 298 struct nouveau_gpio *gpio = nouveau_gpio(drm->device); 299 const u32 bw_list[] = { 270000, 162000, 0 }; 300 const u32 *link_bw = bw_list; 301 struct dp_state dp; 302 303 dp.auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index); 304 if (!dp.auxch) 305 return false; 306 307 dp.func = func; 308 dp.dcb = nv_encoder->dcb; 309 dp.crtc = nv_crtc->index; 310 dp.dpcd = nv_encoder->dp.dpcd; 311 312 /* adjust required bandwidth for 8B/10B coding overhead */ 313 datarate = (datarate / 8) * 10; 314 315 /* some sinks toggle hotplug in response to some of the actions 316 * we take during link training (DP_SET_POWER is one), we need 317 * to ignore them for the moment to avoid races. 318 */ 319 gpio->irq(gpio, 0, nv_connector->hpd, 0xff, false); 320 321 /* enable down-spreading, if possible */ 322 dp_set_downspread(dev, &dp, nv_encoder->dp.dpcd[3] & 1); 323 324 /* execute pre-train script from vbios */ 325 dp_link_train_init(dev, &dp); 326 327 /* start off at highest link rate supported by encoder and display */ 328 while (*link_bw > nv_encoder->dp.link_bw) 329 link_bw++; 330 331 while (link_bw[0]) { 332 /* find minimum required lane count at this link rate */ 333 dp.link_nr = nv_encoder->dp.link_nr; 334 while ((dp.link_nr >> 1) * link_bw[0] > datarate) 335 dp.link_nr >>= 1; 336 337 /* drop link rate to minimum with this lane count */ 338 while ((link_bw[1] * dp.link_nr) > datarate) 339 link_bw++; 340 dp.link_bw = link_bw[0]; 341 342 /* program selected link configuration */ 343 dp_set_link_config(dev, &dp); 344 345 /* attempt to train the link at this configuration */ 346 memset(dp.stat, 0x00, sizeof(dp.stat)); 347 if (!dp_link_train_cr(dev, &dp) && 348 !dp_link_train_eq(dev, &dp)) 349 break; 350 351 /* retry at lower rate */ 352 link_bw++; 353 } 354 355 /* finish link training */ 356 dp_set_training_pattern(dev, &dp, DP_TRAINING_PATTERN_DISABLE); 357 358 /* execute post-train script from vbios */ 359 dp_link_train_fini(dev, &dp); 360 361 /* re-enable hotplug detect */ 362 gpio->irq(gpio, 0, nv_connector->hpd, 0xff, true); 363 return true; 364 } 365 366 void 367 nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate, 368 struct dp_train_func *func) 369 { 370 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 371 struct nouveau_drm *drm = nouveau_drm(encoder->dev); 372 struct nouveau_i2c *i2c = nouveau_i2c(drm->device); 373 struct nouveau_i2c_port *auxch; 374 u8 status; 375 376 auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index); 377 if (!auxch) 378 return; 379 380 if (mode == DRM_MODE_DPMS_ON) 381 status = DP_SET_POWER_D0; 382 else 383 status = DP_SET_POWER_D3; 384 385 nv_wraux(auxch, DP_SET_POWER, &status, 1); 386 387 if (mode == DRM_MODE_DPMS_ON) 388 nouveau_dp_link_train(encoder, datarate, func); 389 } 390 391 static void 392 nouveau_dp_probe_oui(struct drm_device *dev, struct nouveau_i2c_port *auxch, 393 u8 *dpcd) 394 { 395 struct nouveau_drm *drm = nouveau_drm(dev); 396 u8 buf[3]; 397 398 if (!(dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) 399 return; 400 401 if (!nv_rdaux(auxch, DP_SINK_OUI, buf, 3)) 402 NV_DEBUG(drm, "Sink OUI: %02hx%02hx%02hx\n", 403 buf[0], buf[1], buf[2]); 404 405 if (!nv_rdaux(auxch, DP_BRANCH_OUI, buf, 3)) 406 NV_DEBUG(drm, "Branch OUI: %02hx%02hx%02hx\n", 407 buf[0], buf[1], buf[2]); 408 409 } 410 411 bool 412 nouveau_dp_detect(struct drm_encoder *encoder) 413 { 414 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 415 struct drm_device *dev = encoder->dev; 416 struct nouveau_drm *drm = nouveau_drm(dev); 417 struct nouveau_i2c *i2c = nouveau_i2c(drm->device); 418 struct nouveau_i2c_port *auxch; 419 u8 *dpcd = nv_encoder->dp.dpcd; 420 int ret; 421 422 auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index); 423 if (!auxch) 424 return false; 425 426 ret = nv_rdaux(auxch, DP_DPCD_REV, dpcd, 8); 427 if (ret) 428 return false; 429 430 nv_encoder->dp.link_bw = 27000 * dpcd[1]; 431 nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK; 432 433 NV_DEBUG(drm, "display: %dx%d dpcd 0x%02x\n", 434 nv_encoder->dp.link_nr, nv_encoder->dp.link_bw, dpcd[0]); 435 NV_DEBUG(drm, "encoder: %dx%d\n", 436 nv_encoder->dcb->dpconf.link_nr, 437 nv_encoder->dcb->dpconf.link_bw); 438 439 if (nv_encoder->dcb->dpconf.link_nr < nv_encoder->dp.link_nr) 440 nv_encoder->dp.link_nr = nv_encoder->dcb->dpconf.link_nr; 441 if (nv_encoder->dcb->dpconf.link_bw < nv_encoder->dp.link_bw) 442 nv_encoder->dp.link_bw = nv_encoder->dcb->dpconf.link_bw; 443 444 NV_DEBUG(drm, "maximum: %dx%d\n", 445 nv_encoder->dp.link_nr, nv_encoder->dp.link_bw); 446 447 nouveau_dp_probe_oui(dev, auxch, dpcd); 448 449 return true; 450 } 451