summaryrefslogtreecommitdiff
path: root/driver/xf86-video-ati/src/radeon_bios.c
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2009-08-25 18:51:46 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2009-08-25 18:51:46 +0000
commit269f87e08fd080a8849c7bbadaedbf53ba1186c3 (patch)
treea30cd6e744358b3167711a0f9b63963b82914266 /driver/xf86-video-ati/src/radeon_bios.c
parent94721b7febf9ff5092d1d32a3e378ceaaf294b89 (diff)
update do xf86-video-ati 6.12.2
This has been in snapshots for weeks. ok oga@, todd@.
Diffstat (limited to 'driver/xf86-video-ati/src/radeon_bios.c')
-rw-r--r--driver/xf86-video-ati/src/radeon_bios.c839
1 files changed, 567 insertions, 272 deletions
diff --git a/driver/xf86-video-ati/src/radeon_bios.c b/driver/xf86-video-ati/src/radeon_bios.c
index 529dda7f3..9b5cb88ae 100644
--- a/driver/xf86-video-ati/src/radeon_bios.c
+++ b/driver/xf86-video-ati/src/radeon_bios.c
@@ -98,7 +98,7 @@ radeon_read_bios(ScrnInfoPtr pScrn)
}
static Bool
-radeon_read_unposted_bios(ScrnInfoPtr pScrn)
+radeon_read_disabled_bios(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
@@ -266,6 +266,26 @@ radeon_read_unposted_bios(ScrnInfoPtr pScrn)
return ret;
}
+Bool
+radeon_card_posted(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ uint32_t reg;
+
+ if (IS_AVIVO_VARIANT) {
+ reg = INREG(AVIVO_D1CRTC_CONTROL) | INREG(AVIVO_D2CRTC_CONTROL);
+ if (reg & AVIVO_CRTC_EN)
+ return TRUE;
+ } else {
+ reg = INREG(RADEON_CRTC_GEN_CNTL) | INREG(RADEON_CRTC2_GEN_CNTL);
+ if (reg & RADEON_CRTC_EN)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/* Read the Video BIOS block and the FP registers (if applicable). */
Bool
RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
@@ -289,9 +309,8 @@ RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
info->BIOSAddr = pInt10->BIOSseg << 4;
(void)memcpy(info->VBIOS, xf86int10Addr(pInt10, info->BIOSAddr),
RADEON_VBIOS_SIZE);
- } else if (!radeon_read_bios(pScrn)) {
- (void)radeon_read_unposted_bios(pScrn);
- }
+ } else if (!radeon_read_bios(pScrn))
+ (void)radeon_read_disabled_bios(pScrn);
}
if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
@@ -326,7 +345,7 @@ RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
info->VBIOS = NULL;
return FALSE;
}
-
+
tmp = info->ROMHeaderStart + 4;
if ((RADEON_BIOS8(tmp) == 'A' &&
RADEON_BIOS8(tmp+1) == 'T' &&
@@ -344,51 +363,62 @@ RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
info->IsAtomBios ? "ATOM":"Legacy");
if (info->IsAtomBios) {
- AtomBiosArgRec atomBiosArg;
+ AtomBiosArgRec atomBiosArg;
- if (RHDAtomBiosFunc(pScrn->scrnIndex, NULL, ATOMBIOS_INIT, &atomBiosArg)
- == ATOM_SUCCESS) {
- info->atomBIOS = atomBiosArg.atomhandle;
- }
+ if (RHDAtomBiosFunc(pScrn->scrnIndex, NULL, ATOMBIOS_INIT, &atomBiosArg)
+ == ATOM_SUCCESS) {
+ info->atomBIOS = atomBiosArg.atomhandle;
+ }
- atomBiosArg.fb.start = info->FbFreeStart;
- atomBiosArg.fb.size = info->FbFreeSize;
- if (RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS, ATOMBIOS_ALLOCATE_FB_SCRATCH,
+ atomBiosArg.fb.start = info->FbFreeStart;
+ atomBiosArg.fb.size = info->FbFreeSize;
+ if (RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS, ATOMBIOS_ALLOCATE_FB_SCRATCH,
&atomBiosArg) == ATOM_SUCCESS) {
info->FbFreeStart = atomBiosArg.fb.start;
info->FbFreeSize = atomBiosArg.fb.size;
- }
-
- RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS, GET_DEFAULT_ENGINE_CLOCK,
- &atomBiosArg);
- RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS, GET_DEFAULT_MEMORY_CLOCK,
- &atomBiosArg);
- RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
- GET_MAX_PIXEL_CLOCK_PLL_OUTPUT, &atomBiosArg);
- RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
- GET_MIN_PIXEL_CLOCK_PLL_OUTPUT, &atomBiosArg);
- RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
- GET_MAX_PIXEL_CLOCK_PLL_INPUT, &atomBiosArg);
- RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
+ }
+
+ RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS, GET_DEFAULT_ENGINE_CLOCK,
+ &atomBiosArg);
+ RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS, GET_DEFAULT_MEMORY_CLOCK,
+ &atomBiosArg);
+ RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
+ GET_MAX_PIXEL_CLOCK_PLL_OUTPUT, &atomBiosArg);
+ RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
+ GET_MIN_PIXEL_CLOCK_PLL_OUTPUT, &atomBiosArg);
+ RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
+ GET_MAX_PIXEL_CLOCK_PLL_INPUT, &atomBiosArg);
+ RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
GET_MIN_PIXEL_CLOCK_PLL_INPUT, &atomBiosArg);
- RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
+ RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
GET_MAX_PIXEL_CLK, &atomBiosArg);
- RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
- GET_REF_CLOCK, &atomBiosArg);
+ RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
+ GET_REF_CLOCK, &atomBiosArg);
info->MasterDataStart = RADEON_BIOS16 (info->ROMHeaderStart + 32);
}
+
+ /* We are a bit too quick at using this "unposted" to re-post the
+ * card. This causes some problems with VT switch on some machines,
+ * so let's work around this for now by only POSTing if none of the
+ * CRTCs are enabled
+ */
+ if ((!radeon_card_posted(pScrn)) && info->VBIOS) {
+ if (info->IsAtomBios) {
+ if (!rhdAtomASICInit(info->atomBIOS))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "%s: AsicInit failed.\n",__func__);
+ } else {
#if 0
- else {
- /* non-primary card may need posting */
- if (!pInt10) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Attempting to POST via BIOS tables\n");
+ /* FIX ME */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Attempting to POST via legacy BIOS tables\n");
RADEONGetBIOSInitTableOffsets(pScrn);
RADEONPostCardFromBIOSTables(pScrn);
+#endif
}
}
-#endif
+
return TRUE;
}
@@ -397,7 +427,7 @@ static Bool RADEONGetATOMConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
RADEONInfoPtr info = RADEONPTR (pScrn);
if (!info->VBIOS) return FALSE;
-
+
if (RADEONGetATOMConnectorInfoFromBIOSObject(pScrn))
return TRUE;
@@ -411,28 +441,31 @@ static void RADEONApplyLegacyQuirks(ScrnInfoPtr pScrn, int index)
{
RADEONInfoPtr info = RADEONPTR (pScrn);
- /* on XPRESS chips, CRT2_DDC and MONID_DCC both use the
- * MONID gpio, but use different pins.
- * CRT2_DDC uses the standard pinout, MONID_DDC uses
- * something else.
- */
+ /* XPRESS DDC quirks */
if ((info->ChipFamily == CHIP_FAMILY_RS400 ||
info->ChipFamily == CHIP_FAMILY_RS480) &&
- info->BiosConnector[index].ConnectorType == CONNECTOR_VGA &&
info->BiosConnector[index].ddc_i2c.mask_clk_reg == RADEON_GPIO_CRT2_DDC) {
info->BiosConnector[index].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
- }
-
- /* XPRESS desktop chips seem to have a proprietary connector listed for
- * DVI-D, try and do the right thing here.
- */
- if ((!info->IsMobility) &&
- (info->BiosConnector[index].ConnectorType == CONNECTOR_LVDS)) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Proprietary connector found, assuming DVI-D\n");
- info->BiosConnector[index].DACType = DAC_NONE;
- info->BiosConnector[index].TMDSType = TMDS_EXT;
- info->BiosConnector[index].ConnectorType = CONNECTOR_DVI_D;
+ } else if ((info->ChipFamily == CHIP_FAMILY_RS400 ||
+ info->ChipFamily == CHIP_FAMILY_RS480) &&
+ info->BiosConnector[index].ddc_i2c.mask_clk_reg == RADEON_GPIO_MONID) {
+ info->BiosConnector[index].ddc_i2c.valid = TRUE;
+ info->BiosConnector[index].ddc_i2c.mask_clk_mask = (0x20 << 8);
+ info->BiosConnector[index].ddc_i2c.mask_data_mask = 0x80;
+ info->BiosConnector[index].ddc_i2c.a_clk_mask = (0x20 << 8);
+ info->BiosConnector[index].ddc_i2c.a_data_mask = 0x80;
+ info->BiosConnector[index].ddc_i2c.put_clk_mask = (0x20 << 8);
+ info->BiosConnector[index].ddc_i2c.put_data_mask = 0x80;
+ info->BiosConnector[index].ddc_i2c.get_clk_mask = (0x20 << 8);
+ info->BiosConnector[index].ddc_i2c.get_data_mask = 0x80;
+ info->BiosConnector[index].ddc_i2c.mask_clk_reg = RADEON_GPIOPAD_MASK;
+ info->BiosConnector[index].ddc_i2c.mask_data_reg = RADEON_GPIOPAD_MASK;
+ info->BiosConnector[index].ddc_i2c.a_clk_reg = RADEON_GPIOPAD_A;
+ info->BiosConnector[index].ddc_i2c.a_data_reg = RADEON_GPIOPAD_A;
+ info->BiosConnector[index].ddc_i2c.put_clk_reg = RADEON_GPIOPAD_EN;
+ info->BiosConnector[index].ddc_i2c.put_data_reg = RADEON_GPIOPAD_EN;
+ info->BiosConnector[index].ddc_i2c.get_clk_reg = RADEON_LCD_GPIO_Y_REG;
+ info->BiosConnector[index].ddc_i2c.get_data_reg = RADEON_LCD_GPIO_Y_REG;
}
/* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
@@ -454,6 +487,26 @@ static void RADEONApplyLegacyQuirks(ScrnInfoPtr pScrn, int index)
}
}
+ /* X300 card with extra non-existent DVI port */
+ if (info->Chipset == PCI_CHIP_RV370_5B60 &&
+ PCI_SUB_VENDOR_ID(info->PciInfo) == 0x17af &&
+ PCI_SUB_DEVICE_ID(info->PciInfo) == 0x201e &&
+ index == 2) {
+ if (info->BiosConnector[index].ConnectorType == CONNECTOR_DVI_I) {
+ info->BiosConnector[index].valid = FALSE;
+ }
+ }
+
+ /* r200 card with primary dac routed to both VGA and DVI - disable load detection
+ * otherwise you end up detecing load if either port is attached
+ */
+ if (info->Chipset == PCI_CHIP_R200_QL &&
+ PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1569 &&
+ PCI_SUB_DEVICE_ID(info->PciInfo) == 0x514c &&
+ (info->BiosConnector[index].devices & ATOM_DEVICE_CRT1_SUPPORT)) {
+ info->BiosConnector[index].load_detection = FALSE;
+ }
+
}
static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
@@ -479,22 +532,127 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
ConnectorType = (tmp >> 12) & 0xf;
switch (ConnectorType) {
case CONNECTOR_PROPRIETARY_LEGACY:
- info->BiosConnector[i].ConnectorType = CONNECTOR_LVDS;
+ info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_D;
+ if ((tmp >> 4) & 0x1) {
+ info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_DFP2_SUPPORT,
+ 0),
+ ATOM_DEVICE_DFP2_SUPPORT))
+ return FALSE;
+ } else {
+ info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_DFP1_SUPPORT,
+ 0),
+ ATOM_DEVICE_DFP1_SUPPORT))
+ return FALSE;
+ }
break;
case CONNECTOR_CRT_LEGACY:
info->BiosConnector[i].ConnectorType = CONNECTOR_VGA;
+ if (tmp & 0x1) {
+ info->BiosConnector[i].load_detection = FALSE;
+ info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_CRT2_SUPPORT,
+ 2),
+ ATOM_DEVICE_CRT2_SUPPORT))
+ return FALSE;
+ } else {
+ info->BiosConnector[i].load_detection = TRUE;
+ info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_CRT1_SUPPORT,
+ 1),
+ ATOM_DEVICE_CRT1_SUPPORT))
+ return FALSE;
+ }
break;
case CONNECTOR_DVI_I_LEGACY:
info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_I;
+ if (tmp & 0x1) {
+ info->BiosConnector[i].load_detection = FALSE;
+ info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_CRT2_SUPPORT,
+ 2),
+ ATOM_DEVICE_CRT2_SUPPORT))
+ return FALSE;
+ } else {
+ info->BiosConnector[i].load_detection = TRUE;
+ info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_CRT1_SUPPORT,
+ 1),
+ ATOM_DEVICE_CRT1_SUPPORT))
+ return FALSE;
+ }
+ if ((tmp >> 4) & 0x1) {
+ info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_DFP2_SUPPORT,
+ 0),
+ ATOM_DEVICE_DFP2_SUPPORT))
+ return FALSE;
+ } else {
+ info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_DFP1_SUPPORT,
+ 0),
+ ATOM_DEVICE_DFP1_SUPPORT))
+ return FALSE;
+ }
break;
case CONNECTOR_DVI_D_LEGACY:
info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_D;
+ if ((tmp >> 4) & 0x1) {
+ info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_DFP2_SUPPORT,
+ 0),
+ ATOM_DEVICE_DFP2_SUPPORT))
+ return FALSE;
+ } else {
+ info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_DFP1_SUPPORT,
+ 0),
+ ATOM_DEVICE_DFP1_SUPPORT))
+ return FALSE;
+ }
break;
case CONNECTOR_CTV_LEGACY:
info->BiosConnector[i].ConnectorType = CONNECTOR_CTV;
+ info->BiosConnector[i].load_detection = FALSE;
+ info->BiosConnector[i].devices = ATOM_DEVICE_TV1_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_TV1_SUPPORT,
+ 2),
+ ATOM_DEVICE_TV1_SUPPORT))
+ return FALSE;
break;
case CONNECTOR_STV_LEGACY:
info->BiosConnector[i].ConnectorType = CONNECTOR_STV;
+ info->BiosConnector[i].load_detection = FALSE;
+ info->BiosConnector[i].devices = ATOM_DEVICE_TV1_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_TV1_SUPPORT,
+ 2),
+ ATOM_DEVICE_TV1_SUPPORT))
+ return FALSE;
break;
default:
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown Connector Type: %d\n", ConnectorType);
@@ -523,20 +681,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
break;
}
- if (tmp & 0x1)
- info->BiosConnector[i].DACType = DAC_TVDAC;
- else
- info->BiosConnector[i].DACType = DAC_PRIMARY;
-
- /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC*/
- if (info->IsIGP)
- info->BiosConnector[i].DACType = DAC_TVDAC;
-
- if ((tmp >> 4) & 0x1)
- info->BiosConnector[i].TMDSType = TMDS_EXT;
- else
- info->BiosConnector[i].TMDSType = TMDS_INT;
-
RADEONApplyLegacyQuirks(pScrn, i);
}
@@ -552,23 +696,42 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
"Found DFP table, assuming DVI connector\n");
info->BiosConnector[0].valid = TRUE;
info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
- info->BiosConnector[0].DACType = DAC_PRIMARY;
- info->BiosConnector[0].TMDSType = TMDS_INT;
+ info->BiosConnector[0].load_detection = TRUE;
info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+ info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_DFP1_SUPPORT,
+ 0),
+ ATOM_DEVICE_DFP1_SUPPORT))
+ return FALSE;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_CRT1_SUPPORT,
+ 1),
+ ATOM_DEVICE_CRT1_SUPPORT))
+ return FALSE;
} else
return FALSE;
}
/* check LVDS table */
- if (info->IsMobility) {
+ /* IGP can be mobile or desktop so check the connectors */
+ if (info->IsMobility || info->IsIGP) {
offset = RADEON_BIOS16(info->ROMHeaderStart + 0x40);
if (offset) {
info->BiosConnector[4].valid = TRUE;
info->BiosConnector[4].ConnectorType = CONNECTOR_LVDS;
- info->BiosConnector[4].DACType = DAC_NONE;
- info->BiosConnector[4].TMDSType = TMDS_NONE;
info->BiosConnector[4].ddc_i2c.valid = FALSE;
+ info->BiosConnector[4].devices = ATOM_DEVICE_LCD1_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_LCD1_SUPPORT,
+ 0),
+ ATOM_DEVICE_LCD1_SUPPORT))
+ return FALSE;
+
tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42);
if (tmp) {
tmp0 = RADEON_BIOS16(tmp + 0x15);
@@ -577,6 +740,9 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
if (tmp1) {
DDCType = tmp1;
switch (DDCType) {
+ case DDC_NONE_DETECTED:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No DDC for LCD\n");
+ break;
case DDC_MONID:
info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
break;
@@ -591,10 +757,10 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
break;
case DDC_LCD:
info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
- info->BiosConnector[4].ddc_i2c.mask_clk_mask =
- RADEON_BIOS32(tmp0 + 0x03) | RADEON_BIOS32(tmp0 + 0x07);
- info->BiosConnector[4].ddc_i2c.mask_data_mask =
- RADEON_BIOS32(tmp0 + 0x03) | RADEON_BIOS32(tmp0 + 0x07);
+ info->BiosConnector[4].ddc_i2c.mask_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
+ info->BiosConnector[4].ddc_i2c.mask_data_mask = RADEON_BIOS32(tmp0 + 0x07);
+ info->BiosConnector[4].ddc_i2c.a_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
+ info->BiosConnector[4].ddc_i2c.a_data_mask = RADEON_BIOS32(tmp0 + 0x07);
info->BiosConnector[4].ddc_i2c.put_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
info->BiosConnector[4].ddc_i2c.put_data_mask = RADEON_BIOS32(tmp0 + 0x07);
info->BiosConnector[4].ddc_i2c.get_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
@@ -602,10 +768,10 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
break;
case DDC_GPIO:
info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_MDGPIO_EN_REG);
- info->BiosConnector[4].ddc_i2c.mask_clk_mask =
- RADEON_BIOS32(tmp0 + 0x03) | RADEON_BIOS32(tmp0 + 0x07);
- info->BiosConnector[4].ddc_i2c.mask_data_mask =
- RADEON_BIOS32(tmp0 + 0x03) | RADEON_BIOS32(tmp0 + 0x07);
+ info->BiosConnector[4].ddc_i2c.mask_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
+ info->BiosConnector[4].ddc_i2c.mask_data_mask = RADEON_BIOS32(tmp0 + 0x07);
+ info->BiosConnector[4].ddc_i2c.a_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
+ info->BiosConnector[4].ddc_i2c.a_data_mask = RADEON_BIOS32(tmp0 + 0x07);
info->BiosConnector[4].ddc_i2c.put_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
info->BiosConnector[4].ddc_i2c.put_data_mask = RADEON_BIOS32(tmp0 + 0x07);
info->BiosConnector[4].ddc_i2c.get_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
@@ -618,9 +784,8 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "LCD DDC Info Table found!\n");
}
}
- } else {
+ } else
info->BiosConnector[4].ddc_i2c.valid = FALSE;
- }
}
}
@@ -632,22 +797,19 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
info->BiosConnector[5].valid = TRUE;
/* assume s-video for now */
info->BiosConnector[5].ConnectorType = CONNECTOR_STV;
- info->BiosConnector[5].DACType = DAC_TVDAC;
- info->BiosConnector[5].TMDSType = TMDS_NONE;
+ info->BiosConnector[5].load_detection = FALSE;
info->BiosConnector[5].ddc_i2c.valid = FALSE;
+ info->BiosConnector[5].devices = ATOM_DEVICE_TV1_SUPPORT;
+ if (!radeon_add_encoder(pScrn,
+ radeon_get_encoder_id_from_supported_device(pScrn,
+ ATOM_DEVICE_TV1_SUPPORT,
+ 2),
+ ATOM_DEVICE_TV1_SUPPORT))
+ return FALSE;
}
}
}
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
- for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
- if (info->BiosConnector[i].valid) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-0x%x, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
- i, (unsigned int)info->BiosConnector[i].ddc_i2c.mask_clk_reg, info->BiosConnector[i].DACType,
- info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType);
- }
- }
-
return TRUE;
}
@@ -667,83 +829,84 @@ Bool RADEONGetTVInfoFromBIOS (xf86OutputPtr output) {
ScrnInfoPtr pScrn = output->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ radeon_tvout_ptr tvout = &radeon_output->tvout;
int offset, refclk, stds;
if (!info->VBIOS) return FALSE;
- if (info->IsAtomBios) {
+ if (info->IsAtomBios)
return RADEONGetATOMTVInfo(output);
- } else {
+ else {
offset = RADEON_BIOS16(info->ROMHeaderStart + 0x32);
if (offset) {
if (RADEON_BIOS8(offset + 6) == 'T') {
switch (RADEON_BIOS8(offset + 7) & 0xf) {
case 1:
- radeon_output->default_tvStd = TV_STD_NTSC;
+ tvout->default_tvStd = TV_STD_NTSC;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC\n");
break;
case 2:
- radeon_output->default_tvStd = TV_STD_PAL;
+ tvout->default_tvStd = TV_STD_PAL;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL\n");
break;
case 3:
- radeon_output->default_tvStd = TV_STD_PAL_M;
+ tvout->default_tvStd = TV_STD_PAL_M;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-M\n");
break;
case 4:
- radeon_output->default_tvStd = TV_STD_PAL_60;
+ tvout->default_tvStd = TV_STD_PAL_60;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-60\n");
break;
case 5:
- radeon_output->default_tvStd = TV_STD_NTSC_J;
+ tvout->default_tvStd = TV_STD_NTSC_J;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC-J\n");
break;
case 6:
- radeon_output->default_tvStd = TV_STD_SCART_PAL;
+ tvout->default_tvStd = TV_STD_SCART_PAL;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: SCART-PAL\n");
break;
default:
- radeon_output->default_tvStd = TV_STD_NTSC;
+ tvout->default_tvStd = TV_STD_NTSC;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Unknown TV standard; defaulting to NTSC\n");
break;
}
- radeon_output->tvStd = radeon_output->default_tvStd;
+ tvout->tvStd = tvout->default_tvStd;
refclk = (RADEON_BIOS8(offset + 9) >> 2) & 0x3;
if (refclk == 0)
- radeon_output->TVRefClk = 29.498928713; /* MHz */
+ tvout->TVRefClk = 29.498928713; /* MHz */
else if (refclk == 1)
- radeon_output->TVRefClk = 28.636360000;
+ tvout->TVRefClk = 28.636360000;
else if (refclk == 2)
- radeon_output->TVRefClk = 14.318180000;
+ tvout->TVRefClk = 14.318180000;
else if (refclk == 3)
- radeon_output->TVRefClk = 27.000000000;
+ tvout->TVRefClk = 27.000000000;
- radeon_output->SupportedTVStds = radeon_output->default_tvStd;
+ tvout->SupportedTVStds = tvout->default_tvStd;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standards supported by chip: ");
stds = RADEON_BIOS8(offset + 10) & 0x1f;
if (stds & TV_STD_NTSC) {
- radeon_output->SupportedTVStds |= TV_STD_NTSC;
+ tvout->SupportedTVStds |= TV_STD_NTSC;
ErrorF("NTSC ");
}
if (stds & TV_STD_PAL) {
- radeon_output->SupportedTVStds |= TV_STD_PAL;
+ tvout->SupportedTVStds |= TV_STD_PAL;
ErrorF("PAL ");
}
if (stds & TV_STD_PAL_M) {
- radeon_output->SupportedTVStds |= TV_STD_PAL_M;
+ tvout->SupportedTVStds |= TV_STD_PAL_M;
ErrorF("PAL-M ");
}
if (stds & TV_STD_PAL_60) {
- radeon_output->SupportedTVStds |= TV_STD_PAL_60;
+ tvout->SupportedTVStds |= TV_STD_PAL_60;
ErrorF("PAL-60 ");
}
if (stds & TV_STD_NTSC_J) {
- radeon_output->SupportedTVStds |= TV_STD_NTSC_J;
+ tvout->SupportedTVStds |= TV_STD_NTSC_J;
ErrorF("NTSC-J ");
}
if (stds & TV_STD_SCART_PAL) {
- radeon_output->SupportedTVStds |= TV_STD_SCART_PAL;
+ tvout->SupportedTVStds |= TV_STD_SCART_PAL;
ErrorF("SCART-PAL");
}
ErrorF("\n");
@@ -813,8 +976,8 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn)
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;
+ info->sclk = RADEON_BIOS16(pll_info_block + 10) / 100.0;
+ info->mclk = RADEON_BIOS16(pll_info_block + 8) / 100.0;
}
if (info->sclk == 0) info->sclk = 200;
@@ -831,11 +994,9 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn)
return TRUE;
}
-Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output)
+Bool RADEONGetDAC2InfoFromBIOS (ScrnInfoPtr pScrn, radeon_tvdac_ptr tvdac)
{
- ScrnInfoPtr pScrn = output->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
int offset, rev, bg, dac;
if (!info->VBIOS) return FALSE;
@@ -854,29 +1015,29 @@ Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output)
if (rev > 4) {
bg = RADEON_BIOS8(offset + 0xc) & 0xf;
dac = RADEON_BIOS8(offset + 0xd) & 0xf;
- radeon_output->ps2_tvdac_adj = (bg << 16) | (dac << 20);
+ tvdac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
bg = RADEON_BIOS8(offset + 0xe) & 0xf;
dac = RADEON_BIOS8(offset + 0xf) & 0xf;
- radeon_output->pal_tvdac_adj = (bg << 16) | (dac << 20);
+ tvdac->pal_tvdac_adj = (bg << 16) | (dac << 20);
bg = RADEON_BIOS8(offset + 0x10) & 0xf;
dac = RADEON_BIOS8(offset + 0x11) & 0xf;
- radeon_output->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
+ tvdac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
return TRUE;
} else 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);
+ tvdac->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);
+ tvdac->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);
+ tvdac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
return TRUE;
}
@@ -888,17 +1049,17 @@ Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output)
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;
+ tvdac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
+ tvdac->pal_tvdac_adj = tvdac->ps2_tvdac_adj;
+ tvdac->ntsc_tvdac_adj = tvdac->ps2_tvdac_adj;
return TRUE;
} else {
bg = RADEON_BIOS8(offset + 0x4) & 0xf;
dac = RADEON_BIOS8(offset + 0x5) & 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;
+ tvdac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
+ tvdac->pal_tvdac_adj = tvdac->ps2_tvdac_adj;
+ tvdac->ntsc_tvdac_adj = tvdac->ps2_tvdac_adj;
return TRUE;
}
@@ -908,40 +1069,17 @@ Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output)
return FALSE;
}
-Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output)
+Bool
+RADEONGetLVDSInfoFromBIOS(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds)
{
- ScrnInfoPtr pScrn = output->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ radeon_native_mode_ptr native_mode = &lvds->native_mode;
unsigned long tmp, i;
- if (!info->VBIOS) return FALSE;
-
- if (info->IsAtomBios) {
- if((tmp = RADEON_BIOS16 (info->MasterDataStart + 16))) {
-
- radeon_output->PanelXRes = RADEON_BIOS16(tmp+6);
- radeon_output->PanelYRes = RADEON_BIOS16(tmp+10);
- radeon_output->DotClock = RADEON_BIOS16(tmp+4)*10;
- radeon_output->HBlank = RADEON_BIOS16(tmp+8);
- radeon_output->HOverPlus = RADEON_BIOS16(tmp+14);
- radeon_output->HSyncWidth = RADEON_BIOS16(tmp+16);
- radeon_output->VBlank = RADEON_BIOS16(tmp+12);
- radeon_output->VOverPlus = RADEON_BIOS16(tmp+18);
- radeon_output->VSyncWidth = RADEON_BIOS16(tmp+20);
- radeon_output->PanelPwrDly = RADEON_BIOS16(tmp+40);
-
- if (radeon_output->PanelPwrDly > 2000 || radeon_output->PanelPwrDly < 0)
- radeon_output->PanelPwrDly = 2000;
-
- radeon_output->Flags = 0;
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "No LVDS Info Table found in BIOS!\n");
- return FALSE;
- }
- } else {
+ if (!info->VBIOS)
+ return FALSE;
+ if (!info->IsAtomBios) {
tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x40);
if (!tmp) {
@@ -959,14 +1097,14 @@ Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Panel ID string: %s\n", stmp);
- radeon_output->PanelXRes = RADEON_BIOS16(tmp+25);
- radeon_output->PanelYRes = RADEON_BIOS16(tmp+27);
+ native_mode->PanelXRes = RADEON_BIOS16(tmp+25);
+ native_mode->PanelYRes = RADEON_BIOS16(tmp+27);
xf86DrvMsg(0, X_INFO, "Panel Size from BIOS: %dx%d\n",
- radeon_output->PanelXRes, radeon_output->PanelYRes);
-
- radeon_output->PanelPwrDly = RADEON_BIOS16(tmp+44);
- if (radeon_output->PanelPwrDly > 2000 || radeon_output->PanelPwrDly < 0)
- radeon_output->PanelPwrDly = 2000;
+ native_mode->PanelXRes, native_mode->PanelYRes);
+
+ lvds->PanelPwrDly = RADEON_BIOS16(tmp+44);
+ if (lvds->PanelPwrDly > 2000 || lvds->PanelPwrDly < 0)
+ lvds->PanelPwrDly = 2000;
/* some panels only work well with certain divider combinations.
*/
@@ -987,77 +1125,64 @@ Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output)
for (i = 0; i < 32; i++) {
tmp0 = RADEON_BIOS16(tmp+64+i*2);
if (tmp0 == 0) break;
- if ((RADEON_BIOS16(tmp0) == radeon_output->PanelXRes) &&
- (RADEON_BIOS16(tmp0+2) == radeon_output->PanelYRes)) {
- radeon_output->HBlank = (RADEON_BIOS16(tmp0+17) -
- RADEON_BIOS16(tmp0+19)) * 8;
- radeon_output->HOverPlus = (RADEON_BIOS16(tmp0+21) -
- RADEON_BIOS16(tmp0+19) - 1) * 8;
- radeon_output->HSyncWidth = RADEON_BIOS8(tmp0+23) * 8;
- radeon_output->VBlank = (RADEON_BIOS16(tmp0+24) -
- RADEON_BIOS16(tmp0+26));
- radeon_output->VOverPlus = ((RADEON_BIOS16(tmp0+28) & 0x7ff) -
- RADEON_BIOS16(tmp0+26));
- radeon_output->VSyncWidth = ((RADEON_BIOS16(tmp0+28) & 0xf800) >> 11);
- radeon_output->DotClock = RADEON_BIOS16(tmp0+9) * 10;
- radeon_output->Flags = 0;
+ if ((RADEON_BIOS16(tmp0) == native_mode->PanelXRes) &&
+ (RADEON_BIOS16(tmp0+2) == native_mode->PanelYRes)) {
+ native_mode->HBlank = (RADEON_BIOS16(tmp0+17) -
+ RADEON_BIOS16(tmp0+19)) * 8;
+ native_mode->HOverPlus = (RADEON_BIOS16(tmp0+21) -
+ RADEON_BIOS16(tmp0+19) - 1) * 8;
+ native_mode->HSyncWidth = RADEON_BIOS8(tmp0+23) * 8;
+ native_mode->VBlank = (RADEON_BIOS16(tmp0+24) -
+ RADEON_BIOS16(tmp0+26));
+ native_mode->VOverPlus = ((RADEON_BIOS16(tmp0+28) & 0x7ff) -
+ RADEON_BIOS16(tmp0+26));
+ native_mode->VSyncWidth = ((RADEON_BIOS16(tmp0+28) & 0xf800) >> 11);
+ native_mode->DotClock = RADEON_BIOS16(tmp0+9) * 10;
+ native_mode->Flags = 0;
}
}
}
- }
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "LVDS Info:\n"
- "XRes: %d, YRes: %d, DotClock: %d\n"
- "HBlank: %d, HOverPlus: %d, HSyncWidth: %d\n"
- "VBlank: %d, VOverPlus: %d, VSyncWidth: %d\n",
- radeon_output->PanelXRes, radeon_output->PanelYRes, radeon_output->DotClock,
- radeon_output->HBlank, radeon_output->HOverPlus, radeon_output->HSyncWidth,
- radeon_output->VBlank, radeon_output->VOverPlus, radeon_output->VSyncWidth);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "LVDS Info:\n"
+ "XRes: %d, YRes: %d, DotClock: %d\n"
+ "HBlank: %d, HOverPlus: %d, HSyncWidth: %d\n"
+ "VBlank: %d, VOverPlus: %d, VSyncWidth: %d\n",
+ native_mode->PanelXRes, native_mode->PanelYRes, native_mode->DotClock,
+ native_mode->HBlank, native_mode->HOverPlus, native_mode->HSyncWidth,
+ native_mode->VBlank, native_mode->VOverPlus, native_mode->VSyncWidth);
- return TRUE;
+ return TRUE;
+ }
+ return FALSE;
}
-Bool RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output)
+xf86MonPtr RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned long tmp;
- char EDID[256];
+ unsigned char edid[256];
+ xf86MonPtr mon = NULL;
- if (!info->VBIOS) return FALSE;
+ if (!info->VBIOS)
+ return mon;
- if (info->IsAtomBios) {
- /* Not yet */
- return FALSE;
- } else {
- if (!(tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x4c))) {
- return FALSE;
+ if (!info->IsAtomBios) {
+ tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x4c);
+ if (tmp) {
+ memcpy(edid, (unsigned char*)(info->VBIOS + tmp), 256);
+ if (edid[1] == 0xff)
+ mon = xf86InterpretEDID(output->scrn->scrnIndex, edid);
}
-
- memcpy(EDID, (char*)(info->VBIOS + tmp), 256);
-
- radeon_output->DotClock = (*(uint16_t*)(EDID+54)) * 10;
- radeon_output->PanelXRes = (*(uint8_t*)(EDID+56)) + ((*(uint8_t*)(EDID+58))>>4)*256;
- radeon_output->HBlank = (*(uint8_t*)(EDID+57)) + ((*(uint8_t*)(EDID+58)) & 0xf)*256;
- radeon_output->HOverPlus = (*(uint8_t*)(EDID+62)) + ((*(uint8_t*)(EDID+65)>>6)*256);
- radeon_output->HSyncWidth = (*(uint8_t*)(EDID+63)) + (((*(uint8_t*)(EDID+65)>>4) & 3)*256);
- radeon_output->PanelYRes = (*(uint8_t*)(EDID+59)) + ((*(uint8_t*)(EDID+61))>>4)*256;
- radeon_output->VBlank = ((*(uint8_t*)(EDID+60)) + ((*(uint8_t*)(EDID+61)) & 0xf)*256);
- radeon_output->VOverPlus = (((*(uint8_t*)(EDID+64))>>4) + (((*(uint8_t*)(EDID+65)>>2) & 3)*16));
- radeon_output->VSyncWidth = (((*(uint8_t*)(EDID+64)) & 0xf) + ((*(uint8_t*)(EDID+65)) & 3)*256);
- radeon_output->Flags = V_NHSYNC | V_NVSYNC; /**(uint8_t*)(EDID+71);*/
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardcoded EDID data will be used for TMDS panel\n");
}
- return TRUE;
+
+ return mon;
}
-Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output)
+Bool RADEONGetTMDSInfoFromBIOS (ScrnInfoPtr pScrn, radeon_tmds_ptr tmds)
{
- ScrnInfoPtr pScrn = output->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
uint32_t tmp, maxfreq;
int i, n;
@@ -1067,21 +1192,21 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output)
if((tmp = RADEON_BIOS16 (info->MasterDataStart + 18))) {
maxfreq = RADEON_BIOS16(tmp+4);
-
+
for (i=0; i<4; i++) {
- radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*6+6);
+ tmds->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*6+6);
/* This assumes each field in TMDS_PLL has 6 bit as in R300/R420 */
- radeon_output->tmds_pll[i].value = ((RADEON_BIOS8(tmp+i*6+8) & 0x3f) |
+ tmds->tmds_pll[i].value = ((RADEON_BIOS8(tmp+i*6+8) & 0x3f) |
((RADEON_BIOS8(tmp+i*6+10) & 0x3f)<<6) |
((RADEON_BIOS8(tmp+i*6+9) & 0xf)<<12) |
((RADEON_BIOS8(tmp+i*6+11) & 0xf)<<16));
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "TMDS PLL from BIOS: %u %x\n",
- (unsigned)radeon_output->tmds_pll[i].freq,
- (unsigned)radeon_output->tmds_pll[i].value);
-
- if (maxfreq == radeon_output->tmds_pll[i].freq) {
- radeon_output->tmds_pll[i].freq = 0xffffffff;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "TMDS PLL from BIOS: %u %x\n",
+ (unsigned)tmds->tmds_pll[i].freq,
+ (unsigned)tmds->tmds_pll[i].value);
+
+ if (maxfreq == tmds->tmds_pll[i].freq) {
+ tmds->tmds_pll[i].freq = 0xffffffff;
break;
}
}
@@ -1097,8 +1222,8 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output)
n = RADEON_BIOS8(tmp + 5) + 1;
if (n > 4) n = 4;
for (i=0; i<n; i++) {
- radeon_output->tmds_pll[i].value = RADEON_BIOS32(tmp+i*10+0x08);
- radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*10+0x10);
+ tmds->tmds_pll[i].value = RADEON_BIOS32(tmp+i*10+0x08);
+ tmds->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*10+0x10);
}
return TRUE;
} else if (RADEON_BIOS8(tmp) == 4) {
@@ -1106,8 +1231,8 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output)
n = RADEON_BIOS8(tmp + 5) + 1;
if (n > 4) n = 4;
for (i=0; i<n; i++) {
- radeon_output->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08);
- radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10);
+ tmds->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08);
+ tmds->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10);
if (i == 0) stride += 10;
else stride += 6;
}
@@ -1118,17 +1243,106 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output)
return FALSE;
}
-Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output)
+static RADEONI2CBusRec
+RADEONLookupI2CBlock(ScrnInfoPtr pScrn, int id)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ int offset, blocks, i;
+ RADEONI2CBusRec i2c;
+
+ memset(&i2c, 0, sizeof(RADEONI2CBusRec));
+ i2c.valid = FALSE;
+
+ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x70);
+ if (offset) {
+ blocks = RADEON_BIOS8(offset + 2);
+ for (i = 0; i < blocks; i++) {
+ int i2c_id = RADEON_BIOS8(offset + 3 + (i * 5) + 0);
+ if (id == i2c_id) {
+ int reg = RADEON_BIOS16(offset + 3 + (i * 5) + 1) * 4;
+ int clock_shift = RADEON_BIOS8(offset + 3 + (i * 5) + 3);
+ int data_shift = RADEON_BIOS8(offset + 3 + (i * 5) + 4);
+
+ i2c.mask_clk_mask = (1 << clock_shift);
+ i2c.mask_data_mask = (1 << data_shift);
+ i2c.a_clk_mask = (1 << clock_shift);
+ i2c.a_data_mask = (1 << data_shift);
+ i2c.put_clk_mask = (1 << clock_shift);
+ i2c.put_data_mask = (1 << data_shift);
+ i2c.get_clk_mask = (1 << clock_shift);
+ i2c.get_data_mask = (1 << data_shift);
+ i2c.mask_clk_reg = reg;
+ i2c.mask_data_reg = reg;
+ i2c.a_clk_reg = reg;
+ i2c.a_data_reg = reg;
+ i2c.put_clk_reg = reg;
+ i2c.put_data_reg = reg;
+ i2c.get_clk_reg = reg;
+ i2c.get_data_reg = reg;
+ i2c.valid = TRUE;
+ break;
+ }
+ }
+ }
+ return i2c;
+}
+
+Bool RADEONGetExtTMDSInfoFromBIOS (ScrnInfoPtr pScrn, radeon_dvo_ptr dvo)
{
- 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->VBIOS)
+ return FALSE;
- if (info->IsAtomBios) {
+ if (info->IsAtomBios)
return FALSE;
+ else if (info->IsIGP) {
+ /* RS4xx TMDS stuff is in the mobile table */
+ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x42);
+ if (offset) {
+ int rev = RADEON_BIOS8(offset);
+ if (rev >= 6) {
+ offset = RADEON_BIOS16(offset + 0x17);
+ if (offset) {
+ offset = RADEON_BIOS16(offset + 2);
+ rev = RADEON_BIOS8(offset);
+ if (offset && (rev > 1)) {
+ int blocks = RADEON_BIOS8(offset + 3);
+ int index = offset + 4;
+ dvo->dvo_i2c.valid = FALSE;
+ while (blocks > 0) {
+ int id = RADEON_BIOS16(index);
+ index += 2;
+ switch (id >> 13) {
+ case 0:
+ index += 6;
+ break;
+ case 2:
+ index += 10;
+ break;
+ case 3:
+ index += 2;
+ break;
+ case 4:
+ index += 2;
+ break;
+ case 6:
+ dvo->dvo_i2c_slave_addr =
+ RADEON_BIOS16(index) & 0xff;
+ index += 2;
+ dvo->dvo_i2c =
+ RADEONLookupI2CBlock(pScrn, RADEON_BIOS8(index));
+ return TRUE;
+ default:
+ break;
+ }
+ blocks--;
+ }
+ }
+ }
+ }
+ }
} else {
offset = RADEON_BIOS16(info->ROMHeaderStart + 0x58);
if (offset) {
@@ -1137,28 +1351,29 @@ Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output)
RADEON_BIOS8(offset));
table_start = offset+4;
max_freq = RADEON_BIOS16(table_start);
- radeon_output->dvo_i2c_slave_addr = RADEON_BIOS8(table_start+2);
- radeon_output->dvo_i2c.valid = FALSE;
+ dvo->dvo_i2c_slave_addr = RADEON_BIOS8(table_start+2);
+ dvo->dvo_i2c.valid = FALSE;
gpio_reg = RADEON_BIOS8(table_start+3);
if (gpio_reg == 1)
- radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
+ dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
else if (gpio_reg == 2)
- radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+ dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
else if (gpio_reg == 3)
- radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+ dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
else if (gpio_reg == 4)
- radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
- else if (gpio_reg == 5)
+ dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+ else if (gpio_reg == 5) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"unsupported MM gpio_reg\n");
- else {
+ return FALSE;
+ } 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) {
+ dvo->dvo_duallink = flags & 0x01;
+ if (dvo->dvo_duallink) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Duallink TMDS detected\n");
}
@@ -1177,14 +1392,94 @@ Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output)
ScrnInfoPtr pScrn = output->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
+ radeon_dvo_ptr dvo = NULL;
int offset, index, id;
- uint32_t val, reg, andmask, ormask;
+ uint32_t val, reg, and_mask, or_mask;
- if (!info->VBIOS) return FALSE;
+ if (radeon_encoder == NULL)
+ return FALSE;
- if (info->IsAtomBios) {
+ dvo = (radeon_dvo_ptr)radeon_encoder->dev_priv;
+
+ if (dvo == NULL)
+ return FALSE;
+
+ if (!info->VBIOS)
+ return FALSE;
+
+ if (info->IsAtomBios)
return FALSE;
+ else if (info->IsIGP) {
+ /* RS4xx TMDS stuff is in the mobile table */
+ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x42);
+ if (offset) {
+ int rev = RADEON_BIOS8(offset);
+ if (rev >= 6) {
+ offset = RADEON_BIOS16(offset + 0x17);
+ if (offset) {
+ offset = RADEON_BIOS16(offset + 2);
+ rev = RADEON_BIOS8(offset);
+ if (offset && (rev > 1)) {
+ int blocks = RADEON_BIOS8(offset + 3);
+ index = offset + 4;
+ while (blocks > 0) {
+ id = RADEON_BIOS16(index);
+ index += 2;
+ switch (id >> 13) {
+ case 0:
+ reg = (id & 0x1fff) * 4;
+ val = RADEON_BIOS32(index);
+ index += 4;
+ ErrorF("MMIO: 0x%x 0x%x\n",
+ (unsigned)reg, (unsigned)val);
+ OUTREG(reg, val);
+ break;
+ case 2:
+ reg = (id & 0x1fff) * 4;
+ and_mask = RADEON_BIOS32(index);
+ index += 4;
+ or_mask = RADEON_BIOS32(index);
+ index += 4;
+ ErrorF("MMIO mask: 0x%x 0x%x 0x%x\n",
+ (unsigned)reg, (unsigned)and_mask, (unsigned)or_mask);
+ val = INREG(reg);
+ val = (val & and_mask) | or_mask;
+ OUTREG(reg, val);
+ break;
+ case 3:
+ val = RADEON_BIOS16(index);
+ index += 2;
+ ErrorF("delay: %u\n", (unsigned)val);
+ usleep(val);
+ break;
+ case 4:
+ val = RADEON_BIOS16(index);
+ index += 2;
+ ErrorF("delay: %u\n", (unsigned)val * 1000);
+ usleep(val * 1000);
+ break;
+ case 6:
+ index++;
+ reg = RADEON_BIOS8(index);
+ index++;
+ val = RADEON_BIOS8(index);
+ index++;
+ ErrorF("i2c write: 0x%x, 0x%x\n", (unsigned)reg,
+ (unsigned)val);
+ RADEONDVOWriteByte(dvo->DVOChip, reg, val);
+ break;
+ default:
+ ErrorF("unknown id %d\n", id>>13);
+ return FALSE;
+ }
+ blocks--;
+ }
+ return TRUE;
+ }
+ }
+ }
+ }
} else {
offset = RADEON_BIOS16(info->ROMHeaderStart + 0x58);
if (offset) {
@@ -1194,24 +1489,24 @@ Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output)
index += 2;
switch(id >> 13) {
case 0:
- reg = id & 0x1fff;
+ reg = (id & 0x1fff) * 4;
val = RADEON_BIOS32(index);
index += 4;
- ErrorF("WRITE INDEXED: 0x%x 0x%x\n",
+ ErrorF("MMIO: 0x%x 0x%x\n",
(unsigned)reg, (unsigned)val);
- /*OUTREG(reg, val);*/
+ OUTREG(reg, val);
break;
case 2:
- reg = id & 0x1fff;
- andmask = RADEON_BIOS32(index);
+ reg = (id & 0x1fff) * 4;
+ and_mask = RADEON_BIOS32(index);
index += 4;
- ormask = RADEON_BIOS32(index);
+ or_mask = RADEON_BIOS32(index);
index += 4;
val = INREG(reg);
- val = (val & andmask) | ormask;
- ErrorF("MASK DIRECT: 0x%x 0x%x 0x%x\n",
- (unsigned)reg, (unsigned)andmask, (unsigned)ormask);
- /*OUTREG(reg, val);*/
+ val = (val & and_mask) | or_mask;
+ ErrorF("MMIO mask: 0x%x 0x%x 0x%x\n",
+ (unsigned)reg, (unsigned)and_mask, (unsigned)or_mask);
+ OUTREG(reg, val);
break;
case 4:
val = RADEON_BIOS16(index);
@@ -1221,15 +1516,15 @@ Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output)
break;
case 5:
reg = id & 0x1fff;
- andmask = RADEON_BIOS32(index);
+ and_mask = RADEON_BIOS32(index);
index += 4;
- ormask = RADEON_BIOS32(index);
+ or_mask = RADEON_BIOS32(index);
index += 4;
- ErrorF("MASK PLL: 0x%x 0x%x 0x%x\n",
- (unsigned)reg, (unsigned)andmask, (unsigned)ormask);
- /*val = INPLL(pScrn, reg);
- val = (val & andmask) | ormask;
- OUTPLL(pScrn, reg, val);*/
+ ErrorF("PLL mask: 0x%x 0x%x 0x%x\n",
+ (unsigned)reg, (unsigned)and_mask, (unsigned)or_mask);
+ val = INPLL(pScrn, reg);
+ val = (val & and_mask) | or_mask;
+ OUTPLL(pScrn, reg, val);
break;
case 6:
reg = id & 0x1fff;
@@ -1237,7 +1532,7 @@ Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output)
index += 1;
ErrorF("i2c write: 0x%x, 0x%x\n", (unsigned)reg,
(unsigned)val);
- RADEONDVOWriteByte(radeon_output->DVOChip, reg, val);
+ RADEONDVOWriteByte(dvo->DVOChip, reg, val);
break;
default:
ErrorF("unknown id %d\n", id>>13);