Commit 1ae5a62b authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/disp/dp: fix tmds passthrough on dp connector

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 8777c5c1
...@@ -1171,7 +1171,7 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int or, u32 ctrl, ...@@ -1171,7 +1171,7 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int or, u32 ctrl,
return NULL; return NULL;
} }
static bool static struct nvkm_output *
exec_script(struct nv50_disp_priv *priv, int head, int id) exec_script(struct nv50_disp_priv *priv, int head, int id)
{ {
struct nouveau_bios *bios = nouveau_bios(priv); struct nouveau_bios *bios = nouveau_bios(priv);
...@@ -1208,7 +1208,7 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) ...@@ -1208,7 +1208,7 @@ exec_script(struct nv50_disp_priv *priv, int head, int id)
} }
if (!(ctrl & (1 << head))) if (!(ctrl & (1 << head)))
return false; return NULL;
i--; i--;
outp = exec_lookup(priv, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info); outp = exec_lookup(priv, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info);
...@@ -1222,10 +1222,10 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) ...@@ -1222,10 +1222,10 @@ exec_script(struct nv50_disp_priv *priv, int head, int id)
.execute = 1, .execute = 1,
}; };
return nvbios_exec(&init) == 0; nvbios_exec(&init);
} }
return false; return outp;
} }
static struct nvkm_output * static struct nvkm_output *
...@@ -1325,7 +1325,35 @@ nv50_disp_intr_unk10_0(struct nv50_disp_priv *priv, int head) ...@@ -1325,7 +1325,35 @@ nv50_disp_intr_unk10_0(struct nv50_disp_priv *priv, int head)
static void static void
nv50_disp_intr_unk20_0(struct nv50_disp_priv *priv, int head) nv50_disp_intr_unk20_0(struct nv50_disp_priv *priv, int head)
{ {
exec_script(priv, head, 2); struct nvkm_output *outp = exec_script(priv, head, 2);
/* the binary driver does this outside of the supervisor handling
* (after the third supervisor from a detach). we (currently?)
* allow both detach/attach to happen in the same set of
* supervisor interrupts, so it would make sense to execute this
* (full power down?) script after all the detach phases of the
* supervisor handling. like with training if needed from the
* second supervisor, nvidia doesn't do this, so who knows if it's
* entirely safe, but it does appear to work..
*
* without this script being run, on some configurations i've
* seen, switching from DP to TMDS on a DP connector may result
* in a blank screen (SOR_PWR off/on can restore it)
*/
if (outp && outp->info.type == DCB_OUTPUT_DP) {
struct nvkm_output_dp *outpdp = (void *)outp;
struct nvbios_init init = {
.subdev = nv_subdev(priv),
.bios = nouveau_bios(priv),
.outp = &outp->info,
.crtc = head,
.offset = outpdp->info.script[4],
.execute = 1,
};
nvbios_exec(&init);
atomic_set(&outpdp->lt.done, 0);
}
} }
static void static void
......
...@@ -962,7 +962,7 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int or, u32 ctrl, ...@@ -962,7 +962,7 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int or, u32 ctrl,
return NULL; return NULL;
} }
static bool static struct nvkm_output *
exec_script(struct nv50_disp_priv *priv, int head, int id) exec_script(struct nv50_disp_priv *priv, int head, int id)
{ {
struct nouveau_bios *bios = nouveau_bios(priv); struct nouveau_bios *bios = nouveau_bios(priv);
...@@ -979,7 +979,7 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) ...@@ -979,7 +979,7 @@ exec_script(struct nv50_disp_priv *priv, int head, int id)
} }
if (or == 8) if (or == 8)
return false; return NULL;
outp = exec_lookup(priv, head, or, ctrl, &data, &ver, &hdr, &cnt, &len, &info); outp = exec_lookup(priv, head, or, ctrl, &data, &ver, &hdr, &cnt, &len, &info);
if (outp) { if (outp) {
...@@ -992,10 +992,10 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) ...@@ -992,10 +992,10 @@ exec_script(struct nv50_disp_priv *priv, int head, int id)
.execute = 1, .execute = 1,
}; };
return nvbios_exec(&init) == 0; nvbios_exec(&init);
} }
return false; return outp;
} }
static struct nvkm_output * static struct nvkm_output *
...@@ -1069,7 +1069,23 @@ nvd0_disp_intr_unk1_0(struct nv50_disp_priv *priv, int head) ...@@ -1069,7 +1069,23 @@ nvd0_disp_intr_unk1_0(struct nv50_disp_priv *priv, int head)
static void static void
nvd0_disp_intr_unk2_0(struct nv50_disp_priv *priv, int head) nvd0_disp_intr_unk2_0(struct nv50_disp_priv *priv, int head)
{ {
exec_script(priv, head, 2); struct nvkm_output *outp = exec_script(priv, head, 2);
/* see note in nv50_disp_intr_unk20_0() */
if (outp && outp->info.type == DCB_OUTPUT_DP) {
struct nvkm_output_dp *outpdp = (void *)outp;
struct nvbios_init init = {
.subdev = nv_subdev(priv),
.bios = nouveau_bios(priv),
.outp = &outp->info,
.crtc = head,
.offset = outpdp->info.script[4],
.execute = 1,
};
nvbios_exec(&init);
atomic_set(&outpdp->lt.done, 0);
}
} }
static void static 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