drm/nouveau/bios: extend connector table parsing
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
377b1f165c
commit
20014cbe8b
4 changed files with 79 additions and 16 deletions
|
@ -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 @@
|
||||||
#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)
|
||||||
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
|
||||||
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)
|
||||||
* 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 */
|
||||||
|
|
Loading…
Add table
Reference in a new issue