mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-28 23:23:55 +08:00
drm/nouveau/disp: semi-complete link training sequence even if display disappears
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
4767fae8f8
commit
8df1d0c07f
@ -70,17 +70,10 @@ dp_set_link_config(struct dp_state *dp)
|
||||
};
|
||||
u32 lnkcmp;
|
||||
u8 sink[2];
|
||||
int ret;
|
||||
|
||||
DBG("%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw);
|
||||
|
||||
/* set desired link configuration on the sink */
|
||||
sink[0] = dp->link_bw / 27000;
|
||||
sink[1] = dp->link_nr;
|
||||
if (dp->dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP)
|
||||
sink[1] |= DPCD_LC01_ENHANCED_FRAME_EN;
|
||||
|
||||
nv_wraux(dp->aux, DPCD_LC00, sink, 2);
|
||||
|
||||
/* set desired link configuration on the source */
|
||||
if ((lnkcmp = dp->info.lnkcmp)) {
|
||||
if (dp->version < 0x30) {
|
||||
@ -96,10 +89,22 @@ dp_set_link_config(struct dp_state *dp)
|
||||
nvbios_exec(&init);
|
||||
}
|
||||
|
||||
return dp->func->lnk_ctl(dp->disp, dp->outp, dp->head,
|
||||
dp->link_nr, dp->link_bw / 27000,
|
||||
dp->dpcd[DPCD_RC02] &
|
||||
DPCD_RC02_ENHANCED_FRAME_CAP);
|
||||
ret = dp->func->lnk_ctl(dp->disp, dp->outp, dp->head,
|
||||
dp->link_nr, dp->link_bw / 27000,
|
||||
dp->dpcd[DPCD_RC02] &
|
||||
DPCD_RC02_ENHANCED_FRAME_CAP);
|
||||
if (ret) {
|
||||
ERR("lnk_ctl failed with %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set desired link configuration on the sink */
|
||||
sink[0] = dp->link_bw / 27000;
|
||||
sink[1] = dp->link_nr;
|
||||
if (dp->dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP)
|
||||
sink[1] |= DPCD_LC01_ENHANCED_FRAME_EN;
|
||||
|
||||
return nv_wraux(dp->aux, DPCD_LC00, sink, 2);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -294,8 +299,17 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func,
|
||||
|
||||
ret = nv_rdaux(dp->aux, 0x00000, dp->dpcd, sizeof(dp->dpcd));
|
||||
if (ret) {
|
||||
/* it's possible the display has been unplugged before we
|
||||
* get here. we still need to execute the full set of
|
||||
* vbios scripts, and program the OR at a high enough
|
||||
* frequency to satisfy the target mode. failure to do
|
||||
* so results at best in an UPDATE hanging, and at worst
|
||||
* with PDISP running away to join the circus.
|
||||
*/
|
||||
dp->dpcd[1] = link_bw[0] / 27000;
|
||||
dp->dpcd[2] = 4;
|
||||
dp->dpcd[3] = 0x00;
|
||||
ERR("failed to read DPCD\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* adjust required bandwidth for 8B/10B coding overhead */
|
||||
@ -328,8 +342,10 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func,
|
||||
!dp_link_train_eq(dp))
|
||||
break;
|
||||
} else
|
||||
if (ret >= 1) {
|
||||
/* dp_set_link_config() handled training */
|
||||
if (ret) {
|
||||
/* dp_set_link_config() handled training, or
|
||||
* we failed to communicate with the sink.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
@ -344,5 +360,5 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func,
|
||||
|
||||
/* execute post-train script from vbios */
|
||||
dp_link_train_fini(dp);
|
||||
return true;
|
||||
return (ret < 0) ? false : true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user