Commit 20014cbe authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/bios: extend connector table parsing

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 377b1f16
...@@ -22,7 +22,25 @@ enum dcb_connector_type { ...@@ -22,7 +22,25 @@ enum dcb_connector_type {
DCB_CONNECTOR_NONE = 0xff DCB_CONNECTOR_NONE = 0xff
}; };
u16 dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); struct nvbios_connT {
u16 dcb_conn(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len); };
u32 nvbios_connTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u32 nvbios_connTp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
struct nvbios_connT *info);
struct nvbios_connE {
u8 type;
u8 location;
u8 hpd;
u8 dp;
u8 di;
u8 sr;
u8 lcdid;
};
u32 nvbios_connEe(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *hdr);
u32 nvbios_connEp(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *hdr,
struct nvbios_connE *info);
#endif #endif
...@@ -28,12 +28,12 @@ ...@@ -28,12 +28,12 @@
#include <subdev/bios/dcb.h> #include <subdev/bios/dcb.h>
#include <subdev/bios/conn.h> #include <subdev/bios/conn.h>
u16 u32
dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) 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) { if (dcb && *ver >= 0x30 && *hdr >= 0x16) {
u16 data = nv_ro16(bios, dcb + 0x14); u32 data = nv_ro16(bios, dcb + 0x14);
if (data) { if (data) {
*ver = nv_ro08(bios, data + 0); *ver = nv_ro08(bios, data + 0);
*hdr = nv_ro08(bios, data + 1); *hdr = nv_ro08(bios, data + 1);
...@@ -42,15 +42,59 @@ dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) ...@@ -42,15 +42,59 @@ dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
return data; return data;
} }
} }
return 0x0000; return 0x00000000;
} }
u16 u32
dcb_conn(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len) 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; 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) if (data && idx < cnt)
return data + hdr + (idx * *len); 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;
} }
...@@ -98,15 +98,16 @@ static u8 ...@@ -98,15 +98,16 @@ static u8
init_conn(struct nvbios_init *init) init_conn(struct nvbios_init *init)
{ {
struct nouveau_bios *bios = init->bios; struct nouveau_bios *bios = init->bios;
u8 ver, len; struct nvbios_connE connE;
u16 conn; u8 ver, hdr;
u32 conn;
if (init_exec(init)) { if (init_exec(init)) {
if (init->outp) { if (init->outp) {
conn = init->outp->connector; conn = init->outp->connector;
conn = dcb_conn(bios, conn, &ver, &len); conn = nvbios_connEp(bios, conn, &ver, &hdr, &connE);
if (conn) if (conn)
return nv_ro08(bios, conn); return connE.type;
} }
error("script needs connector type\n"); error("script needs connector type\n");
......
...@@ -150,7 +150,7 @@ mxm_dcb_sanitise_entry(struct nouveau_bios *bios, void *data, int idx, u16 pdcb) ...@@ -150,7 +150,7 @@ mxm_dcb_sanitise_entry(struct nouveau_bios *bios, void *data, int idx, u16 pdcb)
* common example is DP->eDP. * common example is DP->eDP.
*/ */
conn = bios->data; conn = bios->data;
conn += dcb_conn(bios, (ctx.outp[0] & 0x0000f000) >> 12, &ver, &len); conn += nvbios_connEe(bios, (ctx.outp[0] & 0x0000f000) >> 12, &ver, &len);
type = conn[0]; type = conn[0];
switch (ctx.desc.conn_type) { switch (ctx.desc.conn_type) {
case 0x01: /* LVDS */ case 0x01: /* LVDS */
......
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