Lines Matching +full:nr +full:- +full:outputs
42 #define AMPERE_IED_HACK(disp) ((disp)->engine.subdev.device->card_type >= GA100)
53 *pid = BIT(outp->index); in nvkm_dp_mst_id_get()
60 int ret = nvkm_i2c_aux_acquire(outp->dp.aux); in nvkm_dp_aux_xfer()
65 ret = nvkm_i2c_aux_xfer(outp->dp.aux, false, type, addr, data, size); in nvkm_dp_aux_xfer()
66 nvkm_i2c_aux_release(outp->dp.aux); in nvkm_dp_aux_xfer()
73 outp->dp.enabled = pu; in nvkm_dp_aux_pwr()
74 nvkm_dp_enable(outp, outp->dp.enabled); in nvkm_dp_aux_pwr()
94 struct nvkm_outp *outp = lt->outp; in nvkm_dp_train_sense()
100 if (lt->repeater) in nvkm_dp_train_sense()
101 addr = DPCD_LTTPR_LANE0_1_STATUS(lt->repeater); in nvkm_dp_train_sense()
105 ret = nvkm_rdaux(outp->dp.aux, addr, <->stat[0], 3); in nvkm_dp_train_sense()
109 if (lt->repeater) in nvkm_dp_train_sense()
110 addr = DPCD_LTTPR_LANE0_1_ADJUST(lt->repeater); in nvkm_dp_train_sense()
114 ret = nvkm_rdaux(outp->dp.aux, addr, <->stat[4], 2); in nvkm_dp_train_sense()
119 ret = nvkm_rdaux(outp->dp.aux, DPCD_LS0C, <->pc2stat, 1); in nvkm_dp_train_sense()
121 lt->pc2stat = 0x00; in nvkm_dp_train_sense()
123 OUTP_TRACE(outp, "status %6ph pc2 %02x", lt->stat, lt->pc2stat); in nvkm_dp_train_sense()
125 OUTP_TRACE(outp, "status %6ph", lt->stat); in nvkm_dp_train_sense()
134 struct nvkm_outp *outp = lt->outp; in nvkm_dp_train_drive()
135 struct nvkm_ior *ior = outp->ior; in nvkm_dp_train_drive()
136 struct nvkm_bios *bios = ior->disp->engine.subdev.device->bios; in nvkm_dp_train_drive()
144 for (i = 0; i < ior->dp.nr; i++) { in nvkm_dp_train_drive()
145 u8 lane = (lt->stat[4 + (i >> 1)] >> ((i & 1) * 4)) & 0xf; in nvkm_dp_train_drive()
146 u8 lpc2 = (lt->pc2stat >> (i * 2)) & 0x3; in nvkm_dp_train_drive()
149 u8 hivs = 3 - lpre; in nvkm_dp_train_drive()
157 lvsw = hivs = 3 - (lpre & 3); in nvkm_dp_train_drive()
163 lt->conf[i] = (lpre << 3) | lvsw; in nvkm_dp_train_drive()
164 lt->pc2conf[i >> 1] |= lpc2 << ((i & 1) * 4); in nvkm_dp_train_drive()
166 OUTP_TRACE(outp, "config lane %d %02x %02x", i, lt->conf[i], lpc2); in nvkm_dp_train_drive()
168 if (lt->repeater != lt->repeaters) in nvkm_dp_train_drive()
171 data = nvbios_dpout_match(bios, outp->info.hasht, outp->info.hashm, in nvkm_dp_train_drive()
181 ior->func->dp->drive(ior, i, ocfg.pc, ocfg.dc, ocfg.pe, ocfg.tx_pu); in nvkm_dp_train_drive()
184 if (lt->repeater) in nvkm_dp_train_drive()
185 addr = DPCD_LTTPR_LANE0_SET(lt->repeater); in nvkm_dp_train_drive()
189 ret = nvkm_wraux(outp->dp.aux, addr, lt->conf, 4); in nvkm_dp_train_drive()
194 ret = nvkm_wraux(outp->dp.aux, DPCD_LC0F, lt->pc2conf, 2); in nvkm_dp_train_drive()
205 struct nvkm_outp *outp = lt->outp; in nvkm_dp_train_pattern()
210 outp->ior->func->dp->pattern(outp->ior, pattern); in nvkm_dp_train_pattern()
212 if (lt->repeater) in nvkm_dp_train_pattern()
213 addr = DPCD_LTTPR_PATTERN_SET(lt->repeater); in nvkm_dp_train_pattern()
217 nvkm_rdaux(outp->dp.aux, addr, &sink_tp, 1); in nvkm_dp_train_pattern()
225 nvkm_wraux(outp->dp.aux, addr, &sink_tp, 1); in nvkm_dp_train_pattern()
231 struct nvkm_i2c_aux *aux = lt->outp->dp.aux; in nvkm_dp_train_eq()
236 if (lt->repeater) { in nvkm_dp_train_eq()
237 if (!nvkm_rdaux(aux, DPCD_LTTPR_AUX_RD_INTERVAL(lt->repeater), &data, sizeof(data))) in nvkm_dp_train_eq()
242 if (lt->outp->dp.dpcd[DPCD_RC00_DPCD_REV] >= 0x14 && in nvkm_dp_train_eq()
243 lt->outp->dp.dpcd[DPCD_RC03] & DPCD_RC03_TPS4_SUPPORTED) in nvkm_dp_train_eq()
246 if (lt->outp->dp.dpcd[DPCD_RC00_DPCD_REV] >= 0x12 && in nvkm_dp_train_eq()
247 lt->outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED) in nvkm_dp_train_eq()
252 usec = (lt->outp->dp.dpcd[DPCD_RC0E] & DPCD_RC0E_AUX_RD_INTERVAL) * 4000; in nvkm_dp_train_eq()
257 nvkm_dp_train_drive(lt, lt->pc2)) || in nvkm_dp_train_eq()
258 nvkm_dp_train_sense(lt, lt->pc2, usec ? usec : 400)) in nvkm_dp_train_eq()
261 eq_done = !!(lt->stat[2] & DPCD_LS04_INTERLANE_ALIGN_DONE); in nvkm_dp_train_eq()
262 for (i = 0; i < lt->outp->ior->dp.nr && eq_done; i++) { in nvkm_dp_train_eq()
263 u8 lane = (lt->stat[i >> 1] >> ((i & 1) * 4)) & 0xf; in nvkm_dp_train_eq()
272 return eq_done ? 0 : -1; in nvkm_dp_train_eq()
279 int voltage = lt->conf[0] & DPCD_LC03_VOLTAGE_SWING_SET; in nvkm_dp_train_cr()
284 if (lt->outp->dp.dpcd[DPCD_RC00_DPCD_REV] < 0x14 && !lt->repeater) in nvkm_dp_train_cr()
285 usec = (lt->outp->dp.dpcd[DPCD_RC0E] & DPCD_RC0E_AUX_RD_INTERVAL) * 4000; in nvkm_dp_train_cr()
293 for (i = 0; i < lt->outp->ior->dp.nr; i++) { in nvkm_dp_train_cr()
294 u8 lane = (lt->stat[i >> 1] >> ((i & 1) * 4)) & 0xf; in nvkm_dp_train_cr()
297 if (lt->conf[i] & DPCD_LC03_MAX_SWING_REACHED) in nvkm_dp_train_cr()
303 if ((lt->conf[0] & DPCD_LC03_VOLTAGE_SWING_SET) != voltage) { in nvkm_dp_train_cr()
304 voltage = lt->conf[0] & DPCD_LC03_VOLTAGE_SWING_SET; in nvkm_dp_train_cr()
309 return cr_done ? 0 : -1; in nvkm_dp_train_cr()
315 struct nvkm_ior *ior = outp->ior; in nvkm_dp_train_link()
318 .pc2 = outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED, in nvkm_dp_train_link()
319 .repeaters = outp->dp.lttprs, in nvkm_dp_train_link()
324 OUTP_DBG(outp, "training %dx%02x", ior->dp.nr, ior->dp.bw); in nvkm_dp_train_link()
327 sink[0] = (outp->dp.rate[rate].dpcd < 0) ? ior->dp.bw : 0; in nvkm_dp_train_link()
328 sink[1] = ior->dp.nr; in nvkm_dp_train_link()
329 if (ior->dp.ef) in nvkm_dp_train_link()
331 if (outp->dp.lt.post_adj) in nvkm_dp_train_link()
334 ret = nvkm_wraux(outp->dp.aux, DPCD_LC00_LINK_BW_SET, sink, 2); in nvkm_dp_train_link()
338 if (outp->dp.rate[rate].dpcd >= 0) { in nvkm_dp_train_link()
339 ret = nvkm_rdaux(outp->dp.aux, DPCD_LC15_LINK_RATE_SET, &sink[0], sizeof(sink[0])); in nvkm_dp_train_link()
344 sink[0] |= outp->dp.rate[rate].dpcd; in nvkm_dp_train_link()
346 ret = nvkm_wraux(outp->dp.aux, DPCD_LC15_LINK_RATE_SET, &sink[0], sizeof(sink[0])); in nvkm_dp_train_link()
352 for (lt.repeater = lt.repeaters; lt.repeater >= 0; lt.repeater--) { in nvkm_dp_train_link()
371 struct nvkm_ior *ior = outp->ior; in nvkm_dp_train_links()
372 struct nvkm_disp *disp = outp->disp; in nvkm_dp_train_links()
373 struct nvkm_subdev *subdev = &disp->engine.subdev; in nvkm_dp_train_links()
374 struct nvkm_bios *bios = subdev->device->bios; in nvkm_dp_train_links()
378 OUTP_DBG(outp, "programming link for %dx%02x", ior->dp.nr, ior->dp.bw); in nvkm_dp_train_links()
381 if (disp->engine.subdev.device->chipset < 0x110) in nvkm_dp_train_links()
382 outp->dp.dpcd[DPCD_RC03] &= ~DPCD_RC03_TPS4_SUPPORTED; in nvkm_dp_train_links()
383 if (disp->engine.subdev.device->chipset < 0xd0) in nvkm_dp_train_links()
384 outp->dp.dpcd[DPCD_RC02] &= ~DPCD_RC02_TPS3_SUPPORTED; in nvkm_dp_train_links()
386 if (AMPERE_IED_HACK(disp) && (lnkcmp = outp->dp.info.script[0])) { in nvkm_dp_train_links()
388 while (ior->dp.bw < nvbios_rd08(bios, lnkcmp)) in nvkm_dp_train_links()
392 nvbios_init(&outp->disp->engine.subdev, lnkcmp, in nvkm_dp_train_links()
393 init.outp = &outp->info; in nvkm_dp_train_links()
394 init.or = ior->id; in nvkm_dp_train_links()
395 init.link = ior->asy.link; in nvkm_dp_train_links()
400 if ((lnkcmp = outp->dp.info.lnkcmp)) { in nvkm_dp_train_links()
401 if (outp->dp.version < 0x30) { in nvkm_dp_train_links()
402 while ((ior->dp.bw * 2700) < nvbios_rd16(bios, lnkcmp)) in nvkm_dp_train_links()
406 while (ior->dp.bw < nvbios_rd08(bios, lnkcmp)) in nvkm_dp_train_links()
412 init.outp = &outp->info; in nvkm_dp_train_links()
413 init.or = ior->id; in nvkm_dp_train_links()
414 init.link = ior->asy.link; in nvkm_dp_train_links()
418 ret = ior->func->dp->links(ior, outp->dp.aux); in nvkm_dp_train_links()
427 ior->func->dp->power(ior, ior->dp.nr); in nvkm_dp_train_links()
437 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[1], in nvkm_dp_train_fini()
438 init.outp = &outp->info; in nvkm_dp_train_fini()
439 init.or = outp->ior->id; in nvkm_dp_train_fini()
440 init.link = outp->ior->asy.link; in nvkm_dp_train_fini()
448 if (outp->dp.dpcd[DPCD_RC03] & DPCD_RC03_MAX_DOWNSPREAD) { in nvkm_dp_train_init()
449 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[2], in nvkm_dp_train_init()
450 init.outp = &outp->info; in nvkm_dp_train_init()
451 init.or = outp->ior->id; in nvkm_dp_train_init()
452 init.link = outp->ior->asy.link; in nvkm_dp_train_init()
455 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[3], in nvkm_dp_train_init()
456 init.outp = &outp->info; in nvkm_dp_train_init()
457 init.or = outp->ior->id; in nvkm_dp_train_init()
458 init.link = outp->ior->asy.link; in nvkm_dp_train_init()
462 if (!AMPERE_IED_HACK(outp->disp)) { in nvkm_dp_train_init()
464 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[0], in nvkm_dp_train_init()
465 init.outp = &outp->info; in nvkm_dp_train_init()
466 init.or = outp->ior->id; in nvkm_dp_train_init()
467 init.link = outp->ior->asy.link; in nvkm_dp_train_init()
489 struct nvkm_ior *ior = outp->ior; in nvkm_dp_train()
492 for (rate = 0; rate < outp->dp.rates; rate++) { in nvkm_dp_train()
493 if (outp->dp.rate[rate].rate == (retrain ? ior->dp.bw : outp->dp.lt.bw) * 27000) in nvkm_dp_train()
497 if (WARN_ON(rate == outp->dp.rates)) in nvkm_dp_train()
498 return -EINVAL; in nvkm_dp_train()
502 mutex_lock(&outp->dp.mutex); in nvkm_dp_train()
504 mutex_unlock(&outp->dp.mutex); in nvkm_dp_train()
508 mutex_lock(&outp->dp.mutex); in nvkm_dp_train()
511 ior->dp.mst = outp->dp.lt.mst; in nvkm_dp_train()
512 ior->dp.ef = outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP; in nvkm_dp_train()
513 ior->dp.bw = outp->dp.lt.bw; in nvkm_dp_train()
514 ior->dp.nr = outp->dp.lt.nr; in nvkm_dp_train()
524 mutex_unlock(&outp->dp.mutex); in nvkm_dp_train()
532 nvbios_init(&ior->disp->engine.subdev, outp->dp.info.script[4], in nvkm_dp_disable()
533 init.outp = &outp->info; in nvkm_dp_disable()
534 init.or = ior->id; in nvkm_dp_disable()
535 init.link = ior->arm.link; in nvkm_dp_disable()
542 outp->ior->dp.nr = 0; in nvkm_dp_release()
543 nvkm_dp_disable(outp, outp->ior); in nvkm_dp_release()
551 struct nvkm_gpio *gpio = outp->disp->engine.subdev.device->gpio; in nvkm_dp_enable()
552 struct nvkm_i2c_aux *aux = outp->dp.aux; in nvkm_dp_enable()
554 if (auxpwr && !outp->dp.aux_pwr) { in nvkm_dp_enable()
559 if (outp->conn->info.type == DCB_CONNECTOR_eDP) { in nvkm_dp_enable()
563 outp->dp.aux_pwr_pu = true; in nvkm_dp_enable()
576 OUTP_DBG(outp, "aux power -> always"); in nvkm_dp_enable()
578 outp->dp.aux_pwr = true; in nvkm_dp_enable()
580 if (!auxpwr && outp->dp.aux_pwr) { in nvkm_dp_enable()
581 OUTP_DBG(outp, "aux power -> demand"); in nvkm_dp_enable()
583 outp->dp.aux_pwr = false; in nvkm_dp_enable()
586 * it could potentially interfere with other outputs. in nvkm_dp_enable()
588 if (outp->conn->info.type == DCB_CONNECTOR_eDP) { in nvkm_dp_enable()
589 if (outp->dp.aux_pwr_pu) { in nvkm_dp_enable()
591 outp->dp.aux_pwr_pu = false; in nvkm_dp_enable()
607 nvkm_dp_enable(outp, outp->dp.enabled); in nvkm_dp_init()
638 struct nvkm_device *device = disp->engine.subdev.device; in nvkm_dp_new()
639 struct nvkm_bios *bios = device->bios; in nvkm_dp_new()
640 struct nvkm_i2c *i2c = device->i2c; in nvkm_dp_new()
651 if (dcbE->location == 0) in nvkm_dp_new()
652 outp->dp.aux = nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_CCB(dcbE->i2c_index)); in nvkm_dp_new()
654 outp->dp.aux = nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_EXT(dcbE->extdev)); in nvkm_dp_new()
655 if (!outp->dp.aux) { in nvkm_dp_new()
657 return -EINVAL; in nvkm_dp_new()
661 data = nvbios_dpout_match(bios, outp->info.hasht, outp->info.hashm, in nvkm_dp_new()
662 &outp->dp.version, &hdr, &cnt, &len, &outp->dp.info); in nvkm_dp_new()
665 return -EINVAL; in nvkm_dp_new()
668 OUTP_DBG(outp, "bios dp %02x %02x %02x %02x", outp->dp.version, hdr, cnt, len); in nvkm_dp_new()
671 outp->dp.mst = data && ver >= 0x40 && (nvbios_rd08(bios, data + 0x08) & 0x04); in nvkm_dp_new()
673 mutex_init(&outp->dp.mutex); in nvkm_dp_new()