xf86-video-ati: Branch 'master'

Alex Deucher agd5f at kemper.freedesktop.org
Fri Oct 3 12:29:45 PDT 2008


 src/radeon_atombios.c |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/radeon_atombios.h |    3 ++
 src/radeon_driver.c   |    2 -
 src/radeon_output.c   |   19 +++++++++++++---
 src/radeon_probe.h    |    2 +
 5 files changed, 80 insertions(+), 4 deletions(-)

New commits:
commit f9826a5694b7adb6920eb5bdf45d840d8fb14d53
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Fri Oct 3 15:24:12 2008 -0400

    Add support for DDC via atom commands for RV410
    
    The atom calls use the hw i2c engine for DDC.  For some
    reason, sw i2c doesn't seem to work on the VGA GPIO on
    RV410 chips, so we use atom in that case.
    
    This fixes the longstanding VGA DDC problems on RV410/M26
    chips.

diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index b81d2cb..12aeeca 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -1386,6 +1386,58 @@ const int object_connector_convert[] =
       CONNECTOR_DISPLAY_PORT,
     };
 
+xf86MonPtr radeon_atom_get_edid(xf86OutputPtr output)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    READ_EDID_FROM_HW_I2C_DATA_PS_ALLOCATION edid_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+    int i2c_clock = 50;
+    int engine_clk = info->sclk * 100;
+    int prescale;
+    unsigned char *edid;
+    xf86MonPtr mon = NULL;
+
+    if (!radeon_output->ddc_i2c.hw_capable)
+	return mon;
+
+    if (info->atomBIOS->fbBase)
+	edid = (unsigned char *)info->FB + info->atomBIOS->fbBase;
+    else if (info->atomBIOS->scratchBase)
+	edid = (unsigned char *)info->atomBIOS->scratchBase;
+    else
+	return mon;
+
+    memset(edid, 0, ATOM_EDID_RAW_DATASIZE);
+
+    if (info->ChipFamily == CHIP_FAMILY_R520)
+	prescale = (127 << 8) + (engine_clk * 10) / (4 * 127 * i2c_clock);
+    else if (info->ChipFamily < CHIP_FAMILY_R600)
+	prescale = (((engine_clk * 10)/(4 * 128 * 100) + 1) << 8) + 128;
+    else
+	prescale = (info->pll.reference_freq * 10) / i2c_clock;
+
+    edid_data.usPrescale = prescale;
+    edid_data.usVRAMAddress = 0;
+    edid_data.ucSlaveAddr = 0xa0;
+    edid_data.ucLineNumber = radeon_output->ddc_i2c.hw_line;
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, ReadEDIDFromHWAssistedI2C);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &edid_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS)
+	ErrorF("Atom Get EDID success\n");
+    else
+	ErrorF("Atom Get EDID failed\n");
+
+    if (edid[1] == 0xff)
+	mon = xf86InterpretEDID(output->scrn->scrnIndex, edid);
+
+    return mon;
+
+}
 
 static RADEONI2CBusRec
 RADEONLookupGPIOLineForDDC(ScrnInfoPtr pScrn, uint8_t id)
@@ -1425,9 +1477,15 @@ RADEONLookupGPIOLineForDDC(ScrnInfoPtr pScrn, uint8_t id)
     i2c.get_data_mask = (1 <<  gpio.ucDataY_Shift);
     i2c.a_clk_mask = (1 << gpio.ucClkA_Shift);
     i2c.a_data_mask = (1 <<  gpio.ucDataA_Shift);
+    i2c.hw_line = gpio.sucI2cId.sbfAccess.bfI2C_LineMux;
+    i2c.hw_capable = gpio.sucI2cId.sbfAccess.bfHW_Capable;
     i2c.valid = TRUE;
 
 #if 0
