xf86-video-ati: Branch 'master' - 3 commits

Alex Deucher agd5f at kemper.freedesktop.org
Sun Jan 20 15:37:34 PST 2008


 src/legacy_output.c |    2 
 src/radeon.h        |    1 
 src/radeon_bios.c   |   87 ++++++++++++++++---
 src/radeon_output.c |  234 ++++++++++++++++++++++------------------------------
 src/radeon_probe.h  |   20 ++++
 src/radeon_tv.c     |   12 ++
 6 files changed, 205 insertions(+), 151 deletions(-)

New commits:
commit b2db8657fb888cff6d64c6dcb182caac389776ce
Author: Alex Deucher <alex at botch2.(none)>
Date:   Sun Jan 20 18:33:22 2008 -0500

    RADEON: re-work i2c for DDC
    
    Unify the radeon/avivo paths and grab the data/clk masks from bios
    if available

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 829a641..46f4a3b 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -274,12 +274,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    case DDC_CRT2:
 		info->BiosConnector[i].ddc_line = RADEON_GPIO_CRT2_DDC;
 		break;
-	    case DDC_LCD:
-		info->BiosConnector[i].ddc_line = RADEON_LCD_GPIO_MASK;
-		break;
-	    case DDC_GPIO:
-		info->BiosConnector[i].ddc_line = RADEON_MDGPIO_EN_REG;
-		break;
 	    default:
 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown DDC Type: %d\n", DDCType);
 		break;
@@ -371,9 +365,13 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 			    break;
 			case DDC_LCD:
 			    info->BiosConnector[4].ddc_line = RADEON_LCD_GPIO_MASK;
+			    info->BiosConnector[4].ddc_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
+			    info->BiosConnector[4].ddc_data_mask = RADEON_BIOS32(tmp0 + 0x07);
 			    break;
 			case DDC_GPIO:
 			    info->BiosConnector[4].ddc_line = RADEON_MDGPIO_EN_REG;
+			    info->BiosConnector[4].ddc_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
+			    info->BiosConnector[4].ddc_data_mask = RADEON_BIOS32(tmp0 + 0x07);
 			    break;
 			default:
 			    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown DDC Type: %d\n", DDCType);
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 8fc6bc6..42477b6 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -172,7 +172,7 @@ static void RADEONUpdatePanelSize(xf86OutputPtr output);
 static void RADEONGetTMDSInfoFromTable(xf86OutputPtr output);
 #define AVIVO_I2C_DISABLE 0
 #define AVIVO_I2C_ENABLE 1
