u16 nvbios_dpcfg_match(struct nvkm_bios *bios, u16 outp, u8 pc, u8 vs, u8 pe, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_dpcfg *info) { u8 idx = 0xff; u16 data; if (*ver >= 0x30) { const u8 vsoff[] = { 0, 4, 7, 9 }; idx = (pc * 10) + vsoff[vs] + pe; if (*ver >= 0x40 && *ver <= 0x41 && *hdr >= 0x12) idx += nvbios_rd08(bios, outp + 0x11) * 40; else if (*ver >= 0x42) idx += nvbios_rd08(bios, outp + 0x11) * 10; } else { while ((data = nvbios_dpcfg_entry(bios, outp, ++idx, ver, hdr, cnt, len))) { if (nvbios_rd08(bios, data + 0x00) == vs && nvbios_rd08(bios, data + 0x01) == pe) break; } } return nvbios_dpcfg_parse(bios, outp, idx, ver, hdr, cnt, len, info); }
u16 nvbios_dpcfg_parse(struct nouveau_bios *bios, u16 outp, u8 idx, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_dpcfg *info) { u16 data = nvbios_dpcfg_entry(bios, outp, idx, ver, hdr, cnt, len); 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); 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); break; default: data = 0x0000; break; } } return data; }
u16 nvbios_dpcfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, 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 0x20: case 0x21: info->dc = nvbios_rd08(bios, data + 0x02); info->pe = nvbios_rd08(bios, data + 0x03); info->tx_pu = nvbios_rd08(bios, data + 0x04); break; case 0x30: case 0x40: case 0x41: info->pc = nvbios_rd08(bios, data + 0x00); info->dc = nvbios_rd08(bios, data + 0x01); info->pe = nvbios_rd08(bios, data + 0x02); info->tx_pu = nvbios_rd08(bios, data + 0x03); break; case 0x42: info->dc = nvbios_rd08(bios, data + 0x00); info->pe = nvbios_rd08(bios, data + 0x01); info->tx_pu = nvbios_rd08(bios, data + 0x02); break; default: data = 0x0000; break; } } return data; }
u16 nvbios_dpcfg_match(struct nouveau_bios *bios, u16 outp, u8 un, u8 vs, u8 pe, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_dpcfg *info) { u8 idx = 0xff; u16 data; if (*ver >= 0x30) { const u8 vsoff[] = { 0, 4, 7, 9 }; idx = (un * 10) + vsoff[vs] + pe; } else { 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); }