Lines Matching full:outp

45 	struct nvkm_outp *outp;  member
60 struct nvkm_outp *outp = lt->outp; in nvkm_dp_train_sense() local
71 ret = nvkm_rdaux(outp->dp.aux, addr, &lt->stat[0], 3); in nvkm_dp_train_sense()
80 ret = nvkm_rdaux(outp->dp.aux, addr, &lt->stat[4], 2); in nvkm_dp_train_sense()
85 ret = nvkm_rdaux(outp->dp.aux, DPCD_LS0C, &lt->pc2stat, 1); in nvkm_dp_train_sense()
89 OUTP_TRACE(outp, "status %6ph pc2 %02x", lt->stat, lt->pc2stat); in nvkm_dp_train_sense()
91 OUTP_TRACE(outp, "status %6ph", lt->stat); in nvkm_dp_train_sense()
100 struct nvkm_outp *outp = lt->outp; in nvkm_dp_train_drive() local
101 struct nvkm_ior *ior = outp->ior; in nvkm_dp_train_drive()
132 OUTP_TRACE(outp, "config lane %d %02x %02x", i, lt->conf[i], lpc2); in nvkm_dp_train_drive()
137 data = nvbios_dpout_match(bios, outp->info.hasht, outp->info.hashm, in nvkm_dp_train_drive()
155 ret = nvkm_wraux(outp->dp.aux, addr, lt->conf, 4); in nvkm_dp_train_drive()
160 ret = nvkm_wraux(outp->dp.aux, DPCD_LC0F, lt->pc2conf, 2); in nvkm_dp_train_drive()
171 struct nvkm_outp *outp = lt->outp; in nvkm_dp_train_pattern() local
175 OUTP_TRACE(outp, "training pattern %d", pattern); in nvkm_dp_train_pattern()
176 outp->ior->func->dp->pattern(outp->ior, pattern); in nvkm_dp_train_pattern()
183 nvkm_rdaux(outp->dp.aux, addr, &sink_tp, 1); in nvkm_dp_train_pattern()
191 nvkm_wraux(outp->dp.aux, addr, &sink_tp, 1); in nvkm_dp_train_pattern()
197 struct nvkm_i2c_aux *aux = lt->outp->dp.aux; in nvkm_dp_train_eq()
208 if (lt->outp->dp.dpcd[DPCD_RC00_DPCD_REV] >= 0x14 && in nvkm_dp_train_eq()
209 lt->outp->dp.dpcd[DPCD_RC03] & DPCD_RC03_TPS4_SUPPORTED) in nvkm_dp_train_eq()
212 if (lt->outp->dp.dpcd[DPCD_RC00_DPCD_REV] >= 0x12 && in nvkm_dp_train_eq()
213 lt->outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED) in nvkm_dp_train_eq()
218 usec = (lt->outp->dp.dpcd[DPCD_RC0E] & DPCD_RC0E_AUX_RD_INTERVAL) * 4000; in nvkm_dp_train_eq()
228 for (i = 0; i < lt->outp->ior->dp.nr && eq_done; i++) { in nvkm_dp_train_eq()
250 if (lt->outp->dp.dpcd[DPCD_RC00_DPCD_REV] < 0x14 && !lt->repeater) in nvkm_dp_train_cr()
251 usec = (lt->outp->dp.dpcd[DPCD_RC0E] & DPCD_RC0E_AUX_RD_INTERVAL) * 4000; in nvkm_dp_train_cr()
259 for (i = 0; i < lt->outp->ior->dp.nr; i++) { in nvkm_dp_train_cr()
279 nvkm_dp_train_link(struct nvkm_outp *outp, int rate) in nvkm_dp_train_link() argument
281 struct nvkm_ior *ior = outp->ior; in nvkm_dp_train_link()
283 .outp = outp, in nvkm_dp_train_link()
284 .pc2 = outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED, in nvkm_dp_train_link()
289 OUTP_DBG(outp, "training %dx%02x", ior->dp.nr, ior->dp.bw); in nvkm_dp_train_link()
294 if (outp->dp.lttpr[0] >= 0x14) { in nvkm_dp_train_link()
296 nvkm_wraux(outp->dp.aux, DPCD_LTTPR_MODE, &data, sizeof(data)); in nvkm_dp_train_link()
298 if (outp->dp.lttprs) { in nvkm_dp_train_link()
300 nvkm_wraux(outp->dp.aux, DPCD_LTTPR_MODE, &data, sizeof(data)); in nvkm_dp_train_link()
301 lt.repeaters = outp->dp.lttprs; in nvkm_dp_train_link()
306 sink[0] = (outp->dp.rate[rate].dpcd < 0) ? ior->dp.bw : 0; in nvkm_dp_train_link()
311 ret = nvkm_wraux(outp->dp.aux, DPCD_LC00_LINK_BW_SET, sink, 2); in nvkm_dp_train_link()
315 if (outp->dp.rate[rate].dpcd >= 0) { in nvkm_dp_train_link()
316 ret = nvkm_rdaux(outp->dp.aux, DPCD_LC15_LINK_RATE_SET, &sink[0], sizeof(sink[0])); in nvkm_dp_train_link()
321 sink[0] |= outp->dp.rate[rate].dpcd; in nvkm_dp_train_link()
323 ret = nvkm_wraux(outp->dp.aux, DPCD_LC15_LINK_RATE_SET, &sink[0], sizeof(sink[0])); in nvkm_dp_train_link()
331 OUTP_DBG(outp, "training LTTPR%d", lt.repeater); in nvkm_dp_train_link()
333 OUTP_DBG(outp, "training sink"); in nvkm_dp_train_link()
346 nvkm_dp_train_links(struct nvkm_outp *outp, int rate) in nvkm_dp_train_links() argument
348 struct nvkm_ior *ior = outp->ior; in nvkm_dp_train_links()
349 struct nvkm_disp *disp = outp->disp; in nvkm_dp_train_links()
355 OUTP_DBG(outp, "programming link for %dx%02x", ior->dp.nr, ior->dp.bw); in nvkm_dp_train_links()
359 outp->dp.dpcd[DPCD_RC03] &= ~DPCD_RC03_TPS4_SUPPORTED; in nvkm_dp_train_links()
361 outp->dp.dpcd[DPCD_RC02] &= ~DPCD_RC02_TPS3_SUPPORTED; in nvkm_dp_train_links()
363 if (AMPERE_IED_HACK(disp) && (lnkcmp = outp->dp.info.script[0])) { in nvkm_dp_train_links()
369 nvbios_init(&outp->disp->engine.subdev, lnkcmp, in nvkm_dp_train_links()
370 init.outp = &outp->info; in nvkm_dp_train_links()
377 if ((lnkcmp = outp->dp.info.lnkcmp)) { in nvkm_dp_train_links()
378 if (outp->dp.version < 0x30) { in nvkm_dp_train_links()
389 init.outp = &outp->info; in nvkm_dp_train_links()
395 ret = ior->func->dp->links(ior, outp->dp.aux); in nvkm_dp_train_links()
398 OUTP_ERR(outp, "train failed with %d", ret); in nvkm_dp_train_links()
407 return nvkm_dp_train_link(outp, rate); in nvkm_dp_train_links()
411 nvkm_dp_train_fini(struct nvkm_outp *outp) in nvkm_dp_train_fini() argument
414 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[1], in nvkm_dp_train_fini()
415 init.outp = &outp->info; in nvkm_dp_train_fini()
416 init.or = outp->ior->id; in nvkm_dp_train_fini()
417 init.link = outp->ior->asy.link; in nvkm_dp_train_fini()
422 nvkm_dp_train_init(struct nvkm_outp *outp) in nvkm_dp_train_init() argument
425 if (outp->dp.dpcd[DPCD_RC03] & DPCD_RC03_MAX_DOWNSPREAD) { in nvkm_dp_train_init()
426 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[2], in nvkm_dp_train_init()
427 init.outp = &outp->info; in nvkm_dp_train_init()
428 init.or = outp->ior->id; in nvkm_dp_train_init()
429 init.link = outp->ior->asy.link; in nvkm_dp_train_init()
432 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[3], in nvkm_dp_train_init()
433 init.outp = &outp->info; in nvkm_dp_train_init()
434 init.or = outp->ior->id; in nvkm_dp_train_init()
435 init.link = outp->ior->asy.link; in nvkm_dp_train_init()
439 if (!AMPERE_IED_HACK(outp->disp)) { in nvkm_dp_train_init()
441 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[0], in nvkm_dp_train_init()
442 init.outp = &outp->info; in nvkm_dp_train_init()
443 init.or = outp->ior->id; in nvkm_dp_train_init()
444 init.link = outp->ior->asy.link; in nvkm_dp_train_init()
450 nvkm_dp_train(struct nvkm_outp *outp, u32 dataKBps) in nvkm_dp_train() argument
452 struct nvkm_ior *ior = outp->ior; in nvkm_dp_train()
457 if (atomic_read(&outp->dp.lt.done)) { in nvkm_dp_train()
458 for (rate = 0; rate < outp->dp.rates; rate++) { in nvkm_dp_train()
459 if (outp->dp.rate[rate].rate == ior->dp.bw * 27000) in nvkm_dp_train()
460 return nvkm_dp_train_link(outp, ret); in nvkm_dp_train()
467 if (!nvkm_rdaux(outp->dp.aux, DPCD_SC00, &pwr, 1)) { in nvkm_dp_train()
471 nvkm_wraux(outp->dp.aux, DPCD_SC00, &pwr, 1); in nvkm_dp_train()
475 ior->dp.mst = outp->dp.lt.mst; in nvkm_dp_train()
476 ior->dp.ef = outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP; in nvkm_dp_train()
480 OUTP_DBG(outp, "training"); in nvkm_dp_train()
481 nvkm_dp_train_init(outp); in nvkm_dp_train()
484 if (outp->dp.lt.nr) { in nvkm_dp_train()
485 for (nr = outp->dp.links; ret < 0 && nr; nr >>= 1) { in nvkm_dp_train()
486 for (rate = 0; nr == outp->dp.lt.nr && rate < outp->dp.rates; rate++) { in nvkm_dp_train()
487 if (outp->dp.rate[rate].rate / 27000 == outp->dp.lt.bw) { in nvkm_dp_train()
488 ior->dp.bw = outp->dp.rate[rate].rate / 27000; in nvkm_dp_train()
490 ret = nvkm_dp_train_links(outp, rate); in nvkm_dp_train()
497 for (nr = outp->dp.links; ret < 0 && nr; nr >>= 1) { in nvkm_dp_train()
498 for (rate = 0; ret < 0 && rate < outp->dp.rates; rate++) { in nvkm_dp_train()
499 if (outp->dp.rate[rate].rate * nr >= dataKBps || WARN_ON(!ior->dp.nr)) { in nvkm_dp_train()
501 ior->dp.bw = outp->dp.rate[rate].rate / 27000; in nvkm_dp_train()
503 ret = nvkm_dp_train_links(outp, rate); in nvkm_dp_train()
509 nvkm_dp_train_fini(outp); in nvkm_dp_train()
511 OUTP_ERR(outp, "training failed"); in nvkm_dp_train()
513 OUTP_DBG(outp, "training done"); in nvkm_dp_train()
514 atomic_set(&outp->dp.lt.done, 1); in nvkm_dp_train()
519 nvkm_dp_disable(struct nvkm_outp *outp, struct nvkm_ior *ior) in nvkm_dp_disable() argument
522 nvbios_init(&ior->disp->engine.subdev, outp->dp.info.script[4], in nvkm_dp_disable()
523 init.outp = &outp->info; in nvkm_dp_disable()
530 nvkm_dp_release(struct nvkm_outp *outp) in nvkm_dp_release() argument
533 atomic_set(&outp->dp.lt.done, 0); in nvkm_dp_release()
534 outp->ior->dp.nr = 0; in nvkm_dp_release()
538 nvkm_dp_acquire(struct nvkm_outp *outp) in nvkm_dp_acquire() argument
540 struct nvkm_ior *ior = outp->ior; in nvkm_dp_acquire()
549 mutex_lock(&outp->dp.mutex); in nvkm_dp_acquire()
552 list_for_each_entry(head, &outp->disp->heads, head) { in nvkm_dp_acquire()
561 OUTP_DBG(outp, "data %d KB/s link %d KB/s mst %d->%d", in nvkm_dp_acquire()
562 dataKBps, linkKBps, ior->dp.mst, outp->dp.lt.mst); in nvkm_dp_acquire()
563 if (linkKBps < dataKBps || ior->dp.mst != outp->dp.lt.mst) { in nvkm_dp_acquire()
564 OUTP_DBG(outp, "link requirements changed"); in nvkm_dp_acquire()
569 ret = nvkm_rdaux(outp->dp.aux, DPCD_LS02, stat, 3); in nvkm_dp_acquire()
571 OUTP_DBG(outp, "failed to read link status, assuming no sink"); in nvkm_dp_acquire()
581 OUTP_DBG(outp, "lane %d not equalised", lane); in nvkm_dp_acquire()
587 OUTP_DBG(outp, "no inter-lane alignment"); in nvkm_dp_acquire()
591 if (retrain || !atomic_read(&outp->dp.lt.done)) in nvkm_dp_acquire()
592 ret = nvkm_dp_train(outp, dataKBps); in nvkm_dp_acquire()
593 mutex_unlock(&outp->dp.mutex); in nvkm_dp_acquire()
598 nvkm_dp_enable_supported_link_rates(struct nvkm_outp *outp) in nvkm_dp_enable_supported_link_rates() argument
603 if (outp->conn->info.type != DCB_CONNECTOR_eDP || in nvkm_dp_enable_supported_link_rates()
604 outp->dp.dpcd[DPCD_RC00_DPCD_REV] < 0x13 || in nvkm_dp_enable_supported_link_rates()
605 nvkm_rdaux(outp->dp.aux, DPCD_RC10_SUPPORTED_LINK_RATES(0), in nvkm_dp_enable_supported_link_rates()
612 if (!rate || WARN_ON(outp->dp.rates == ARRAY_SIZE(outp->dp.rate))) in nvkm_dp_enable_supported_link_rates()
615 if (rate > outp->info.dpconf.link_bw * 27000) { in nvkm_dp_enable_supported_link_rates()
616 OUTP_DBG(outp, "rate %d !outp", rate); in nvkm_dp_enable_supported_link_rates()
620 for (j = 0; j < outp->dp.rates; j++) { in nvkm_dp_enable_supported_link_rates()
621 if (rate > outp->dp.rate[j].rate) { in nvkm_dp_enable_supported_link_rates()
622 for (k = outp->dp.rates; k > j; k--) in nvkm_dp_enable_supported_link_rates()
623 outp->dp.rate[k] = outp->dp.rate[k - 1]; in nvkm_dp_enable_supported_link_rates()
628 outp->dp.rate[j].dpcd = i / 2; in nvkm_dp_enable_supported_link_rates()
629 outp->dp.rate[j].rate = rate; in nvkm_dp_enable_supported_link_rates()
630 outp->dp.rates++; in nvkm_dp_enable_supported_link_rates()
633 for (i = 0; i < outp->dp.rates; i++) in nvkm_dp_enable_supported_link_rates()
634 OUTP_DBG(outp, "link_rate[%d] = %d", outp->dp.rate[i].dpcd, outp->dp.rate[i].rate); in nvkm_dp_enable_supported_link_rates()
636 return outp->dp.rates != 0; in nvkm_dp_enable_supported_link_rates()
644 nvkm_dp_read_dpcd_caps(struct nvkm_outp *outp) in nvkm_dp_read_dpcd_caps() argument
646 struct nvkm_i2c_aux *aux = outp->dp.aux; in nvkm_dp_read_dpcd_caps()
650 ret = nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, DP_RECEIVER_CAP_SIZE); in nvkm_dp_read_dpcd_caps()
661 if (!(outp->dp.dpcd[DP_TRAINING_AUX_RD_INTERVAL] & in nvkm_dp_read_dpcd_caps()
669 if (outp->dp.dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) { in nvkm_dp_read_dpcd_caps()
670 OUTP_DBG(outp, "Extended DPCD rev less than base DPCD rev (%d > %d)\n", in nvkm_dp_read_dpcd_caps()
671 outp->dp.dpcd[DP_DPCD_REV], dpcd_ext[DP_DPCD_REV]); in nvkm_dp_read_dpcd_caps()
675 if (!memcmp(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext))) in nvkm_dp_read_dpcd_caps()
678 memcpy(outp->dp.dpcd, dpcd_ext, sizeof(dpcd_ext)); in nvkm_dp_read_dpcd_caps()
684 nvkm_dp_enable(struct nvkm_outp *outp, bool auxpwr) in nvkm_dp_enable() argument
686 struct nvkm_gpio *gpio = outp->disp->engine.subdev.device->gpio; in nvkm_dp_enable()
687 struct nvkm_i2c_aux *aux = outp->dp.aux; in nvkm_dp_enable()
689 if (auxpwr && !outp->dp.aux_pwr) { in nvkm_dp_enable()
694 if (outp->conn->info.type == DCB_CONNECTOR_eDP) { in nvkm_dp_enable()
698 outp->dp.aux_pwr_pu = true; in nvkm_dp_enable()
711 OUTP_DBG(outp, "aux power -> always"); in nvkm_dp_enable()
713 outp->dp.aux_pwr = true; in nvkm_dp_enable()
716 if (!nvkm_rdaux(aux, DPCD_LTTPR_REV, outp->dp.lttpr, sizeof(outp->dp.lttpr)) && in nvkm_dp_enable()
717 outp->dp.lttpr[0] >= 0x14 && outp->dp.lttpr[2]) { in nvkm_dp_enable()
718 switch (outp->dp.lttpr[2]) { in nvkm_dp_enable()
719 case 0x80: outp->dp.lttprs = 1; break; in nvkm_dp_enable()
720 case 0x40: outp->dp.lttprs = 2; break; in nvkm_dp_enable()
721 case 0x20: outp->dp.lttprs = 3; break; in nvkm_dp_enable()
722 case 0x10: outp->dp.lttprs = 4; break; in nvkm_dp_enable()
723 case 0x08: outp->dp.lttprs = 5; break; in nvkm_dp_enable()
724 case 0x04: outp->dp.lttprs = 6; break; in nvkm_dp_enable()
725 case 0x02: outp->dp.lttprs = 7; break; in nvkm_dp_enable()
726 case 0x01: outp->dp.lttprs = 8; break; in nvkm_dp_enable()
730 outp->dp.lttprs = 0; in nvkm_dp_enable()
735 memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr)); in nvkm_dp_enable()
738 if (!nvkm_dp_read_dpcd_caps(outp)) { in nvkm_dp_enable()
743 outp->dp.rates = 0; in nvkm_dp_enable()
744 outp->dp.links = outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_MAX_LANE_COUNT; in nvkm_dp_enable()
745 outp->dp.links = min(outp->dp.links, outp->info.dpconf.link_nr); in nvkm_dp_enable()
746 if (outp->dp.lttprs && outp->dp.lttpr[4]) in nvkm_dp_enable()
747 outp->dp.links = min_t(int, outp->dp.links, outp->dp.lttpr[4]); in nvkm_dp_enable()
749 rate_max = outp->dp.dpcd[DPCD_RC01_MAX_LINK_RATE]; in nvkm_dp_enable()
750 rate_max = min(rate_max, outp->info.dpconf.link_bw); in nvkm_dp_enable()
751 if (outp->dp.lttprs && outp->dp.lttpr[1]) in nvkm_dp_enable()
752 rate_max = min_t(int, rate_max, outp->dp.lttpr[1]); in nvkm_dp_enable()
754 if (!nvkm_dp_enable_supported_link_rates(outp)) { in nvkm_dp_enable()
759 if (WARN_ON(outp->dp.rates == ARRAY_SIZE(outp->dp.rate))) in nvkm_dp_enable()
762 outp->dp.rate[outp->dp.rates].dpcd = -1; in nvkm_dp_enable()
763 outp->dp.rate[outp->dp.rates].rate = *rate * 27000; in nvkm_dp_enable()
764 outp->dp.rates++; in nvkm_dp_enable()
769 if (!auxpwr && outp->dp.aux_pwr) { in nvkm_dp_enable()
770 OUTP_DBG(outp, "aux power -> demand"); in nvkm_dp_enable()
772 outp->dp.aux_pwr = false; in nvkm_dp_enable()
773 atomic_set(&outp->dp.lt.done, 0); in nvkm_dp_enable()
778 if (outp->conn->info.type == DCB_CONNECTOR_eDP) { in nvkm_dp_enable()
779 if (outp->dp.aux_pwr_pu) { in nvkm_dp_enable()
781 outp->dp.aux_pwr_pu = false; in nvkm_dp_enable()
788 nvkm_dp_fini(struct nvkm_outp *outp) in nvkm_dp_fini() argument
790 nvkm_dp_enable(outp, false); in nvkm_dp_fini()
794 nvkm_dp_init(struct nvkm_outp *outp) in nvkm_dp_init() argument
796 nvkm_dp_enable(outp, outp->dp.enabled); in nvkm_dp_init()
800 nvkm_dp_dtor(struct nvkm_outp *outp) in nvkm_dp_dtor() argument
802 return outp; in nvkm_dp_dtor()
821 struct nvkm_outp *outp; in nvkm_dp_new() local
827 outp = *poutp; in nvkm_dp_new()
832 outp->dp.aux = nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_CCB(dcbE->i2c_index)); in nvkm_dp_new()
834 outp->dp.aux = nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_EXT(dcbE->extdev)); in nvkm_dp_new()
835 if (!outp->dp.aux) { in nvkm_dp_new()
836 OUTP_ERR(outp, "no aux"); in nvkm_dp_new()
841 data = nvbios_dpout_match(bios, outp->info.hasht, outp->info.hashm, in nvkm_dp_new()
842 &outp->dp.version, &hdr, &cnt, &len, &outp->dp.info); in nvkm_dp_new()
844 OUTP_ERR(outp, "no bios dp data"); in nvkm_dp_new()
848 OUTP_DBG(outp, "bios dp %02x %02x %02x %02x", outp->dp.version, hdr, cnt, len); in nvkm_dp_new()
850 mutex_init(&outp->dp.mutex); in nvkm_dp_new()
851 atomic_set(&outp->dp.lt.done, 0); in nvkm_dp_new()