1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <subdev/bios.h>
25#include <subdev/bios/bit.h>
26#include <subdev/bios/mxm.h>
27
28u16
29mxm_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr)
30{
31 struct nvkm_subdev *subdev = &bios->subdev;
32 struct bit_entry x;
33
34 if (bit_entry(bios, 'x', &x)) {
35 nvkm_debug(subdev, "BIT 'x' table not present\n");
36 return 0x0000;
37 }
38
39 *ver = x.version;
40 *hdr = x.length;
41 if (*ver != 1 || *hdr < 3) {
42 nvkm_warn(subdev, "BIT 'x' table %d/%d unknown\n", *ver, *hdr);
43 return 0x0000;
44 }
45
46 return x.offset;
47}
48
49
50
51
52
53
54static u8 g84_sor_map[16] = {
55 0x00, 0x12, 0x22, 0x11, 0x32, 0x31, 0x11, 0x31,
56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
57};
58
59static u8 g92_sor_map[16] = {
60 0x00, 0x12, 0x22, 0x11, 0x32, 0x31, 0x11, 0x31,
61 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
62};
63
64static u8 g94_sor_map[16] = {
65 0x00, 0x14, 0x24, 0x11, 0x34, 0x31, 0x11, 0x31,
66 0x11, 0x31, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00
67};
68
69static u8 g98_sor_map[16] = {
70 0x00, 0x14, 0x12, 0x11, 0x00, 0x31, 0x11, 0x31,
71 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
72};
73
74u8
75mxm_sor_map(struct nvkm_bios *bios, u8 conn)
76{
77 struct nvkm_subdev *subdev = &bios->subdev;
78 u8 ver, hdr;
79 u16 mxm = mxm_table(bios, &ver, &hdr);
80 if (mxm && hdr >= 6) {
81 u16 map = nvbios_rd16(bios, mxm + 4);
82 if (map) {
83 ver = nvbios_rd08(bios, map);
84 if (ver == 0x10 || ver == 0x11) {
85 if (conn < nvbios_rd08(bios, map + 3)) {
86 map += nvbios_rd08(bios, map + 1);
87 map += conn;
88 return nvbios_rd08(bios, map);
89 }
90
91 return 0x00;
92 }
93
94 nvkm_warn(subdev, "unknown sor map v%02x\n", ver);
95 }
96 }
97
98 if (bios->version.chip == 0x84 || bios->version.chip == 0x86)
99 return g84_sor_map[conn];
100 if (bios->version.chip == 0x92)
101 return g92_sor_map[conn];
102 if (bios->version.chip == 0x94 || bios->version.chip == 0x96)
103 return g94_sor_map[conn];
104 if (bios->version.chip == 0x98)
105 return g98_sor_map[conn];
106
107 nvkm_warn(subdev, "missing sor map\n");
108 return 0x00;
109}
110
111u8
112mxm_ddc_map(struct nvkm_bios *bios, u8 port)
113{
114 struct nvkm_subdev *subdev = &bios->subdev;
115 u8 ver, hdr;
116 u16 mxm = mxm_table(bios, &ver, &hdr);
117 if (mxm && hdr >= 8) {
118 u16 map = nvbios_rd16(bios, mxm + 6);
119 if (map) {
120 ver = nvbios_rd08(bios, map);
121 if (ver == 0x10) {
122 if (port < nvbios_rd08(bios, map + 3)) {
123 map += nvbios_rd08(bios, map + 1);
124 map += port;
125 return nvbios_rd08(bios, map);
126 }
127
128 return 0x00;
129 }
130
131 nvkm_warn(subdev, "unknown ddc map v%02x\n", ver);
132 }
133 }
134
135
136 return (port << 4) | port;
137}
138