diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-05-13 21:10:02 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-06-11 02:10:36 -0400 |
commit | 20014cbe8b2b9921476531a051735ed3f932fb13 (patch) | |
tree | cf8855618d07d9ef083282dcdce155ae3561a51c | |
parent | 377b1f165c22ab1f74d62fbfce3d0b900e03193c (diff) |
drm/nouveau/bios: extend connector table parsing
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/bios/conn.c | 62 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/bios/init.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c | 2 |
4 files changed, 79 insertions, 16 deletions
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h index a32feb3f3fb6..f3930c27cb7a 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h | |||
@@ -22,7 +22,25 @@ enum dcb_connector_type { | |||
22 | DCB_CONNECTOR_NONE = 0xff | 22 | DCB_CONNECTOR_NONE = 0xff |
23 | }; | 23 | }; |
24 | 24 | ||
25 | u16 dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); | 25 | struct nvbios_connT { |
26 | u16 dcb_conn(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len); | 26 | }; |
27 | |||
28 | u32 nvbios_connTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); | ||
29 | u32 nvbios_connTp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, | ||
30 | struct nvbios_connT *info); | ||
31 | |||
32 | struct nvbios_connE { | ||
33 | u8 type; | ||
34 | u8 location; | ||
35 | u8 hpd; | ||
36 | u8 dp; | ||
37 | u8 di; | ||
38 | u8 sr; | ||
39 | u8 lcdid; | ||
40 | }; | ||
41 | |||
42 | u32 nvbios_connEe(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *hdr); | ||
43 | u32 nvbios_connEp(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *hdr, | ||
44 | struct nvbios_connE *info); | ||
27 | 45 | ||
28 | #endif | 46 | #endif |
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 @@ | |||
28 | #include <subdev/bios/dcb.h> | 28 | #include <subdev/bios/dcb.h> |
29 | #include <subdev/bios/conn.h> | 29 | #include <subdev/bios/conn.h> |
30 | 30 | ||
31 | u16 | 31 | u32 |
32 | dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) | 32 | nvbios_connTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) |
33 | { | 33 | { |
34 | u16 dcb = dcb_table(bios, ver, hdr, cnt, len); | 34 | u32 dcb = dcb_table(bios, ver, hdr, cnt, len); |
35 | if (dcb && *ver >= 0x30 && *hdr >= 0x16) { | 35 | if (dcb && *ver >= 0x30 && *hdr >= 0x16) { |
36 | u16 data = nv_ro16(bios, dcb + 0x14); | 36 | u32 data = nv_ro16(bios, dcb + 0x14); |
37 | if (data) { | 37 | if (data) { |
38 | *ver = nv_ro08(bios, data + 0); | 38 | *ver = nv_ro08(bios, data + 0); |
39 | *hdr = nv_ro08(bios, data + 1); | 39 | *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 | return data; | 42 | return data; |
43 | } | 43 | } |
44 | } | 44 | } |
45 | return 0x0000; | 45 | return 0x00000000; |
46 | } | 46 | } |
47 | 47 | ||
48 | u16 | 48 | u32 |
49 | dcb_conn(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len) | 49 | nvbios_connTp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, |
50 | struct nvbios_connT *info) | ||
51 | { | ||
52 | u32 data = nvbios_connTe(bios, ver, hdr, cnt, len); | ||
53 | memset(info, 0x00, sizeof(*info)); | ||
54 | switch (!!data * *ver) { | ||
55 | case 0x30: | ||
56 | case 0x40: | ||
57 | return data; | ||
58 | default: | ||
59 | break; | ||
60 | } | ||
61 | return 0x00000000; | ||
62 | } | ||
63 | |||
64 | u32 | ||
65 | nvbios_connEe(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len) | ||
50 | { | 66 | { |
51 | u8 hdr, cnt; | 67 | u8 hdr, cnt; |
52 | u16 data = dcb_conntab(bios, ver, &hdr, &cnt, len); | 68 | u32 data = nvbios_connTe(bios, ver, &hdr, &cnt, len); |
53 | if (data && idx < cnt) | 69 | if (data && idx < cnt) |
54 | return data + hdr + (idx * *len); | 70 | return data + hdr + (idx * *len); |
55 | return 0x0000; | 71 | return 0x00000000; |
72 | } | ||
73 | |||
74 | u32 | ||
75 | nvbios_connEp(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len, | ||
76 | struct nvbios_connE *info) | ||
77 | { | ||
78 | u32 data = nvbios_connEe(bios, idx, ver, len); | ||
79 | memset(info, 0x00, sizeof(*info)); | ||
80 | switch (!!data * *ver) { | ||
81 | case 0x30: | ||
82 | case 0x40: | ||
83 | info->type = nv_ro08(bios, data + 0x00); | ||
84 | info->location = nv_ro08(bios, data + 0x01) & 0x0f; | ||
85 | info->hpd = (nv_ro08(bios, data + 0x01) & 0x30) >> 4; | ||
86 | info->dp = (nv_ro08(bios, data + 0x01) & 0xc0) >> 6; | ||
87 | if (*len < 4) | ||
88 | return data; | ||
89 | info->hpd |= (nv_ro08(bios, data + 0x02) & 0x03) << 2; | ||
90 | info->dp |= nv_ro08(bios, data + 0x02) & 0x0c; | ||
91 | info->di = (nv_ro08(bios, data + 0x02) & 0xf0) >> 4; | ||
92 | info->hpd |= (nv_ro08(bios, data + 0x03) & 0x07) << 4; | ||
93 | info->sr = (nv_ro08(bios, data + 0x03) & 0x08) >> 3; | ||
94 | info->lcdid = (nv_ro08(bios, data + 0x03) & 0x70) >> 4; | ||
95 | return data; | ||
96 | default: | ||
97 | break; | ||
98 | } | ||
99 | return 0x00000000; | ||
56 | } | 100 | } |
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 | |||
98 | init_conn(struct nvbios_init *init) | 98 | init_conn(struct nvbios_init *init) |
99 | { | 99 | { |
100 | struct nouveau_bios *bios = init->bios; | 100 | struct nouveau_bios *bios = init->bios; |
101 | u8 ver, len; | 101 | struct nvbios_connE connE; |
102 | u16 conn; | 102 | u8 ver, hdr; |
103 | u32 conn; | ||
103 | 104 | ||
104 | if (init_exec(init)) { | 105 | if (init_exec(init)) { |
105 | if (init->outp) { | 106 | if (init->outp) { |
106 | conn = init->outp->connector; | 107 | conn = init->outp->connector; |
107 | conn = dcb_conn(bios, conn, &ver, &len); | 108 | conn = nvbios_connEp(bios, conn, &ver, &hdr, &connE); |
108 | if (conn) | 109 | if (conn) |
109 | return nv_ro08(bios, conn); | 110 | return connE.type; |
110 | } | 111 | } |
111 | 112 | ||
112 | error("script needs connector type\n"); | 113 | error("script needs connector type\n"); |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c index 64f8b4702bf7..fcaabe8456e3 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c | |||
@@ -150,7 +150,7 @@ mxm_dcb_sanitise_entry(struct nouveau_bios *bios, void *data, int idx, u16 pdcb) | |||
150 | * common example is DP->eDP. | 150 | * common example is DP->eDP. |
151 | */ | 151 | */ |
152 | conn = bios->data; | 152 | conn = bios->data; |
153 | conn += dcb_conn(bios, (ctx.outp[0] & 0x0000f000) >> 12, &ver, &len); | 153 | conn += nvbios_connEe(bios, (ctx.outp[0] & 0x0000f000) >> 12, &ver, &len); |
154 | type = conn[0]; | 154 | type = conn[0]; |
155 | switch (ctx.desc.conn_type) { | 155 | switch (ctx.desc.conn_type) { |
156 | case 0x01: /* LVDS */ | 156 | case 0x01: /* LVDS */ |