diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/subdev/bios')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/bios/conn.c | 62 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/bios/dp.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/bios/init.c | 9 |
3 files changed, 70 insertions, 24 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/conn.c b/drivers/gpu/drm/nouveau/core/subdev/bios/conn.c index 5ac010efd959..2ede3bcd96a1 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/conn.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/conn.c @@ -28,12 +28,12 @@ #include <subdev/bios/dcb.h> #include <subdev/bios/conn.h> -u16 -dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) +u32 +nvbios_connTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) { - u16 dcb = dcb_table(bios, ver, hdr, cnt, len); + u32 dcb = dcb_table(bios, ver, hdr, cnt, len); if (dcb && *ver >= 0x30 && *hdr >= 0x16) { - u16 data = nv_ro16(bios, dcb + 0x14); + u32 data = nv_ro16(bios, dcb + 0x14); if (data) { *ver = nv_ro08(bios, data + 0); *hdr = nv_ro08(bios, data + 1); @@ -42,15 +42,59 @@ dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) return data; } } - return 0x0000; + return 0x00000000; } -u16 -dcb_conn(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len) +u32 +nvbios_connTp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, + struct nvbios_connT *info) +{ + u32 data = nvbios_connTe(bios, ver, hdr, cnt, len); + memset(info, 0x00, sizeof(*info)); + switch (!!data * *ver) { + case 0x30: + case 0x40: + return data; + default: + break; + } + return 0x00000000; +} + +u32 +nvbios_connEe(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len) { u8 hdr, cnt; - u16 data = dcb_conntab(bios, ver, &hdr, &cnt, len); + u32 data = nvbios_connTe(bios, ver, &hdr, &cnt, len); if (data && idx < cnt) return data + hdr + (idx * *len); - return 0x0000; + return 0x00000000; +} + +u32 +nvbios_connEp(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len, + struct nvbios_connE *info) +{ + u32 data = nvbios_connEe(bios, idx, ver, len); + memset(info, 0x00, sizeof(*info)); + switch (!!data * *ver) { + case 0x30: + case 0x40: + info->type = nv_ro08(bios, data + 0x00); + info->location = nv_ro08(bios, data + 0x01) & 0x0f; + info->hpd = (nv_ro08(bios, data + 0x01) & 0x30) >> 4; + info->dp = (nv_ro08(bios, data + 0x01) & 0xc0) >> 6; + if (*len < 4) + return data; + info->hpd |= (nv_ro08(bios, data + 0x02) & 0x03) << 2; + info->dp |= nv_ro08(bios, data + 0x02) & 0x0c; + info->di = (nv_ro08(bios, data + 0x02) & 0xf0) >> 4; + info->hpd |= (nv_ro08(bios, data + 0x03) & 0x07) << 4; + info->sr = (nv_ro08(bios, data + 0x03) & 0x08) >> 3; + info->lcdid = (nv_ro08(bios, data + 0x03) & 0x70) >> 4; + return data; + default: + break; + } + return 0x00000000; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c index 7628fe759220..f309dd657250 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c @@ -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); } diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index acaeaf79e3f0..626380f9e4c0 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c @@ -98,15 +98,16 @@ static u8 init_conn(struct nvbios_init *init) { struct nouveau_bios *bios = init->bios; - u8 ver, len; - u16 conn; + struct nvbios_connE connE; + u8 ver, hdr; + u32 conn; if (init_exec(init)) { if (init->outp) { conn = init->outp->connector; - conn = dcb_conn(bios, conn, &ver, &len); + conn = nvbios_connEp(bios, conn, &ver, &hdr, &connE); if (conn) - return nv_ro08(bios, conn); + return connE.type; } error("script needs connector type\n"); |