summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-04-23 14:06:06 -0400
committerAlex Deucher <alexdeucher@gmail.com>2009-05-08 12:07:28 -0400
commitdb375c70a00865976ddb3b32bb4b25113735bf1e (patch)
tree68ca4660fd2b66bfd2f09f8adb99bf75c5cb7090
parent0ea75453eaa5bb41bf12666d454a203ee1481461 (diff)
r2xx/r3xx/r4xx: further i2c fixups
- hw i2c engine has pin selection on r2xx/r2xx/r3xx chips - also switch hw i2c pin sel for external tmds
-rw-r--r--src/legacy_output.c11
-rw-r--r--src/radeon.h2
-rw-r--r--src/radeon_output.c31
-rw-r--r--src/radeon_probe.h1
-rw-r--r--src/radeon_reg.h32
5 files changed, 41 insertions, 36 deletions
diff --git a/src/legacy_output.c b/src/legacy_output.c
index 423a3e27..7134ee15 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -150,7 +150,6 @@ void
RADEONGetExtTMDSInfo(ScrnInfoPtr pScrn, radeon_dvo_ptr dvo)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- I2CBusPtr pDVOBus;
if (!info->IsAtomBios) {
#if defined(__powerpc__)
@@ -162,11 +161,11 @@ RADEONGetExtTMDSInfo(ScrnInfoPtr pScrn, radeon_dvo_ptr dvo)
dvo->dvo_i2c_slave_addr = 0x70;
}
#endif
- if (RADEONI2CInit(pScrn, &pDVOBus, "DVO", &dvo->dvo_i2c)) {
+ if (RADEONI2CInit(pScrn, &dvo->pI2CBus, "DVO", &dvo->dvo_i2c)) {
dvo->DVOChip =
- RADEONDVODeviceInit(pDVOBus, dvo->dvo_i2c_slave_addr);
+ RADEONDVODeviceInit(dvo->pI2CBus, dvo->dvo_i2c_slave_addr);
if (!dvo->DVOChip)
- xfree(pDVOBus);
+ xfree(dvo->pI2CBus);
}
}
}
@@ -481,7 +480,7 @@ RADEONRestoreDVOChip(ScrnInfoPtr pScrn, xf86OutputPtr output)
if (!dvo->DVOChip)
return;
- RADEONI2CDoLock(output, TRUE);
+ RADEONI2CDoLock(output, dvo->pI2CBus, TRUE);
if (!RADEONInitExtTMDSInfoFromBIOS(output)) {
if (dvo->DVOChip) {
switch(info->ext_tmds_chip) {
@@ -511,7 +510,7 @@ RADEONRestoreDVOChip(ScrnInfoPtr pScrn, xf86OutputPtr output)
}
}
}
- RADEONI2CDoLock(output, FALSE);
+ RADEONI2CDoLock(output, dvo->pI2CBus, FALSE);
}
#if 0
diff --git a/src/radeon.h b/src/radeon.h
index d56d94df..c9237933 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -1114,7 +1114,7 @@ extern void RADEONPrintPortMap(ScrnInfoPtr pScrn);
extern void RADEONSetOutputType(ScrnInfoPtr pScrn,
RADEONOutputPrivatePtr radeon_output);
extern Bool RADEONSetupConnectors(ScrnInfoPtr pScrn);
-extern Bool RADEONI2CDoLock(xf86OutputPtr output, Bool lock_state);
+extern Bool RADEONI2CDoLock(xf86OutputPtr output, I2CBusPtr b, Bool lock_state);
/* radeon_tv.c */
diff --git a/src/radeon_output.c b/src/radeon_output.c
index e545c79c..67d94feb 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -217,24 +217,14 @@ radeon_ddc_connected(xf86OutputPtr output)
RADEONMonitorType MonType = MT_NONE;
xf86MonPtr MonInfo = NULL;
RADEONOutputPrivatePtr radeon_output = output->driver_private;
- unsigned char *RADEONMMIO = info->MMIO;
if (radeon_output->pI2CBus) {
- /* RV410 appears to have a bug where the hw i2c in reset
- * holds the i2c port in a bad state - switch hw i2c away before
- * doing DDC - do this for all r300s for safety sakes */
- if (IS_R300_VARIANT) {
- if (radeon_output->ddc_i2c.mask_clk_reg == RADEON_GPIO_VGA_DDC)
- OUTREG(RADEON_DVI_I2C_CNTL_0, 0x30);
- else
- OUTREG(RADEON_DVI_I2C_CNTL_0, 0x20);
- }
if (info->get_hardcoded_edid_from_bios)
MonInfo = RADEONGetHardCodedEDIDFromBIOS(output);
if (MonInfo == NULL) {
- RADEONI2CDoLock(output, TRUE);
+ RADEONI2CDoLock(output, radeon_output->pI2CBus, TRUE);
MonInfo = xf86OutputGetEDID(output, radeon_output->pI2CBus);
- RADEONI2CDoLock(output, FALSE);
+ RADEONI2CDoLock(output, radeon_output->pI2CBus, FALSE);
}
}
if (MonInfo) {
@@ -1653,16 +1643,27 @@ static const xf86OutputFuncsRec radeon_output_funcs = {
};
Bool
-RADEONI2CDoLock(xf86OutputPtr output, int lock_state)
+RADEONI2CDoLock(xf86OutputPtr output, I2CBusPtr b, int lock_state)
{
ScrnInfoPtr pScrn = output->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
- RADEONI2CBusPtr pRADEONI2CBus = radeon_output->pI2CBus->DriverPrivate.ptr;
+ RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr;
unsigned char *RADEONMMIO = info->MMIO;
uint32_t temp;
if (lock_state) {
+ /* RV410 appears to have a bug where the hw i2c in reset
+ * holds the i2c port in a bad state - switch hw i2c away before
+ * doing DDC - do this for all r200s/r300s for safety sakes */
+ if ((info->ChipFamily >= CHIP_FAMILY_R200) && (!IS_AVIVO_VARIANT)) {
+ if (pRADEONI2CBus->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
+ OUTREG(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
+ R200_DVI_I2C_PIN_SEL(R200_SEL_DVI_DDC)));
+ else
+ OUTREG(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST |
+ R200_DVI_I2C_PIN_SEL(R200_SEL_CRT2_DDC)));
+ }
+
temp = INREG(pRADEONI2CBus->a_clk_reg);
temp &= ~(pRADEONI2CBus->a_clk_mask);
OUTREG(pRADEONI2CBus->a_clk_reg, temp);
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 64799729..3e4f47c3 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -216,6 +216,7 @@ typedef struct _radeon_lvds {
typedef struct _radeon_dvo {
/* dvo */
+ I2CBusPtr pI2CBus;
I2CDevPtr DVOChip;
RADEONI2CBusRec dvo_i2c;
int dvo_i2c_slave_addr;
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index d74a30a4..c0d34d1b 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -979,24 +979,28 @@
/* Multimedia I2C bus */
#define RADEON_I2C_CNTL_0 0x0090
-#define RADEON_I2C_DONE (1<<0)
-#define RADEON_I2C_NACK (1<<1)
-#define RADEON_I2C_HALT (1<<2)
-#define RADEON_I2C_SOFT_RST (1<<5)
-#define RADEON_I2C_DRIVE_EN (1<<6)
-#define RADEON_I2C_DRIVE_SEL (1<<7)
-#define RADEON_I2C_START (1<<8)
-#define RADEON_I2C_STOP (1<<9)
-#define RADEON_I2C_RECEIVE (1<<10)
-#define RADEON_I2C_ABORT (1<<11)
-#define RADEON_I2C_GO (1<<12)
+#define RADEON_I2C_DONE (1 << 0)
+#define RADEON_I2C_NACK (1 << 1)
+#define RADEON_I2C_HALT (1 << 2)
+#define RADEON_I2C_SOFT_RST (1 << 5)
+#define RADEON_I2C_DRIVE_EN (1 << 6)
+#define RADEON_I2C_DRIVE_SEL (1 << 7)
+#define RADEON_I2C_START (1 << 8)
+#define RADEON_I2C_STOP (1 << 9)
+#define RADEON_I2C_RECEIVE (1 << 10)
+#define RADEON_I2C_ABORT (1 << 11)
+#define RADEON_I2C_GO (1 << 12)
#define RADEON_I2C_CNTL_1 0x0094
-#define RADEON_I2C_SEL (1<<16)
-#define RADEON_I2C_EN (1<<17)
+#define RADEON_I2C_SEL (1 << 16)
+#define RADEON_I2C_EN (1 << 17)
#define RADEON_I2C_DATA 0x0098
#define RADEON_DVI_I2C_CNTL_0 0x02e0
-#define RADEON_DVI_I2C_CNTL_1 0x02e4 /* ? */
+# define R200_DVI_I2C_PIN_SEL(x) ((x) << 3)
+# define R200_SEL_DVI_DDC 0
+# define R200_SEL_VGA_DDC 1
+# define R200_SEL_CRT2_DDC 2
+#define RADEON_DVI_I2C_CNTL_1 0x02e4
#define RADEON_DVI_I2C_DATA 0x02e8
#define RADEON_INTERRUPT_LINE 0x0f3c /* PCI */