Lines Matching refs:outp

43 	struct nvkm_outp *outp;  member
58 struct nvkm_outp *outp = lt->outp; in nvkm_dp_train_sense() local
69 ret = nvkm_rdaux(outp->dp.aux, addr, &lt->stat[0], 3); in nvkm_dp_train_sense()
78 ret = nvkm_rdaux(outp->dp.aux, addr, &lt->stat[4], 2); in nvkm_dp_train_sense()
83 ret = nvkm_rdaux(outp->dp.aux, DPCD_LS0C, &lt->pc2stat, 1); in nvkm_dp_train_sense()
87 OUTP_TRACE(outp, "status %6ph pc2 %02x", lt->stat, lt->pc2stat); in nvkm_dp_train_sense()
89 OUTP_TRACE(outp, "status %6ph", lt->stat); in nvkm_dp_train_sense()
98 struct nvkm_outp *outp = lt->outp; in nvkm_dp_train_drive() local
99 struct nvkm_ior *ior = outp->ior; in nvkm_dp_train_drive()
130 OUTP_TRACE(outp, "config lane %d %02x %02x", i, lt->conf[i], lpc2); in nvkm_dp_train_drive()
135 data = nvbios_dpout_match(bios, outp->info.hasht, outp->info.hashm, in nvkm_dp_train_drive()
153 ret = nvkm_wraux(outp->dp.aux, addr, lt->conf, 4); in nvkm_dp_train_drive()
158 ret = nvkm_wraux(outp->dp.aux, DPCD_LC0F, lt->pc2conf, 2); in nvkm_dp_train_drive()
169 struct nvkm_outp *outp = lt->outp; in nvkm_dp_train_pattern() local
173 OUTP_TRACE(outp, "training pattern %d", pattern); in nvkm_dp_train_pattern()
174 outp->ior->func->dp->pattern(outp->ior, pattern); in nvkm_dp_train_pattern()
181 nvkm_rdaux(outp->dp.aux, addr, &sink_tp, 1); in nvkm_dp_train_pattern()
189 nvkm_wraux(outp->dp.aux, addr, &sink_tp, 1); in nvkm_dp_train_pattern()
195 struct nvkm_i2c_aux *aux = lt->outp->dp.aux; in nvkm_dp_train_eq()
206 if (lt->outp->dp.dpcd[DPCD_RC00_DPCD_REV] >= 0x14 && in nvkm_dp_train_eq()
207 lt->outp->dp.dpcd[DPCD_RC03] & DPCD_RC03_TPS4_SUPPORTED) in nvkm_dp_train_eq()
210 if (lt->outp->dp.dpcd[DPCD_RC00_DPCD_REV] >= 0x12 && in nvkm_dp_train_eq()
211 lt->outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED) in nvkm_dp_train_eq()
216 usec = (lt->outp->dp.dpcd[DPCD_RC0E] & DPCD_RC0E_AUX_RD_INTERVAL) * 4000; in nvkm_dp_train_eq()
226 for (i = 0; i < lt->outp->ior->dp.nr && eq_done; i++) { in nvkm_dp_train_eq()
248 if (lt->outp->dp.dpcd[DPCD_RC00_DPCD_REV] < 0x14 && !lt->repeater) in nvkm_dp_train_cr()
249 usec = (lt->outp->dp.dpcd[DPCD_RC0E] & DPCD_RC0E_AUX_RD_INTERVAL) * 4000; in nvkm_dp_train_cr()
257 for (i = 0; i < lt->outp->ior->dp.nr; i++) { in nvkm_dp_train_cr()
277 nvkm_dp_train_link(struct nvkm_outp *outp, int rate) in nvkm_dp_train_link() argument
279 struct nvkm_ior *ior = outp->ior; in nvkm_dp_train_link()
281 .outp = outp, in nvkm_dp_train_link()
282 .pc2 = outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED, in nvkm_dp_train_link()
287 OUTP_DBG(outp, "training %dx%02x", ior->dp.nr, ior->dp.bw); in nvkm_dp_train_link()
292 if (outp->dp.lttpr[0] >= 0x14) { in nvkm_dp_train_link()
294 nvkm_wraux(outp->dp.aux, DPCD_LTTPR_MODE, &data, sizeof(data)); in nvkm_dp_train_link()
296 if (outp->dp.lttprs) { in nvkm_dp_train_link()
298 nvkm_wraux(outp->dp.aux, DPCD_LTTPR_MODE, &data, sizeof(data)); in nvkm_dp_train_link()
299 lt.repeaters = outp->dp.lttprs; in nvkm_dp_train_link()
304 sink[0] = (outp->dp.rate[rate].dpcd < 0) ? ior->dp.bw : 0; in nvkm_dp_train_link()
309 ret = nvkm_wraux(outp->dp.aux, DPCD_LC00_LINK_BW_SET, sink, 2); in nvkm_dp_train_link()
313 if (outp->dp.rate[rate].dpcd >= 0) { in nvkm_dp_train_link()
314 ret = nvkm_rdaux(outp->dp.aux, DPCD_LC15_LINK_RATE_SET, &sink[0], sizeof(sink[0])); in nvkm_dp_train_link()
319 sink[0] |= outp->dp.rate[rate].dpcd; in nvkm_dp_train_link()
321 ret = nvkm_wraux(outp->dp.aux, DPCD_LC15_LINK_RATE_SET, &sink[0], sizeof(sink[0])); in nvkm_dp_train_link()
329 OUTP_DBG(outp, "training LTTPR%d", lt.repeater); in nvkm_dp_train_link()
331 OUTP_DBG(outp, "training sink"); in nvkm_dp_train_link()
344 nvkm_dp_train_links(struct nvkm_outp *outp, int rate) in nvkm_dp_train_links() argument
346 struct nvkm_ior *ior = outp->ior; in nvkm_dp_train_links()
347 struct nvkm_disp *disp = outp->disp; in nvkm_dp_train_links()
353 OUTP_DBG(outp, "programming link for %dx%02x", ior->dp.nr, ior->dp.bw); in nvkm_dp_train_links()
357 outp->dp.dpcd[DPCD_RC03] &= ~DPCD_RC03_TPS4_SUPPORTED; in nvkm_dp_train_links()
359 outp->dp.dpcd[DPCD_RC02] &= ~DPCD_RC02_TPS3_SUPPORTED; in nvkm_dp_train_links()
361 if (AMPERE_IED_HACK(disp) && (lnkcmp = outp->dp.info.script[0])) { in nvkm_dp_train_links()
367 nvbios_init(&outp->disp->engine.subdev, lnkcmp, in nvkm_dp_train_links()
368 init.outp = &outp->info; in nvkm_dp_train_links()
375 if ((lnkcmp = outp->dp.info.lnkcmp)) { in nvkm_dp_train_links()
376 if (outp->dp.version < 0x30) { in nvkm_dp_train_links()
387 init.outp = &outp->info; in nvkm_dp_train_links()
393 ret = ior->func->dp->links(ior, outp->dp.aux); in nvkm_dp_train_links()
396 OUTP_ERR(outp, "train failed with %d", ret); in nvkm_dp_train_links()
405 return nvkm_dp_train_link(outp, rate); in nvkm_dp_train_links()
409 nvkm_dp_train_fini(struct nvkm_outp *outp) in nvkm_dp_train_fini() argument
412 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[1], in nvkm_dp_train_fini()
413 init.outp = &outp->info; in nvkm_dp_train_fini()
414 init.or = outp->ior->id; in nvkm_dp_train_fini()
415 init.link = outp->ior->asy.link; in nvkm_dp_train_fini()
420 nvkm_dp_train_init(struct nvkm_outp *outp) in nvkm_dp_train_init() argument
423 if (outp->dp.dpcd[DPCD_RC03] & DPCD_RC03_MAX_DOWNSPREAD) { in nvkm_dp_train_init()
424 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[2], in nvkm_dp_train_init()
425 init.outp = &outp->info; in nvkm_dp_train_init()
426 init.or = outp->ior->id; in nvkm_dp_train_init()
427 init.link = outp->ior->asy.link; in nvkm_dp_train_init()
430 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[3], in nvkm_dp_train_init()
431 init.outp = &outp->info; in nvkm_dp_train_init()
432 init.or = outp->ior->id; in nvkm_dp_train_init()
433 init.link = outp->ior->asy.link; in nvkm_dp_train_init()
437 if (!AMPERE_IED_HACK(outp->disp)) { in nvkm_dp_train_init()
439 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[0], in nvkm_dp_train_init()
440 init.outp = &outp->info; in nvkm_dp_train_init()
441 init.or = outp->ior->id; in nvkm_dp_train_init()
442 init.link = outp->ior->asy.link; in nvkm_dp_train_init()
448 nvkm_dp_train(struct nvkm_outp *outp, u32 dataKBps) in nvkm_dp_train() argument
450 struct nvkm_ior *ior = outp->ior; in nvkm_dp_train()
455 if (atomic_read(&outp->dp.lt.done)) { in nvkm_dp_train()
456 for (rate = 0; rate < outp->dp.rates; rate++) { in nvkm_dp_train()
457 if (outp->dp.rate[rate].rate == ior->dp.bw * 27000) in nvkm_dp_train()
458 return nvkm_dp_train_link(outp, ret); in nvkm_dp_train()
465 if (!nvkm_rdaux(outp->dp.aux, DPCD_SC00, &pwr, 1)) { in nvkm_dp_train()
469 nvkm_wraux(outp->dp.aux, DPCD_SC00, &pwr, 1); in nvkm_dp_train()
473 ior->dp.mst = outp->dp.lt.mst; in nvkm_dp_train()
474 ior->dp.ef = outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP; in nvkm_dp_train()
478 OUTP_DBG(outp, "training"); in nvkm_dp_train()
479 nvkm_dp_train_init(outp); in nvkm_dp_train()
482 if (outp->dp.lt.nr) { in nvkm_dp_train()
483 for (nr = outp->dp.links; ret < 0 && nr; nr >>= 1) { in nvkm_dp_train()
484 for (rate = 0; nr == outp->dp.lt.nr && rate < outp->dp.rates; rate++) { in nvkm_dp_train()
485 if (outp->dp.rate[rate].rate / 27000 == outp->dp.lt.bw) { in nvkm_dp_train()
486 ior->dp.bw = outp->dp.rate[rate].rate / 27000; in nvkm_dp_train()
488 ret = nvkm_dp_train_links(outp, rate); in nvkm_dp_train()
495 for (nr = outp->dp.links; ret < 0 && nr; nr >>= 1) { in nvkm_dp_train()
496 for (rate = 0; ret < 0 && rate < outp->dp.rates; rate++) { in nvkm_dp_train()
497 if (outp->dp.rate[rate].rate * nr >= dataKBps || WARN_ON(!ior->dp.nr)) { in nvkm_dp_train()
499 ior->dp.bw = outp->dp.rate[rate].rate / 27000; in nvkm_dp_train()
501 ret = nvkm_dp_train_links(outp, rate); in nvkm_dp_train()
507 nvkm_dp_train_fini(outp); in nvkm_dp_train()
509 OUTP_ERR(outp, "training failed"); in nvkm_dp_train()
511 OUTP_DBG(outp, "training done"); in nvkm_dp_train()
512 atomic_set(&outp->dp.lt.done, 1); in nvkm_dp_train()
517 nvkm_dp_disable(struct nvkm_outp *outp, struct nvkm_ior *ior) in nvkm_dp_disable() argument
520 nvbios_init(&ior->disp->engine.subdev, outp->dp.info.script[4], in nvkm_dp_disable()
521 init.outp = &outp->info; in nvkm_dp_disable()
528 nvkm_dp_release(struct nvkm_outp *outp) in nvkm_dp_release() argument
531 atomic_set(&outp->dp.lt.done, 0); in nvkm_dp_release()
532 outp->ior->dp.nr = 0; in nvkm_dp_release()
536 nvkm_dp_acquire(struct nvkm_outp *outp) in nvkm_dp_acquire() argument
538 struct nvkm_ior *ior = outp->ior; in nvkm_dp_acquire()
547 mutex_lock(&outp->dp.mutex); in nvkm_dp_acquire()
550 list_for_each_entry(head, &outp->disp->heads, head) { in nvkm_dp_acquire()
559 OUTP_DBG(outp, "data %d KB/s link %d KB/s mst %d->%d", in nvkm_dp_acquire()
560 dataKBps, linkKBps, ior->dp.mst, outp->dp.lt.mst); in nvkm_dp_acquire()
561 if (linkKBps < dataKBps || ior->dp.mst != outp->dp.lt.mst) { in nvkm_dp_acquire()
562 OUTP_DBG(outp, "link requirements changed"); in nvkm_dp_acquire()
567 ret = nvkm_rdaux(outp->dp.aux, DPCD_LS02, stat, 3); in nvkm_dp_acquire()
569 OUTP_DBG(outp, "failed to read link status, assuming no sink"); in nvkm_dp_acquire()
579 OUTP_DBG(outp, "lane %d not equalised", lane); in nvkm_dp_acquire()
585 OUTP_DBG(outp, "no inter-lane alignment"); in nvkm_dp_acquire()
589 if (retrain || !atomic_read(&outp->dp.lt.done)) in nvkm_dp_acquire()
590 ret = nvkm_dp_train(outp, dataKBps); in nvkm_dp_acquire()
591 mutex_unlock(&outp->dp.mutex); in nvkm_dp_acquire()
596 nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp) in nvkm_dp_enable_supported_link_rates() argument
601 if (outp->conn->info.type != DCB_CONNECTOR_eDP || in nvkm_dp_enable_supported_link_rates()
602 outp->dp.dpcd[DPCD_RC00_DPCD_REV] < 0x13 || in nvkm_dp_enable_supported_link_rates()
603 nvkm_rdaux(outp->dp.aux, DPCD_RC10_SUPPORTED_LINK_RATES(0), in nvkm_dp_enable_supported_link_rates()
610 if (!rate || WARN_ON(outp->dp.rates == ARRAY_SIZE(outp->dp.rate))) in nvkm_dp_enable_supported_link_rates()
613 if (rate > outp->info.dpconf.link_bw * 27000) { in nvkm_dp_enable_supported_link_rates()
614 OUTP_DBG(outp, "rate %d !outp", rate); in nvkm_dp_enable_supported_link_rates()
618 for (j = 0; j < outp->dp.rates; j++) { in nvkm_dp_enable_supported_link_rates()
619 if (rate > outp->dp.rate[j].rate) { in nvkm_dp_enable_supported_link_rates()
620 for (k = outp->dp.rates; k > j; k--) in nvkm_dp_enable_supported_link_rates()
621 outp->dp.rate[k] = outp->dp.rate[k - 1]; in nvkm_dp_enable_supported_link_rates()
626 outp->dp.rate[j].dpcd = i / 2; in nvkm_dp_enable_supported_link_rates()
627 outp->dp.rate[j].rate = rate; in nvkm_dp_enable_supported_link_rates()
628 outp->dp.rates++; in nvkm_dp_enable_supported_link_rates()
631 for (i = 0; i < outp->dp.rates; i++) in nvkm_dp_enable_supported_link_rates()
632 OUTP_DBG(outp, "link_rate[%d] = %d", outp->dp.rate[i].dpcd, outp->dp.rate[i].rate); in nvkm_dp_enable_supported_link_rates()
634 return outp->dp.rates != 0; in nvkm_dp_enable_supported_link_rates()
638 nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr) in nvkm_dp_enable() argument
640 struct nvkm_gpio *gpio = outp->disp->engine.subdev.device->gpio; in nvkm_dp_enable()
641 struct nvkm_i2c_aux *aux = outp->dp.aux; in nvkm_dp_enable()
643 if (auxpwr && !outp->dp.aux_pwr) { in nvkm_dp_enable()
648 if (outp->conn->info.type == DCB_CONNECTOR_eDP) { in nvkm_dp_enable()
652 outp->dp.aux_pwr_pu = true; in nvkm_dp_enable()
665 OUTP_DBG(outp, "aux power -> always"); in nvkm_dp_enable()
667 outp->dp.aux_pwr = true; in nvkm_dp_enable()
670 if (!nvkm_rdaux(aux, DPCD_LTTPR_REV, outp->dp.lttpr, sizeof(outp->dp.lttpr)) && in nvkm_dp_enable()
671 outp->dp.lttpr[0] >= 0x14 && outp->dp.lttpr[2]) { in nvkm_dp_enable()
672 switch (outp->dp.lttpr[2]) { in nvkm_dp_enable()
673 case 0x80: outp->dp.lttprs = 1; break; in nvkm_dp_enable()
674 case 0x40: outp->dp.lttprs = 2; break; in nvkm_dp_enable()
675 case 0x20: outp->dp.lttprs = 3; break; in nvkm_dp_enable()
676 case 0x10: outp->dp.lttprs = 4; break; in nvkm_dp_enable()
677 case 0x08: outp->dp.lttprs = 5; break; in nvkm_dp_enable()
678 case 0x04: outp->dp.lttprs = 6; break; in nvkm_dp_enable()
679 case 0x02: outp->dp.lttprs = 7; break; in nvkm_dp_enable()
680 case 0x01: outp->dp.lttprs = 8; break; in nvkm_dp_enable()
684 outp->dp.lttprs = 0; in nvkm_dp_enable()
689 memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr)); in nvkm_dp_enable()
692 if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) { in nvkm_dp_enable()
697 outp->dp.rates = 0; in nvkm_dp_enable()
698 outp->dp.links = outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_MAX_LANE_COUNT; in nvkm_dp_enable()
699 outp->dp.links = min(outp->dp.links, outp->info.dpconf.link_nr); in nvkm_dp_enable()
700 if (outp->dp.lttprs && outp->dp.lttpr[4]) in nvkm_dp_enable()
701 outp->dp.links = min_t(int, outp->dp.links, outp->dp.lttpr[4]); in nvkm_dp_enable()
703 rate_max = outp->dp.dpcd[DPCD_RC01_MAX_LINK_RATE]; in nvkm_dp_enable()
704 rate_max = min(rate_max, outp->info.dpconf.link_bw); in nvkm_dp_enable()
705 if (outp->dp.lttprs && outp->dp.lttpr[1]) in nvkm_dp_enable()
706 rate_max = min_t(int, rate_max, outp->dp.lttpr[1]); in nvkm_dp_enable()
708 if (!nvkm_dp_enable_supported_link_rates(outp)) { in nvkm_dp_enable()
713 if (WARN_ON(outp->dp.rates == ARRAY_SIZE(outp->dp.rate))) in nvkm_dp_enable()
716 outp->dp.rate[outp->dp.rates].dpcd = -1; in nvkm_dp_enable()
717 outp->dp.rate[outp->dp.rates].rate = *rate * 27000; in nvkm_dp_enable()
718 outp->dp.rates++; in nvkm_dp_enable()
723 if (!auxpwr && outp->dp.aux_pwr) { in nvkm_dp_enable()
724 OUTP_DBG(outp, "aux power -> demand"); in nvkm_dp_enable()
726 outp->dp.aux_pwr = false; in nvkm_dp_enable()
727 atomic_set(&outp->dp.lt.done, 0); in nvkm_dp_enable()
732 if (outp->conn->info.type == DCB_CONNECTOR_eDP) { in nvkm_dp_enable()
733 if (outp->dp.aux_pwr_pu) { in nvkm_dp_enable()
735 outp->dp.aux_pwr_pu = false; in nvkm_dp_enable()
742 nvkm_dp_fini(struct nvkm_outp *outp) in nvkm_dp_fini() argument
744 nvkm_dp_enable(outp, false); in nvkm_dp_fini()
748 nvkm_dp_init(struct nvkm_outp *outp) in nvkm_dp_init() argument
750 nvkm_dp_enable(outp, outp->dp.enabled); in nvkm_dp_init()
754 nvkm_dp_dtor(struct nvkm_outp *outp) in nvkm_dp_dtor() argument
756 return outp; in nvkm_dp_dtor()
775 struct nvkm_outp *outp; in nvkm_dp_new() local
781 outp = *poutp; in nvkm_dp_new()
786 outp->dp.aux = nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_CCB(dcbE->i2c_index)); in nvkm_dp_new()
788 outp->dp.aux = nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_EXT(dcbE->extdev)); in nvkm_dp_new()
789 if (!outp->dp.aux) { in nvkm_dp_new()
790 OUTP_ERR(outp, "no aux"); in nvkm_dp_new()
795 data = nvbios_dpout_match(bios, outp->info.hasht, outp->info.hashm, in nvkm_dp_new()
796 &outp->dp.version, &hdr, &cnt, &len, &outp->dp.info); in nvkm_dp_new()
798 OUTP_ERR(outp, "no bios dp data"); in nvkm_dp_new()
802 OUTP_DBG(outp, "bios dp %02x %02x %02x %02x", outp->dp.version, hdr, cnt, len); in nvkm_dp_new()
804 mutex_init(&outp->dp.mutex); in nvkm_dp_new()
805 atomic_set(&outp->dp.lt.done, 0); in nvkm_dp_new()