Lines Matching full:dp

24 #include "dp.h"
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()
108 for (i = 0; i < ior->dp.nr; i++) { in nvkm_dp_train_drive()
145 ior->func->dp->drive(ior, i, ocfg.pc, ocfg.dc, ocfg.pe, ocfg.tx_pu); 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()
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()
290 OUTP_DBG(outp, "training %d x %d MB/s", ior->dp.nr, ior->dp.bw * 27); in nvkm_dp_train_links()
294 outp->dp.dpcd[DPCD_RC03] &= ~DPCD_RC03_TPS4_SUPPORTED; in nvkm_dp_train_links()
296 outp->dp.dpcd[DPCD_RC02] &= ~DPCD_RC02_TPS3_SUPPORTED; in nvkm_dp_train_links()
297 lt.pc2 = outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED; in nvkm_dp_train_links()
299 if (AMPERE_IED_HACK(disp) && (lnkcmp = lt.outp->dp.info.script[0])) { in nvkm_dp_train_links()
300 /* Execute BeforeLinkTraining script from DP Info table. */ in nvkm_dp_train_links()
301 while (ior->dp.bw < nvbios_rd08(bios, lnkcmp)) in nvkm_dp_train_links()
313 if ((lnkcmp = lt.outp->dp.info.lnkcmp)) { in nvkm_dp_train_links()
314 if (outp->dp.version < 0x30) { in nvkm_dp_train_links()
315 while ((ior->dp.bw * 2700) < nvbios_rd16(bios, lnkcmp)) in nvkm_dp_train_links()
319 while (ior->dp.bw < nvbios_rd08(bios, lnkcmp)) in nvkm_dp_train_links()
331 ret = ior->func->dp->links(ior, outp->dp.aux); in nvkm_dp_train_links()
340 ior->func->dp->power(ior, ior->dp.nr); in nvkm_dp_train_links()
345 if (outp->dp.lttpr[0] >= 0x14) { in nvkm_dp_train_links()
347 nvkm_wraux(outp->dp.aux, DPCD_LTTPR_MODE, &data, sizeof(data)); in nvkm_dp_train_links()
349 if (outp->dp.lttprs) { in nvkm_dp_train_links()
351 nvkm_wraux(outp->dp.aux, DPCD_LTTPR_MODE, &data, sizeof(data)); in nvkm_dp_train_links()
352 lt.repeaters = outp->dp.lttprs; in nvkm_dp_train_links()
357 sink[0] = (outp->dp.rate[rate].dpcd < 0) ? ior->dp.bw : 0; in nvkm_dp_train_links()
358 sink[1] = ior->dp.nr; in nvkm_dp_train_links()
359 if (ior->dp.ef) in nvkm_dp_train_links()
362 ret = nvkm_wraux(outp->dp.aux, DPCD_LC00_LINK_BW_SET, sink, 2); in nvkm_dp_train_links()
366 if (outp->dp.rate[rate].dpcd >= 0) { in nvkm_dp_train_links()
367 ret = nvkm_rdaux(outp->dp.aux, DPCD_LC15_LINK_RATE_SET, &sink[0], sizeof(sink[0])); in nvkm_dp_train_links()
372 sink[0] |= outp->dp.rate[rate].dpcd; in nvkm_dp_train_links()
374 ret = nvkm_wraux(outp->dp.aux, DPCD_LC15_LINK_RATE_SET, &sink[0], sizeof(sink[0])); in nvkm_dp_train_links()
399 /* Execute AfterLinkTraining script from DP Info table. */ in nvkm_dp_train_fini()
400 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[1], in nvkm_dp_train_fini()
410 /* Execute EnableSpread/DisableSpread script from DP Info table. */ in nvkm_dp_train_init()
411 if (outp->dp.dpcd[DPCD_RC03] & DPCD_RC03_MAX_DOWNSPREAD) { in nvkm_dp_train_init()
412 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[2], in nvkm_dp_train_init()
418 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[3], in nvkm_dp_train_init()
426 /* Execute BeforeLinkTraining script from DP Info table. */ in nvkm_dp_train_init()
427 nvbios_init(&outp->disp->engine.subdev, outp->dp.info.script[0], in nvkm_dp_train_init()
443 if (!nvkm_rdaux(outp->dp.aux, DPCD_SC00, &pwr, 1)) { in nvkm_dp_train()
447 nvkm_wraux(outp->dp.aux, DPCD_SC00, &pwr, 1); in nvkm_dp_train()
451 ior->dp.mst = outp->dp.lt.mst; in nvkm_dp_train()
452 ior->dp.ef = outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP; in nvkm_dp_train()
453 ior->dp.nr = 0; in nvkm_dp_train()
458 for (nr = outp->dp.links; ret < 0 && nr; nr >>= 1) { in nvkm_dp_train()
459 for (rate = 0; ret < 0 && rate < outp->dp.rates; rate++) { in nvkm_dp_train()
460 if (outp->dp.rate[rate].rate * nr >= dataKBps || WARN_ON(!ior->dp.nr)) { in nvkm_dp_train()
462 ior->dp.bw = outp->dp.rate[rate].rate / 27000; in nvkm_dp_train()
463 ior->dp.nr = nr; in nvkm_dp_train()
473 atomic_set(&outp->dp.lt.done, 1); in nvkm_dp_train()
480 /* Execute DisableLT script from DP Info Table. */ in nvkm_dp_disable()
481 nvbios_init(&ior->disp->engine.subdev, outp->dp.info.script[4], in nvkm_dp_disable()
492 atomic_set(&outp->dp.lt.done, 0); in nvkm_dp_release()
493 outp->ior->dp.nr = 0; in nvkm_dp_release()
508 mutex_lock(&outp->dp.mutex); in nvkm_dp_acquire()
518 linkKBps = ior->dp.bw * 27000 * ior->dp.nr; in nvkm_dp_acquire()
521 dataKBps, linkKBps, ior->dp.mst, outp->dp.lt.mst); in nvkm_dp_acquire()
522 if (linkKBps < dataKBps || ior->dp.mst != outp->dp.lt.mst) { in nvkm_dp_acquire()
528 ret = nvkm_rdaux(outp->dp.aux, DPCD_LS02, stat, 3); in nvkm_dp_acquire()
535 for (i = 0; i < ior->dp.nr; i++) { in nvkm_dp_acquire()
550 if (retrain || !atomic_read(&outp->dp.lt.done)) in nvkm_dp_acquire()
552 mutex_unlock(&outp->dp.mutex); in nvkm_dp_acquire()
563 outp->dp.dpcd[DPCD_RC00_DPCD_REV] < 0x13 || in nvkm_dp_enable_supported_link_rates()
564 nvkm_rdaux(outp->dp.aux, DPCD_RC10_SUPPORTED_LINK_RATES(0), in nvkm_dp_enable_supported_link_rates()
571 if (!rate || WARN_ON(outp->dp.rates == ARRAY_SIZE(outp->dp.rate))) in nvkm_dp_enable_supported_link_rates()
579 for (j = 0; j < outp->dp.rates; j++) { in nvkm_dp_enable_supported_link_rates()
580 if (rate > outp->dp.rate[j].rate) { in nvkm_dp_enable_supported_link_rates()
581 for (k = outp->dp.rates; k > j; k--) in nvkm_dp_enable_supported_link_rates()
582 outp->dp.rate[k] = outp->dp.rate[k - 1]; in nvkm_dp_enable_supported_link_rates()
587 outp->dp.rate[j].dpcd = i / 2; in nvkm_dp_enable_supported_link_rates()
588 outp->dp.rate[j].rate = rate; in nvkm_dp_enable_supported_link_rates()
589 outp->dp.rates++; in nvkm_dp_enable_supported_link_rates()
592 for (i = 0; i < outp->dp.rates; i++) in nvkm_dp_enable_supported_link_rates()
593 OUTP_DBG(outp, "link_rate[%d] = %d", outp->dp.rate[i].dpcd, outp->dp.rate[i].rate); in nvkm_dp_enable_supported_link_rates()
595 return outp->dp.rates != 0; in nvkm_dp_enable_supported_link_rates()
601 struct nvkm_i2c_aux *aux = outp->dp.aux; in nvkm_dp_enable()
604 if (!outp->dp.present) { in nvkm_dp_enable()
607 outp->dp.present = true; in nvkm_dp_enable()
611 if (!nvkm_rdaux(aux, DPCD_LTTPR_REV, outp->dp.lttpr, sizeof(outp->dp.lttpr)) && in nvkm_dp_enable()
612 outp->dp.lttpr[0] >= 0x14 && outp->dp.lttpr[2]) { in nvkm_dp_enable()
613 switch (outp->dp.lttpr[2]) { in nvkm_dp_enable()
614 case 0x80: outp->dp.lttprs = 1; break; in nvkm_dp_enable()
615 case 0x40: outp->dp.lttprs = 2; break; in nvkm_dp_enable()
616 case 0x20: outp->dp.lttprs = 3; break; in nvkm_dp_enable()
617 case 0x10: outp->dp.lttprs = 4; break; in nvkm_dp_enable()
618 case 0x08: outp->dp.lttprs = 5; break; in nvkm_dp_enable()
619 case 0x04: outp->dp.lttprs = 6; break; in nvkm_dp_enable()
620 case 0x02: outp->dp.lttprs = 7; break; in nvkm_dp_enable()
621 case 0x01: outp->dp.lttprs = 8; break; in nvkm_dp_enable()
625 outp->dp.lttprs = 0; in nvkm_dp_enable()
630 memset(outp->dp.lttpr, 0x00, sizeof(outp->dp.lttpr)); in nvkm_dp_enable()
633 if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dp.dpcd, sizeof(outp->dp.dpcd))) { in nvkm_dp_enable()
638 outp->dp.rates = 0; in nvkm_dp_enable()
639 outp->dp.links = outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_MAX_LANE_COUNT; in nvkm_dp_enable()
640 outp->dp.links = min(outp->dp.links, outp->info.dpconf.link_nr); in nvkm_dp_enable()
641 if (outp->dp.lttprs && outp->dp.lttpr[4]) in nvkm_dp_enable()
642 outp->dp.links = min_t(int, outp->dp.links, outp->dp.lttpr[4]); in nvkm_dp_enable()
644 rate_max = outp->dp.dpcd[DPCD_RC01_MAX_LINK_RATE]; in nvkm_dp_enable()
646 if (outp->dp.lttprs && outp->dp.lttpr[1]) in nvkm_dp_enable()
647 rate_max = min_t(int, rate_max, outp->dp.lttpr[1]); in nvkm_dp_enable()
654 if (WARN_ON(outp->dp.rates == ARRAY_SIZE(outp->dp.rate))) in nvkm_dp_enable()
657 outp->dp.rate[outp->dp.rates].dpcd = -1; in nvkm_dp_enable()
658 outp->dp.rate[outp->dp.rates].rate = *rate * 27000; in nvkm_dp_enable()
659 outp->dp.rates++; in nvkm_dp_enable()
667 if (outp->dp.present) { in nvkm_dp_enable()
670 outp->dp.present = false; in nvkm_dp_enable()
673 atomic_set(&outp->dp.lt.done, 0); in nvkm_dp_enable()
681 struct nvkm_outp *outp = container_of(notify, typeof(*outp), dp.hpd); in nvkm_dp_hpd()
688 if (atomic_read(&outp->dp.lt.done)) in nvkm_dp_hpd()
707 nvkm_notify_put(&outp->dp.hpd); in nvkm_dp_fini()
745 nvkm_notify_get(&outp->dp.hpd); in nvkm_dp_init()
751 nvkm_notify_fini(&outp->dp.hpd); in nvkm_dp_dtor()
782 outp->dp.aux = nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_CCB(dcbE->i2c_index)); in nvkm_dp_new()
784 outp->dp.aux = nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_EXT(dcbE->extdev)); in nvkm_dp_new()
785 if (!outp->dp.aux) { in nvkm_dp_new()
792 &outp->dp.version, &hdr, &cnt, &len, &outp->dp.info); in nvkm_dp_new()
794 OUTP_ERR(outp, "no bios dp data"); in nvkm_dp_new()
798 OUTP_DBG(outp, "bios dp %02x %02x %02x %02x", outp->dp.version, hdr, cnt, len); in nvkm_dp_new()
805 .port = outp->dp.aux->id, in nvkm_dp_new()
809 &outp->dp.hpd); in nvkm_dp_new()
815 mutex_init(&outp->dp.mutex); in nvkm_dp_new()
816 atomic_set(&outp->dp.lt.done, 0); in nvkm_dp_new()