-static Bool AVIVOI2CDoLock(ScrnInfoPtr pScrn, int lock_state, int gpio);
+static Bool AVIVOI2CDoLock(xf86OutputPtr output, int lock_state);
 
 extern void atombios_output_mode_set(xf86OutputPtr output,
 				     DisplayModePtr mode,
@@ -220,9 +220,9 @@ avivo_display_ddc_connected(ScrnInfoPtr pScrn, xf86OutputPtr output)
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
     if (radeon_output->pI2CBus) {
-	AVIVOI2CDoLock(pScrn, AVIVO_I2C_ENABLE, radeon_output->ddc_line);
+	AVIVOI2CDoLock(output, AVIVO_I2C_ENABLE);
 	MonInfo = xf86OutputGetEDID(output, radeon_output->pI2CBus);
-	AVIVOI2CDoLock(pScrn, AVIVO_I2C_DISABLE, radeon_output->ddc_line);
+	AVIVOI2CDoLock(output, AVIVO_I2C_DISABLE);
     }
     if (MonInfo) {
 	if (!xf86ReturnOptValBool(info->Options, OPTION_IGNORE_EDID, FALSE))
@@ -1267,91 +1267,23 @@ Bool AVIVOI2CReset(ScrnInfoPtr pScrn)
 #endif
 
 static
-Bool AVIVOI2CDoLock(ScrnInfoPtr pScrn, int lock_state, int gpio_reg)
+Bool AVIVOI2CDoLock(xf86OutputPtr output, int lock_state)
 {
-    RADEONInfoPtr info = RADEONPTR(pScrn);
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONI2CBusPtr pRADEONI2CBus = radeon_output->pI2CBus->DriverPrivate.ptr;
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32 temp;
 
-    temp = INREG(gpio_reg);
-    if (gpio_reg == AVIVO_GPIO_0) {
-	if (lock_state == AVIVO_I2C_ENABLE)
-	    temp |= (1 << 19) | (1 << 18);
-	else
-	    temp &= ~((1 << 19) | (1 << 18));
-    } else {
-	if (lock_state == AVIVO_I2C_ENABLE)
-	    temp |= (1 << 0) | (1 << 8);
-	else
-	    temp &= ~((1 << 0) | (1 << 8));
-    }
-    OUTREG(gpio_reg, temp);
-    temp = INREG(gpio_reg);
-
-    return TRUE;
-}
-
-void
-avivo_i2c_gpio_get_bits(I2CBusPtr b, int *Clock, int *data)
-{
-    ScrnInfoPtr screen_info = xf86Screens[b->scrnIndex]; 
-    RADEONInfoPtr info       = RADEONPTR(screen_info);
-    unsigned char *RADEONMMIO = info->MMIO;
-    unsigned long  val;
-
-    /* Get the result */
-    if (b->DriverPrivate.uval == AVIVO_GPIO_0) {
-	val = INREG(b->DriverPrivate.uval + 0xc);
-	*Clock = (val & (1<<19)) != 0;
-	*data  = (val & (1<<18)) != 0;
-    } else {
-	val = INREG(b->DriverPrivate.uval + 0xc);
-	*Clock = (val & (1<<0)) != 0;
-	*data  = (val & (1<<8)) != 0;
-    }
-}
-
-static void
-avivo_i2c_gpio_put_bits(I2CBusPtr b, int Clock, int data)
-{
-    ScrnInfoPtr screen_info = xf86Screens[b->scrnIndex]; 
-    RADEONInfoPtr info       = RADEONPTR(screen_info);
-    unsigned char *RADEONMMIO = info->MMIO;
-    unsigned long  val;
-
-    val = 0;
-    if (b->DriverPrivate.uval == AVIVO_GPIO_0) {
-	val |= (Clock ? 0:(1<<19));
-	val |= (data ? 0:(1<<18));
-    } else {
-	val |= (Clock ? 0:(1<<0));
-	val |= (data ? 0:(1<<8));
-
-    }
-
-    OUTREG(b->DriverPrivate.uval + 0x8, val);
-    /* read back to improve reliability on some cards. */
-    val = INREG(b->DriverPrivate.uval + 0x8);
-}
-
-static Bool
-avivo_i2c_init(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name)
-{
-    I2CBusPtr pI2CBus;
-
-    pI2CBus = xf86CreateI2CBusRec();
-    if (!pI2CBus) return FALSE;
-
-    pI2CBus->BusName    = name;
-    pI2CBus->scrnIndex  = pScrn->scrnIndex;
-    pI2CBus->I2CPutBits = avivo_i2c_gpio_put_bits;
-    pI2CBus->I2CGetBits = avivo_i2c_gpio_get_bits;
-    pI2CBus->AcknTimeout = 5;
-    pI2CBus->DriverPrivate.uval = i2c_reg;
-
-    if (!xf86I2CBusInit(pI2CBus)) return FALSE;
+    temp = INREG(pRADEONI2CBus->gpio_reg);
+    if (lock_state == AVIVO_I2C_ENABLE)
+	temp |= (pRADEONI2CBus->put_clk_mask | pRADEONI2CBus->put_data_mask);
+    else
+	temp &= ~(pRADEONI2CBus->put_clk_mask | pRADEONI2CBus->put_data_mask);;
+    OUTREG(pRADEONI2CBus->gpio_reg, temp);
+    temp = INREG(pRADEONI2CBus->gpio_reg);
 
-    *bus_ptr = pI2CBus;
     return TRUE;
 }
 
@@ -1361,22 +1293,12 @@ static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data)
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned long  val;
     unsigned char *RADEONMMIO = info->MMIO;
+    RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr;
 
     /* Get the result */
-
-    if (b->DriverPrivate.uval == RADEON_LCD_GPIO_MASK) { 
-        val = INREG(b->DriverPrivate.uval+4);
-        *Clock = (val & (1<<13)) != 0;
-        *data  = (val & (1<<12)) != 0;
-    } else if (b->DriverPrivate.uval == RADEON_MDGPIO_EN_REG) {
-        val = INREG(b->DriverPrivate.uval+4);
-        *Clock = (val & (1<<19)) != 0;
-        *data  = (val & (1<<18)) != 0;
-    } else {
-        val = INREG(b->DriverPrivate.uval);
-        *Clock = (val & RADEON_GPIO_Y_1) != 0;
-        *data  = (val & RADEON_GPIO_Y_0) != 0;
-    }
+    val = INREG(pRADEONI2CBus->get_reg);
+    *Clock = (val & pRADEONI2CBus->get_clk_mask) != 0;
+    *data  = (val & pRADEONI2CBus->get_data_mask) != 0;
 }
 
 static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
