Commit 7a14bc78 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/bios/dp: parse lane postcursor data

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