summaryrefslogtreecommitdiff
path: root/nvkm/engine/disp/dport.c
diff options
context:
space:
mode:
Diffstat (limited to 'nvkm/engine/disp/dport.c')
-rw-r--r--nvkm/engine/disp/dport.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/nvkm/engine/disp/dport.c b/nvkm/engine/disp/dport.c
index 5d4b0348..c2bf611d 100644
--- a/nvkm/engine/disp/dport.c
+++ b/nvkm/engine/disp/dport.c
@@ -102,7 +102,7 @@ dp_set_link_config(struct dp_state *dp)
if (outp->dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP)
sink[1] |= DPCD_LC01_ENHANCED_FRAME_EN;
- return nv_wraux(outp->base.edid, DPCD_LC00, sink, 2);
+ return nv_wraux(outp->base.edid, DPCD_LC00_LINK_BW_SET, sink, 2);
}
static void
@@ -313,14 +313,16 @@ static const struct dp_rates {
{}
};
-int
-nouveau_dp_train(struct nvkm_output_dp *outp, u32 datarate)
+void
+nouveau_dp_train(struct work_struct *w)
{
+ struct nvkm_output_dp *outp = container_of(w, typeof(*outp), lt.work);
struct nouveau_disp *disp = nouveau_disp(outp);
const struct dp_rates *cfg = nouveau_dp_rates;
struct dp_state _dp = {
.outp = outp,
}, *dp = &_dp;
+ u32 datarate = 0;
int ret;
/* bring capabilities within encoder limits */
@@ -342,6 +344,9 @@ nouveau_dp_train(struct nvkm_output_dp *outp, u32 datarate)
}
cfg--;
+ /* disable link interrupt handling during link training */
+ nouveau_event_put(outp->irq);
+
/* enable down-spreading and execute pre-train script from vbios */
dp_link_train_init(dp, outp->dpcd[3] & 0x01);
@@ -370,12 +375,16 @@ nouveau_dp_train(struct nvkm_output_dp *outp, u32 datarate)
}
}
- /* finish link training */
+ /* finish link training and execute post-train script from vbios */
dp_set_training_pattern(dp, 0);
if (ret < 0)
ERR("link training failed\n");
- /* execute post-train script from vbios */
dp_link_train_fini(dp);
- return (ret < 0) ? false : true;
+
+ /* signal completion and enable link interrupt handling */
+ DBG("training complete\n");
+ atomic_set(&outp->lt.done, 1);
+ wake_up(&outp->lt.wait);
+ nouveau_event_get(outp->irq);
}