diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2016-05-24 20:56:24 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2016-06-01 23:53:30 -0400 |
commit | bc9139d23f6b038e32bcd2dffdee70a8d76b3976 (patch) | |
tree | 1f5a61a57f04166372a61b6837a50f9e338c1443 | |
parent | 92181d47ee74749bdf902f080dab9fa9ef44b37f (diff) |
drm/nouveau/bios/disp: fix handling of "match any protocol" entries
As it turns out, a value of 0xff means "any protocol" and not "VGA".
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Cc: stable@vger.kernel.org
4 files changed, 17 insertions, 21 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h index db10c11f0595..c5a6ebd5a478 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h | |||
@@ -25,7 +25,8 @@ u16 nvbios_outp_match(struct nvkm_bios *, u16 type, u16 mask, | |||
25 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *); | 25 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *); |
26 | 26 | ||
27 | struct nvbios_ocfg { | 27 | struct nvbios_ocfg { |
28 | u16 match; | 28 | u8 proto; |
29 | u8 flags; | ||
29 | u16 clkcmp[2]; | 30 | u16 clkcmp[2]; |
30 | }; | 31 | }; |
31 | 32 | ||
@@ -33,7 +34,7 @@ u16 nvbios_ocfg_entry(struct nvkm_bios *, u16 outp, u8 idx, | |||
33 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len); | 34 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len); |
34 | u16 nvbios_ocfg_parse(struct nvkm_bios *, u16 outp, u8 idx, | 35 | u16 nvbios_ocfg_parse(struct nvkm_bios *, u16 outp, u8 idx, |
35 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *); | 36 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *); |
36 | u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u16 type, | 37 | u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u8 proto, u8 flags, |
37 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *); | 38 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *); |
38 | u16 nvbios_oclk_match(struct nvkm_bios *, u16 cmp, u32 khz); | 39 | u16 nvbios_oclk_match(struct nvkm_bios *, u16 cmp, u32 khz); |
39 | #endif | 40 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c index f0314664349c..5dd34382f55a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c | |||
@@ -76,6 +76,7 @@ exec_lookup(struct nv50_disp *disp, int head, int or, u32 ctrl, | |||
76 | mask |= 0x0001 << or; | 76 | mask |= 0x0001 << or; |
77 | mask |= 0x0100 << head; | 77 | mask |= 0x0100 << head; |
78 | 78 | ||
79 | |||
79 | list_for_each_entry(outp, &disp->base.outp, head) { | 80 | list_for_each_entry(outp, &disp->base.outp, head) { |
80 | if ((outp->info.hasht & 0xff) == type && | 81 | if ((outp->info.hasht & 0xff) == type && |
81 | (outp->info.hashm & mask) == mask) { | 82 | (outp->info.hashm & mask) == mask) { |
@@ -155,25 +156,21 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf) | |||
155 | if (!outp) | 156 | if (!outp) |
156 | return NULL; | 157 | return NULL; |
157 | 158 | ||
159 | *conf = (ctrl & 0x00000f00) >> 8; | ||
158 | switch (outp->info.type) { | 160 | switch (outp->info.type) { |
159 | case DCB_OUTPUT_TMDS: | 161 | case DCB_OUTPUT_TMDS: |
160 | *conf = (ctrl & 0x00000f00) >> 8; | ||
161 | if (*conf == 5) | 162 | if (*conf == 5) |
162 | *conf |= 0x0100; | 163 | *conf |= 0x0100; |
163 | break; | 164 | break; |
164 | case DCB_OUTPUT_LVDS: | 165 | case DCB_OUTPUT_LVDS: |
165 | *conf = disp->sor.lvdsconf; | 166 | *conf |= disp->sor.lvdsconf; |
166 | break; | ||
167 | case DCB_OUTPUT_DP: | ||
168 | *conf = (ctrl & 0x00000f00) >> 8; | ||
169 | break; | 167 | break; |
170 | case DCB_OUTPUT_ANALOG: | ||
171 | default: | 168 | default: |
172 | *conf = 0x00ff; | ||
173 | break; | 169 | break; |
174 | } | 170 | } |
175 | 171 | ||
176 | data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2); | 172 | data = nvbios_ocfg_match(bios, data, *conf & 0xff, *conf >> 8, |
173 | &ver, &hdr, &cnt, &len, &info2); | ||
177 | if (data && id < 0xff) { | 174 | if (data && id < 0xff) { |
178 | data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); | 175 | data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); |
179 | if (data) { | 176 | if (data) { |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c index 4226d2153b9c..fcb1b0c46d64 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c | |||
@@ -387,22 +387,17 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf) | |||
387 | if (!outp) | 387 | if (!outp) |
388 | return NULL; | 388 | return NULL; |
389 | 389 | ||
390 | *conf = (ctrl & 0x00000f00) >> 8; | ||
390 | if (outp->info.location == 0) { | 391 | if (outp->info.location == 0) { |
391 | switch (outp->info.type) { | 392 | switch (outp->info.type) { |
392 | case DCB_OUTPUT_TMDS: | 393 | case DCB_OUTPUT_TMDS: |
393 | *conf = (ctrl & 0x00000f00) >> 8; | ||
394 | if (*conf == 5) | 394 | if (*conf == 5) |
395 | *conf |= 0x0100; | 395 | *conf |= 0x0100; |
396 | break; | 396 | break; |
397 | case DCB_OUTPUT_LVDS: | 397 | case DCB_OUTPUT_LVDS: |
398 | *conf = disp->sor.lvdsconf; | 398 | *conf |= disp->sor.lvdsconf; |
399 | break; | 399 | break; |
400 | case DCB_OUTPUT_DP: | ||
401 | *conf = (ctrl & 0x00000f00) >> 8; | ||
402 | break; | ||
403 | case DCB_OUTPUT_ANALOG: | ||
404 | default: | 400 | default: |
405 | *conf = 0x00ff; | ||
406 | break; | 401 | break; |
407 | } | 402 | } |
408 | } else { | 403 | } else { |
@@ -410,7 +405,8 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf) | |||
410 | pclk = pclk / 2; | 405 | pclk = pclk / 2; |
411 | } | 406 | } |
412 | 407 | ||
413 | data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2); | 408 | data = nvbios_ocfg_match(bios, data, *conf & 0xff, *conf >> 8, |
409 | &ver, &hdr, &cnt, &len, &info2); | ||
414 | if (data && id < 0xff) { | 410 | if (data && id < 0xff) { |
415 | data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); | 411 | data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); |
416 | if (data) { | 412 | if (data) { |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c index a5e92135cd77..9efb1b48cd54 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c | |||
@@ -141,7 +141,8 @@ nvbios_ocfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx, | |||
141 | { | 141 | { |
142 | u16 data = nvbios_ocfg_entry(bios, outp, idx, ver, hdr, cnt, len); | 142 | u16 data = nvbios_ocfg_entry(bios, outp, idx, ver, hdr, cnt, len); |
143 | if (data) { | 143 | if (data) { |
144 | info->match = nvbios_rd16(bios, data + 0x00); | 144 | info->proto = nvbios_rd08(bios, data + 0x00); |
145 | info->flags = nvbios_rd16(bios, data + 0x01); | ||
145 | info->clkcmp[0] = nvbios_rd16(bios, data + 0x02); | 146 | info->clkcmp[0] = nvbios_rd16(bios, data + 0x02); |
146 | info->clkcmp[1] = nvbios_rd16(bios, data + 0x04); | 147 | info->clkcmp[1] = nvbios_rd16(bios, data + 0x04); |
147 | } | 148 | } |
@@ -149,12 +150,13 @@ nvbios_ocfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx, | |||
149 | } | 150 | } |
150 | 151 | ||
151 | u16 | 152 | u16 |
152 | nvbios_ocfg_match(struct nvkm_bios *bios, u16 outp, u16 type, | 153 | nvbios_ocfg_match(struct nvkm_bios *bios, u16 outp, u8 proto, u8 flags, |
153 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *info) | 154 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *info) |
154 | { | 155 | { |
155 | u16 data, idx = 0; | 156 | u16 data, idx = 0; |
156 | while ((data = nvbios_ocfg_parse(bios, outp, idx++, ver, hdr, cnt, len, info))) { | 157 | while ((data = nvbios_ocfg_parse(bios, outp, idx++, ver, hdr, cnt, len, info))) { |
157 | if (info->match == type) | 158 | if ((info->proto == proto || info->proto == 0xff) && |
159 | (info->flags == flags)) | ||
158 | break; | 160 | break; |
159 | } | 161 | } |
160 | return data; | 162 | return data; |