static void nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head) { struct dcb_output outp; u32 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000; u32 conf = exec_clkcmp(priv, head, 0xff, pclk, &outp); if (conf != ~0) { u32 addr, data; if (outp.type == DCB_OUTPUT_DP) { u32 sync = nv_rd32(priv, 0x660404 + (head * 0x300)); switch ((sync & 0x000003c0) >> 6) { case 6: pclk = pclk * 30 / 8; break; case 5: pclk = pclk * 24 / 8; break; case 2: default: pclk = pclk * 18 / 8; break; } nouveau_dp_train(&priv->base, priv->sor.dp, &outp, head, pclk); }
static void nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head) { struct dcb_output outp; u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; u32 hval, hreg = 0x614200 + (head * 0x800); u32 oval, oreg; u32 mask; u32 conf = exec_clkcmp(priv, head, 0xff, pclk, &outp); if (conf != ~0) { if (outp.location == 0 && outp.type == DCB_OUTPUT_DP) { u32 soff = (ffs(outp.or) - 1) * 0x08; u32 ctrl = nv_rd32(priv, 0x610794 + soff); u32 datarate; switch ((ctrl & 0x000f0000) >> 16) { case 6: datarate = pclk * 30 / 8; break; case 5: datarate = pclk * 24 / 8; break; case 2: default: datarate = pclk * 18 / 8; break; } nouveau_dp_train(&priv->base, priv->sor.dp, &outp, head, datarate); } exec_clkcmp(priv, head, 0, pclk, &outp); if (!outp.location && outp.type == DCB_OUTPUT_ANALOG) { oreg = 0x614280 + (ffs(outp.or) - 1) * 0x800; oval = 0x00000000; hval = 0x00000000; mask = 0xffffffff; } else if (!outp.location) { if (outp.type == DCB_OUTPUT_DP) nv50_disp_intr_unk20_2_dp(priv, &outp, pclk); oreg = 0x614300 + (ffs(outp.or) - 1) * 0x800; oval = (conf & 0x0100) ? 0x00000101 : 0x00000000; hval = 0x00000000; mask = 0x00000707; } else { oreg = 0x614380 + (ffs(outp.or) - 1) * 0x800; oval = 0x00000001; hval = 0x00000001; mask = 0x00000707; } nv_mask(priv, hreg, 0x0000000f, hval); nv_mask(priv, oreg, mask, oval); }