summaryrefslogtreecommitdiff
path: root/src/radeon_bios.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/radeon_bios.c')
-rw-r--r--src/radeon_bios.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index e106a168..cfa5d2bc 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -672,6 +672,139 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output)
return FALSE;
}
+Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int offset, table_start, max_freq, gpio_reg, flags;
+
+ if (!info->VBIOS) return FALSE;
+
+ if (info->IsAtomBios) {
+ return FALSE;
+ } else {
+ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x58);
+ if (offset) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "External TMDS Table revision: %d\n",
+ RADEON_BIOS8(offset));
+ table_start = offset+4;
+ max_freq = RADEON_BIOS16(table_start);
+ radeon_output->dvo_i2c_slave_addr = RADEON_BIOS8(table_start+2);
+ gpio_reg = RADEON_BIOS8(table_start+3);
+ if (gpio_reg == 1)
+ radeon_output->dvo_i2c_reg = RADEON_GPIO_MONID;
+ else if (gpio_reg == 2)
+ radeon_output->dvo_i2c_reg = RADEON_GPIO_DVI_DDC;
+ else if (gpio_reg == 3)
+ radeon_output->dvo_i2c_reg = RADEON_GPIO_VGA_DDC;
+ else if (gpio_reg == 4)
+ radeon_output->dvo_i2c_reg = RADEON_GPIO_CRT2_DDC;
+ else if (gpio_reg == 5)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "unsupported MM gpio_reg\n");
+ /*radeon_output->i2c_reg = RADEON_GPIO_MM;*/
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unknown gpio reg: %d\n", gpio_reg);
+ return FALSE;
+ }
+ flags = RADEON_BIOS8(table_start+5);
+ radeon_output->dvo_duallink = flags & 0x01;
+ if (radeon_output->dvo_duallink) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Duallink TMDS detected\n");
+ }
+ return TRUE;
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "No External TMDS Table found\n");
+
+ return FALSE;
+}
+
+Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int offset, index, id;
+ CARD32 val, reg, andmask, ormask;
+
+ if (!info->VBIOS) return FALSE;
+
+ if (info->IsAtomBios) {
+ return FALSE;
+ } else {
+ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x58);
+ if (offset) {
+ index = offset+10;
+ id = RADEON_BIOS16(index);
+ while (id != 0xffff) {
+ index += 2;
+ switch(id >> 13) {
+ case 0:
+ reg = id & 0x1fff;
+ val = RADEON_BIOS32(index);
+ index += 4;
+ ErrorF("WRITE INDEXED: 0x%x 0x%x\n",
+ reg, (unsigned)val);
+ /*OUTREG(reg, val);*/
+ break;
+ case 2:
+ reg = id & 0x1fff;
+ andmask = RADEON_BIOS32(index);
+ index += 4;
+ ormask = RADEON_BIOS32(index);
+ index += 4;
+ val = INREG(reg);
+ val = (val & andmask) | ormask;
+ ErrorF("MASK DIRECT: 0x%x 0x%x 0x%x\n",
+ reg, (unsigned)andmask, (unsigned)ormask);
+ /*OUTREG(reg, val);*/
+ break;
+ case 4:
+ val = RADEON_BIOS16(index);
+ index += 2;
+ ErrorF("delay: %d\n", val);
+ usleep(val);
+ break;
+ case 5:
+ reg = id & 0x1fff;
+ andmask = RADEON_BIOS32(index);
+ index += 4;
+ ormask = RADEON_BIOS32(index);
+ index += 4;
+ ErrorF("MASK PLL: 0x%x 0x%x 0x%x\n",
+ reg, (unsigned)andmask, (unsigned)ormask);
+ /*val = INPLL(pScrn, reg);
+ val = (val & andmask) | ormask;
+ OUTPLL(pScrn, reg, val);*/
+ break;
+ case 6:
+ reg = id & 0x1fff;
+ val = RADEON_BIOS8(index);
+ index += 1;
+ ErrorF("i2c write: 0x%x, 0x%x\n", reg, val);
+ RADEONDVOWriteByte(radeon_output->DVOChip, reg, val);
+ break;
+ default:
+ ErrorF("unknown id %d\n", id>>13);
+ return FALSE;
+ };
+ id = RADEON_BIOS16(index);
+ }
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
/* support for init from bios tables
*
* Based heavily on the netbsd radeonfb driver