From 668eacce8a31b6b2b0be19320c259c817a935bcf Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Thu, 3 Jan 2013 19:38:45 +0100 Subject: [PATCH] drm/nv50/disp: fix resume from s2ram for analog output Analog output number was overwritten by value from digital output path. Fix it. Additionally, don't encode output mode in output number. It's confusing. Fixes regression from commit 186ecad21c854385823a430b1402053ae7fd59dc ("drm/nv50/disp: move remaining interrupt handling into core"). Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=58729 Signed-off-by: Marcin Slusarz --- drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | 61 ++++++++++++++----------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 0f09af1..e470a4a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -801,18 +801,17 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) } static u16 -exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, - struct dcb_output *dcb, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, - struct nvbios_outp *info) +exec_lookup(struct nv50_disp_priv *priv, int head, bool digital, int outp, + u32 ctrl, struct dcb_output *dcb, u8 *ver, u8 *hdr, u8 *cnt, + u8 *len, struct nvbios_outp *info) { struct nouveau_bios *bios = nouveau_bios(priv); u16 mask, type, data; - if (outp < 4) { + if (!digital) { type = DCB_OUTPUT_ANALOG; mask = 0; } else { - outp -= 4; switch (ctrl & 0x00000f00) { case 0x00000000: type = DCB_OUTPUT_LVDS; mask = 1; break; case 0x00000100: type = DCB_OUTPUT_TMDS; mask = 1; break; @@ -847,26 +846,30 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) u16 data; u32 ctrl = 0x00000000; int i; + bool digital = false; for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) ctrl = nv_rd32(priv, 0x610b5c + (i * 8)); - if (nv_device(priv)->chipset < 0x90 || - nv_device(priv)->chipset == 0x92 || - nv_device(priv)->chipset == 0xa0) { - for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) - ctrl = nv_rd32(priv, 0x610b74 + (i * 8)); - i += 3; - } else { - for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) - ctrl = nv_rd32(priv, 0x610798 + (i * 8)); - i += 3; + if (!(ctrl & (1 << head))) { + digital = true; + if (nv_device(priv)->chipset < 0x90 || + nv_device(priv)->chipset == 0x92 || + nv_device(priv)->chipset == 0xa0) { + for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) + ctrl = nv_rd32(priv, 0x610b74 + (i * 8)); + } else { + for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) + ctrl = nv_rd32(priv, 0x610798 + (i * 8)); + } } if (!(ctrl & (1 << head))) return false; + i--; - data = exec_lookup(priv, head, i, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info); + data = exec_lookup(priv, head, digital, i, ctrl, &dcb, &ver, &hdr, &cnt, + &len, &info); if (data) { struct nvbios_init init = { .subdev = nv_subdev(priv), @@ -894,26 +897,30 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, u16 data, conf; u32 ctrl = 0x00000000; int i; + bool digital = false; for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) ctrl = nv_rd32(priv, 0x610b58 + (i * 8)); - if (nv_device(priv)->chipset < 0x90 || - nv_device(priv)->chipset == 0x92 || - nv_device(priv)->chipset == 0xa0) { - for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) - ctrl = nv_rd32(priv, 0x610b70 + (i * 8)); - i += 3; - } else { - for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) - ctrl = nv_rd32(priv, 0x610794 + (i * 8)); - i += 3; + if (!(ctrl & (1 << head))) { + digital = 1; + if (nv_device(priv)->chipset < 0x90 || + nv_device(priv)->chipset == 0x92 || + nv_device(priv)->chipset == 0xa0) { + for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) + ctrl = nv_rd32(priv, 0x610b70 + (i * 8)); + } else { + for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) + ctrl = nv_rd32(priv, 0x610794 + (i * 8)); + } } if (!(ctrl & (1 << head))) return 0x0000; + i--; - data = exec_lookup(priv, head, i, ctrl, outp, &ver, &hdr, &cnt, &len, &info1); + data = exec_lookup(priv, head, digital, i, ctrl, outp, &ver, &hdr, &cnt, + &len, &info1); if (!data) return 0x0000; -- 1.8.0.2