Commit e6867ffa authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/disp: modify OR allocation policy to account for HDA requirements

Since GM200, SORs are no longer tied to a specific connector, and we
allocate them instead, with the assumption that all SORs are equally
capable.

However, there's a 1<->1 mapping between SOR and HDA pin widget, and
it turns out that it's possible for some widgets to be disabled...

In order to avoid picking a SOR without a valid pin widget, some new
rules need to be added.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent f24b6ae1
...@@ -121,14 +121,14 @@ nvkm_outp_acquire_hda(struct nvkm_outp *outp, enum nvkm_ior_type type, ...@@ -121,14 +121,14 @@ nvkm_outp_acquire_hda(struct nvkm_outp *outp, enum nvkm_ior_type type,
* on HW, if any, in order to prevent unnecessary switching. * on HW, if any, in order to prevent unnecessary switching.
*/ */
list_for_each_entry(ior, &outp->disp->ior, head) { list_for_each_entry(ior, &outp->disp->ior, head) {
if (!ior->identity && if (!ior->identity && !!ior->func->hda.hpd == hda &&
!ior->asy.outp && ior->arm.outp == outp) !ior->asy.outp && ior->arm.outp == outp)
return nvkm_outp_acquire_ior(outp, user, ior); return nvkm_outp_acquire_ior(outp, user, ior);
} }
/* Failing that, a completely unused OR is the next best thing. */ /* Failing that, a completely unused OR is the next best thing. */
list_for_each_entry(ior, &outp->disp->ior, head) { list_for_each_entry(ior, &outp->disp->ior, head) {
if (!ior->identity && if (!ior->identity && !!ior->func->hda.hpd == hda &&
!ior->asy.outp && ior->type == type && !ior->arm.outp && !ior->asy.outp && ior->type == type && !ior->arm.outp &&
(ior->func->route.set || ior->id == __ffs(outp->info.or))) (ior->func->route.set || ior->id == __ffs(outp->info.or)))
return nvkm_outp_acquire_ior(outp, user, ior); return nvkm_outp_acquire_ior(outp, user, ior);
...@@ -138,7 +138,7 @@ nvkm_outp_acquire_hda(struct nvkm_outp *outp, enum nvkm_ior_type type, ...@@ -138,7 +138,7 @@ nvkm_outp_acquire_hda(struct nvkm_outp *outp, enum nvkm_ior_type type,
* but will be released during the next modeset. * but will be released during the next modeset.
*/ */
list_for_each_entry(ior, &outp->disp->ior, head) { list_for_each_entry(ior, &outp->disp->ior, head) {
if (!ior->identity && if (!ior->identity && !!ior->func->hda.hpd == hda &&
!ior->asy.outp && ior->type == type && !ior->asy.outp && ior->type == type &&
(ior->func->route.set || ior->id == __ffs(outp->info.or))) (ior->func->route.set || ior->id == __ffs(outp->info.or)))
return nvkm_outp_acquire_ior(outp, user, ior); return nvkm_outp_acquire_ior(outp, user, ior);
...@@ -173,7 +173,25 @@ nvkm_outp_acquire(struct nvkm_outp *outp, u8 user, bool hda) ...@@ -173,7 +173,25 @@ nvkm_outp_acquire(struct nvkm_outp *outp, u8 user, bool hda)
return nvkm_outp_acquire_ior(outp, user, ior); return nvkm_outp_acquire_ior(outp, user, ior);
} }
return nvkm_outp_acquire_hda(outp, type, user, true); /* If we don't need HDA, first try to acquire an OR that doesn't
* support it to leave free the ones that do.
*/
if (!hda) {
if (!nvkm_outp_acquire_hda(outp, type, user, false))
return 0;
/* Use a HDA-supporting SOR anyway. */
return nvkm_outp_acquire_hda(outp, type, user, true);
}
/* We want HDA, try to acquire an OR that supports it. */
if (!nvkm_outp_acquire_hda(outp, type, user, true))
return 0;
/* There weren't any free ORs that support HDA, grab one that
* doesn't and at least allow display to work still.
*/
return nvkm_outp_acquire_hda(outp, type, user, false);
} }
void void
......
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