diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2012-01-25 21:33:36 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2012-01-25 21:33:36 +0000 |
commit | 46e73e726a6a3567a4bb19b06c59826b9c6767d1 (patch) | |
tree | 8df52bebcc8ecbe55a8f8be1afae536b5fb46319 /driver/xf86-video-ati/src/radeon_atombios.c | |
parent | ee1cf1e0a2b9e0f7070a4d1efa6b426373e8ba67 (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.c | 647 |
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));*/ } |