diff options
author | Dave Airlie <airlied@linux.ie> | 2007-04-22 17:47:35 +1000 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2007-04-22 17:47:35 +1000 |
commit | 2dc5c1d36ec6e5f499120ff4f73512f81486ad43 (patch) | |
tree | fd370b323658ac60f7da3f39de596af1087a4002 /src/nv_bios.c | |
parent | a6b98e0a2e15f4fe1a3f3d928c64bdc0f91984f1 (diff) | |
download | xorg-driver-xf86-video-nouveau-2dc5c1d36ec6e5f499120ff4f73512f81486ad43.tar.gz |
attempt to figure out nv28 DCB table
Diffstat (limited to 'src/nv_bios.c')
-rw-r--r-- | src/nv_bios.c | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/src/nv_bios.c b/src/nv_bios.c index dae3199..f9878dc 100644 --- a/src/nv_bios.c +++ b/src/nv_bios.c @@ -1456,6 +1456,14 @@ static void parse_bit_structure(ScrnInfoPtr pScrn, bios_t *bios, unsigned int of } } +static unsigned short brs(unsigned char *data, int offset) +{ + unsigned short ret; + + ret = (data[offset]) | ((data[offset+1]) << 8); + return ret; +} + static void parse_pins_structure(ScrnInfoPtr pScrn, bios_t *bios, unsigned int offset) { int pins_version_major=bios->data[offset+5]; @@ -1464,7 +1472,6 @@ static void parse_pins_structure(ScrnInfoPtr pScrn, bios_t *bios, unsigned int o int init2 = bios->data[offset + 20] + (bios->data[offset + 21] * 256); int init_size = bios->data[offset + 22] + (bios->data[offset + 23] * 256) + 1; int ram_tab; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PINS version %d.%d\n",pins_version_major,pins_version_minor); #if 0 @@ -1512,10 +1519,13 @@ static unsigned int nv_find_dcb_table(ScrnInfoPtr pScrn, bios_t *bios) unsigned char headerSize, entries; CARD32 header_word; int i; + int sig_offsets[2] = { 0x4, 0x6 }; + int offset = -1; /* get the offset from 0x36 */ bufloc = *(CARD16 *)&bios->data[0x36]; + if (bufloc == 0x0) { if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV43) { is_g5 = 1; @@ -1526,19 +1536,33 @@ static unsigned int nv_find_dcb_table(ScrnInfoPtr pScrn, bios_t *bios) } table2 = &bios->data[bufloc]; - sig = *(uint32_t*)(table2 + 6); - if ((sig != 0x4edcbdcb) && (sig!=0xcbbddc4e)) - return 0; - header_word = *(uint32_t *)table2; - if (is_g5) { - headerSize = 0x3c; - entries = 0xa; + /* lets play hunt the signature */ + for (i = 0; i < sizeof(sig_offsets) / sizeof(int); i++) { + sig = *(uint32_t*)(table2 + sig_offsets[i]); + if ((sig == 0x4edcbdcb) || (sig == 0xcbbddc4e)) { + offset = sig_offsets[i]; + break; + } + } + if (offset == -1) + return 0; + + if (offset == 6) { + header_word = *(uint32_t *)table2; + if (is_g5) { + headerSize = 0x3c; + entries = 0xa; + } else { + headerSize = (header_word >> 8) & 0xff; + entries = (header_word >> 16) & 0xff; + } } else { - headerSize = (header_word >> 8) & 0xff; - entries = (header_word >> 16) & 0xff; + entries = 0xa; + headerSize = 0x8; } - + + ErrorF("DCB size is %02X, entries is %02X\n", headerSize, entries); if (entries >= NV40_NUM_DCB_ENTRIES) entries = NV40_NUM_DCB_ENTRIES; |