@@ -1385,31 +1307,25 @@ static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned long  val;
     unsigned char *RADEONMMIO = info->MMIO;
+    RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr;
+
+    val = INREG(pRADEONI2CBus->put_reg) & (CARD32)~(pRADEONI2CBus->put_clk_mask | pRADEONI2CBus->put_data_mask);
+    val |= (Clock ? 0:pRADEONI2CBus->put_clk_mask);
+    val |= (data ? 0:pRADEONI2CBus->put_data_mask);
+    OUTREG(pRADEONI2CBus->put_reg, val);
 
-    if (b->DriverPrivate.uval == RADEON_LCD_GPIO_MASK) {
-        val = INREG(b->DriverPrivate.uval) & (CARD32)~((1<<12) | (1<<13));
-        val |= (Clock ? 0:(1<<13));
-        val |= (data ? 0:(1<<12));
-        OUTREG(b->DriverPrivate.uval, val);
-    } else if (b->DriverPrivate.uval == RADEON_MDGPIO_EN_REG) {
-        val = INREG(b->DriverPrivate.uval) & (CARD32)~((1<<18) | (1<<19));
-        val |= (Clock ? 0:(1<<19));
-        val |= (data ? 0:(1<<18));
-        OUTREG(b->DriverPrivate.uval, val);
-    } else {
-        val = INREG(b->DriverPrivate.uval) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
-        val |= (Clock ? 0:RADEON_GPIO_EN_1);
-        val |= (data ? 0:RADEON_GPIO_EN_0);
-        OUTREG(b->DriverPrivate.uval, val);
-   }
     /* read back to improve reliability on some cards. */
-    val = INREG(b->DriverPrivate.uval);
+    val = INREG(pRADEONI2CBus->put_reg);
 }
 
 static Bool
-RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name)
+RADEONI2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name, Bool dvo)
 {
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     I2CBusPtr pI2CBus;
+    RADEONI2CBusPtr pRADEONI2CBus;
 
     pI2CBus = xf86CreateI2CBusRec();
     if (!pI2CBus) return FALSE;
@@ -1419,9 +1335,62 @@ RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name)
     pI2CBus->I2CPutBits = RADEONI2CPutBits;
     pI2CBus->I2CGetBits = RADEONI2CGetBits;
     pI2CBus->AcknTimeout = 5;
-    pI2CBus->DriverPrivate.uval = i2c_reg;
 
