aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-01-14 02:53:04 -0500
committerBen Skeggs <bskeggs@redhat.com>2010-01-14 03:48:59 -0500
commitb0d2de860bd621959bc826ffd42618fe1de37a61 (patch)
tree0d9d506c8cbc698489e7c0569a63f0089ce9d1e9
parented42f8240cfea13580fe91195e52c5247275e7df (diff)
drm/nouveau: less magic DCB 1.5 parsing
This in the very least matches the parsing of all the previously known entries, and hopefully (at least closer to) correct for any we haven't seen yet. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c79
1 files changed, 40 insertions, 39 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 9dd2efa07f6..ca2fcdf32b8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -5393,52 +5393,49 @@ static bool
5393parse_dcb15_entry(struct drm_device *dev, struct parsed_dcb *dcb, 5393parse_dcb15_entry(struct drm_device *dev, struct parsed_dcb *dcb,
5394 uint32_t conn, uint32_t conf, struct dcb_entry *entry) 5394 uint32_t conn, uint32_t conf, struct dcb_entry *entry)
5395{ 5395{
5396 if (conn != 0xf0003f00 && conn != 0xf2247f10 && conn != 0xf2204001 && 5396 switch (conn & 0x0000000f) {
5397 conn != 0xf2204301 && conn != 0xf2204311 && conn != 0xf2208001 && 5397 case 0:
5398 conn != 0xf2244001 && conn != 0xf2244301 && conn != 0xf2244311 && 5398 entry->type = OUTPUT_ANALOG;
5399 conn != 0xf4204011 && conn != 0xf4208011 && conn != 0xf4248011 && 5399 break;
5400 conn != 0xf2045ff2 && conn != 0xf2045f14 && conn != 0xf207df14 && 5400 case 1:
5401 conn != 0xf2205004 && conn != 0xf2209004) { 5401 entry->type = OUTPUT_TV;
5402 NV_ERROR(dev, "Unknown DCB 1.5 entry, please report\n"); 5402 break;
5403 5403 case 2:
5404 /* cause output setting to fail for !TV, so message is seen */ 5404 case 3:
5405 if ((conn & 0xf) != 0x1)
5406 dcb->entries = 0;
5407
5408 return false;
5409 }
5410 /* most of the below is a "best guess" atm */
5411 entry->type = conn & 0xf;
5412 if (entry->type == 2)
5413 /* another way of specifying straps based lvds... */
5414 entry->type = OUTPUT_LVDS; 5405 entry->type = OUTPUT_LVDS;
5415 if (entry->type == 4) { /* digital */ 5406 break;
5416 if (conn & 0x10) 5407 case 4:
5417 entry->type = OUTPUT_LVDS; 5408 switch ((conn & 0x000000f0) >> 4) {
5418 else 5409 case 0:
5419 entry->type = OUTPUT_TMDS; 5410 entry->type = OUTPUT_TMDS;
5411 break;
5412 case 1:
5413 entry->type = OUTPUT_LVDS;
5414 break;
5415 default:
5416 NV_ERROR(dev, "Unknown DCB subtype 4/%d\n",
5417 (conn & 0x000000f0) >> 4);
5418 return false;
5419 }
5420 break;
5421 default:
5422 NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f);
5423 return false;
5420 } 5424 }
5421 /* what's in bits 5-13? could be some encoder maker thing, in tv case */ 5425
5422 entry->i2c_index = (conn >> 14) & 0xf; 5426 entry->i2c_index = (conn & 0x0003c000) >> 14;
5423 /* raw heads field is in range 0-1, so move to 1-2 */ 5427 entry->heads = ((conn & 0x001c0000) >> 18) + 1;
5424 entry->heads = ((conn >> 18) & 0x7) + 1; 5428 entry->or = entry->heads; /* same as heads, hopefully safe enough */
5425 entry->location = (conn >> 21) & 0xf; 5429 entry->location = (conn & 0x01e00000) >> 21;
5426 /* unused: entry->bus = (conn >> 25) & 0x7; */ 5430 entry->bus = (conn & 0x0e000000) >> 25;
5427 /* set or to be same as heads -- hopefully safe enough */
5428 entry->or = entry->heads;
5429 entry->duallink_possible = false; 5431 entry->duallink_possible = false;
5430 5432
5431 switch (entry->type) { 5433 switch (entry->type) {
5432 case OUTPUT_ANALOG: 5434 case OUTPUT_ANALOG:
5433 entry->crtconf.maxfreq = (conf & 0xffff) * 10; 5435 entry->crtconf.maxfreq = (conf & 0xffff) * 10;
5434 break; 5436 break;
5435 case OUTPUT_LVDS: 5437 case OUTPUT_TV:
5436 /* 5438 entry->tvconf.has_component_output = false;
5437 * This is probably buried in conn's unknown bits.
5438 * This will upset EDID-ful models, if they exist
5439 */
5440 entry->lvdsconf.use_straps_for_mode = true;
5441 entry->lvdsconf.use_power_scripts = true;
5442 break; 5439 break;
5443 case OUTPUT_TMDS: 5440 case OUTPUT_TMDS:
5444 /* 5441 /*
@@ -5447,8 +5444,12 @@ parse_dcb15_entry(struct drm_device *dev, struct parsed_dcb *dcb,
5447 */ 5444 */
5448 fabricate_vga_output(dcb, entry->i2c_index, entry->heads); 5445 fabricate_vga_output(dcb, entry->i2c_index, entry->heads);
5449 break; 5446 break;
5450 case OUTPUT_TV: 5447 case OUTPUT_LVDS:
5451 entry->tvconf.has_component_output = false; 5448 if ((conn & 0x00003f00) != 0x10)
5449 entry->lvdsconf.use_straps_for_mode = true;
5450 entry->lvdsconf.use_power_scripts = true;
5451 break;
5452 default:
5452 break; 5453 break;
5453 } 5454 }
5454 5455