Commit | Line | Data |
---|---|---|
0833428e BS |
1 | /* |
2 | * Copyright 2013 Red Hat Inc. | |
3 | * | |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | |
5 | * copy of this software and associated documentation files (the "Software"), | |
6 | * to deal in the Software without restriction, including without limitation | |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
8 | * and/or sell copies of the Software, and to permit persons to whom the | |
9 | * Software is furnished to do so, subject to the following conditions: | |
10 | * | |
11 | * The above copyright notice and this permission notice shall be included in | |
12 | * all copies or substantial portions of the Software. | |
13 | * | |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
20 | * OTHER DEALINGS IN THE SOFTWARE. | |
21 | * | |
22 | * Authors: Ben Skeggs | |
23 | */ | |
0833428e BS |
24 | #include <subdev/bios.h> |
25 | #include <subdev/bios/bit.h> | |
26 | #include <subdev/bios/rammap.h> | |
27 | ||
b655f2bb | 28 | u32 |
d390b480 | 29 | nvbios_rammapTe(struct nvkm_bios *bios, u8 *ver, u8 *hdr, |
b655f2bb | 30 | u8 *cnt, u8 *len, u8 *snr, u8 *ssz) |
0833428e BS |
31 | { |
32 | struct bit_entry bit_P; | |
339e32c0 | 33 | u32 rammap = 0x0000; |
0833428e BS |
34 | |
35 | if (!bit_entry(bios, 'P', &bit_P)) { | |
36 | if (bit_P.version == 2) | |
339e32c0 | 37 | rammap = nvbios_rd32(bios, bit_P.offset + 4); |
0833428e BS |
38 | |
39 | if (rammap) { | |
7f5f518f | 40 | *ver = nvbios_rd08(bios, rammap + 0); |
0833428e BS |
41 | switch (*ver) { |
42 | case 0x10: | |
43 | case 0x11: | |
7f5f518f BS |
44 | *hdr = nvbios_rd08(bios, rammap + 1); |
45 | *cnt = nvbios_rd08(bios, rammap + 5); | |
46 | *len = nvbios_rd08(bios, rammap + 2); | |
47 | *snr = nvbios_rd08(bios, rammap + 4); | |
48 | *ssz = nvbios_rd08(bios, rammap + 3); | |
0833428e BS |
49 | return rammap; |
50 | default: | |
51 | break; | |
52 | } | |
53 | } | |
54 | } | |
55 | ||
56 | return 0x0000; | |
57 | } | |
58 | ||
b655f2bb | 59 | u32 |
d390b480 | 60 | nvbios_rammapEe(struct nvkm_bios *bios, int idx, |
b655f2bb | 61 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len) |
0833428e BS |
62 | { |
63 | u8 snr, ssz; | |
339e32c0 | 64 | u32 rammap = nvbios_rammapTe(bios, ver, hdr, cnt, len, &snr, &ssz); |
0833428e BS |
65 | if (rammap && idx < *cnt) { |
66 | rammap = rammap + *hdr + (idx * (*len + (snr * ssz))); | |
67 | *hdr = *len; | |
68 | *cnt = snr; | |
69 | *len = ssz; | |
70 | return rammap; | |
71 | } | |
72 | return 0x0000; | |
73 | } | |
74 | ||
2813e19f RS |
75 | /* Pretend a performance mode is also a rammap entry, helps coalesce entries |
76 | * later on */ | |
77 | u32 | |
78 | nvbios_rammapEp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, | |
79 | struct nvbios_ramcfg *p) | |
80 | { | |
81 | memset(p, 0x00, sizeof(*p)); | |
82 | ||
7f5f518f BS |
83 | p->rammap_00_16_20 = (nvbios_rd08(bios, data + 0x16) & 0x20) >> 5; |
84 | p->rammap_00_16_40 = (nvbios_rd08(bios, data + 0x16) & 0x40) >> 6; | |
85 | p->rammap_00_17_02 = (nvbios_rd08(bios, data + 0x17) & 0x02) >> 1; | |
2813e19f RS |
86 | |
87 | return data; | |
88 | } | |
89 | ||
b655f2bb | 90 | u32 |
d390b480 BS |
91 | nvbios_rammapEp(struct nvkm_bios *bios, int idx, |
92 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *p) | |
b655f2bb | 93 | { |
5af430ab | 94 | u32 data = nvbios_rammapEe(bios, idx, ver, hdr, cnt, len), temp; |
b655f2bb | 95 | memset(p, 0x00, sizeof(*p)); |
d9b5f261 BS |
96 | p->rammap_ver = *ver; |
97 | p->rammap_hdr = *hdr; | |
b655f2bb | 98 | switch (!!data * *ver) { |
2a7fa674 | 99 | case 0x10: |
7f5f518f BS |
100 | p->rammap_min = nvbios_rd16(bios, data + 0x00); |
101 | p->rammap_max = nvbios_rd16(bios, data + 0x02); | |
102 | p->rammap_10_04_02 = (nvbios_rd08(bios, data + 0x04) & 0x02) >> 1; | |
103 | p->rammap_10_04_08 = (nvbios_rd08(bios, data + 0x04) & 0x08) >> 3; | |
2a7fa674 | 104 | break; |
b655f2bb | 105 | case 0x11: |
7f5f518f BS |
106 | p->rammap_min = nvbios_rd16(bios, data + 0x00); |
107 | p->rammap_max = nvbios_rd16(bios, data + 0x02); | |
108 | p->rammap_11_08_01 = (nvbios_rd08(bios, data + 0x08) & 0x01) >> 0; | |
109 | p->rammap_11_08_0c = (nvbios_rd08(bios, data + 0x08) & 0x0c) >> 2; | |
110 | p->rammap_11_08_10 = (nvbios_rd08(bios, data + 0x08) & 0x10) >> 4; | |
111 | temp = nvbios_rd32(bios, data + 0x09); | |
5af430ab BS |
112 | p->rammap_11_09_01ff = (temp & 0x000001ff) >> 0; |
113 | p->rammap_11_0a_03fe = (temp & 0x0003fe00) >> 9; | |
114 | p->rammap_11_0a_0400 = (temp & 0x00040000) >> 18; | |
115 | p->rammap_11_0a_0800 = (temp & 0x00080000) >> 19; | |
116 | p->rammap_11_0b_01f0 = (temp & 0x01f00000) >> 20; | |
117 | p->rammap_11_0b_0200 = (temp & 0x02000000) >> 25; | |
118 | p->rammap_11_0b_0400 = (temp & 0x04000000) >> 26; | |
119 | p->rammap_11_0b_0800 = (temp & 0x08000000) >> 27; | |
7f5f518f BS |
120 | p->rammap_11_0d = nvbios_rd08(bios, data + 0x0d); |
121 | p->rammap_11_0e = nvbios_rd08(bios, data + 0x0e); | |
122 | p->rammap_11_0f = nvbios_rd08(bios, data + 0x0f); | |
123 | p->rammap_11_11_0c = (nvbios_rd08(bios, data + 0x11) & 0x0c) >> 2; | |
b655f2bb BS |
124 | break; |
125 | default: | |
126 | data = 0; | |
127 | break; | |
128 | } | |
129 | return data; | |
130 | } | |
131 | ||
d9b5f261 | 132 | u32 |
d390b480 BS |
133 | nvbios_rammapEm(struct nvkm_bios *bios, u16 mhz, |
134 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *info) | |
d9b5f261 BS |
135 | { |
136 | int idx = 0; | |
137 | u32 data; | |
138 | while ((data = nvbios_rammapEp(bios, idx++, ver, hdr, cnt, len, info))) { | |
139 | if (mhz >= info->rammap_min && mhz <= info->rammap_max) | |
140 | break; | |
141 | } | |
142 | return data; | |
143 | } | |
144 | ||
b655f2bb | 145 | u32 |
d390b480 BS |
146 | nvbios_rammapSe(struct nvkm_bios *bios, u32 data, |
147 | u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx, u8 *ver, u8 *hdr) | |
b655f2bb BS |
148 | { |
149 | if (idx < ecnt) { | |
150 | data = data + ehdr + (idx * elen); | |
151 | *ver = ever; | |
152 | *hdr = elen; | |
153 | return data; | |
154 | } | |
155 | return 0; | |
156 | } | |
157 | ||
35fe024a RS |
158 | u32 |
159 | nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx, | |
160 | struct nvbios_ramcfg *p) | |
161 | { | |
162 | data += (idx * size); | |
163 | ||
164 | if (size < 11) | |
165 | return 0x00000000; | |
166 | ||
c25bf7b6 | 167 | p->ramcfg_ver = 0; |
7f5f518f BS |
168 | p->ramcfg_timing = nvbios_rd08(bios, data + 0x01); |
169 | p->ramcfg_00_03_01 = (nvbios_rd08(bios, data + 0x03) & 0x01) >> 0; | |
170 | p->ramcfg_00_03_02 = (nvbios_rd08(bios, data + 0x03) & 0x02) >> 1; | |
171 | p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x03) & 0x04) >> 2; | |
172 | p->ramcfg_00_03_08 = (nvbios_rd08(bios, data + 0x03) & 0x08) >> 3; | |
173 | p->ramcfg_RON = (nvbios_rd08(bios, data + 0x03) & 0x10) >> 3; | |
1cf688dd | 174 | p->ramcfg_FBVDDQ = (nvbios_rd08(bios, data + 0x03) & 0x80) >> 7; |
7f5f518f BS |
175 | p->ramcfg_00_04_02 = (nvbios_rd08(bios, data + 0x04) & 0x02) >> 1; |
176 | p->ramcfg_00_04_04 = (nvbios_rd08(bios, data + 0x04) & 0x04) >> 2; | |
177 | p->ramcfg_00_04_20 = (nvbios_rd08(bios, data + 0x04) & 0x20) >> 5; | |
178 | p->ramcfg_00_05 = (nvbios_rd08(bios, data + 0x05) & 0xff) >> 0; | |
179 | p->ramcfg_00_06 = (nvbios_rd08(bios, data + 0x06) & 0xff) >> 0; | |
180 | p->ramcfg_00_07 = (nvbios_rd08(bios, data + 0x07) & 0xff) >> 0; | |
181 | p->ramcfg_00_08 = (nvbios_rd08(bios, data + 0x08) & 0xff) >> 0; | |
182 | p->ramcfg_00_09 = (nvbios_rd08(bios, data + 0x09) & 0xff) >> 0; | |
183 | p->ramcfg_00_0a_0f = (nvbios_rd08(bios, data + 0x0a) & 0x0f) >> 0; | |
184 | p->ramcfg_00_0a_f0 = (nvbios_rd08(bios, data + 0x0a) & 0xf0) >> 4; | |
35fe024a RS |
185 | |
186 | return data; | |
187 | } | |
188 | ||
b655f2bb | 189 | u32 |
d390b480 | 190 | nvbios_rammapSp(struct nvkm_bios *bios, u32 data, |
b655f2bb BS |
191 | u8 ever, u8 ehdr, u8 ecnt, u8 elen, int idx, |
192 | u8 *ver, u8 *hdr, struct nvbios_ramcfg *p) | |
193 | { | |
194 | data = nvbios_rammapSe(bios, data, ever, ehdr, ecnt, elen, idx, ver, hdr); | |
d9b5f261 BS |
195 | p->ramcfg_ver = *ver; |
196 | p->ramcfg_hdr = *hdr; | |
b655f2bb | 197 | switch (!!data * *ver) { |
c378eb74 | 198 | case 0x10: |
7f5f518f BS |
199 | p->ramcfg_timing = nvbios_rd08(bios, data + 0x01); |
200 | p->ramcfg_10_02_01 = (nvbios_rd08(bios, data + 0x02) & 0x01) >> 0; | |
201 | p->ramcfg_10_02_02 = (nvbios_rd08(bios, data + 0x02) & 0x02) >> 1; | |
202 | p->ramcfg_10_02_04 = (nvbios_rd08(bios, data + 0x02) & 0x04) >> 2; | |
203 | p->ramcfg_10_02_08 = (nvbios_rd08(bios, data + 0x02) & 0x08) >> 3; | |
204 | p->ramcfg_10_02_10 = (nvbios_rd08(bios, data + 0x02) & 0x10) >> 4; | |
205 | p->ramcfg_10_02_20 = (nvbios_rd08(bios, data + 0x02) & 0x20) >> 5; | |
206 | p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 6; | |
207 | p->ramcfg_10_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 0; | |
208 | p->ramcfg_10_04_01 = (nvbios_rd08(bios, data + 0x04) & 0x01) >> 0; | |
ef6e8f4c | 209 | p->ramcfg_FBVDDQ = (nvbios_rd08(bios, data + 0x04) & 0x08) >> 3; |
7f5f518f BS |
210 | p->ramcfg_10_05 = (nvbios_rd08(bios, data + 0x05) & 0xff) >> 0; |
211 | p->ramcfg_10_06 = (nvbios_rd08(bios, data + 0x06) & 0xff) >> 0; | |
212 | p->ramcfg_10_07 = (nvbios_rd08(bios, data + 0x07) & 0xff) >> 0; | |
213 | p->ramcfg_10_08 = (nvbios_rd08(bios, data + 0x08) & 0xff) >> 0; | |
214 | p->ramcfg_10_09_0f = (nvbios_rd08(bios, data + 0x09) & 0x0f) >> 0; | |
215 | p->ramcfg_10_09_f0 = (nvbios_rd08(bios, data + 0x09) & 0xf0) >> 4; | |
c378eb74 | 216 | break; |
b655f2bb | 217 | case 0x11: |
7f5f518f BS |
218 | p->ramcfg_timing = nvbios_rd08(bios, data + 0x00); |
219 | p->ramcfg_11_01_01 = (nvbios_rd08(bios, data + 0x01) & 0x01) >> 0; | |
220 | p->ramcfg_11_01_02 = (nvbios_rd08(bios, data + 0x01) & 0x02) >> 1; | |
221 | p->ramcfg_11_01_04 = (nvbios_rd08(bios, data + 0x01) & 0x04) >> 2; | |
222 | p->ramcfg_11_01_08 = (nvbios_rd08(bios, data + 0x01) & 0x08) >> 3; | |
223 | p->ramcfg_11_01_10 = (nvbios_rd08(bios, data + 0x01) & 0x10) >> 4; | |
b4f2bf33 | 224 | p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x01) & 0x20) >> 5; |
7f5f518f BS |
225 | p->ramcfg_11_01_40 = (nvbios_rd08(bios, data + 0x01) & 0x40) >> 6; |
226 | p->ramcfg_11_01_80 = (nvbios_rd08(bios, data + 0x01) & 0x80) >> 7; | |
227 | p->ramcfg_11_02_03 = (nvbios_rd08(bios, data + 0x02) & 0x03) >> 0; | |
228 | p->ramcfg_11_02_04 = (nvbios_rd08(bios, data + 0x02) & 0x04) >> 2; | |
229 | p->ramcfg_11_02_08 = (nvbios_rd08(bios, data + 0x02) & 0x08) >> 3; | |
230 | p->ramcfg_11_02_10 = (nvbios_rd08(bios, data + 0x02) & 0x10) >> 4; | |
231 | p->ramcfg_11_02_40 = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 6; | |
232 | p->ramcfg_11_02_80 = (nvbios_rd08(bios, data + 0x02) & 0x80) >> 7; | |
233 | p->ramcfg_11_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 0; | |
234 | p->ramcfg_11_03_30 = (nvbios_rd08(bios, data + 0x03) & 0x30) >> 4; | |
235 | p->ramcfg_11_03_c0 = (nvbios_rd08(bios, data + 0x03) & 0xc0) >> 6; | |
236 | p->ramcfg_11_03_f0 = (nvbios_rd08(bios, data + 0x03) & 0xf0) >> 4; | |
237 | p->ramcfg_11_04 = (nvbios_rd08(bios, data + 0x04) & 0xff) >> 0; | |
238 | p->ramcfg_11_06 = (nvbios_rd08(bios, data + 0x06) & 0xff) >> 0; | |
239 | p->ramcfg_11_07_02 = (nvbios_rd08(bios, data + 0x07) & 0x02) >> 1; | |
240 | p->ramcfg_11_07_04 = (nvbios_rd08(bios, data + 0x07) & 0x04) >> 2; | |
241 | p->ramcfg_11_07_08 = (nvbios_rd08(bios, data + 0x07) & 0x08) >> 3; | |
242 | p->ramcfg_11_07_10 = (nvbios_rd08(bios, data + 0x07) & 0x10) >> 4; | |
243 | p->ramcfg_11_07_40 = (nvbios_rd08(bios, data + 0x07) & 0x40) >> 6; | |
244 | p->ramcfg_11_07_80 = (nvbios_rd08(bios, data + 0x07) & 0x80) >> 7; | |
245 | p->ramcfg_11_08_01 = (nvbios_rd08(bios, data + 0x08) & 0x01) >> 0; | |
246 | p->ramcfg_11_08_02 = (nvbios_rd08(bios, data + 0x08) & 0x02) >> 1; | |
247 | p->ramcfg_11_08_04 = (nvbios_rd08(bios, data + 0x08) & 0x04) >> 2; | |
248 | p->ramcfg_11_08_08 = (nvbios_rd08(bios, data + 0x08) & 0x08) >> 3; | |
249 | p->ramcfg_11_08_10 = (nvbios_rd08(bios, data + 0x08) & 0x10) >> 4; | |
250 | p->ramcfg_11_08_20 = (nvbios_rd08(bios, data + 0x08) & 0x20) >> 5; | |
251 | p->ramcfg_11_09 = (nvbios_rd08(bios, data + 0x09) & 0xff) >> 0; | |
b655f2bb BS |
252 | break; |
253 | default: | |
254 | data = 0; | |
255 | break; | |
256 | } | |
257 | return data; | |
258 | } |