-    if (!xf86I2CBusInit(pI2CBus)) return FALSE;
+    pRADEONI2CBus = xcalloc(sizeof(RADEONI2CBusRec), 1);
+    if (!pRADEONI2CBus) {
+	xf86DrvMsg(pScrn->scrnIndex,X_ERROR, "Failed to allocate radeon i2c bus info\n");
+	return FALSE;
+    }
+
+    if (dvo) {
+	/* these only seem to work properly on MACs */
+	pRADEONI2CBus->gpio_reg = radeon_output->dvo_i2c_reg;
+	pRADEONI2CBus->put_reg = radeon_output->dvo_i2c_reg;
+	pRADEONI2CBus->get_reg = radeon_output->dvo_i2c_reg;
+	pRADEONI2CBus->put_clk_mask = RADEON_GPIO_EN_1;
+	pRADEONI2CBus->put_data_mask = RADEON_GPIO_EN_0;
+	pRADEONI2CBus->get_clk_mask = RADEON_GPIO_Y_1;
+	pRADEONI2CBus->get_data_mask = RADEON_GPIO_Y_0;
+    } else {
+	if (IS_AVIVO_VARIANT) {
+	    pRADEONI2CBus->gpio_reg = radeon_output->ddc_line;
+	    pRADEONI2CBus->put_reg = radeon_output->ddc_line + 0x8;
+	    pRADEONI2CBus->get_reg = radeon_output->ddc_line + 0xc;
+	    /* FIXME: get these from the BIOS */
+	    if (radeon_output->ddc_line == AVIVO_GPIO_0) {
+		pRADEONI2CBus->put_clk_mask = (1 << 19);
+		pRADEONI2CBus->put_data_mask = (1 << 18);
+		pRADEONI2CBus->get_clk_mask = (1 << 19);
+		pRADEONI2CBus->get_data_mask = (1 << 18);
+	    } else {
+		pRADEONI2CBus->put_clk_mask = (1 << 0);
+		pRADEONI2CBus->put_data_mask = (1 << 8);
+		pRADEONI2CBus->get_clk_mask = (1 << 0);
+		pRADEONI2CBus->get_data_mask = (1 << 8);
+	    }
+	} else {
+	    pRADEONI2CBus->gpio_reg = radeon_output->ddc_line;
+	    pRADEONI2CBus->put_reg = radeon_output->ddc_line;
+	    pRADEONI2CBus->get_reg = radeon_output->ddc_line;
+	    if ((radeon_output->ddc_line == RADEON_LCD_GPIO_MASK) ||
+		(radeon_output->ddc_line == RADEON_MDGPIO_EN_REG)) {
+		pRADEONI2CBus->put_clk_mask = radeon_output->ddc_clk_mask;
+		pRADEONI2CBus->put_data_mask = radeon_output->ddc_data_mask;
+		pRADEONI2CBus->get_clk_mask = radeon_output->ddc_clk_mask;
+		pRADEONI2CBus->get_data_mask = radeon_output->ddc_data_mask;
+	    } else {
+		pRADEONI2CBus->put_clk_mask = RADEON_GPIO_EN_1;
+		pRADEONI2CBus->put_data_mask = RADEON_GPIO_EN_0;
+		pRADEONI2CBus->get_clk_mask = RADEON_GPIO_Y_1;
+		pRADEONI2CBus->get_data_mask = RADEON_GPIO_Y_0;
+	    }
+	}
+    }
+
+    pI2CBus->DriverPrivate.ptr = (pointer)pRADEONI2CBus;
+
+    if (!xf86I2CBusInit(pI2CBus))
+	return FALSE;
 
     *bus_ptr = pI2CBus;
     return TRUE;
@@ -1757,14 +1726,6 @@ void RADEONInitConnector(xf86OutputPtr output)
     name = xnfalloc(strlen(stmp) + 1);
     strcpy(name, stmp);
 
