]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blobdiff - drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
drm/nvd0/disp: calculate U script id in supervisor interrupt
[mirror_ubuntu-eoan-kernel.git] / drivers / gpu / drm / nouveau / core / engine / disp / nvd0.c
index 5ac8c429852d26885ed7007de4818c5074f26223..a618f2213a1478f76df9d9bfa91c6d6076b03e84 100644 (file)
@@ -634,38 +634,59 @@ exec_script(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, int id)
        return false;
 }
 
-static bool
+static u32
 exec_clkcmp(struct nv50_disp_priv *priv, int head, int outp,
-           u32 ctrl, u32 conf, int id, u32 pclk)
+           u32 ctrl, int id, u32 pclk)
 {
        struct nouveau_bios *bios = nouveau_bios(priv);
        struct nvbios_outp info1;
        struct nvbios_ocfg info2;
        struct dcb_output dcb;
        u8  ver, hdr, cnt, len;
-       u16 data;
+       u16 data, conf;
 
        data = exec_lookup(priv, head, outp, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info1);
+       if (data == 0x0000)
+               return false;
+
+       switch (dcb.type) {
+       case DCB_OUTPUT_TMDS:
+               conf = (ctrl & 0x00000f00) >> 8;
+               if (pclk >= 165000)
+                       conf |= 0x0100;
+               break;
+       case DCB_OUTPUT_LVDS:
+               conf = priv->sor.lvdsconf;
+               break;
+       case DCB_OUTPUT_DP:
+               conf = (ctrl & 0x00000f00) >> 8;
+               break;
+       case DCB_OUTPUT_ANALOG:
+       default:
+               conf = 0x00ff;
+               break;
+       }
+
+       data = nvbios_ocfg_match(bios, data, conf, &ver, &hdr, &cnt, &len, &info2);
        if (data) {
-               data = nvbios_ocfg_match(bios, data, conf, &ver, &hdr, &cnt, &len, &info2);
+               data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk);
                if (data) {
-                       data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk);
-                       if (data) {
-                               struct nvbios_init init = {
-                                       .subdev = nv_subdev(priv),
-                                       .bios = bios,
-                                       .offset = data,
-                                       .outp = &dcb,
-                                       .crtc = head,
-                                       .execute = 1,
-                               };
-
-                               return nvbios_exec(&init) == 0;
-                       }
+                       struct nvbios_init init = {
+                               .subdev = nv_subdev(priv),
+                               .bios = bios,
+                               .offset = data,
+                               .outp = &dcb,
+                               .crtc = head,
+                               .execute = 1,
+                       };
+
+                       if (nvbios_exec(&init))
+                               return 0x0000;
+                       return conf;
                }
        }
 
-       return false;
+       return 0x0000;
 }
 
 static void
@@ -747,10 +768,9 @@ nvd0_display_unk2_handler(struct nv50_disp_priv *priv, u32 head, u32 mask)
        nv_wr32(priv, 0x612200 + (head * 0x800), 0x00000000);
 
        for (i = 0; mask && i < 8; i++) {
-               u32 mcp = nv_rd32(priv, 0x660180 + (i * 0x20));
-               u32 cfg = nv_rd32(priv, 0x660184 + (i * 0x20));
+               u32 mcp = nv_rd32(priv, 0x660180 + (i * 0x20)), cfg;
                if (mcp & (1 << head)) {
-                       if (exec_clkcmp(priv, head, i, mcp, cfg, 0, pclk)) {
+                       if ((cfg = exec_clkcmp(priv, head, i, mcp, 0, pclk))) {
                                u32 addr, mask, data = 0x00000000;
                                if (i < 4) {
                                        addr = 0x612280 + ((i - 0) * 0x800);
@@ -790,9 +810,8 @@ nvd0_display_unk4_handler(struct nv50_disp_priv *priv, u32 head, u32 mask)
 
        for (i = 0; mask && i < 8; i++) {
                u32 mcp = nv_rd32(priv, 0x660180 + (i * 0x20));
-               u32 cfg = nv_rd32(priv, 0x660184 + (i * 0x20));
                if (mcp & (1 << head))
-                       exec_clkcmp(priv, head, i, mcp, cfg, 1, pclk);
+                       exec_clkcmp(priv, head, i, mcp, 1, pclk);
        }
 
        nv_wr32(priv, 0x6101d4, 0x00000000);