Lines Matching full:dp

24 #include "dp.h"
37 struct nvkm_dp *dp; member
48 struct nvkm_dp *dp = lt->dp; in nvkm_dp_train_sense() local
51 if (dp->dpcd[DPCD_RC0E_AUX_RD_INTERVAL]) in nvkm_dp_train_sense()
52 mdelay(dp->dpcd[DPCD_RC0E_AUX_RD_INTERVAL] * 4); in nvkm_dp_train_sense()
56 ret = nvkm_rdaux(dp->aux, DPCD_LS02, lt->stat, 6); in nvkm_dp_train_sense()
61 ret = nvkm_rdaux(dp->aux, DPCD_LS0C, &lt->pc2stat, 1); in nvkm_dp_train_sense()
64 OUTP_TRACE(&dp->outp, "status %6ph pc2 %02x", in nvkm_dp_train_sense()
67 OUTP_TRACE(&dp->outp, "status %6ph", lt->stat); in nvkm_dp_train_sense()
76 struct nvkm_dp *dp = lt->dp; in nvkm_dp_train_drive() local
77 struct nvkm_ior *ior = dp->outp.ior; in nvkm_dp_train_drive()
85 for (i = 0; i < ior->dp.nr; i++) { in nvkm_dp_train_drive()
107 OUTP_TRACE(&dp->outp, "config lane %d %02x %02x", in nvkm_dp_train_drive()
110 data = nvbios_dpout_match(bios, dp->outp.info.hasht, in nvkm_dp_train_drive()
111 dp->outp.info.hashm, in nvkm_dp_train_drive()
122 ior->func->dp.drive(ior, i, ocfg.pc, ocfg.dc, in nvkm_dp_train_drive()
126 ret = nvkm_wraux(dp->aux, DPCD_LC03(0), lt->conf, 4); in nvkm_dp_train_drive()
131 ret = nvkm_wraux(dp->aux, DPCD_LC0F, lt->pc2conf, 2); in nvkm_dp_train_drive()
142 struct nvkm_dp *dp = lt->dp; in nvkm_dp_train_pattern() local
145 OUTP_TRACE(&dp->outp, "training pattern %d", pattern); in nvkm_dp_train_pattern()
146 dp->outp.ior->func->dp.pattern(dp->outp.ior, pattern); in nvkm_dp_train_pattern()
148 nvkm_rdaux(dp->aux, DPCD_LC02, &sink_tp, 1); in nvkm_dp_train_pattern()
151 nvkm_wraux(dp->aux, DPCD_LC02, &sink_tp, 1); in nvkm_dp_train_pattern()
160 if (lt->dp->dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED) in nvkm_dp_train_eq()
172 for (i = 0; i < lt->dp->outp.ior->dp.nr && eq_done; i++) { in nvkm_dp_train_eq()
200 for (i = 0; i < lt->dp->outp.ior->dp.nr; i++) { in nvkm_dp_train_cr()
220 nvkm_dp_train_links(struct nvkm_dp *dp) in nvkm_dp_train_links() argument
222 struct nvkm_ior *ior = dp->outp.ior; in nvkm_dp_train_links()
223 struct nvkm_disp *disp = dp->outp.disp; in nvkm_dp_train_links()
227 .dp = dp, in nvkm_dp_train_links()
233 OUTP_DBG(&dp->outp, "training %d x %d MB/s", in nvkm_dp_train_links()
234 ior->dp.nr, ior->dp.bw * 27); in nvkm_dp_train_links()
238 dp->dpcd[DPCD_RC02] &= ~DPCD_RC02_TPS3_SUPPORTED; in nvkm_dp_train_links()
239 lt.pc2 = dp->dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED; in nvkm_dp_train_links()
242 if ((lnkcmp = lt.dp->info.lnkcmp)) { in nvkm_dp_train_links()
243 if (dp->version < 0x30) { in nvkm_dp_train_links()
244 while ((ior->dp.bw * 2700) < nvbios_rd16(bios, lnkcmp)) in nvkm_dp_train_links()
248 while (ior->dp.bw < nvbios_rd08(bios, lnkcmp)) in nvkm_dp_train_links()
254 init.outp = &dp->outp.info; in nvkm_dp_train_links()
260 ret = ior->func->dp.links(ior, dp->aux); in nvkm_dp_train_links()
263 OUTP_ERR(&dp->outp, "train failed with %d", ret); in nvkm_dp_train_links()
269 ior->func->dp.power(ior, ior->dp.nr); in nvkm_dp_train_links()
272 sink[0] = ior->dp.bw; in nvkm_dp_train_links()
273 sink[1] = ior->dp.nr; in nvkm_dp_train_links()
274 if (ior->dp.ef) in nvkm_dp_train_links()
277 ret = nvkm_wraux(dp->aux, DPCD_LC00_LINK_BW_SET, sink, 2); in nvkm_dp_train_links()
291 nvkm_dp_train_fini(struct nvkm_dp *dp) in nvkm_dp_train_fini() argument
293 /* Execute AfterLinkTraining script from DP Info table. */ in nvkm_dp_train_fini()
294 nvbios_init(&dp->outp.disp->engine.subdev, dp->info.script[1], in nvkm_dp_train_fini()
295 init.outp = &dp->outp.info; in nvkm_dp_train_fini()
296 init.or = dp->outp.ior->id; in nvkm_dp_train_fini()
297 init.link = dp->outp.ior->asy.link; in nvkm_dp_train_fini()
302 nvkm_dp_train_init(struct nvkm_dp *dp) in nvkm_dp_train_init() argument
304 /* Execute EnableSpread/DisableSpread script from DP Info table. */ in nvkm_dp_train_init()
305 if (dp->dpcd[DPCD_RC03] & DPCD_RC03_MAX_DOWNSPREAD) { in nvkm_dp_train_init()
306 nvbios_init(&dp->outp.disp->engine.subdev, dp->info.script[2], in nvkm_dp_train_init()
307 init.outp = &dp->outp.info; in nvkm_dp_train_init()
308 init.or = dp->outp.ior->id; in nvkm_dp_train_init()
309 init.link = dp->outp.ior->asy.link; in nvkm_dp_train_init()
312 nvbios_init(&dp->outp.disp->engine.subdev, dp->info.script[3], in nvkm_dp_train_init()
313 init.outp = &dp->outp.info; in nvkm_dp_train_init()
314 init.or = dp->outp.ior->id; in nvkm_dp_train_init()
315 init.link = dp->outp.ior->asy.link; in nvkm_dp_train_init()
319 /* Execute BeforeLinkTraining script from DP Info table. */ in nvkm_dp_train_init()
320 nvbios_init(&dp->outp.disp->engine.subdev, dp->info.script[0], in nvkm_dp_train_init()
321 init.outp = &dp->outp.info; in nvkm_dp_train_init()
322 init.or = dp->outp.ior->id; in nvkm_dp_train_init()
323 init.link = dp->outp.ior->asy.link; in nvkm_dp_train_init()
345 nvkm_dp_train(struct nvkm_dp *dp, u32 dataKBps) in nvkm_dp_train() argument
347 struct nvkm_ior *ior = dp->outp.ior; in nvkm_dp_train()
348 const u8 sink_nr = dp->dpcd[DPCD_RC02] & DPCD_RC02_MAX_LANE_COUNT; in nvkm_dp_train()
349 const u8 sink_bw = dp->dpcd[DPCD_RC01_MAX_LINK_RATE]; in nvkm_dp_train()
350 const u8 outp_nr = dp->outp.info.dpconf.link_nr; in nvkm_dp_train()
351 const u8 outp_bw = dp->outp.info.dpconf.link_bw; in nvkm_dp_train()
385 if (!nvkm_rdaux(dp->aux, DPCD_SC00, &pwr, 1)) { in nvkm_dp_train()
389 nvkm_wraux(dp->aux, DPCD_SC00, &pwr, 1); in nvkm_dp_train()
394 OUTP_DBG(&dp->outp, "training (min: %d x %d MB/s)", in nvkm_dp_train()
396 nvkm_dp_train_init(dp); in nvkm_dp_train()
403 OUTP_ERR(&dp->outp, "link rate unsupported by sink"); in nvkm_dp_train()
405 ior->dp.mst = dp->lt.mst; in nvkm_dp_train()
406 ior->dp.ef = dp->dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP; in nvkm_dp_train()
407 ior->dp.bw = cfg->bw; in nvkm_dp_train()
408 ior->dp.nr = cfg->nr; in nvkm_dp_train()
411 ret = nvkm_dp_train_links(dp); in nvkm_dp_train()
413 nvkm_dp_train_fini(dp); in nvkm_dp_train()
415 OUTP_ERR(&dp->outp, "training failed"); in nvkm_dp_train()
417 OUTP_DBG(&dp->outp, "training done"); in nvkm_dp_train()
418 atomic_set(&dp->lt.done, 1); in nvkm_dp_train()
425 struct nvkm_dp *dp = nvkm_dp(outp); in nvkm_dp_disable() local
427 /* Execute DisableLT script from DP Info Table. */ in nvkm_dp_disable()
428 nvbios_init(&ior->disp->engine.subdev, dp->info.script[4], in nvkm_dp_disable()
429 init.outp = &dp->outp.info; in nvkm_dp_disable()
438 struct nvkm_dp *dp = nvkm_dp(outp); in nvkm_dp_release() local
441 atomic_set(&dp->lt.done, 0); in nvkm_dp_release()
442 dp->outp.ior->dp.nr = 0; in nvkm_dp_release()
448 struct nvkm_dp *dp = nvkm_dp(outp); in nvkm_dp_acquire() local
449 struct nvkm_ior *ior = dp->outp.ior; in nvkm_dp_acquire()
458 mutex_lock(&dp->mutex); in nvkm_dp_acquire()
468 linkKBps = ior->dp.bw * 27000 * ior->dp.nr; in nvkm_dp_acquire()
470 OUTP_DBG(&dp->outp, "data %d KB/s link %d KB/s mst %d->%d", in nvkm_dp_acquire()
471 dataKBps, linkKBps, ior->dp.mst, dp->lt.mst); in nvkm_dp_acquire()
472 if (linkKBps < dataKBps || ior->dp.mst != dp->lt.mst) { in nvkm_dp_acquire()
473 OUTP_DBG(&dp->outp, "link requirements changed"); in nvkm_dp_acquire()
478 ret = nvkm_rdaux(dp->aux, DPCD_LS02, stat, 3); in nvkm_dp_acquire()
480 OUTP_DBG(&dp->outp, in nvkm_dp_acquire()
486 for (i = 0; i < ior->dp.nr; i++) { in nvkm_dp_acquire()
491 OUTP_DBG(&dp->outp, in nvkm_dp_acquire()
498 OUTP_DBG(&dp->outp, "no inter-lane alignment"); in nvkm_dp_acquire()
502 if (retrain || !atomic_read(&dp->lt.done)) in nvkm_dp_acquire()
503 ret = nvkm_dp_train(dp, dataKBps); in nvkm_dp_acquire()
504 mutex_unlock(&dp->mutex); in nvkm_dp_acquire()
509 nvkm_dp_enable(struct nvkm_dp *dp, bool enable) in nvkm_dp_enable() argument
511 struct nvkm_i2c_aux *aux = dp->aux; in nvkm_dp_enable()
514 if (!dp->present) { in nvkm_dp_enable()
515 OUTP_DBG(&dp->outp, "aux power -> always"); in nvkm_dp_enable()
517 dp->present = true; in nvkm_dp_enable()
520 if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, dp->dpcd, in nvkm_dp_enable()
521 sizeof(dp->dpcd))) in nvkm_dp_enable()
525 if (dp->present) { in nvkm_dp_enable()
526 OUTP_DBG(&dp->outp, "aux power -> demand"); in nvkm_dp_enable()
528 dp->present = false; in nvkm_dp_enable()
531 atomic_set(&dp->lt.done, 0); in nvkm_dp_enable()
539 struct nvkm_dp *dp = container_of(notify, typeof(*dp), hpd); in nvkm_dp_hpd() local
540 struct nvkm_conn *conn = dp->outp.conn; in nvkm_dp_hpd()
541 struct nvkm_disp *disp = dp->outp.disp; in nvkm_dp_hpd()
544 OUTP_DBG(&dp->outp, "HPD: %d", line->mask); in nvkm_dp_hpd()
546 if (atomic_read(&dp->lt.done)) in nvkm_dp_hpd()
547 dp->outp.func->acquire(&dp->outp); in nvkm_dp_hpd()
550 nvkm_dp_enable(dp, true); in nvkm_dp_hpd()
565 struct nvkm_dp *dp = nvkm_dp(outp); in nvkm_dp_fini() local
566 nvkm_notify_put(&dp->hpd); in nvkm_dp_fini()
567 nvkm_dp_enable(dp, false); in nvkm_dp_fini()
574 struct nvkm_dp *dp = nvkm_dp(outp); in nvkm_dp_init() local
576 nvkm_notify_put(&dp->outp.conn->hpd); in nvkm_dp_init()
582 if (dp->outp.conn->info.type == DCB_CONNECTOR_eDP) { in nvkm_dp_init()
599 if (!nvkm_dp_enable(dp, true) && power == 0) in nvkm_dp_init()
602 nvkm_dp_enable(dp, true); in nvkm_dp_init()
605 nvkm_notify_get(&dp->hpd); in nvkm_dp_init()
611 struct nvkm_dp *dp = nvkm_dp(outp); in nvkm_dp_dtor() local
612 nvkm_notify_fini(&dp->hpd); in nvkm_dp_dtor()
613 return dp; in nvkm_dp_dtor()
628 struct nvkm_i2c_aux *aux, struct nvkm_dp *dp) in nvkm_dp_ctor() argument
637 ret = nvkm_outp_ctor(&nvkm_dp_func, disp, index, dcbE, &dp->outp); in nvkm_dp_ctor()
641 dp->aux = aux; in nvkm_dp_ctor()
642 if (!dp->aux) { in nvkm_dp_ctor()
643 OUTP_ERR(&dp->outp, "no aux"); in nvkm_dp_ctor()
648 data = nvbios_dpout_match(bios, dp->outp.info.hasht, in nvkm_dp_ctor()
649 dp->outp.info.hashm, &dp->version, in nvkm_dp_ctor()
650 &hdr, &cnt, &len, &dp->info); in nvkm_dp_ctor()
652 OUTP_ERR(&dp->outp, "no bios dp data"); in nvkm_dp_ctor()
656 OUTP_DBG(&dp->outp, "bios dp %02x %02x %02x %02x", in nvkm_dp_ctor()
657 dp->version, hdr, cnt, len); in nvkm_dp_ctor()
664 .port = dp->aux->id, in nvkm_dp_ctor()
668 &dp->hpd); in nvkm_dp_ctor()
670 OUTP_ERR(&dp->outp, "error monitoring aux hpd: %d", ret); in nvkm_dp_ctor()
674 mutex_init(&dp->mutex); in nvkm_dp_ctor()
675 atomic_set(&dp->lt.done, 0); in nvkm_dp_ctor()
685 struct nvkm_dp *dp; in nvkm_dp_new() local
692 if (!(dp = kzalloc(sizeof(*dp), GFP_KERNEL))) in nvkm_dp_new()
694 *poutp = &dp->outp; in nvkm_dp_new()
696 return nvkm_dp_ctor(disp, index, dcbE, aux, dp); in nvkm_dp_new()