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

drm/nouveau/bios: extend connector table parsing



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 377b1f16
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -22,7 +22,25 @@ enum dcb_connector_type {
	DCB_CONNECTOR_NONE = 0xff
};

u16 dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
u16 dcb_conn(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len);
struct nvbios_connT {
};

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
+53 −9
Original line number Diff line number Diff line
@@ -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;
}
+5 −4
Original line number Diff line number Diff line
@@ -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");
+1 −1
Original line number Diff line number Diff line
@@ -150,7 +150,7 @@ mxm_dcb_sanitise_entry(struct nouveau_bios *bios, void *data, int idx, u16 pdcb)
	 * common example is DP->eDP.
	 */
	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];
	switch (ctx.desc.conn_type) {
	case 0x01: /* LVDS */