-    if (IS_AVIVO_VARIANT) {
-	if (radeon_output->ddc_line)
-	    avivo_i2c_init(pScrn, &radeon_output->pI2CBus, radeon_output->ddc_line, name);
-    } else {
-	if (radeon_output->ddc_line)
-	    RADEONI2CInit(pScrn, &radeon_output->pI2CBus, radeon_output->ddc_line, name);
-    }
-
     if (radeon_output->DACType == DAC_PRIMARY)
 	radeon_output->load_detection = 1; /* primary dac, only drives vga */
     /*else if (radeon_output->DACType == DAC_TVDAC &&
@@ -1784,7 +1745,7 @@ void RADEONInitConnector(xf86OutputPtr output)
     if (OUTPUT_IS_DVI) {
 	I2CBusPtr pDVOBus;
 	radeon_output->rmx_type = RMX_OFF;
-	if ((!IS_AVIVO_VARIANT) && radeon_output->TMDSType == TMDS_EXT) {
+	if ((!info->IsAtomBios) && radeon_output->TMDSType == TMDS_EXT) {
 #if defined(__powerpc__)
 	    radeon_output->dvo_i2c_reg = RADEON_GPIO_MONID;
 	    radeon_output->dvo_i2c_slave_addr = 0x70;
@@ -1794,7 +1755,7 @@ void RADEONInitConnector(xf86OutputPtr output)
 		radeon_output->dvo_i2c_slave_addr = 0x70;
 	    }
 #endif
-	    if (RADEONI2CInit(pScrn, &pDVOBus, radeon_output->dvo_i2c_reg, "DVO")) {
+	    if (RADEONI2CInit(output, &pDVOBus, "DVO", TRUE)) {
 		radeon_output->DVOChip =
 		    RADEONDVODeviceInit(pDVOBus,
 					radeon_output->dvo_i2c_slave_addr);
@@ -1815,6 +1776,9 @@ void RADEONInitConnector(xf86OutputPtr output)
 	RADEONGetTVDacAdjInfo(output);
     }
 
+    if (radeon_output->ddc_line)
+	RADEONI2CInit(output, &radeon_output->pI2CBus, name, FALSE);
+
 }
 
 #if defined(__powerpc__)
@@ -2365,6 +2329,8 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    radeon_output->ddc_line = info->BiosConnector[i].ddc_line;
 	    radeon_output->devices = info->BiosConnector[i].devices;
 	    radeon_output->output_id = info->BiosConnector[i].output_id;
+	    radeon_output->ddc_clk_mask = info->BiosConnector[i].ddc_clk_mask;
+	    radeon_output->ddc_data_mask = info->BiosConnector[i].ddc_data_mask;
 
 	    if (radeon_output->ConnectorType == CONNECTOR_DVI_D)
 		radeon_output->DACType = DAC_NONE;
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index dd75d2c..d24d8ed 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -160,6 +160,17 @@ typedef enum
     TV_STD_PAL_CN    = 128,
 } TVStd;
 
+typedef struct
+{
+    CARD32 gpio_reg;
+    CARD32 put_reg;
+    CARD32 get_reg;
+    CARD32 put_clk_mask;
+    CARD32 put_data_mask;
+    CARD32 get_clk_mask;
+    CARD32 get_data_mask;
+} RADEONI2CBusRec, *RADEONI2CBusPtr;
+
 typedef struct _RADEONCrtcPrivateRec {
 #ifdef USE_XAA
     FBLinearPtr rotate_mem_xaa;
@@ -191,6 +202,8 @@ typedef struct {
     int output_id;
     int devices;
     int hpd_mask;
+    CARD32 ddc_clk_mask;
+    CARD32 ddc_data_mask;
 } RADEONBIOSConnector;
 
 typedef struct _RADEONOutputPrivateRec {
@@ -239,6 +252,9 @@ typedef struct _RADEONOutputPrivateRec {
     Bool              tv_on;
     int               load_detection;
 
+    CARD32            ddc_clk_mask;
+    CARD32            ddc_data_mask;
+
     char              *name;
     int               output_id;
     int               devices;
commit a43003b24022a833e604f41b2873c0350b34181c
Author: Alex Deucher <alex at botch2.(none)>
Date:   Sat Jan 19 18:49:53 2008 -0500

    RADEON: get dac2 adj values from the bios tables

diff --git a/src/legacy_output.c b/src/legacy_output.c
index db128ca..d2d0de6 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -1126,7 +1126,7 @@ RADEONInitTvDacCntl(xf86OutputPtr output, RADEONSavePtr save)
     save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
 			  RADEON_TV_DAC_NHOLD |
 			  RADEON_TV_DAC_STD_PS2 |
-			  radeon_output->tv_dac_adj);
+			  radeon_output->ps2_tvdac_adj);
 
 }
 
diff --git a/src/radeon.h b/src/radeon.h
index 2a3838c..d538196 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -811,6 +811,7 @@ extern Bool        RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn);
 extern Bool        RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output);
 extern Bool        RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output);
 extern Bool        RADEONGetTVInfoFromBIOS (xf86OutputPtr output);
+extern Bool        RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output);
 extern Bool        RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output);
 
 extern void        RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index f928eb4..829a641 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -595,6 +595,58 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn)
     return TRUE;
 }
 
+Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int offset, rev, bg, dac;
+
+    if (!info->VBIOS) return FALSE;
+
+    if (info->IsAtomBios) {
+	/* not implemented yet */
+	return FALSE;
+    } else {
+	/* first check TV table */
+	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x32);
+        if (offset) {
+	    rev = RADEON_BIOS8(offset + 0x3);
+	    if (rev > 1) {
+		bg = RADEON_BIOS8(offset + 0xc) & 0xf;
+		dac = (RADEON_BIOS8(offset + 0xc) >> 4) & 0xf;
+		radeon_output->ps2_tvdac_adj = (bg << 16) | (dac << 20);
+
+		bg = RADEON_BIOS8(offset + 0xd) & 0xf;
+		dac = (RADEON_BIOS8(offset + 0xd) >> 4) & 0xf;
+		radeon_output->pal_tvdac_adj = (bg << 16) | (dac << 20);
+
+		bg = RADEON_BIOS8(offset + 0xe) & 0xf;
+		dac = (RADEON_BIOS8(offset + 0xe) >> 4) & 0xf;
+		radeon_output->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
+
+		return TRUE;
+	    }
+	}
+	/* then check CRT table */
+	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x60);
+        if (offset) {
+	    rev = RADEON_BIOS8(offset) & 0x3;
+	    if (rev < 2) {
+		bg = RADEON_BIOS8(offset + 0x3) & 0xf;
+		dac = (RADEON_BIOS8(offset + 0x3) >> 4) & 0xf;
+		radeon_output->ps2_tvdac_adj = (bg << 16) | (dac << 20);
+		radeon_output->pal_tvdac_adj = radeon_output->ps2_tvdac_adj;
+		radeon_output->ntsc_tvdac_adj = radeon_output->ps2_tvdac_adj;
+
+		return TRUE;
+	    }
+	}
+    }
+
+    return FALSE;
+}
+
 Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 367d0a6..8fc6bc6 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1734,12 +1734,16 @@ RADEONGetTVDacAdjInfo(xf86OutputPtr output)
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
-    /* Todo: get this setting from BIOS */
-    radeon_output->tv_dac_adj = default_tvdac_adj[info->ChipFamily];
-    if (info->IsMobility) { /* some mobility chips may different */
-	if (info->ChipFamily == CHIP_FAMILY_RV250)
-	    radeon_output->tv_dac_adj = 0x00880000;
+    if (!RADEONGetDAC2InfoFromBIOS(output)) {
+	radeon_output->ps2_tvdac_adj = default_tvdac_adj[info->ChipFamily];
+	if (info->IsMobility) { /* some mobility chips may different */
+	    if (info->ChipFamily == CHIP_FAMILY_RV250)
+		radeon_output->ps2_tvdac_adj = 0x00880000;
+	}
+	radeon_output->pal_tvdac_adj = radeon_output->ps2_tvdac_adj;
+	radeon_output->ntsc_tvdac_adj = radeon_output->ps2_tvdac_adj;
     }
+
 }
 
 void RADEONInitConnector(xf86OutputPtr output)
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 17c0f1b..dd75d2c 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -206,7 +206,9 @@ typedef struct _RADEONOutputPrivateRec {
     int crtc_num;
     int DDCReg;
     I2CBusPtr         pI2CBus;
-    CARD32            tv_dac_adj;
+    CARD32            ps2_tvdac_adj;
+    CARD32            pal_tvdac_adj;
+    CARD32            ntsc_tvdac_adj;
     /* panel stuff */
     int               PanelXRes;
     int               PanelYRes;
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 51f21d0..d5d1e9e 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -841,9 +841,15 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
     tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;
     save->tv_timing_cntl = tmp;
 
-    save->tv_dac_cntl = (RADEON_TV_DAC_NBLANK |
-			 RADEON_TV_DAC_NHOLD |
-			 radeon_output->tv_dac_adj /*(8 << 16) | (6 << 20)*/);
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+        radeon_output->tvStd == TV_STD_NTSC_J ||
+        radeon_output->tvStd == TV_STD_PAL_M ||
+        radeon_output->tvStd == TV_STD_PAL_60)
+	save->tv_dac_cntl = radeon_output->ntsc_tvdac_adj;
+    else
+	save->tv_dac_cntl = radeon_output->pal_tvdac_adj;
+
+    save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
 
     if (radeon_output->tvStd == TV_STD_NTSC ||
 	radeon_output->tvStd == TV_STD_NTSC_J)
