Commit fafa8b5c authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/disp/dp: use cached link configuration when checking link status

Saves some trips across the aux channel.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 4423c743
...@@ -326,7 +326,7 @@ static const struct dp_rates { ...@@ -326,7 +326,7 @@ static const struct dp_rates {
{} {}
}; };
static void static int
nvkm_dp_train(struct nvkm_dp *dp) nvkm_dp_train(struct nvkm_dp *dp)
{ {
struct nv50_disp *disp = nv50_disp(dp->outp.disp); struct nv50_disp *disp = nv50_disp(dp->outp.disp);
...@@ -370,39 +370,34 @@ nvkm_dp_train(struct nvkm_dp *dp) ...@@ -370,39 +370,34 @@ nvkm_dp_train(struct nvkm_dp *dp)
nvkm_dp_train_fini(dp); nvkm_dp_train_fini(dp);
if (ret < 0) if (ret < 0)
OUTP_ERR(&dp->outp, "training failed"); OUTP_ERR(&dp->outp, "training failed");
else
OUTP_DBG(&dp->outp, "training done"); OUTP_DBG(&dp->outp, "training done");
atomic_set(&dp->lt.done, 1); atomic_set(&dp->lt.done, 1);
return ret;
} }
int int
nvkm_output_dp_train(struct nvkm_outp *outp, u32 datarate) nvkm_output_dp_train(struct nvkm_outp *outp, u32 datakbps)
{ {
struct nvkm_dp *dp = nvkm_dp(outp); struct nvkm_dp *dp = nvkm_dp(outp);
struct nvkm_ior *ior = dp->outp.ior;
bool retrain = true; bool retrain = true;
u8 link[2], stat[3]; u32 linkKBps;
u32 linkrate; u32 dataKBps;
u8 stat[3];
int ret, i; int ret, i;
mutex_lock(&dp->mutex); mutex_lock(&dp->mutex);
/* check that the link is trained at a high enough rate */ /* Check that link configuration meets current requirements. */
ret = nvkm_rdaux(dp->aux, DPCD_LC00_LINK_BW_SET, link, 2); linkKBps = ior->dp.bw * 27000 * ior->dp.nr;
if (ret) { dataKBps = DIV_ROUND_UP(datakbps, 8);
OUTP_DBG(&dp->outp, if (linkKBps < dataKBps) {
"failed to read link config, assuming no sink"); OUTP_DBG(&dp->outp, "link requirements changed");
goto done;
}
linkrate = link[0] * 27000 * (link[1] & DPCD_LC01_LANE_COUNT_SET);
linkrate = (linkrate * 8) / 10; /* 8B/10B coding overhead */
datarate = (datarate + 9) / 10; /* -> decakilobits */
if (linkrate < datarate) {
OUTP_DBG(&dp->outp, "link not trained at sufficient rate");
goto done; goto done;
} }
/* check that link is still trained */ /* Check that link is still trained. */
ret = nvkm_rdaux(dp->aux, DPCD_LS02, stat, 3); ret = nvkm_rdaux(dp->aux, DPCD_LS02, stat, 3);
if (ret) { if (ret) {
OUTP_DBG(&dp->outp, OUTP_DBG(&dp->outp,
...@@ -411,7 +406,7 @@ nvkm_output_dp_train(struct nvkm_outp *outp, u32 datarate) ...@@ -411,7 +406,7 @@ nvkm_output_dp_train(struct nvkm_outp *outp, u32 datarate)
} }
if (stat[2] & DPCD_LS04_INTERLANE_ALIGN_DONE) { if (stat[2] & DPCD_LS04_INTERLANE_ALIGN_DONE) {
for (i = 0; i < (link[1] & DPCD_LC01_LANE_COUNT_SET); i++) { for (i = 0; i < ior->dp.nr; i++) {
u8 lane = (stat[i >> 1] >> ((i & 1) * 4)) & 0x0f; u8 lane = (stat[i >> 1] >> ((i & 1) * 4)) & 0x0f;
if (!(lane & DPCD_LS02_LANE0_CR_DONE) || if (!(lane & DPCD_LS02_LANE0_CR_DONE) ||
!(lane & DPCD_LS02_LANE0_CHANNEL_EQ_DONE) || !(lane & DPCD_LS02_LANE0_CHANNEL_EQ_DONE) ||
...@@ -435,7 +430,7 @@ nvkm_output_dp_train(struct nvkm_outp *outp, u32 datarate) ...@@ -435,7 +430,7 @@ nvkm_output_dp_train(struct nvkm_outp *outp, u32 datarate)
dp->dpcd[DPCD_RC02] = dp->dpcd[DPCD_RC02] =
dp->outp.info.dpconf.link_nr; dp->outp.info.dpconf.link_nr;
} }
nvkm_dp_train(dp); ret = nvkm_dp_train(dp);
} }
mutex_unlock(&dp->mutex); mutex_unlock(&dp->mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment