drm/nouveau/bios/dp: parse lane postcursor data
authorBen Skeggs <bskeggs@redhat.com>
Tue, 3 Jun 2014 02:47:31 +0000 (12:47 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 11 Jun 2014 06:11:18 +0000 (16:11 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c
drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c
drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h
drivers/gpu/drm/nouveau/core/subdev/bios/dp.c

index 834ee0e..d4dfcde 100644 (file)
@@ -128,9 +128,9 @@ nv94_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc)
        data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift);
        data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift);
        data[2] = nv_rd32(priv, 0x61c130 + loff) & ~(0x0000ff00);
-       nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.drv << shift));
-       nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pre << shift));
-       nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.unk << 8));
+       nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.dc << shift));
+       nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pe << shift));
+       nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.tx_pu << 8));
        return 0;
 }
 
index 07cc2d5..0055f86 100644 (file)
@@ -87,7 +87,7 @@ nvd0_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc)
        struct nouveau_bios *bios = nouveau_bios(priv);
        const u32 shift = nvd0_sor_dp_lane_map(priv, ln);
        const u32 loff = nvd0_sor_loff(outp);
-       u32 addr, data[3];
+       u32 addr, data[4];
        u8  ver, hdr, cnt, len;
        struct nvbios_dpout info;
        struct nvbios_dpcfg ocfg;
@@ -98,7 +98,7 @@ nvd0_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc)
        if (!addr)
                return -ENODEV;
 
-       addr = nvbios_dpcfg_match(bios, addr, 0, vs, pe,
+       addr = nvbios_dpcfg_match(bios, addr, pc, vs, pe,
                                 &ver, &hdr, &cnt, &len, &ocfg);
        if (!addr)
                return -EINVAL;
@@ -106,10 +106,11 @@ nvd0_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc)
        data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift);
        data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift);
        data[2] = nv_rd32(priv, 0x61c130 + loff) & ~(0x0000ff00);
-       nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.drv << shift));
-       nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pre << shift));
-       nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.unk << 8));
-       nv_mask(priv, 0x61c13c + loff, 0x00000000, 0x00000000);
+       nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.dc << shift));
+       nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pe << shift));
+       nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.tx_pu << 8));
+       data[3] = nv_rd32(priv, 0x61c13c + loff) & ~(0x000000ff << shift);
+       nv_wr32(priv, 0x61c13c + loff, data[3] | (ocfg.pc << shift));
        return 0;
 }
 
index 6e54218..728206e 100644 (file)
@@ -17,9 +17,10 @@ u16 nvbios_dpout_match(struct nouveau_bios *, u16 type, u16 mask,
                       struct nvbios_dpout *);
 
 struct nvbios_dpcfg {
-       u8 drv;
-       u8 pre;
-       u8 unk;
+       u8 pc;
+       u8 dc;
+       u8 pe;
+       u8 tx_pu;
 };
 
 u16
@@ -27,7 +28,7 @@ nvbios_dpcfg_parse(struct nouveau_bios *, u16 outp, u8 idx,
                   u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
                   struct nvbios_dpcfg *);
 u16
-nvbios_dpcfg_match(struct nouveau_bios *, u16 outp, u8 un, u8 vs, u8 pe,
+nvbios_dpcfg_match(struct nouveau_bios *, u16 outp, u8 pc, u8 vs, u8 pe,
                   u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
                   struct nvbios_dpcfg *);
 
index 7628fe7..f309dd6 100644 (file)
@@ -162,18 +162,20 @@ nvbios_dpcfg_parse(struct nouveau_bios *bios, u16 outp, u8 idx,
                   struct nvbios_dpcfg *info)
 {
        u16 data = nvbios_dpcfg_entry(bios, outp, idx, ver, hdr, cnt, len);
+       memset(info, 0x00, sizeof(*info));
        if (data) {
                switch (*ver) {
                case 0x21:
-                       info->drv = nv_ro08(bios, data + 0x02);
-                       info->pre = nv_ro08(bios, data + 0x03);
-                       info->unk = nv_ro08(bios, data + 0x04);
+                       info->dc    = nv_ro08(bios, data + 0x02);
+                       info->pe    = nv_ro08(bios, data + 0x03);
+                       info->tx_pu = nv_ro08(bios, data + 0x04);
                        break;
                case 0x30:
                case 0x40:
-                       info->drv = nv_ro08(bios, data + 0x01);
-                       info->pre = nv_ro08(bios, data + 0x02);
-                       info->unk = nv_ro08(bios, data + 0x03);
+                       info->pc    = nv_ro08(bios, data + 0x00);
+                       info->dc    = nv_ro08(bios, data + 0x01);
+                       info->pe    = nv_ro08(bios, data + 0x02);
+                       info->tx_pu = nv_ro08(bios, data + 0x03);
                        break;
                default:
                        data = 0x0000;
@@ -184,7 +186,7 @@ nvbios_dpcfg_parse(struct nouveau_bios *bios, u16 outp, u8 idx,
 }
 
 u16
-nvbios_dpcfg_match(struct nouveau_bios *bios, u16 outp, u8 un, u8 vs, u8 pe,
+nvbios_dpcfg_match(struct nouveau_bios *bios, u16 outp, u8 pc, u8 vs, u8 pe,
                   u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
                   struct nvbios_dpcfg *info)
 {
@@ -193,16 +195,15 @@ nvbios_dpcfg_match(struct nouveau_bios *bios, u16 outp, u8 un, u8 vs, u8 pe,
 
        if (*ver >= 0x30) {
                const u8 vsoff[] = { 0, 4, 7, 9 };
-               idx = (un * 10) + vsoff[vs] + pe;
+               idx = (pc * 10) + vsoff[vs] + pe;
        } else {
-               while ((data = nvbios_dpcfg_entry(bios, outp, idx,
+               while ((data = nvbios_dpcfg_entry(bios, outp, ++idx,
                                                  ver, hdr, cnt, len))) {
                        if (nv_ro08(bios, data + 0x00) == vs &&
                            nv_ro08(bios, data + 0x01) == pe)
                                break;
-                       idx++;
                }
        }
 
-       return nvbios_dpcfg_parse(bios, outp, pe, ver, hdr, cnt, len, info);
+       return nvbios_dpcfg_parse(bios, outp, idx, ver, hdr, cnt, len, info);
 }