summaryrefslogtreecommitdiff
path: root/driver/xf86-video-ati/src/radeon_atombios.c
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2012-01-25 21:33:36 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2012-01-25 21:33:36 +0000
commit46e73e726a6a3567a4bb19b06c59826b9c6767d1 (patch)
tree8df52bebcc8ecbe55a8f8be1afae536b5fb46319 /driver/xf86-video-ati/src/radeon_atombios.c
parentee1cf1e0a2b9e0f7070a4d1efa6b426373e8ba67 (diff)
Update to xf86-video-ati 6.14.3. Tested by many.
Diffstat (limited to 'driver/xf86-video-ati/src/radeon_atombios.c')
-rw-r--r--driver/xf86-video-ati/src/radeon_atombios.c647
1 files changed, 489 insertions, 158 deletions
diff --git a/driver/xf86-video-ati/src/radeon_atombios.c b/driver/xf86-video-ati/src/radeon_atombios.c
index 10fdefeb1..6cc3daa8d 100644
--- a/driver/xf86-video-ati/src/radeon_atombios.c
+++ b/driver/xf86-video-ati/src/radeon_atombios.c
@@ -30,6 +30,7 @@
#include "xf86_OSproc.h"
#include "radeon.h"
+#include "radeon_reg.h"
#include "radeon_atombios.h"
#include "radeon_atomwrapper.h"
#include "radeon_probe.h"
@@ -489,7 +490,7 @@ rhdAtomAllocateFbScratch(atomBiosHandlePtr handle,
xf86DrvMsg(handle->scrnIndex, X_INFO,
"Cannot get VRAM scratch space. "
"Allocating in main memory instead\n");
- handle->scratchBase = xcalloc(fb_size,1);
+ handle->scratchBase = calloc(fb_size,1);
return ATOM_SUCCESS;
}
return ATOM_FAILED;
@@ -524,7 +525,7 @@ rhdAtomASICInit(atomBiosHandlePtr handle)
}
int
-atombios_dyn_clk_setup(ScrnInfoPtr pScrn, int enable)
+atombios_clk_gating_setup(ScrnInfoPtr pScrn, Bool enable)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
DYNAMIC_CLOCK_GATING_PS_ALLOCATION dynclk_data;
@@ -548,13 +549,19 @@ atombios_dyn_clk_setup(ScrnInfoPtr pScrn, int enable)
}
int
-atombios_static_pwrmgt_setup(ScrnInfoPtr pScrn, int enable)
+atombios_static_pwrmgt_setup(ScrnInfoPtr pScrn, Bool enable)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION pwrmgt_data;
AtomBiosArgRec data;
unsigned char *space;
+ /* disabling static power management causes hangs on some r4xx chips */
+ if (((info->ChipFamily == CHIP_FAMILY_R420) ||
+ (info->ChipFamily == CHIP_FAMILY_RV410)) &&
+ !enable)
+ return ATOM_NOT_IMPLEMENTED;
+
pwrmgt_data.ucEnable = enable;
data.exec.index = GetIndexIntoMasterTable(COMMAND, EnableASIC_StaticPwrMgt);
@@ -571,6 +578,59 @@ atombios_static_pwrmgt_setup(ScrnInfoPtr pScrn, int enable)
}
+int
+atombios_set_engine_clock(ScrnInfoPtr pScrn, uint32_t engclock)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ SET_ENGINE_CLOCK_PS_ALLOCATION eng_clock_ps;
+ AtomBiosArgRec data;
+ unsigned char *space;
+
+ RADEONWaitForIdleMMIO(pScrn);
+
+ eng_clock_ps.ulTargetEngineClock = engclock; /* 10 khz */
+
+ /*ErrorF("Attempting to set engine clock to: %d\n", engclock);*/
+ data.exec.index = GetIndexIntoMasterTable(COMMAND, SetEngineClock);
+ data.exec.dataSpace = (void *)&space;
+ data.exec.pspace = &eng_clock_ps;
+
+ if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+ /* ErrorF("Set engine clock success\n"); */
+ return ATOM_SUCCESS;
+ }
+ /* ErrorF("Set engine clock failed\n"); */
+ return ATOM_NOT_IMPLEMENTED;
+}
+
+int
+atombios_set_memory_clock(ScrnInfoPtr pScrn, uint32_t memclock)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ SET_MEMORY_CLOCK_PS_ALLOCATION mem_clock_ps;
+ AtomBiosArgRec data;
+ unsigned char *space;
+
+ if (info->IsIGP)
+ return ATOM_SUCCESS;
+
+ RADEONWaitForIdleMMIO(pScrn);
+
+ mem_clock_ps.ulTargetMemoryClock = memclock; /* 10 khz */
+
+ /* ErrorF("Attempting to set mem clock to: %d\n", memclock); */
+ data.exec.index = GetIndexIntoMasterTable(COMMAND, SetMemoryClock);
+ data.exec.dataSpace = (void *)&space;
+ data.exec.pspace = &mem_clock_ps;
+
+ if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+ /* ErrorF("Set memory clock success\n"); */
+ return ATOM_SUCCESS;
+ }
+ /* ErrorF("Set memory clock failed\n"); */
+ return ATOM_NOT_IMPLEMENTED;
+}
+
# endif
static AtomBiosResult
@@ -591,14 +651,14 @@ rhdAtomInit(atomBiosHandlePtr unused1, AtomBiosRequestID unused2,
BIOSImageSize = RADEON_VBIOS_SIZE;
#endif
- if (!(atomDataPtr = xcalloc(1, sizeof(atomDataTables)))) {
+ if (!(atomDataPtr = calloc(1, sizeof(atomDataTables)))) {
xf86DrvMsg(scrnIndex,X_ERROR,"Cannot allocate memory for "
"ATOM BIOS data tabes\n");
goto error;
}
if (!rhdAtomGetDataTable(scrnIndex, info->VBIOS, atomDataPtr, &cmd_offset, BIOSImageSize))
goto error1;
- if (!(handle = xcalloc(1, sizeof(atomBiosHandleRec)))) {
+ if (!(handle = calloc(1, sizeof(atomBiosHandleRec)))) {
xf86DrvMsg(scrnIndex,X_ERROR,"Cannot allocate memory\n");
goto error1;
}
@@ -617,7 +677,7 @@ rhdAtomInit(atomBiosHandlePtr unused1, AtomBiosRequestID unused2,
return ATOM_SUCCESS;
error1:
- xfree(atomDataPtr);
+ free(atomDataPtr);
error:
return ATOM_FAILED;
}
@@ -628,10 +688,10 @@ rhdAtomTearDown(atomBiosHandlePtr handle,
{
//RHDFUNC(handle);
- xfree(handle->BIOSBase);
- xfree(handle->atomDataPtr);
- if (handle->scratchBase) xfree(handle->scratchBase);
- xfree(handle);
+ free(handle->BIOSBase);
+ free(handle->atomDataPtr);
+ if (handle->scratchBase) free(handle->scratchBase);
+ free(handle);
return ATOM_SUCCESS;
}
@@ -717,20 +777,20 @@ rhdAtomDTDTimings(atomBiosHandlePtr handle, ATOM_DTD_FORMAT *dtd)
if (!dtd->usHActive || !dtd->usVActive)
return NULL;
- if (!(mode = (DisplayModePtr)xcalloc(1,sizeof(DisplayModeRec))))
+ if (!(mode = (DisplayModePtr)calloc(1,sizeof(DisplayModeRec))))
return NULL;
mode->CrtcHDisplay = mode->HDisplay = le16_to_cpu(dtd->usHActive);
mode->CrtcVDisplay = mode->VDisplay = le16_to_cpu(dtd->usVActive);
- mode->CrtcHBlankStart = dtd->usHActive + dtd->ucHBorder;
+ mode->CrtcHBlankStart = le16_to_cpu(dtd->usHActive) + dtd->ucHBorder;
mode->CrtcHBlankEnd = mode->CrtcHBlankStart + le16_to_cpu(dtd->usHBlanking_Time);
mode->CrtcHTotal = mode->HTotal = mode->CrtcHBlankEnd + dtd->ucHBorder;
- mode->CrtcVBlankStart = dtd->usVActive + dtd->ucVBorder;
+ mode->CrtcVBlankStart = le16_to_cpu(dtd->usVActive) + dtd->ucVBorder;
mode->CrtcVBlankEnd = mode->CrtcVBlankStart + le16_to_cpu(dtd->usVBlanking_Time);
mode->CrtcVTotal = mode->VTotal = mode->CrtcVBlankEnd + dtd->ucVBorder;
- mode->CrtcHSyncStart = mode->HSyncStart = dtd->usHActive + le16_to_cpu(dtd->usHSyncOffset);
+ mode->CrtcHSyncStart = mode->HSyncStart = le16_to_cpu(dtd->usHActive) + le16_to_cpu(dtd->usHSyncOffset);
mode->CrtcHSyncEnd = mode->HSyncEnd = mode->HSyncStart + le16_to_cpu(dtd->usHSyncWidth);
- mode->CrtcVSyncStart = mode->VSyncStart = dtd->usVActive + le16_to_cpu(dtd->usVSyncOffset);
+ mode->CrtcVSyncStart = mode->VSyncStart = le16_to_cpu(dtd->usVActive) + le16_to_cpu(dtd->usVSyncOffset);
mode->CrtcVSyncEnd = mode->VSyncEnd = mode->VSyncStart + le16_to_cpu(dtd->usVSyncWidth);
mode->SynthClock = mode->Clock = le16_to_cpu(dtd->usPixClk) * 10;
@@ -801,7 +861,7 @@ rhdAtomLvdsDDC(atomBiosHandlePtr handle, uint32_t offset, unsigned char *record)
- sizeof(UCHAR);
if (offset > handle->BIOSImageSize) break;
/* dup string as we free it later */
- if (!(EDIDBlock = (unsigned char *)xalloc(
+ if (!(EDIDBlock = (unsigned char *)malloc(
((ATOM_FAKE_EDID_PATCH_RECORD*)record)->ucFakeEDIDLength)))
return NULL;
memcpy(EDIDBlock,&((ATOM_FAKE_EDID_PATCH_RECORD*)record)->ucFakeEDIDString,
@@ -811,7 +871,7 @@ rhdAtomLvdsDDC(atomBiosHandlePtr handle, uint32_t offset, unsigned char *record)
{
xf86MonPtr mon = xf86InterpretEDID(handle->scrnIndex,EDIDBlock);
xf86PrintEDID(mon);
- xfree(mon);
+ free(mon);
}
return EDIDBlock;
@@ -841,6 +901,7 @@ rhdAtomCVGetTimings(atomBiosHandlePtr handle, AtomBiosRequestID func,
DisplayModePtr new = NULL;
DisplayModePtr first = NULL;
int i;
+ uint16_t size;
data->modes = NULL;
@@ -848,12 +909,11 @@ rhdAtomCVGetTimings(atomBiosHandlePtr handle, AtomBiosRequestID func,
if (!rhdAtomGetTableRevisionAndSize(
(ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->ComponentVideoInfo.base),
- &frev,&crev,NULL)) {
+ &crev,&frev,&size)) {
return ATOM_FAILED;
}
switch (frev) {
-
case 1:
switch (func) {
case ATOMBIOS_GET_CV_MODES:
@@ -887,6 +947,11 @@ rhdAtomCVGetTimings(atomBiosHandlePtr handle, AtomBiosRequestID func,
switch (func) {
case ATOMBIOS_GET_CV_MODES:
for (i = 0; i < MAX_SUPPORTED_CV_STANDARDS; i++) {
+ /* my rv730 table has only room for one mode */
+ if ((void *)&atomDataPtr->ComponentVideoInfo.ComponentVideoInfo_v21->aModeTimings[i] -
+ atomDataPtr->ComponentVideoInfo.base > size)
+ break;
+
new = rhdAtomDTDTimings(handle,
&atomDataPtr->ComponentVideoInfo
.ComponentVideoInfo_v21->aModeTimings[i]);
@@ -1377,17 +1442,19 @@ const int object_connector_convert[] =
CONNECTOR_CTV,
CONNECTOR_STV,
CONNECTOR_NONE,
+ CONNECTOR_NONE,
CONNECTOR_DIN,
CONNECTOR_SCART,
CONNECTOR_HDMI_TYPE_A,
CONNECTOR_HDMI_TYPE_B,
- CONNECTOR_HDMI_TYPE_B,
CONNECTOR_LVDS,
CONNECTOR_DIN,
CONNECTOR_NONE,
CONNECTOR_NONE,
CONNECTOR_NONE,
CONNECTOR_DISPLAY_PORT,
+ CONNECTOR_EDP,
+ CONNECTOR_NONE,
};
xf86MonPtr radeon_atom_get_edid(xf86OutputPtr output)
@@ -1448,9 +1515,11 @@ RADEONLookupGPIOLineForDDC(ScrnInfoPtr pScrn, uint8_t id)
{
RADEONInfoPtr info = RADEONPTR (pScrn);
atomDataTablesPtr atomDataPtr;
- ATOM_GPIO_I2C_ASSIGMENT gpio;
+ ATOM_GPIO_I2C_ASSIGMENT *gpio;
RADEONI2CBusRec i2c;
uint8_t crev, frev;
+ unsigned short size;
+ int i, num_indices;
memset(&i2c, 0, sizeof(RADEONI2CBusRec));
i2c.valid = FALSE;
@@ -1459,53 +1528,73 @@ RADEONLookupGPIOLineForDDC(ScrnInfoPtr pScrn, uint8_t id)
if (!rhdAtomGetTableRevisionAndSize(
&(atomDataPtr->GPIO_I2C_Info->sHeader),
- &crev,&frev,NULL)) {
+ &crev,&frev,&size)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No GPIO Info Table found!\n");
return i2c;
}
- gpio = atomDataPtr->GPIO_I2C_Info->asGPIO_Info[id];
- i2c.mask_clk_reg = le16_to_cpu(gpio.usClkMaskRegisterIndex) * 4;
- i2c.mask_data_reg = le16_to_cpu(gpio.usDataMaskRegisterIndex) * 4;
- i2c.put_clk_reg = le16_to_cpu(gpio.usClkEnRegisterIndex) * 4;
- i2c.put_data_reg = le16_to_cpu(gpio.usDataEnRegisterIndex) * 4;
- i2c.get_clk_reg = le16_to_cpu(gpio.usClkY_RegisterIndex) * 4;
- i2c.get_data_reg = le16_to_cpu(gpio.usDataY_RegisterIndex) * 4;
- i2c.a_clk_reg = le16_to_cpu(gpio.usClkA_RegisterIndex) * 4;
- i2c.a_data_reg = le16_to_cpu(gpio.usDataA_RegisterIndex) * 4;
- i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift);
- i2c.mask_data_mask = (1 << gpio.ucDataMaskShift);
- i2c.put_clk_mask = (1 << gpio.ucClkEnShift);
- i2c.put_data_mask = (1 << gpio.ucDataEnShift);
- i2c.get_clk_mask = (1 << gpio.ucClkY_Shift);
- 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;
+ num_indices = size / sizeof(ATOM_GPIO_I2C_ASSIGMENT);
+
+ for (i = 0; i < num_indices; i++) {
+ gpio = &atomDataPtr->GPIO_I2C_Info->asGPIO_Info[i];
+
+ if (IS_DCE4_VARIANT) {
+ if ((i == 7) &&
+ (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) &&
+ (gpio->sucI2cId.ucAccess == 0)) {
+ gpio->sucI2cId.ucAccess = 0x97;
+ gpio->ucDataMaskShift = 8;
+ gpio->ucDataEnShift = 8;
+ gpio->ucDataY_Shift = 8;
+ gpio->ucDataA_Shift = 8;
+ }
+ }
+
+ if (gpio->sucI2cId.ucAccess == id) {
+ i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
+ i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
+ i2c.put_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
+ i2c.put_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4;
+ i2c.get_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4;
+ i2c.get_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4;
+ i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4;
+ i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4;
+ i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift);
+ i2c.mask_data_mask = (1 << gpio->ucDataMaskShift);
+ i2c.put_clk_mask = (1 << gpio->ucClkEnShift);
+ i2c.put_data_mask = (1 << gpio->ucDataEnShift);
+ i2c.get_clk_mask = (1 << gpio->ucClkY_Shift);
+ 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.ucAccess;
+ i2c.hw_capable = gpio->sucI2cId.sbfAccess.bfHW_Capable;
+ i2c.valid = TRUE;
+ break;
+ }
+ }
#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);
- ErrorF("put_data_reg: 0x%x\n", gpio.usDataEnRegisterIndex * 4);
- ErrorF("get_clk_reg: 0x%x\n", gpio.usClkY_RegisterIndex * 4);
- ErrorF("get_data_reg: 0x%x\n", gpio.usDataY_RegisterIndex * 4);
- ErrorF("a_clk_reg: 0x%x\n", gpio.usClkA_RegisterIndex * 4);
- ErrorF("a_data_reg: 0x%x\n", gpio.usDataA_RegisterIndex * 4);
- ErrorF("mask_clk_mask: %d\n", gpio.ucClkMaskShift);
- ErrorF("mask_data_mask: %d\n", gpio.ucDataMaskShift);
- ErrorF("put_clk_mask: %d\n", gpio.ucClkEnShift);
- ErrorF("put_data_mask: %d\n", gpio.ucDataEnShift);
- ErrorF("get_clk_mask: %d\n", gpio.ucClkY_Shift);
- ErrorF("get_data_mask: %d\n", gpio.ucDataY_Shift);
- ErrorF("a_clk_mask: %d\n", gpio.ucClkA_Shift);
- ErrorF("a_data_mask: %d\n", gpio.ucDataA_Shift);
+ 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", le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4);
+ ErrorF("mask_data_reg: 0x%x\n", le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4);
+ ErrorF("put_clk_reg: 0x%x\n", le16_to_cpu(gpio->usClkEnRegisterIndex) * 4);
+ ErrorF("put_data_reg: 0x%x\n", le16_to_cpu(gpio->usDataEnRegisterIndex) * 4);
+ ErrorF("get_clk_reg: 0x%x\n", le16_to_cpu(gpio->usClkY_RegisterIndex) * 4);
+ ErrorF("get_data_reg: 0x%x\n", le16_to_cpu(gpio->usDataY_RegisterIndex) * 4);
+ ErrorF("a_clk_reg: 0x%x\n", le16_to_cpu(gpio->usClkA_RegisterIndex) * 4);
+ ErrorF("a_data_reg: 0x%x\n", le16_to_cpu(gpio->usDataA_RegisterIndex) * 4);
+ ErrorF("mask_clk_mask: %d\n", gpio->ucClkMaskShift);
+ ErrorF("mask_data_mask: %d\n", gpio->ucDataMaskShift);
+ ErrorF("put_clk_mask: %d\n", gpio->ucClkEnShift);
+ ErrorF("put_data_mask: %d\n", gpio->ucDataEnShift);
+ ErrorF("get_clk_mask: %d\n", gpio->ucClkY_Shift);
+ ErrorF("get_data_mask: %d\n", gpio->ucDataY_Shift);
+ ErrorF("a_clk_mask: %d\n", gpio->ucClkA_Shift);
+ ErrorF("a_data_mask: %d\n", gpio->ucDataA_Shift);
#endif
return i2c;
@@ -1516,9 +1605,74 @@ rhdAtomParseI2CRecord(ScrnInfoPtr pScrn, atomBiosHandlePtr handle,
ATOM_I2C_RECORD *Record, int i)
{
RADEONInfoPtr info = RADEONPTR (pScrn);
+ uint8_t *temp = &Record->sucI2cId;
+
+ info->BiosConnector[i].i2c_line_mux = *temp;
+ info->BiosConnector[i].ucI2cId = *temp;
+ return RADEONLookupGPIOLineForDDC(pScrn, *temp);
+}
+
+static uint8_t
+radeon_lookup_hpd_id(ScrnInfoPtr pScrn, ATOM_HPD_INT_RECORD *record)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ unsigned short size;
+ uint8_t hpd = 0;
+ int i, num_indices;
+ struct _ATOM_GPIO_PIN_LUT *gpio_info;
+ ATOM_GPIO_PIN_ASSIGNMENT *pin;
+ atomDataTablesPtr atomDataPtr;
+ uint8_t crev, frev;
+ uint32_t reg;
+
+ atomDataPtr = info->atomBIOS->atomDataPtr;
+
+ if (!rhdAtomGetTableRevisionAndSize(
+ &(atomDataPtr->GPIO_Pin_LUT->sHeader),
+ &crev,&frev,&size)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No GPIO Pin Table found!\n");
+ return hpd;
+ }
+
+ num_indices = size / sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
+
+ if (IS_DCE4_VARIANT)
+ reg = EVERGREEN_DC_GPIO_HPD_A;
+ else
+ reg = AVIVO_DC_GPIO_HPD_A;
+
+ gpio_info = atomDataPtr->GPIO_Pin_LUT;
+ for (i = 0; i < num_indices; i++) {
+ pin = &gpio_info->asGPIO_Pin[i];
+ if (record->ucHPDIntGPIOID == pin->ucGPIO_ID) {
+ if ((le16_to_cpu(pin->usGpioPin_AIndex) * 4) == reg) {
+ switch (pin->ucGpioPinBitShift) {
+ case 0:
+ default:
+ hpd = 0;
+ break;
+ case 8:
+ hpd = 1;
+ break;
+ case 16:
+ hpd = 2;
+ break;
+ case 24:
+ hpd = 3;
+ break;
+ case 26:
+ hpd = 4;
+ break;
+ case 28:
+ hpd = 5;
+ break;
+ }
+ break;
+ }
+ }
+ }
- info->BiosConnector[i].i2c_line_mux = Record->sucI2cId.bfI2C_LineMux;
- return RADEONLookupGPIOLineForDDC(pScrn, Record->sucI2cId.bfI2C_LineMux);
+ return hpd;
}
static void RADEONApplyATOMQuirks(ScrnInfoPtr pScrn, int index)
@@ -1534,6 +1688,17 @@ static void RADEONApplyATOMQuirks(ScrnInfoPtr pScrn, int index)
info->BiosConnector[index].ConnectorType = CONNECTOR_DVI_D;
}
}
+
+ /* RS600 board lists the DVI port as HDMI */
+ if ((info->Chipset == PCI_CHIP_RS600_7941) &&
+ (PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1849) &&
+ (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x7941)) {
+ if ((info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A) &&
+ (info->BiosConnector[index].devices & ATOM_DEVICE_DFP3_SUPPORT)) {
+ info->BiosConnector[index].ConnectorType = CONNECTOR_DVI_D;
+ }
+ }
+
/* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */
if ((info->Chipset == PCI_CHIP_RS600_7941) &&
(PCI_SUB_VENDOR_ID(info->PciInfo) == 0x147b) &&
@@ -1565,20 +1730,32 @@ static void RADEONApplyATOMQuirks(ScrnInfoPtr pScrn, int index)
}
}
- /* some BIOSes seem to report DAC on HDMI - they hurt me with their lies */
- if ((info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A) ||
- (info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_B)) {
- info->BiosConnector[index].devices &= ~(ATOM_DEVICE_CRT_SUPPORT);
- }
-
/* ASUS HD 3600 XT board lists the DVI port as HDMI */
if ((info->Chipset == PCI_CHIP_RV635_9598) &&
(PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1043) &&
(PCI_SUB_DEVICE_ID(info->PciInfo) == 0x01da)) {
- if (info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_B)
- info->BiosConnector[index].ConnectorType = CONNECTOR_DVI_D;
+ if (info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A)
+ info->BiosConnector[index].ConnectorType = CONNECTOR_DVI_I;
}
+ /* ASUS HD 3450 board lists the DVI port as HDMI */
+ if ((info->Chipset == PCI_CHIP_RV620_95C5) &&
+ (PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1043) &&
+ (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x01e2)) {
+ if (info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A)
+ info->BiosConnector[index].ConnectorType = CONNECTOR_DVI_I;
+ }
+
+ /* some BIOSes seem to report DAC on HDMI - usually this is a board with
+ * HDMI + VGA reporting as HDMI
+ */
+ if (info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A) {
+ if (info->BiosConnector[index].devices & (ATOM_DEVICE_CRT_SUPPORT)) {
+ info->BiosConnector[index].devices &= ~(ATOM_DEVICE_DFP_SUPPORT);
+ info->BiosConnector[index].ConnectorType = CONNECTOR_VGA;
+ info->BiosConnector[index].connector_object = 0;
+ }
+ }
}
@@ -1638,9 +1815,9 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo
if (device_support & ATOM_DEVICE_LCD1_SUPPORT) {
if (info->encoders[device_index]->dev_priv == NULL) {
info->encoders[device_index]->dev_priv =
- (radeon_lvds_ptr)xcalloc(1,sizeof(radeon_lvds_rec));
+ (radeon_lvds_ptr)calloc(1,sizeof(radeon_lvds_rec));
if (info->encoders[device_index]->dev_priv == NULL) {
- ErrorF("xalloc failed\n");
+ ErrorF("calloc failed\n");
return FALSE;
} else
RADEONGetATOMLVDSInfo(pScrn, (radeon_lvds_ptr)info->encoders[device_index]->dev_priv);
@@ -1652,7 +1829,7 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo
}
}
- info->encoders[device_index] = (radeon_encoder_ptr)xcalloc(1,sizeof(radeon_encoder_rec));
+ info->encoders[device_index] = (radeon_encoder_ptr)calloc(1,sizeof(radeon_encoder_rec));
if (info->encoders[device_index] != NULL) {
info->encoders[device_index]->ref_count++;
info->encoders[device_index]->encoder_id = encoder_id;
@@ -1661,9 +1838,9 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo
// add dev_priv stuff
switch (encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
- info->encoders[device_index]->dev_priv = (radeon_lvds_ptr)xcalloc(1,sizeof(radeon_lvds_rec));
+ info->encoders[device_index]->dev_priv = (radeon_lvds_ptr)calloc(1,sizeof(radeon_lvds_rec));
if (info->encoders[device_index]->dev_priv == NULL) {
- ErrorF("xalloc failed\n");
+ ErrorF("calloc failed\n");
return FALSE;
} else {
if (info->IsAtomBios)
@@ -1674,9 +1851,9 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC2:
if (!IS_AVIVO_VARIANT) {
- info->encoders[device_index]->dev_priv = (radeon_tvdac_ptr)xcalloc(1,sizeof(radeon_tvdac_rec));
+ info->encoders[device_index]->dev_priv = (radeon_tvdac_ptr)calloc(1,sizeof(radeon_tvdac_rec));
if (info->encoders[device_index]->dev_priv == NULL) {
- ErrorF("xalloc failed\n");
+ ErrorF("calloc failed\n");
return FALSE;
} else
RADEONGetTVDacAdjInfo(pScrn, (radeon_tvdac_ptr)info->encoders[device_index]->dev_priv);
@@ -1684,9 +1861,9 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo
break;
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
if (!IS_AVIVO_VARIANT) {
- info->encoders[device_index]->dev_priv = (radeon_tmds_ptr)xcalloc(1,sizeof(radeon_tmds_rec));
+ info->encoders[device_index]->dev_priv = (radeon_tmds_ptr)calloc(1,sizeof(radeon_tmds_rec));
if (info->encoders[device_index]->dev_priv == NULL) {
- ErrorF("xalloc failed\n");
+ ErrorF("calloc failed\n");
return FALSE;
} else
RADEONGetTMDSInfo(pScrn, (radeon_tmds_ptr)info->encoders[device_index]->dev_priv);
@@ -1694,9 +1871,9 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo
break;
case ENCODER_OBJECT_ID_INTERNAL_DVO1:
if (!IS_AVIVO_VARIANT) {
- info->encoders[device_index]->dev_priv = (radeon_dvo_ptr)xcalloc(1,sizeof(radeon_dvo_rec));
+ info->encoders[device_index]->dev_priv = (radeon_dvo_ptr)calloc(1,sizeof(radeon_dvo_rec));
if (info->encoders[device_index]->dev_priv == NULL) {
- ErrorF("xalloc failed\n");
+ ErrorF("calloc failed\n");
return FALSE;
} else
RADEONGetExtTMDSInfo(pScrn, (radeon_dvo_ptr)info->encoders[device_index]->dev_priv);
@@ -1708,9 +1885,9 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
if (device_support & ATOM_DEVICE_LCD1_SUPPORT) {
- info->encoders[device_index]->dev_priv = (radeon_lvds_ptr)xcalloc(1,sizeof(radeon_lvds_rec));
+ info->encoders[device_index]->dev_priv = (radeon_lvds_ptr)calloc(1,sizeof(radeon_lvds_rec));
if (info->encoders[device_index]->dev_priv == NULL) {
- ErrorF("xalloc failed\n");
+ ErrorF("calloc failed\n");
return FALSE;
} else
RADEONGetATOMLVDSInfo(pScrn, (radeon_lvds_ptr)info->encoders[device_index]->dev_priv);
@@ -1719,7 +1896,7 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo
}
return TRUE;
} else {
- ErrorF("xalloc failed\n");
+ ErrorF("calloc failed\n");
return FALSE;
}
}
@@ -1763,17 +1940,17 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
ATOM_DISPLAY_OBJECT_PATH *path;
addr += path_size;
path = (ATOM_DISPLAY_OBJECT_PATH *)addr;
- path_size += path->usSize;
+ path_size += le16_to_cpu(path->usSize);
- if (device_support & path->usDeviceTag) {
+ if (device_support & le16_to_cpu(path->usDeviceTag)) {
uint8_t con_obj_id, con_obj_num, con_obj_type;
- con_obj_id = (path->usConnObjectId & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
- con_obj_num = (path->usConnObjectId & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
- con_obj_type = (path->usConnObjectId & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
+ con_obj_id = (le16_to_cpu(path->usConnObjectId) & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+ con_obj_num = (le16_to_cpu(path->usConnObjectId) & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
+ con_obj_type = (le16_to_cpu(path->usConnObjectId) & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
- if ((path->usDeviceTag == ATOM_DEVICE_TV1_SUPPORT) ||
- (path->usDeviceTag == ATOM_DEVICE_TV2_SUPPORT)) {
+ if ((le16_to_cpu(path->usDeviceTag) == ATOM_DEVICE_TV1_SUPPORT) ||
+ (le16_to_cpu(path->usDeviceTag) == ATOM_DEVICE_TV2_SUPPORT)) {
if (!enable_tv) {
info->BiosConnector[i].valid = FALSE;
continue;
@@ -1781,7 +1958,7 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
}
/* don't support CV yet */
- if (path->usDeviceTag == ATOM_DEVICE_CV_SUPPORT) {
+ if (le16_to_cpu(path->usDeviceTag) == ATOM_DEVICE_CV_SUPPORT) {
info->BiosConnector[i].valid = FALSE;
continue;
}
@@ -1802,25 +1979,28 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
ct = (slot_config >> 16) & 0xff;
info->BiosConnector[i].ConnectorType = object_connector_convert[ct];
+ info->BiosConnector[i].connector_object_id = ct;
info->BiosConnector[i].igp_lane_info = slot_config & 0xffff;
}
- } else
+ } else {
info->BiosConnector[i].ConnectorType = object_connector_convert[con_obj_id];
+ info->BiosConnector[i].connector_object_id = con_obj_id;
+ }
if (info->BiosConnector[i].ConnectorType == CONNECTOR_NONE) {
info->BiosConnector[i].valid = FALSE;
continue;
} else
info->BiosConnector[i].valid = TRUE;
- info->BiosConnector[i].devices = path->usDeviceTag;
- info->BiosConnector[i].connector_object = path->usConnObjectId;
+ info->BiosConnector[i].devices = le16_to_cpu(path->usDeviceTag);
+ info->BiosConnector[i].connector_object = le16_to_cpu(path->usConnObjectId);
- for (j = 0; j < ((path->usSize - 8) / 2); j++) {
+ for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) {
uint8_t enc_obj_id, enc_obj_num, enc_obj_type;
- enc_obj_id = (path->usGraphicObjIds[j] & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
- enc_obj_num = (path->usGraphicObjIds[j] & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
- enc_obj_type = (path->usGraphicObjIds[j] & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
+ enc_obj_id = (le16_to_cpu(path->usGraphicObjIds[j]) & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+ enc_obj_num = (le16_to_cpu(path->usGraphicObjIds[j]) & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
+ enc_obj_type = (le16_to_cpu(path->usGraphicObjIds[j]) & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
if (enc_obj_type == GRAPH_OBJECT_TYPE_ENCODER) {
if (enc_obj_num == 2)
@@ -1828,15 +2008,15 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
else
info->BiosConnector[i].linkb = FALSE;
- if (!radeon_add_encoder(pScrn, enc_obj_id, path->usDeviceTag))
+ if (!radeon_add_encoder(pScrn, enc_obj_id, le16_to_cpu(path->usDeviceTag)))
return FALSE;
}
}
/* look up gpio for ddc */
- if ((path->usDeviceTag & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) {
+ if ((le16_to_cpu(path->usDeviceTag) & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) {
for (j = 0; j < con_obj->ucNumberOfObjects; j++) {
- if (path->usConnObjectId == le16_to_cpu(con_obj->asObjects[j].usObjectID)) {
+ if (le16_to_cpu(path->usConnObjectId) == le16_to_cpu(con_obj->asObjects[j].usObjectID)) {
ATOM_COMMON_RECORD_HEADER *Record = (ATOM_COMMON_RECORD_HEADER *)
((char *)&atomDataPtr->Object_Header->sHeader
+ le16_to_cpu(con_obj->asObjects[j].usRecordOffset));
@@ -1852,6 +2032,9 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
(ATOM_I2C_RECORD *)Record, j);
break;
case ATOM_HPD_INT_RECORD_TYPE:
+ info->BiosConnector[i].hpd_id =
+ radeon_lookup_hpd_id(pScrn,
+ (ATOM_HPD_INT_RECORD *)Record);
break;
case ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE:
break;
@@ -1883,7 +2066,6 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
if (info->BiosConnector[j].valid && (i != j) ) {
if (info->BiosConnector[i].i2c_line_mux == info->BiosConnector[j].i2c_line_mux) {
- ErrorF("Shared DDC line: %d %d\n", i, j);
info->BiosConnector[i].shared_ddc = TRUE;
info->BiosConnector[j].shared_ddc = TRUE;
}
@@ -1902,6 +2084,7 @@ RADEONGetATOMLVDSInfo(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds)
radeon_native_mode_ptr native_mode = &lvds->native_mode;
atomDataTablesPtr atomDataPtr;
uint8_t crev, frev;
+ uint16_t misc;
atomDataPtr = info->atomBIOS->atomDataPtr;
@@ -1922,6 +2105,17 @@ RADEONGetATOMLVDSInfo(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds)
native_mode->VBlank = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVBlanking_Time);
native_mode->VOverPlus = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVSyncOffset);
native_mode->VSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVSyncWidth);
+ misc = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.susModeMiscInfo.usAccess);
+ if (misc & ATOM_VSYNC_POLARITY)
+ native_mode->Flags |= V_NVSYNC;
+ if (misc & ATOM_HSYNC_POLARITY)
+ native_mode->Flags |= V_NHSYNC;
+ if (misc & ATOM_COMPOSITESYNC)
+ native_mode->Flags |= V_CSYNC;
+ if (misc & ATOM_INTERLACE)
+ native_mode->Flags |= V_INTERLACE;
+ if (misc & ATOM_DOUBLE_CLOCK_MODE)
+ native_mode->Flags |= V_DBLSCAN;
lvds->PanelPwrDly = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->usOffDelayInMs);
lvds->lvds_misc = atomDataPtr->LVDS_Info.LVDS_Info->ucLVDS_Misc;
lvds->lvds_ss_id = atomDataPtr->LVDS_Info.LVDS_Info->ucSS_Id;
@@ -1936,6 +2130,17 @@ RADEONGetATOMLVDSInfo(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds)
native_mode->VBlank = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVBlanking_Time);
native_mode->VOverPlus = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVSyncOffset);
native_mode->VSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVSyncWidth);
+ misc = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.susModeMiscInfo.usAccess);
+ if (misc & ATOM_VSYNC_POLARITY)
+ native_mode->Flags |= V_NVSYNC;
+ if (misc & ATOM_HSYNC_POLARITY)
+ native_mode->Flags |= V_NHSYNC;
+ if (misc & ATOM_COMPOSITESYNC)
+ native_mode->Flags |= V_CSYNC;
+ if (misc & ATOM_INTERLACE)
+ native_mode->Flags |= V_INTERLACE;
+ if (misc & ATOM_DOUBLE_CLOCK_MODE)
+ native_mode->Flags |= V_DBLSCAN;
lvds->PanelPwrDly = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->usOffDelayInMs);
lvds->lvds_misc = atomDataPtr->LVDS_Info.LVDS_Info_v12->ucLVDS_Misc;
lvds->lvds_ss_id = atomDataPtr->LVDS_Info.LVDS_Info_v12->ucSS_Id;
@@ -1956,6 +2161,35 @@ RADEONGetATOMLVDSInfo(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds)
native_mode->VBlank, native_mode->VOverPlus, native_mode->VSyncWidth);
}
+void
+RADEONATOMGetIGPInfo(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ atomDataTablesPtr atomDataPtr;
+ unsigned short size;
+ uint8_t crev, frev;
+
+ atomDataPtr = info->atomBIOS->atomDataPtr;
+
+ if (!rhdAtomGetTableRevisionAndSize((ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->IntegratedSystemInfo.base), &frev, &crev, &size))
+ return;
+
+ switch (crev) {
+ case 1:
+ info->igp_sideport_mclk = atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo->ulBootUpMemoryClock / 100.0;
+ info->igp_system_mclk = le16_to_cpu(atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo->usK8MemoryClock);
+ info->igp_ht_link_clk = le16_to_cpu(atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo->usFSBClock);
+ info->igp_ht_link_width = atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo->ucHTLinkWidth;
+ break;
+ case 2:
+ info->igp_sideport_mclk = atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2->ulBootUpSidePortClock / 100.0;
+ info->igp_system_mclk = atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2->ulBootUpUMAClock / 100.0;
+ info->igp_ht_link_clk = atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2->ulHTLinkFreq / 100.0;
+ info->igp_ht_link_width = le16_to_cpu(atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2->usMinHTLinkWidth);
+ break;
+ }
+}
+
Bool
RADEONGetATOMTVInfo(xf86OutputPtr output)
{
@@ -2029,7 +2263,76 @@ RADEONGetATOMTVInfo(xf86OutputPtr output)
}
Bool
-RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, int32_t *pixel_clock)
+RADEONGetATOMClockInfo(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ RADEONPLLPtr pll = &info->pll;
+ atomDataTablesPtr atomDataPtr;
+ uint8_t crev, frev;
+
+ atomDataPtr = info->atomBIOS->atomDataPtr;
+ if (!rhdAtomGetTableRevisionAndSize(
+ (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->FirmwareInfo.base),
+ &crev,&frev,NULL)) {
+ return FALSE;
+ }
+
+ switch(crev) {
+ case 1:
+ info->sclk = le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->ulDefaultEngineClock) / 100.0;
+ info->mclk = le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->ulDefaultMemoryClock) / 100.0;
+ pll->xclk = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->usMaxPixelClock);
+ pll->pll_in_min = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->usMinPixelClockPLL_Input);
+ pll->pll_in_max = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->usMaxPixelClockPLL_Input);
+ pll->pll_out_min = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->usMinPixelClockPLL_Output);
+ pll->pll_out_max = le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->ulMaxPixelClockPLL_Output);
+ pll->reference_freq = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo->usReferenceClock);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ default:
+ info->sclk = le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->ulDefaultEngineClock) / 100.0;
+ info->mclk = le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->ulDefaultMemoryClock) / 100.0;
+ pll->xclk = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->usMaxPixelClock);
+ pll->pll_in_min = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->usMinPixelClockPLL_Input);
+ pll->pll_in_max = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->usMaxPixelClockPLL_Input);
+ pll->pll_out_min = le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->ulMinPixelClockPLL_Output);
+ pll->pll_out_max = le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->ulMaxPixelClockPLL_Output);
+ pll->reference_freq = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_1_2->usReferenceClock);
+ break;
+ }
+ pll->reference_div = 0;
+ if (pll->pll_out_min == 0) {
+ if (IS_AVIVO_VARIANT)
+ pll->pll_out_min = 64800;
+ else
+ pll->pll_out_min = 20000;
+ }
+
+ /* limiting the range is a good thing in most cases
+ * as it limits the number of matching pll combinations,
+ * however, some duallink DVI monitors seem to prefer combinations that
+ * would be limited by this. This may need to be revisited
+ * per chip family.
+ */
+ if (!xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, TRUE)) {
+ if (pll->pll_out_min > 64800)
+ pll->pll_out_min = 64800;
+ }
+
+ if (IS_DCE4_VARIANT) {
+ info->default_dispclk =
+ le32_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_2_1->ulDefaultDispEngineClkFreq);
+ if (info->default_dispclk == 0)
+ info->default_dispclk = 60000;
+ info->dp_extclk = le16_to_cpu(atomDataPtr->FirmwareInfo.FirmwareInfo_V_2_1->usUniphyDPModeExtClkFreq);
+ }
+ return TRUE;
+}
+
+Bool
+RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, DisplayModePtr mode)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
ATOM_ANALOG_TV_INFO *tv_info;
@@ -2037,6 +2340,7 @@ RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_
ATOM_DTD_FORMAT *dtd_timings;
atomDataTablesPtr atomDataPtr;
uint8_t crev, frev;
+ uint16_t misc;
atomDataPtr = info->atomBIOS->atomDataPtr;
if (!rhdAtomGetTableRevisionAndSize(
@@ -2048,32 +2352,41 @@ RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_
switch(crev) {
case 1:
tv_info = atomDataPtr->AnalogTV_Info.AnalogTV_Info;
-
+
if (index > MAX_SUPPORTED_TV_TIMING)
return FALSE;
-
- crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
- crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp);
- crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart);
- crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth);
-
- crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total);
- crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp);
- crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart);
- crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth);
-
- crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo;
-
- crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight);
- crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft);
- crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom);
- crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop);
- *pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10;
+
+ mode->CrtcHTotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
+ mode->CrtcHDisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp);
+ mode->CrtcHSyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart);
+ mode->CrtcHSyncEnd = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart) +
+ le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth);
+
+ mode->CrtcVTotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total);
+ mode->CrtcVDisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp);
+ mode->CrtcVSyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart);
+ mode->CrtcVSyncEnd = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart) +
+ le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth);
+
+ mode->Flags = 0;
+ misc = le16_to_cpu(tv_info->aModeTimings[index].susModeMiscInfo.usAccess);
+ if (misc & ATOM_VSYNC_POLARITY)
+ mode->Flags |= V_NVSYNC;
+ if (misc & ATOM_HSYNC_POLARITY)
+ mode->Flags |= V_NHSYNC;
+ if (misc & ATOM_COMPOSITESYNC)
+ mode->Flags |= V_CSYNC;
+ if (misc & ATOM_INTERLACE)
+ mode->Flags |= V_INTERLACE;
+ if (misc & ATOM_DOUBLE_CLOCK_MODE)
+ mode->Flags |= V_DBLSCAN;
+
+ mode->Clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10;
if (index == 1) {
/* PAL timings appear to have wrong values for totals */
- crtc_timing->usH_Total -= 1;
- crtc_timing->usV_Total -= 1;
+ mode->CrtcHTotal -= 1;
+ mode->CrtcVTotal -= 1;
}
break;
case 2:
@@ -2082,18 +2395,31 @@ RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_
return FALSE;
dtd_timings = &tv_info_v1_2->aModeTimings[index];
- crtc_timing->usH_Total = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time);
- crtc_timing->usH_Disp = le16_to_cpu(dtd_timings->usHActive);
- crtc_timing->usH_SyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset);
- crtc_timing->usH_SyncWidth = le16_to_cpu(dtd_timings->usHSyncWidth);
-
- crtc_timing->usV_Total = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time);
- crtc_timing->usV_Disp = le16_to_cpu(dtd_timings->usVActive);
- crtc_timing->usV_SyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset);
- crtc_timing->usV_SyncWidth = le16_to_cpu(dtd_timings->usVSyncWidth);
-
- crtc_timing->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess);
- *pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10;
+ mode->CrtcHTotal = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time);
+ mode->CrtcHDisplay = le16_to_cpu(dtd_timings->usHActive);
+ mode->CrtcHSyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset);
+ mode->CrtcHSyncEnd = mode->CrtcHSyncStart + le16_to_cpu(dtd_timings->usHSyncWidth);
+
+ mode->CrtcVTotal = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time);
+ mode->CrtcVDisplay = le16_to_cpu(dtd_timings->usVActive);
+ mode->CrtcVSyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset);
+ mode->CrtcVSyncEnd = mode->CrtcVSyncStart + le16_to_cpu(dtd_timings->usVSyncWidth);
+
+ mode->Flags = 0;
+ misc = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess);
+ if (misc & ATOM_VSYNC_POLARITY)
+ mode->Flags |= V_NVSYNC;
+ if (misc & ATOM_HSYNC_POLARITY)
+ mode->Flags |= V_NHSYNC;
+ if (misc & ATOM_COMPOSITESYNC)
+ mode->Flags |= V_CSYNC;
+ if (misc & ATOM_INTERLACE)
+ mode->Flags |= V_INTERLACE;
+ if (misc & ATOM_DOUBLE_CLOCK_MODE)
+ mode->Flags |= V_DBLSCAN;
+
+ mode->Clock = le16_to_cpu(dtd_timings->usPixClk) * 10;
+
break;
}
@@ -2226,7 +2552,7 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
info->BiosConnector[i].valid = TRUE;
info->BiosConnector[i].load_detection = TRUE;
info->BiosConnector[i].shared_ddc = FALSE;
- info->BiosConnector[i].output_id = ci.sucI2cId.sbfAccess.bfI2C_LineMux;
+ info->BiosConnector[i].output_id = ci.sucI2cId.ucAccess;
info->BiosConnector[i].devices = (1 << i);
info->BiosConnector[i].ConnectorType = ci.sucConnectorInfo.sbfAccess.bfConnectorType;
@@ -2240,18 +2566,9 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
(i == ATOM_DEVICE_TV2_INDEX) ||
(i == ATOM_DEVICE_CV_INDEX))
info->BiosConnector[i].ddc_i2c.valid = FALSE;
- else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
- (info->ChipFamily == CHIP_FAMILY_RS740)) {
- /* IGP DFP ports use non-standard gpio entries */
- if ((i == ATOM_DEVICE_DFP2_INDEX) || (i == ATOM_DEVICE_DFP3_INDEX))
- info->BiosConnector[i].ddc_i2c =
- RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1);
- else
- info->BiosConnector[i].ddc_i2c =
- RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
- } else
+ else
info->BiosConnector[i].ddc_i2c =
- RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
+ RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.ucAccess);
if (!radeon_add_encoder(pScrn,
radeon_get_encoder_id_from_supported_device(pScrn, (1 << i),
@@ -2305,6 +2622,8 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
((j == ATOM_DEVICE_CRT1_INDEX) ||
(j == ATOM_DEVICE_CRT2_INDEX))) {
info->BiosConnector[i].devices |= info->BiosConnector[j].devices;
+ if (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D)
+ info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_I;
info->BiosConnector[j].valid = FALSE;
} else if (((j == ATOM_DEVICE_DFP1_INDEX) ||
(j == ATOM_DEVICE_DFP2_INDEX) ||
@@ -2312,6 +2631,8 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
((i == ATOM_DEVICE_CRT1_INDEX) ||
(i == ATOM_DEVICE_CRT2_INDEX))) {
info->BiosConnector[j].devices |= info->BiosConnector[i].devices;
+ if (info->BiosConnector[j].ConnectorType == CONNECTOR_DVI_D)
+ info->BiosConnector[j].ConnectorType = CONNECTOR_DVI_I;
info->BiosConnector[i].valid = FALSE;
} else {
info->BiosConnector[i].shared_ddc = TRUE;
@@ -2324,12 +2645,6 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
}
}
- for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
- if (info->encoders[i] != NULL) {
- ErrorF("encoder: 0x%x\n", info->encoders[i]->encoder_id);
- }
- }
-
return TRUE;
}
@@ -2474,12 +2789,20 @@ UINT32
CailReadATIRegister(VOID* CAIL, UINT32 idx)
{
ScrnInfoPtr pScrn = xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
unsigned char *RADEONMMIO = pRADEONEnt->MMIO;
UINT32 ret;
+ UINT32 mm_reg = idx << 2;
CAILFUNC(CAIL);
- ret = INREG(idx << 2);
+ if (mm_reg < info->MMIOSize)
+ ret = INREG(mm_reg);
+ else {
+ OUTREG(RADEON_MM_INDEX, mm_reg);
+ ret = INREG(RADEON_MM_DATA);
+ }
+
/*DEBUGP(ErrorF("%s(%x) = %x\n",__func__,idx << 2,ret));*/
return ret;
}
@@ -2488,11 +2811,19 @@ VOID
CailWriteATIRegister(VOID *CAIL, UINT32 idx, UINT32 data)
{
ScrnInfoPtr pScrn = xf86Screens[((atomBiosHandlePtr)CAIL)->scrnIndex];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
unsigned char *RADEONMMIO = pRADEONEnt->MMIO;
+ UINT32 mm_reg = idx << 2;
CAILFUNC(CAIL);
- OUTREG(idx << 2,data);
+ if (mm_reg < info->MMIOSize)
+ OUTREG(mm_reg, data);
+ else {
+ OUTREG(RADEON_MM_INDEX, mm_reg);
+ OUTREG(RADEON_MM_DATA, data);
+ }
+
/*DEBUGP(ErrorF("%s(%x,%x)\n",__func__,idx << 2,data));*/
}