commit d4596c52ac9994be26e9ec2d7d57b3892c34abdb
Author: Alex Deucher <alex at botch2.(none)>
Date:   Sat Jan 19 17:17:26 2008 -0500

    RADEON: grab pll_in_min/pll_in_max from bios tables if available

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 92a4927..f928eb4 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -556,18 +556,26 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn)
 	    info->sclk = RADEON_BIOS32(pll_info_block + 8) / 100.0;
 	    info->mclk = RADEON_BIOS32(pll_info_block + 12) / 100.0;
 	} else {
+	    int rev;
+
 	    pll_info_block = RADEON_BIOS16 (info->ROMHeaderStart + 0x30);
 
+	    rev = RADEON_BIOS8(pll_info_block);
+
 	    pll->reference_freq = RADEON_BIOS16 (pll_info_block + 0x0e);
 	    pll->reference_div = RADEON_BIOS16 (pll_info_block + 0x10);
 	    pll->pll_out_min = RADEON_BIOS32 (pll_info_block + 0x12);
 	    pll->pll_out_max = RADEON_BIOS32 (pll_info_block + 0x16);
 
-	    /* not available in the bios */
-	    pll->pll_in_min = 40;
-	    pll->pll_in_max = 500;
+	    if (rev > 9) {
+		pll->pll_in_min = RADEON_BIOS32(pll_info_block + 0x36);
+		pll->pll_in_max = RADEON_BIOS32(pll_info_block + 0x3a);
+	    } else {
+		pll->pll_in_min = 40;
+		pll->pll_in_max = 500;
+	    }
 
-	    pll->xclk = RADEON_BIOS16 (pll_info_block + 0x08);
+	    pll->xclk = RADEON_BIOS16(pll_info_block + 0x08);
 
 	    info->sclk = RADEON_BIOS16(pll_info_block + 8) / 100.0;
 	    info->mclk = RADEON_BIOS16(pll_info_block + 10) / 100.0;
@@ -577,11 +585,12 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn)
 	if (info->mclk == 0) info->mclk = 200;
     }
 
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ref_freq: %d, min_pll: %u, "
-	       "max_pll: %u, xclk: %d, sclk: %f, mclk: %f\n",
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ref_freq: %d, min_out_pll: %u, "
+	       "max_out_pll: %u, min_in_pll: %u, max_in_pll: %u, xclk: %d, "
+	       "sclk: %f, mclk: %f\n",
 	       pll->reference_freq, (unsigned)pll->pll_out_min,
-	       (unsigned)pll->pll_out_max, pll->xclk, info->sclk,
-	       info->mclk);
+	       (unsigned)pll->pll_out_max, (unsigned)pll->pll_in_min,
+	       (unsigned)pll->pll_in_max, pll->xclk, info->sclk, info->mclk);
 
     return TRUE;
 }


More information about the xorg-commit mailing list