+    ErrorF("id: %d\n", id);
+    ErrorF("hw capable: %d\n", gpio.sucI2cId.sbfAccess.bfHW_Capable);
+    ErrorF("hw engine id: %d\n", gpio.sucI2cId.sbfAccess.bfHW_EngineID);
+    ErrorF("line mux %d\n", gpio.sucI2cId.sbfAccess.bfI2C_LineMux);
     ErrorF("mask_clk_reg: 0x%x\n", gpio.usClkMaskRegisterIndex * 4);
     ErrorF("mask_data_reg: 0x%x\n", gpio.usDataMaskRegisterIndex * 4);
     ErrorF("put_clk_reg: 0x%x\n", gpio.usClkEnRegisterIndex * 4);
diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h
index fe7044d..1ec0e2d 100644
--- a/src/radeon_atombios.h
+++ b/src/radeon_atombios.h
@@ -131,6 +131,9 @@ atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode);
 extern void
 atombios_get_command_table_version(atomBiosHandlePtr atomBIOS, int index, int *major, int *minor);
 
+extern xf86MonPtr
+radeon_atom_get_edid(xf86OutputPtr output);
+
 Bool
 rhdAtomASICInit(atomBiosHandlePtr handle);
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index eac07d0..c759bd6 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -498,7 +498,7 @@ static Bool RADEONUnmapMem(ScrnInfoPtr pScrn)
 void RADEONPllErrataAfterIndex(RADEONInfoPtr info)
 {
     unsigned char *RADEONMMIO = info->MMIO;
-	
+
     if (!(info->ChipErrata & CHIP_ERRATA_PLL_DUMMYREADS))
 	return;
 
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 2cc38a5..4947478 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -222,9 +222,18 @@ radeon_ddc_connected(xf86OutputPtr output)
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
     if (radeon_output->pI2CBus) {
-	RADEONI2CDoLock(output, TRUE);
-	MonInfo = xf86OutputGetEDID(output, radeon_output->pI2CBus);
-	RADEONI2CDoLock(output, FALSE);
+	/* RV410 RADEON_GPIO_VGA_DDC seems to only work via hw i2c
+	 * We may want to extend this to other cases if the need arises...
+	 */
+	if ((info->ChipFamily == CHIP_FAMILY_RV410) &&
+	    (radeon_output->ddc_i2c.mask_clk_reg == RADEON_GPIO_VGA_DDC) &&
+	    info->IsAtomBios)
+	    MonInfo = radeon_atom_get_edid(output);
+	else {
+	    RADEONI2CDoLock(output, TRUE);
+	    MonInfo = xf86OutputGetEDID(output, radeon_output->pI2CBus);
+	    RADEONI2CDoLock(output, FALSE);
+	}
     }
     if (MonInfo) {
 	if (!xf86ReturnOptValBool(info->Options, OPTION_IGNORE_EDID, FALSE))
@@ -1732,6 +1741,8 @@ legacy_setup_i2c_bus(int ddc_line)
 {
     RADEONI2CBusRec i2c;
 
+    i2c.hw_line = 0;
+    i2c.hw_capable = FALSE;
     i2c.mask_clk_mask = RADEON_GPIO_EN_1;
     i2c.mask_data_mask = RADEON_GPIO_EN_0;
     i2c.a_clk_mask = RADEON_GPIO_A_1;
@@ -1774,6 +1785,8 @@ atom_setup_i2c_bus(int ddc_line)
 {
     RADEONI2CBusRec i2c;
 
+    i2c.hw_line = 0;
+    i2c.hw_capable = FALSE;
     if (ddc_line == AVIVO_GPIO_0) {
 	i2c.put_clk_mask = (1 << 19);
 	i2c.put_data_mask = (1 << 18);
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index ce4ba93..83b3428 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -180,6 +180,8 @@ typedef struct
     uint32_t get_data_mask;
     uint32_t a_clk_mask;
     uint32_t a_data_mask;
+    int hw_line;
+    Bool hw_capable;
 } RADEONI2CBusRec, *RADEONI2CBusPtr;
 
 typedef struct _RADEONCrtcPrivateRec {


More information about the xorg-commit mailing list