diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | man/radeon.man | 16 | ||||
-rw-r--r-- | src/radeon.h | 33 | ||||
-rw-r--r-- | src/radeon_bios.c | 391 | ||||
-rw-r--r-- | src/radeon_crtc.c | 8 | ||||
-rw-r--r-- | src/radeon_cursor.c | 20 | ||||
-rw-r--r-- | src/radeon_display.c | 12 | ||||
-rw-r--r-- | src/radeon_driver.c | 192 | ||||
-rw-r--r-- | src/radeon_exa.c | 2 | ||||
-rw-r--r-- | src/radeon_exa_funcs.c | 19 | ||||
-rw-r--r-- | src/radeon_modes.c | 190 | ||||
-rw-r--r-- | src/radeon_output.c | 412 | ||||
-rw-r--r-- | src/radeon_probe.c | 2 | ||||
-rw-r--r-- | src/radeon_probe.h | 15 | ||||
-rw-r--r-- | src/radeon_reg.h | 10 | ||||
-rw-r--r-- | src/radeon_video.c | 27 | ||||
-rw-r--r-- | src/radeon_vip.c | 7 |
17 files changed, 748 insertions, 610 deletions
diff --git a/configure.ac b/configure.ac index 03b3440c..c662168e 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ AC_PREREQ(2.57) AC_INIT([xf86-video-ati], - 6.7.192, + 6.7.194, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-ati) diff --git a/man/radeon.man b/man/radeon.man index 88665bf0..35dd7010 100644 --- a/man/radeon.man +++ b/man/radeon.man @@ -397,6 +397,22 @@ driver defaults for each chip. The default is .B off .TP +.BI "Option \*qMacModel\*q \*q" string \*q +.br +Used to specify Mac models for connector tables and quirks. Only valid + on PowerPC. +.br +ibook \-\- ibooks +.br +powerbook-duallink \-\- Powerbooks with external DVI +.br +powerbook \-\- Powerbooks with integrated DVI +.br +mini \-\- Mac Mini +.br +The default value is +.B undefined. +.TP .SH SEE ALSO __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) diff --git a/src/radeon.h b/src/radeon.h index fa2bccdf..610e2b3e 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -149,10 +149,13 @@ typedef enum { OPTION_REVERSE_DDC, OPTION_LVDS_PROBE_PLL, OPTION_ACCELMETHOD, - OPTION_CONSTANTDPI, OPTION_CONNECTORTABLE, OPTION_DRI, - OPTION_DEFAULT_CONNECTOR_TABLE + OPTION_DEFAULT_CONNECTOR_TABLE, +#if defined(__powerpc__) + OPTION_MAC_MODEL, +#endif + OPTION_DEFAULT_TMDS_PLL } RADEONOpts; @@ -422,6 +425,15 @@ typedef enum { CHIP_ERRATA_PLL_DELAY = 0x00000004 } RADEONErrata; +#if defined(__powerpc__) +typedef enum { + RADEON_MAC_IBOOK = 0x00000001, + RADEON_MAC_POWERBOOK_DL = 0x00000002, + RADEON_MAC_POWERBOOK = 0x00000004, + RADEON_MAC_MINI = 0x00000008 +} RADEONMacModel; +#endif + typedef enum { CARD_PCI, CARD_AGP, @@ -776,9 +788,6 @@ typedef struct { DisplayModePtr currentMode, savedCurrentMode; - int constantDPI; /* -1 = auto, 0 = off, 1 = on */ - int RADEONDPIVX, RADEONDPIVY; - /* special handlings for DELL triple-head server */ Bool IsDellServer; @@ -801,6 +810,10 @@ typedef struct { Bool InternalTVOut; int tvdac_use_count; +#if defined(__powerpc__) + RADEONMacModel MacModel; +#endif + Rotation rotation; void (*PointerMoved)(int, int, int); CreateScreenResourcesProcPtr CreateScreenResources; @@ -927,7 +940,6 @@ extern Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn); extern int RADEONValidateMergeModes(ScrnInfoPtr pScrn); extern int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName, RADEONMonitorType DisplayType, int crtc2); -extern int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePtr *modeList); extern void RADEONSetPitch (ScrnInfoPtr pScrn); extern void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode); @@ -937,6 +949,15 @@ extern Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1, DisplayModePtr crtc2, int crtc_mask, RADEONSavePtr save, RADEONMonitorType montype); +extern Bool +RADEONDVOReadByte(I2CDevPtr dvo, int addr, CARD8 *ch); +extern Bool +RADEONDVOWriteByte(I2CDevPtr dvo, int addr, CARD8 ch); +extern Bool +RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output); +extern Bool +RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output); + void radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y); void diff --git a/src/radeon_bios.c b/src/radeon_bios.c index b24c4817..cfa5d2bc 100644 --- a/src/radeon_bios.c +++ b/src/radeon_bios.c @@ -41,20 +41,6 @@ #include "radeon_probe.h" #include "vbe.h" -int RADEONBIOSApplyConnectorQuirks(ScrnInfoPtr pScrn, int connector_found) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - - /* quirk for compaq nx6125 - the bios lies about the VGA DDC */ - if (info->PciInfo->subsysVendor == PCI_VENDOR_HP) { - if (info->PciInfo->subsysCard == 0x308b) { - if (info->BiosConnector[1].DDCType == DDC_CRT2) - info->BiosConnector[1].DDCType = DDC_MONID; - } - } - return connector_found; -} - /* Read the Video BIOS block and the FP registers (if applicable). */ Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) { @@ -242,7 +228,19 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn) info->BiosConnector[i].ConnectorType = (tmp >> 12) & 0xf; info->BiosConnector[i].DDCType = (tmp >> 8) & 0xf; info->BiosConnector[i].DACType = tmp & 0x1; - info->BiosConnector[i].TMDSType = tmp & 0x10; + info->BiosConnector[i].TMDSType = (tmp >> 4) & 0x1; + + /* most XPRESS chips seem to specify DDC_CRT2 for their + * VGA DDC port, however DDC never seems to work on that + * port. Some have reported success on DDC_MONID, so + * lets see what happens with that. + */ + if (info->ChipFamily == CHIP_FAMILY_RS400 && + info->BiosConnector[i].ConnectorType == CONNECTOR_CRT && + info->BiosConnector[i].DDCType == DDC_CRT2) { + info->BiosConnector[i].DDCType = DDC_MONID; + } + } } else { @@ -320,218 +318,6 @@ Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn) return RADEONGetLegacyConnectorInfoFromBIOS(pScrn); } -#if 0 -Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn) -{ - RADEONInfoPtr info = RADEONPTR (pScrn); - int i = 0, j, tmp, tmp0=0, tmp1=0; - RADEONBIOSConnector tempConnector; - - if(!info->VBIOS) return FALSE; - - if (info->IsAtomBios) { - if((tmp = RADEON_BIOS16 (info->MasterDataStart + 22))) { - int crtc = 0, id[2]; - tmp1 = RADEON_BIOS16 (tmp + 4); - for (i=0; i<8; i++) { - if(tmp1 & (1<<i)) { - CARD16 portinfo = RADEON_BIOS16(tmp+6+i*2); - if (crtc < 2) { - if ((i==2) || (i==6)) continue; /* ignore TV here */ - - if (crtc == 1) { - /* sharing same port with id[0] */ - if (((portinfo>>8) & 0xf) == id[0]) { - if (i == 3) - info->BiosConnector[0].TMDSType = TMDS_INT; - else if (i == 7) - info->BiosConnector[0].TMDSType = TMDS_EXT; - - if (info->BiosConnector[0].DACType == DAC_UNKNOWN) - info->BiosConnector[0].DACType = (portinfo & 0xf) - 1; - continue; - } - } - - id[crtc] = (portinfo>>8) & 0xf; - info->BiosConnector[crtc].DACType = (portinfo & 0xf) - 1; - info->BiosConnector[crtc].ConnectorType = (portinfo>>4) & 0xf; - if (i == 3) - info->BiosConnector[crtc].TMDSType = TMDS_INT; - else if (i == 7) - info->BiosConnector[crtc].TMDSType = TMDS_EXT; - - if((tmp0 = RADEON_BIOS16 (info->MasterDataStart + 24)) && id[crtc]) { - switch (RADEON_BIOS16 (tmp0 + 4 + 27 * id[crtc]) * 4) - { - case RADEON_GPIO_MONID: - info->BiosConnector[crtc].DDCType = DDC_MONID; - break; - case RADEON_GPIO_DVI_DDC: - info->BiosConnector[crtc].DDCType = DDC_DVI; - break; - case RADEON_GPIO_VGA_DDC: - info->BiosConnector[crtc].DDCType = DDC_VGA; - break; - case RADEON_GPIO_CRT2_DDC: - info->BiosConnector[crtc].DDCType = DDC_CRT2; - break; - case RADEON_LCD_GPIO_MASK: - info->BiosConnector[crtc].DDCType = DDC_LCD; - break; - default: - info->BiosConnector[crtc].DDCType = DDC_NONE_DETECTED; - break; - } - - } else { - info->BiosConnector[crtc].DDCType = DDC_NONE_DETECTED; - } - crtc++; - } else { - /* we have already had two CRTCs assigned. the rest may share the same - * port with the existing connector, fill in them accordingly. - */ - for (j=0; j<2; j++) { - if (((portinfo>>8) & 0xf) == id[j]) { - if (i == 3) - info->BiosConnector[j].TMDSType = TMDS_INT; - else if (i == 7) - info->BiosConnector[j].TMDSType = TMDS_EXT; - - if (info->BiosConnector[j].DACType == DAC_UNKNOWN) - info->BiosConnector[j].DACType = (portinfo & 0xf) - 1; - } - } - } - } - } - - /* R4xx seem to get the connector table backwards */ - tempConnector = info->BiosConnector[0]; - info->BiosConnector[0] = info->BiosConnector[1]; - info->BiosConnector[1] = tempConnector; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n"); - for (i=0; i<2; i++) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n", - i, info->BiosConnector[i].DDCType, info->BiosConnector[i].DACType, - info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType); - } - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Device Info Table found!\n"); - return FALSE; - } - } else { - /* Some laptops only have one connector (VGA) listed in the connector table, - * we need to add LVDS in as a non-DDC display. - * Note, we can't assume the listed VGA will be filled in PortInfo[0], - * when walking through connector table. connector_found has following meaning: - * 0 -- nothing found, - * 1 -- only PortInfo[0] filled, - * 2 -- only PortInfo[1] filled, - * 3 -- both are filled. - */ - int connector_found = 0; - - if ((tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x50))) { - for (i = 1; i < 4; i++) { - - if (!RADEON_BIOS16(tmp + i*2)) - break; /* end of table */ - - tmp0 = RADEON_BIOS16(tmp + i*2); - if (((tmp0 >> 12) & 0x0f) == 0) continue; /* no connector */ - if (connector_found > 0) { - if (info->BiosConnector[tmp1].DDCType == ((tmp0 >> 8) & 0x0f)) - continue; /* same connector */ - } - - /* internal DDC_DVI port will get assigned to PortInfo[0], or if there is no DDC_DVI (like in some IGPs). */ - tmp1 = ((((tmp0 >> 8) & 0xf) == DDC_DVI) || (tmp1 == 1)) ? 0 : 1; /* determine port info index */ - - info->BiosConnector[tmp1].DDCType = (tmp0 >> 8) & 0x0f; - if (info->BiosConnector[tmp1].DDCType > DDC_CRT2) - info->BiosConnector[tmp1].DDCType = DDC_NONE_DETECTED; - info->BiosConnector[tmp1].DACType = (tmp0 & 0x01) ? DAC_TVDAC : DAC_PRIMARY; - info->BiosConnector[tmp1].ConnectorType = (tmp0 >> 12) & 0x0f; - if (info->BiosConnector[tmp1].ConnectorType > CONNECTOR_UNSUPPORTED) - info->BiosConnector[tmp1].ConnectorType = CONNECTOR_UNSUPPORTED; - info->BiosConnector[tmp1].TMDSType = ((tmp0 >> 4) & 0x01) ? TMDS_EXT : TMDS_INT; - - /* some sanity checks */ - if (((info->BiosConnector[tmp1].ConnectorType != CONNECTOR_DVI_D) && - (info->BiosConnector[tmp1].ConnectorType != CONNECTOR_DVI_I)) && - info->BiosConnector[tmp1].TMDSType == TMDS_INT) - info->BiosConnector[tmp1].TMDSType = TMDS_UNKNOWN; - - connector_found += (tmp1 + 1); - } - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Connector Info Table found!\n"); - return FALSE; - } - - if (info->IsMobility) { - if ((tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42))) { - if ((tmp0 = RADEON_BIOS16(tmp + 0x15))) { - if ((tmp1 = RADEON_BIOS8(tmp0+2) & 0x07)) { - info->BiosConnector[0].DDCType = tmp1; - if (info->BiosConnector[0].DDCType > DDC_LCD) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Unknown DDCType %d found\n", - info->BiosConnector[0].DDCType); - info->BiosConnector[0].DDCType = DDC_NONE_DETECTED; - } - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "LCD DDC Info Table found!\n"); - } - } - } - } else if (connector_found == 2) { - memcpy (&info->BiosConnector[0], &info->BiosConnector[1], - sizeof (info->BiosConnector[0])); - info->BiosConnector[1].DACType = DAC_UNKNOWN; - info->BiosConnector[1].TMDSType = TMDS_UNKNOWN; - info->BiosConnector[1].DDCType = DDC_NONE_DETECTED; - info->BiosConnector[1].ConnectorType = CONNECTOR_NONE; - connector_found = 1; - } - - connector_found = RADEONBIOSApplyConnectorQuirks(pScrn, connector_found); - - if (connector_found == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No connector found in Connector Info Table.\n"); - } else { - xf86DrvMsg(0, X_INFO, "Bios Connector0: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n", - info->BiosConnector[0].DDCType, info->BiosConnector[0].DACType, - info->BiosConnector[0].TMDSType, info->BiosConnector[0].ConnectorType); - } - if (connector_found == 3) { - xf86DrvMsg(0, X_INFO, "Bios Connector1: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n", - info->BiosConnector[1].DDCType, info->BiosConnector[1].DACType, - info->BiosConnector[1].TMDSType, info->BiosConnector[1].ConnectorType); - } - -#if 0 -/* External TMDS Table, not used now */ - if ((tmp0 = RADEON_BIOS16(info->ROMHeaderStart + 0x58))) { - - //info->BiosConnector[1].DDCType = (RADEON_BIOS8(tmp0 + 7) & 0x07); - //info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I; - //info->BiosConnector[1].TMDSType = TMDS_EXT; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "External TMDS found.\n"); - - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NO External TMDS Info found\n"); - - } -#endif - - } - return TRUE; -} -#endif - Bool RADEONGetTVInfoFromBIOS (xf86OutputPtr output) { ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); @@ -703,14 +489,6 @@ Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output) radeon_output->PanelPwrDly = 2000; radeon_output->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); } else { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No LVDS Info Table found in BIOS!\n"); @@ -781,6 +559,16 @@ Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output) } } } + + 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); + return TRUE; } @@ -884,6 +672,139 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output) return FALSE; } +Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output) +{ + 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->IsAtomBios) { + return FALSE; + } else { + offset = RADEON_BIOS16(info->ROMHeaderStart + 0x58); + if (offset) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "External TMDS Table revision: %d\n", + RADEON_BIOS8(offset)); + table_start = offset+4; + max_freq = RADEON_BIOS16(table_start); + radeon_output->dvo_i2c_slave_addr = RADEON_BIOS8(table_start+2); + gpio_reg = RADEON_BIOS8(table_start+3); + if (gpio_reg == 1) + radeon_output->dvo_i2c_reg = RADEON_GPIO_MONID; + else if (gpio_reg == 2) + radeon_output->dvo_i2c_reg = RADEON_GPIO_DVI_DDC; + else if (gpio_reg == 3) + radeon_output->dvo_i2c_reg = RADEON_GPIO_VGA_DDC; + else if (gpio_reg == 4) + radeon_output->dvo_i2c_reg = RADEON_GPIO_CRT2_DDC; + else if (gpio_reg == 5) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "unsupported MM gpio_reg\n"); + /*radeon_output->i2c_reg = RADEON_GPIO_MM;*/ + 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) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Duallink TMDS detected\n"); + } + return TRUE; + } + } + + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "No External TMDS Table found\n"); + + return FALSE; +} + +Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONOutputPrivatePtr radeon_output = output->driver_private; + int offset, index, id; + CARD32 val, reg, andmask, ormask; + + if (!info->VBIOS) return FALSE; + + if (info->IsAtomBios) { + return FALSE; + } else { + offset = RADEON_BIOS16(info->ROMHeaderStart + 0x58); + if (offset) { + index = offset+10; + id = RADEON_BIOS16(index); + while (id != 0xffff) { + index += 2; + switch(id >> 13) { + case 0: + reg = id & 0x1fff; + val = RADEON_BIOS32(index); + index += 4; + ErrorF("WRITE INDEXED: 0x%x 0x%x\n", + reg, (unsigned)val); + /*OUTREG(reg, val);*/ + break; + case 2: + reg = id & 0x1fff; + andmask = RADEON_BIOS32(index); + index += 4; + ormask = RADEON_BIOS32(index); + index += 4; + val = INREG(reg); + val = (val & andmask) | ormask; + ErrorF("MASK DIRECT: 0x%x 0x%x 0x%x\n", + reg, (unsigned)andmask, (unsigned)ormask); + /*OUTREG(reg, val);*/ + break; + case 4: + val = RADEON_BIOS16(index); + index += 2; + ErrorF("delay: %d\n", val); + usleep(val); + break; + case 5: + reg = id & 0x1fff; + andmask = RADEON_BIOS32(index); + index += 4; + ormask = RADEON_BIOS32(index); + index += 4; + ErrorF("MASK PLL: 0x%x 0x%x 0x%x\n", + reg, (unsigned)andmask, (unsigned)ormask); + /*val = INPLL(pScrn, reg); + val = (val & andmask) | ormask; + OUTPLL(pScrn, reg, val);*/ + break; + case 6: + reg = id & 0x1fff; + val = RADEON_BIOS8(index); + index += 1; + ErrorF("i2c write: 0x%x, 0x%x\n", reg, val); + RADEONDVOWriteByte(radeon_output->DVOChip, reg, val); + break; + default: + ErrorF("unknown id %d\n", id>>13); + return FALSE; + }; + id = RADEON_BIOS16(index); + } + return TRUE; + } + } + + return FALSE; +} + /* support for init from bios tables * * Based heavily on the netbsd radeonfb driver diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c index e976e2c9..47e46f38 100644 --- a/src/radeon_crtc.c +++ b/src/radeon_crtc.c @@ -680,7 +680,15 @@ RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONInfoPtr info, save->post_div); save->ppll_ref_div = pll->reference_div; + +#if defined(__powerpc__) + /* apparently programming this otherwise causes a hang??? */ + if (info->MacModel == RADEON_MAC_IBOOK) + save->ppll_div_3 = 0x000600ad; + else +#endif save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16)); + save->htotal_cntl = 0; save->vclk_ecp_cntl = (info->SavedReg.vclk_ecp_cntl & diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c index f19f2bc0..3e60d231 100644 --- a/src/radeon_cursor.c +++ b/src/radeon_cursor.c @@ -98,12 +98,22 @@ radeon_crtc_show_cursor (xf86CrtcPtr crtc) RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; +#ifdef XF86DRI + if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0); +#endif + + RADEON_SYNC(info, pScrn); + if (crtc_id == 0) OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN | 2 << 20, ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK)); else if (crtc_id == 1) OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN | 2 << 20, ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_CUR_MODE_MASK)); + +#ifdef XF86DRI + if (info->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen); +#endif } void @@ -115,12 +125,20 @@ radeon_crtc_hide_cursor (xf86CrtcPtr crtc) RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; +#ifdef XF86DRI + if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0); +#endif + + RADEON_SYNC(info, pScrn); + if (crtc_id == 0) OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN); else if (crtc_id == 1) OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN); - +#ifdef XF86DRI + if (info->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen); +#endif } void diff --git a/src/radeon_display.c b/src/radeon_display.c index fa80e104..5c4fbfae 100644 --- a/src/radeon_display.c +++ b/src/radeon_display.c @@ -289,6 +289,7 @@ void RADEONDisableDisplays(ScrnInfoPtr pScrn) { /* FP 2 */ tmp = INREG(RADEON_FP2_GEN_CNTL); + tmp |= RADEON_FP2_BLANK_EN; tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); OUTREG(RADEON_FP2_GEN_CNTL, tmp); @@ -355,10 +356,12 @@ void RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); } else if (radeon_output->TMDSType == TMDS_EXT) { tmp = INREG(RADEON_FP2_GEN_CNTL); + tmp &= ~RADEON_FP2_BLANK_EN; tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); OUTREG(RADEON_FP2_GEN_CNTL, tmp); save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); - } + save->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN; + } } else if (radeon_output->MonType == MT_LCD) { tmp = INREG(RADEON_LVDS_GEN_CNTL); tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON); @@ -406,9 +409,11 @@ void RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); } else if (radeon_output->TMDSType == TMDS_EXT) { tmp = INREG(RADEON_FP2_GEN_CNTL); + tmp |= RADEON_FP2_BLANK_EN; tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); OUTREG(RADEON_FP2_GEN_CNTL, tmp); save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); + save->fp2_gen_cntl |= RADEON_FP2_BLANK_EN; } } else if (radeon_output->MonType == MT_LCD) { unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL); @@ -786,6 +791,11 @@ void RADEONInitDispBandwidth(ScrnInfoPtr pScrn) mode1 = &xf86_config->crtc[1]->mode; } else return; + } else { + if (xf86_config->crtc[0]->enabled) + mode1 = &xf86_config->crtc[0]->mode; + else + return; } RADEONInitDispBandwidth2(pScrn, info, pixel_bytes2, mode1, mode2); diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 158e1e46..d434116d 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -183,10 +183,13 @@ static const OptionInfoRec RADEONOptions[] = { { OPTION_REVERSE_DDC, "ReverseDDC", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_LVDS_PROBE_PLL, "LVDSProbePLL", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, - { OPTION_CONSTANTDPI, "ConstantDPI", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_CONNECTORTABLE, "ConnectorTable", OPTV_STRING, {0}, FALSE }, { OPTION_DEFAULT_CONNECTOR_TABLE, "DefaultConnectorTable", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DEFAULT_TMDS_PLL, "DefaultTMDSPLL", OPTV_BOOLEAN, {0}, FALSE }, +#if defined(__powerpc__) + { OPTION_MAC_MODEL, "MacModel", OPTV_STRING, {0}, FALSE }, +#endif { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -1935,8 +1938,8 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn) #ifdef USE_EXA if (info->useEXA) { - info->exaReq.majorversion = 2; - info->exaReq.minorversion = 0; + info->exaReq.majorversion = EXA_VERSION_MAJOR; + info->exaReq.minorversion = EXA_VERSION_MINOR; if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &info->exaReq, &errmaj, &errmin)) { @@ -2023,15 +2026,17 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) info->pKernelDRMVersion = NULL; if (info->Chipset == PCI_CHIP_RN50_515E || - info->Chipset == PCI_CHIP_RN50_5969) { + info->Chipset == PCI_CHIP_RN50_5969 || + info->Chipset == PCI_CHIP_RC410_5A61 || + info->Chipset == PCI_CHIP_RC410_5A62) { if (xf86ReturnOptValBool(info->Options, OPTION_DRI, FALSE)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Direct rendering for RN50 forced on -- " + "Direct rendering for RN50/RC410 forced on -- " "This is NOT officially supported at the hardware level " "and may cause instability or lockups\n"); } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Direct rendering not officially supported on RN50\n"); + "Direct rendering not officially supported on RN50/RC410\n"); return FALSE; } } @@ -2507,7 +2512,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) xf86Int10InfoPtr pInt10 = NULL; void *int10_save = NULL; const char *s; - MessageType from; int crtc_max_X, crtc_max_Y; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, @@ -2643,25 +2647,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) info->DispPriority = 1; } - info->constantDPI = -1; - from = X_DEFAULT; - if (xf86GetOptValBool(info->Options, OPTION_CONSTANTDPI, &info->constantDPI)) { - from = X_CONFIG; - } else { - if (monitorResolution > 0) { - info->constantDPI = TRUE; - from = X_CMDLINE; - xf86DrvMsg(pScrn->scrnIndex, from, - "\"-dpi %d\" given in command line, assuming \"ConstantDPI\" set\n", - monitorResolution); - } else { - info->constantDPI = FALSE; - } - } - xf86DrvMsg(pScrn->scrnIndex, from, - "X server will %skeep DPI constant for all screen sizes\n", - info->constantDPI ? "" : "not "); - if (!RADEONPreInitInt10(pScrn, &pInt10)) goto fail; @@ -2688,30 +2673,28 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) crtc_max_X = pScrn->display->virtualX; crtc_max_Y = pScrn->display->virtualY; if (info->allowColorTiling) { - if (crtc_max_X > info->MaxSurfaceWidth) - crtc_max_X = info->MaxSurfaceWidth; - if (crtc_max_Y > info->MaxLines) - crtc_max_Y = info->MaxLines; - } else { - if (crtc_max_X > 8192) - crtc_max_X = 8192; - if (crtc_max_Y > 8192) - crtc_max_Y = 8192; + if (crtc_max_X > info->MaxSurfaceWidth || + crtc_max_Y > info->MaxLines) { + info->allowColorTiling = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Requested desktop size exceeds surface limts for tiling, ColorTiling disabled\n"); + } } + if (crtc_max_X > 8192) + crtc_max_X = 8192; + if (crtc_max_Y > 8192) + crtc_max_Y = 8192; } else { - if (pScrn->videoRam < 16384) { + if (pScrn->videoRam <= 16384) { crtc_max_X = 1600; crtc_max_Y = 1200; - } else if (pScrn->videoRam <= 32768) { - crtc_max_X = 2048; - crtc_max_Y = 1200; - } else if (pScrn->videoRam > 32768) { + } else { if (IS_R300_VARIANT) { crtc_max_X = 2560; - crtc_max_Y = 2048; + crtc_max_Y = 1200; } else { crtc_max_X = 2048; - crtc_max_Y = 2048; + crtc_max_Y = 1200; } } } @@ -2719,6 +2702,9 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) crtc_max_X, crtc_max_Y); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "For a larger or smaller max desktop size, add a Virtual line to your xorg.conf\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "If you are having trouble with 3D, " + "reduce the desktop size by adjusting the Virtual line to your xorg.conf\n"); /*xf86CrtcSetSizeRange (pScrn, 320, 200, info->MaxSurfaceWidth, info->MaxLines);*/ xf86CrtcSetSizeRange (pScrn, 320, 200, crtc_max_X, crtc_max_Y); @@ -2769,10 +2755,10 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) } /* Free the video bios (if applicable) */ - if (info->VBIOS) { - xfree(info->VBIOS); - info->VBIOS = NULL; - } + //if (info->VBIOS) { + //xfree(info->VBIOS); + //info->VBIOS = NULL; + //} /* Free int10 info */ if (pInt10) @@ -2785,6 +2771,10 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) "For information on using the multimedia capabilities\n\tof this" " adapter, please see http://gatos.sf.net.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_NOTICE, + "MergedFB support has been removed and replaced with" + " xrandr 1.2 support\n"); + return TRUE; fail: @@ -4184,10 +4174,10 @@ void RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) if (info->IsMobility) { OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl); - /*OUTREG(RADEON_LVDS_PLL_CNTL, restore->lvds_pll_cntl);*/ - OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch); + OUTREG(RADEON_LVDS_PLL_CNTL, restore->lvds_pll_cntl); + /*OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch); OUTREG(RADEON_BIOS_5_SCRATCH, restore->bios_5_scratch); - OUTREG(RADEON_BIOS_6_SCRATCH, restore->bios_6_scratch); + OUTREG(RADEON_BIOS_6_SCRATCH, restore->bios_6_scratch);*/ } } @@ -4566,6 +4556,12 @@ void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, unsigned char *RADEONMMIO = info->MMIO; CARD8 pllGain; +#if defined(__powerpc__) + /* apparently restoring the pll causes a hang??? */ + if (info->MacModel == RADEON_MAC_IBOOK) + return; +#endif + pllGain = RADEONComputePLLGain(info->pll.reference_freq, restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK, restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK); @@ -4664,10 +4660,11 @@ void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, usleep(50000); /* Let the clock to lock */ - /* OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, + OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, RADEON_VCLK_SRC_SEL_PPLLCLK, - ~(RADEON_VCLK_SRC_SEL_MASK));*/ - OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, restore->vclk_ecp_cntl); + ~(RADEON_VCLK_SRC_SEL_MASK)); + + /*OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, restore->vclk_ecp_cntl);*/ ErrorF("finished PLL1\n"); @@ -4738,9 +4735,10 @@ void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn, usleep(5000); /* Let the clock to lock */ - /*OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, + OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, RADEON_PIX2CLK_SRC_SEL_P2PLLCLK, - ~(RADEON_PIX2CLK_SRC_SEL_MASK));*/ + ~(RADEON_PIX2CLK_SRC_SEL_MASK)); + OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl); ErrorF("finished PLL2\n"); @@ -5219,6 +5217,7 @@ static void RADEONSavePLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save) >> 16)); } +#if 0 /* Read palette data */ static void RADEONSavePalette(ScrnInfoPtr pScrn, RADEONSavePtr save) { @@ -5238,35 +5237,13 @@ static void RADEONSavePalette(ScrnInfoPtr pScrn, RADEONSavePtr save) for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT(); save->palette_valid = TRUE; } - -/* Save state that defines current video mode */ -static void RADEONSaveMode(ScrnInfoPtr pScrn, RADEONSavePtr save) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "RADEONSaveMode(%p)\n", save); - - RADEONSaveMemMapRegisters(pScrn, save); - RADEONSaveCommonRegisters(pScrn, save); - RADEONSavePLLRegisters(pScrn, save); - RADEONSaveCrtcRegisters(pScrn, save); - RADEONSaveFPRegisters(pScrn, save); - RADEONSaveDACRegisters(pScrn, save); - RADEONSaveCrtc2Registers(pScrn, save); - RADEONSavePLL2Registers(pScrn, save); - if (info->InternalTVOut) - RADEONSaveTVRegisters(pScrn, save); - /*RADEONSavePalette(pScrn, save);*/ - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, - "RADEONSaveMode returns %p\n", save); -} +#endif /* Save everything needed to restore the original VC state */ static void RADEONSave(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); unsigned char *RADEONMMIO = info->MMIO; RADEONSavePtr save = &info->SavedReg; @@ -5297,7 +5274,19 @@ static void RADEONSave(ScrnInfoPtr pScrn) save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); RADEONPllErrataAfterIndex(info); - RADEONSaveMode(pScrn, save); + RADEONSaveMemMapRegisters(pScrn, save); + RADEONSaveCommonRegisters(pScrn, save); + RADEONSavePLLRegisters(pScrn, save); + RADEONSaveCrtcRegisters(pScrn, save); + RADEONSaveFPRegisters(pScrn, save); + RADEONSaveDACRegisters(pScrn, save); + if (pRADEONEnt->HasCRTC2) { + RADEONSaveCrtc2Registers(pScrn, save); + RADEONSavePLL2Registers(pScrn, save); + } + if (info->InternalTVOut) + RADEONSaveTVRegisters(pScrn, save); + RADEONSaveSurfaces(pScrn, save); } @@ -5328,15 +5317,6 @@ void RADEONRestore(ScrnInfoPtr pScrn) OUTREG(RADEON_GRPH_BUFFER_CNTL, restore->grph_buffer_cntl); OUTREG(RADEON_GRPH2_BUFFER_CNTL, restore->grph2_buffer_cntl); -#if 0 - /* M6 card has trouble restoring text mode for its CRT. - * This is fixed elsewhere and will be removed in the future. - */ - if ((xf86IsEntityShared(info->pEnt->index) || info->MergedFB) - && info->IsM6) - OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl); -#endif - RADEONRestoreMemMapRegisters(pScrn, restore); RADEONRestoreCommonRegisters(pScrn, restore); @@ -5383,9 +5363,11 @@ void RADEONRestore(ScrnInfoPtr pScrn) #endif /* need to make sure we don't enable a crtc by accident or we may get a hang */ - if (info->crtc2_on) { - crtc = xf86_config->crtc[1]; - crtc->funcs->dpms(crtc, DPMSModeOn); + if (pRADEONEnt->HasCRTC2) { + if (info->crtc2_on) { + crtc = xf86_config->crtc[1]; + crtc->funcs->dpms(crtc, DPMSModeOn); + } } if (info->crtc_on) { crtc = xf86_config->crtc[0]; @@ -5431,26 +5413,6 @@ static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode) return TRUE; } -static void -RADEONResetDPI(ScrnInfoPtr pScrn, Bool force) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; - - if(force || - (info->RADEONDPIVX != pScrn->virtualX) || - (info->RADEONDPIVY != pScrn->virtualY) - ) { - - pScreen->mmWidth = (pScrn->virtualX * 254 + pScrn->xDpi * 5) / (pScrn->xDpi * 10); - pScreen->mmHeight = (pScrn->virtualY * 254 + pScrn->yDpi * 5) / (pScrn->yDpi * 10); - - info->RADEONDPIVX = pScrn->virtualX; - info->RADEONDPIVY = pScrn->virtualY; - - } -} - Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; @@ -5508,13 +5470,7 @@ Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) } #endif - /* Since RandR (indirectly) uses SwitchMode(), we need to - * update our Xinerama info here, too, in case of resizing - */ - if(info->constantDPI) { - RADEONResetDPI(pScrn, FALSE); - } - + /* reset ecp for overlay */ info->ecp_div = -1; return ret; diff --git a/src/radeon_exa.c b/src/radeon_exa.c index d074f08a..8a12e1b2 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -157,7 +157,7 @@ static Bool RADEONGetOffsetPitch(PixmapPtr pPix, int bpp, CARD32 *pitch_offset, { RINFO_FROM_SCREEN(pPix->drawable.pScreen); - if (pitch % info->exa->pixmapPitchAlign != 0) + if (pitch > 16320 || pitch % info->exa->pixmapPitchAlign != 0) RADEON_FALLBACK(("Bad pitch 0x%08x\n", pitch)); if (offset % info->exa->pixmapOffsetAlign != 0) diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c index c356de7c..2b7f0e8f 100644 --- a/src/radeon_exa_funcs.c +++ b/src/radeon_exa_funcs.c @@ -241,10 +241,8 @@ static Bool FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch) { -#if X_BYTE_ORDER == X_BIG_ENDIAN || defined(ACCEL_CP) RINFO_FROM_SCREEN(pDst->drawable.pScreen); -#endif - CARD8 *dst = pDst->devPrivate.ptr; + CARD8 *dst = info->FB + exaGetPixmapOffset(pDst); unsigned int dst_pitch = exaGetPixmapPitch(pDst); unsigned int bpp = pDst->drawable.bitsPerPixel; #ifdef ACCEL_CP @@ -353,16 +351,14 @@ static Bool FUNC_NAME(RADEONDownloadFromScreen)(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch) { -#if defined(ACCEL_CP) || X_BYTE_ORDER == X_BIG_ENDIAN RINFO_FROM_SCREEN(pSrc->drawable.pScreen); -#endif #if X_BYTE_ORDER == X_BIG_ENDIAN unsigned char *RADEONMMIO = info->MMIO; unsigned int swapper = info->ModeReg.surface_cntl & ~(RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP | RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP); #endif - CARD8 *src = pSrc->devPrivate.ptr; + CARD8 *src = info->FB + exaGetPixmapOffset(pSrc); int src_pitch = exaGetPixmapPitch(pSrc); int bpp = pSrc->drawable.bitsPerPixel; #ifdef ACCEL_CP @@ -511,8 +507,8 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen) return FALSE; } - info->exa->exa_major = 2; - info->exa->exa_minor = 0; + info->exa->exa_major = EXA_VERSION_MAJOR; + info->exa->exa_minor = EXA_VERSION_MINOR; info->exa->PrepareSolid = FUNC_NAME(RADEONPrepareSolid); info->exa->Solid = FUNC_NAME(RADEONSolid); @@ -564,7 +560,14 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen) } #endif +#if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting EXA maxPitchBytes\n"); + + info->exa->maxPitchBytes = 16320; info->exa->maxX = info->exa->Composite ? 2048 : 8192; +#else + info->exa->maxX = info->exa->Composite ? 2048 : 16320 / 4; +#endif info->exa->maxY = info->exa->Composite ? 2048 : 8192; RADEONEngineInit(pScrn); diff --git a/src/radeon_modes.c b/src/radeon_modes.c index 687e3888..ea2c2291 100644 --- a/src/radeon_modes.c +++ b/src/radeon_modes.c @@ -82,7 +82,7 @@ static DisplayModePtr RADEONTVModes(xf86OutputPtr output) { DisplayModePtr new = NULL; - /* just a place holder */ + /* just a place holder */ new = xf86CVTMode(800, 600, 60.00, FALSE, FALSE); new->type = M_T_DRIVER | M_T_PREFERRED; @@ -97,61 +97,39 @@ static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; RADEONOutputPrivatePtr radeon_output = output->driver_private; DisplayModePtr new = NULL; - char stmp[32]; if (radeon_output->PanelXRes != 0 && radeon_output->PanelYRes != 0 && radeon_output->DotClock != 0) { /* Add native panel size */ - new = xnfcalloc(1, sizeof (DisplayModeRec)); - sprintf(stmp, "%dx%d", radeon_output->PanelXRes, radeon_output->PanelYRes); - new->name = xnfalloc(strlen(stmp) + 1); - strcpy(new->name, stmp); - new->HDisplay = radeon_output->PanelXRes; - new->VDisplay = radeon_output->PanelYRes; - - new->HTotal = new->HDisplay + radeon_output->HBlank; - new->HSyncStart = new->HDisplay + radeon_output->HOverPlus; - new->HSyncEnd = new->HSyncStart + radeon_output->HSyncWidth; - new->VTotal = new->VDisplay + radeon_output->VBlank; - new->VSyncStart = new->VDisplay + radeon_output->VOverPlus; - new->VSyncEnd = new->VSyncStart + radeon_output->VSyncWidth; - - new->Clock = radeon_output->DotClock; - new->Flags = 0; - new->type = M_T_USERDEF | M_T_PREFERRED; + new = xf86CVTMode(radeon_output->PanelXRes, radeon_output->PanelYRes, 60.0, TRUE, FALSE); + + new->type = M_T_DRIVER | M_T_PREFERRED; new->next = NULL; new->prev = NULL; - pScrn->display->virtualX = - pScrn->virtualX = MAX(pScrn->virtualX, radeon_output->PanelXRes); - pScrn->display->virtualY = - pScrn->virtualY = MAX(pScrn->virtualY, radeon_output->PanelYRes); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "No valid mode specified, force to native mode\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Added native panel mode: %dx%d\n", + radeon_output->PanelXRes, radeon_output->PanelYRes); } return new; } -/* FP mode initialization routine for using on-chip RMX to scale - */ -int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePtr *modeList) +/* this function is basically a hack to add the screen modes */ +static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList) { ScrnInfoPtr pScrn = output->scrn; RADEONOutputPrivatePtr radeon_output = output->driver_private; DisplayModePtr last = NULL; DisplayModePtr new = NULL; DisplayModePtr first = NULL; - DisplayModePtr p, tmp; int count = 0; int i, width, height; + char **ppModeName = pScrn->display->modes; - pScrn->virtualX = pScrn->display->virtualX; - pScrn->virtualY = pScrn->display->virtualY; + first = last = *modeList; /* We have a flat panel connected to the primary display, and we * don't have any DDC info. @@ -160,43 +138,28 @@ int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePt if (sscanf(ppModeName[i], "%dx%d", &width, &height) != 2) continue; - /* Note: We allow all non-standard modes as long as they do not - * exceed the native resolution of the panel. Since these modes - * need the internal RMX unit in the video chips (and there is - * only one per card), this will only apply to the primary head. - */ - if (width < 320 || width > radeon_output->PanelXRes || - height < 200 || height > radeon_output->PanelYRes) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Mode %s is out of range.\n", ppModeName[i]); - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Valid modes must be between 320x200-%dx%d\n", - radeon_output->PanelXRes, radeon_output->PanelYRes); - continue; + if (radeon_output->type == OUTPUT_LVDS) { + /* already added the native mode */ + if (width == radeon_output->PanelXRes && height == radeon_output->PanelYRes) + continue; + + /* Note: We allow all non-standard modes as long as they do not + * exceed the native resolution of the panel. Since these modes + * need the internal RMX unit in the video chips (and there is + * only one per card), this will only apply to the primary head. + */ + if (width < 320 || width > radeon_output->PanelXRes || + height < 200 || height > radeon_output->PanelYRes) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Mode %s is out of range.\n", ppModeName[i]); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Valid FP modes must be between 320x200-%dx%d\n", + radeon_output->PanelXRes, radeon_output->PanelYRes); + continue; + } } - new = xnfcalloc(1, sizeof(DisplayModeRec)); - new->name = xnfalloc(strlen(ppModeName[i]) + 1); - strcpy(new->name, ppModeName[i]); - new->HDisplay = width; - new->VDisplay = height; - - /* These values are effective values after expansion They are - * not really used to set CRTC registers. - */ - new->HTotal = radeon_output->PanelXRes + radeon_output->HBlank; - new->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus; - new->HSyncEnd = new->HSyncStart + radeon_output->HSyncWidth; - new->VTotal = radeon_output->PanelYRes + radeon_output->VBlank; - new->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus; - new->VSyncEnd = new->VSyncStart + radeon_output->VSyncWidth; - new->Clock = radeon_output->DotClock; - new->Flags |= RADEON_USE_RMX; - -#ifdef M_T_PREFERRED - if (width == radeon_output->PanelXRes && height == radeon_output->PanelYRes) - new->type |= M_T_PREFERRED; -#endif + new = xf86CVTMode(width, height, 60.0, TRUE, FALSE); new->type |= M_T_USERDEF; @@ -205,95 +168,40 @@ int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePt if (last) last->next = new; last = new; - if (!first) first = new; + if (!first) first = new; - pScrn->display->virtualX = - pScrn->virtualX = MAX(pScrn->virtualX, width); - pScrn->display->virtualY = - pScrn->virtualY = MAX(pScrn->virtualY, height); count++; xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Valid mode using on-chip RMX: %s\n", new->name); - } - - /* If all else fails, add the native mode */ - if (!count) { - first = last = RADEONFPNativeMode(output); - if (first) count = 1; + "Adding Screen mode: %s\n", new->name); } - /* add in all default vesa modes smaller than panel size, used for randr*/ - for (p = *modeList; p && p->next; p = p->next->next) { - if ((p->HDisplay <= radeon_output->PanelXRes) && (p->VDisplay <= radeon_output->PanelYRes)) { - tmp = first; - while (tmp) { - if ((p->HDisplay == tmp->HDisplay) && (p->VDisplay == tmp->VDisplay)) break; - tmp = tmp->next; - } - if (!tmp) { - new = xnfcalloc(1, sizeof(DisplayModeRec)); - new->name = xnfalloc(strlen(p->name) + 1); - strcpy(new->name, p->name); - new->HDisplay = p->HDisplay; - new->VDisplay = p->VDisplay; - - /* These values are effective values after expansion They are - * not really used to set CRTC registers. - */ - new->HTotal = radeon_output->PanelXRes + radeon_output->HBlank; - new->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus; - new->HSyncEnd = new->HSyncStart + radeon_output->HSyncWidth; - new->VTotal = radeon_output->PanelYRes + radeon_output->VBlank; - new->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus; - new->VSyncEnd = new->VSyncStart + radeon_output->VSyncWidth; - new->Clock = radeon_output->DotClock; - new->Flags |= RADEON_USE_RMX; - - new->type |= M_T_DEFAULT; - - if (last) last->next = new; - last = new; - if (!first) first = new; - } - } - } /* Close the doubly-linked mode list, if we found any usable modes */ if (last) { last->next = NULL; //first; first->prev = NULL; //last; *modeList = first; - //RADEONSetPitch(pScrn); } xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Total number of valid FP mode(s) found: %d\n", count); + "Total number of valid Screen mode(s) added: %d\n", count); - return count; } DisplayModePtr RADEONProbeOutputModes(xf86OutputPtr output) { - ScrnInfoPtr pScrn = output->scrn; RADEONOutputPrivatePtr radeon_output = output->driver_private; - DisplayModePtr mode; xf86MonPtr edid_mon; DisplayModePtr modes = NULL; -#if 0 - /* force reprobe */ - radeon_output->MonType = MT_UNKNOWN; - - RADEONConnectorFindMonitor(pScrn, output); -#endif ErrorF("in RADEONProbeOutputModes\n"); if (output->status == XF86OutputStatusConnected) { if (radeon_output->type == OUTPUT_DVI || radeon_output->type == OUTPUT_VGA) { edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus); xf86OutputSetEDID (output, edid_mon); - + modes = xf86OutputGetEDIDModes (output); return modes; } @@ -304,33 +212,19 @@ RADEONProbeOutputModes(xf86OutputPtr output) if (radeon_output->type == OUTPUT_LVDS) { /* okay we got DDC info */ if (output->MonInfo) { - /* Debug info for now, at least */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num); - xf86PrintEDID(output->MonInfo); - - modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo); - - for (mode = modes; mode != NULL; mode = mode->next) { - if (mode->Flags & V_DBLSCAN) { - if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768)) - mode->status = MODE_CLOCK_RANGE; - } - } - xf86PruneInvalidModes(pScrn, &modes, TRUE); - - /* do some physcial size stuff */ + edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus); + xf86OutputSetEDID (output, edid_mon); + + modes = xf86OutputGetEDIDModes (output); } - if (modes == NULL) { - RADEONValidateFPModes(output, pScrn->display->modes, &modes); + modes = RADEONFPNativeMode(output); + /* add the screen modes */ + RADEONAddScreenModes(output, &modes); } + return modes; } } - - if (modes) { - xf86ValidateModesUserConfig(pScrn, modes); - xf86PruneInvalidModes(pScrn, &modes, FALSE); - } return modes; } diff --git a/src/radeon_output.c b/src/radeon_output.c index 4df25972..a6da78e6 100644 --- a/src/radeon_output.c +++ b/src/radeon_output.c @@ -154,6 +154,88 @@ static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color); static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn); static void RADEONGetTMDSInfoFromTable(xf86OutputPtr output); +Bool +RADEONDVOReadByte(I2CDevPtr dvo, int addr, CARD8 *ch) +{ + if (!xf86I2CReadByte(dvo, addr, ch)) { + xf86DrvMsg(dvo->pI2CBus->scrnIndex, X_ERROR, + "Unable to read from %s Slave %d.\n", + dvo->pI2CBus->BusName, dvo->SlaveAddr); + return FALSE; + } + return TRUE; +} + +Bool +RADEONDVOWriteByte(I2CDevPtr dvo, int addr, CARD8 ch) +{ + if (!xf86I2CWriteByte(dvo, addr, ch)) { + xf86DrvMsg(dvo->pI2CBus->scrnIndex, X_ERROR, + "Unable to write to %s Slave %d.\n", + dvo->pI2CBus->BusName, dvo->SlaveAddr); + return FALSE; + } + return TRUE; +} + +static I2CDevPtr +RADEONDVODeviceInit(I2CBusPtr b, I2CSlaveAddr addr) +{ + I2CDevPtr dvo; + + dvo = xcalloc(1, sizeof(I2CDevRec)); + if (dvo == NULL) + return NULL; + + dvo->DevName = "RADEON DVO Controller"; + dvo->SlaveAddr = addr; + dvo->pI2CBus = b; + dvo->StartTimeout = b->StartTimeout; + dvo->BitTimeout = b->BitTimeout; + dvo->AcknTimeout = b->AcknTimeout; + dvo->ByteTimeout = b->ByteTimeout; + + if (xf86I2CDevInit(dvo)) { + return dvo; + } + + xfree(dvo); + return NULL; +} + +void +RADEONRestoreDVOChip(ScrnInfoPtr pScrn, xf86OutputPtr output) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONOutputPrivatePtr radeon_output = output->driver_private; + + if (!radeon_output->DVOChip) + return; + + OUTREG(radeon_output->dvo_i2c_reg, INREG(radeon_output->dvo_i2c_reg) & + (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1)); + + if (!RADEONInitExtTMDSInfoFromBIOS(output)) { + /* do mac stuff here */ +#if defined(__powerpc__) + if (radeon_output->DVOChip) { + switch(info->MacModel) { + case RADEON_MAC_POWERBOOK_DL: + RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x30); + RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x00); + RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x90); + RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0x89); + RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x3b); + break; + default: + break; + } + } +#endif + } +} + void RADEONPrintPortMap(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -266,7 +348,8 @@ RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output) } else if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) || (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D)) { MonType = MT_DFP; - } else if ((*MonInfo)->rawData[0x14] & 0x80) { /* if it's digital */ + } else if (radeon_output->type == OUTPUT_DVI && + ((*MonInfo)->rawData[0x14] & 0x80)) { /* if it's digital and DVI */ MonType = MT_DFP; } else { MonType = MT_CRT; @@ -647,12 +730,16 @@ radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) return MODE_CLOCK_RANGE; } - if (radeon_output->type != OUTPUT_LVDS) - return MODE_OK; - - if (pMode->HDisplay > radeon_output->PanelXRes || - pMode->VDisplay > radeon_output->PanelYRes) - return MODE_PANEL; + if (radeon_output->type == OUTPUT_LVDS) { + if (radeon_output->rmx_type == RMX_OFF) { + if (pMode->HDisplay != radeon_output->PanelXRes || + pMode->VDisplay != radeon_output->PanelYRes) + return MODE_PANEL; + } + if (pMode->HDisplay > radeon_output->PanelXRes || + pMode->VDisplay > radeon_output->PanelYRes) + return MODE_PANEL; + } return MODE_OK; } @@ -663,28 +750,27 @@ radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, { RADEONOutputPrivatePtr radeon_output = output->driver_private; - if (radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP) { + radeon_output->Flags &= ~RADEON_USE_RMX; + + /* decide if we are using RMX */ + if ((radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP) + && radeon_output->rmx_type != RMX_OFF) { xf86CrtcPtr crtc = output->crtc; RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; - if ((mode->HDisplay < radeon_output->PanelXRes || - mode->VDisplay < radeon_output->PanelYRes) && - radeon_crtc->crtc_id == 0) - adjusted_mode->Flags |= RADEON_USE_RMX; - - if (adjusted_mode->Flags & RADEON_USE_RMX) { - adjusted_mode->CrtcHTotal = mode->CrtcHDisplay + radeon_output->HBlank; - adjusted_mode->CrtcHSyncStart = mode->CrtcHDisplay + radeon_output->HOverPlus; - adjusted_mode->CrtcHSyncEnd = mode->CrtcHSyncStart + radeon_output->HSyncWidth; - adjusted_mode->CrtcVTotal = mode->CrtcVDisplay + radeon_output->VBlank; - adjusted_mode->CrtcVSyncStart = mode->CrtcVDisplay + radeon_output->VOverPlus; - adjusted_mode->CrtcVSyncEnd = mode->CrtcVSyncStart + radeon_output->VSyncWidth; - adjusted_mode->Clock = radeon_output->DotClock; - radeon_output->Flags |= RADEON_USE_RMX; - adjusted_mode->Flags = radeon_output->Flags; - } else - radeon_output->Flags &= ~RADEON_USE_RMX; + if (radeon_crtc->crtc_id == 0) { + if (mode->HDisplay < radeon_output->PanelXRes || + mode->VDisplay < radeon_output->PanelYRes) + radeon_output->Flags |= RADEON_USE_RMX; + } + } + /* update clock for LVDS always and DFP if RMX is active */ + if ((radeon_output->MonType == MT_LCD) || + ((radeon_output->MonType == MT_DFP) && + (radeon_output->Flags & RADEON_USE_RMX))) { + adjusted_mode->Clock = radeon_output->DotClock; + adjusted_mode->Flags = radeon_output->Flags; } return TRUE; @@ -765,7 +851,7 @@ static void RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save, DisplayModePtr mode, BOOL IsPrimary) { ScrnInfoPtr pScrn = output->scrn; - RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONInfoPtr info = RADEONPTR(pScrn); if (pScrn->rgbBits == 8) @@ -775,26 +861,33 @@ static void RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save, save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl & ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */ - save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); + save->fp2_gen_cntl &= ~(RADEON_FP2_ON | + RADEON_FP2_DVO_EN | + RADEON_FP2_DVO_RATE_SEL_SDR); + + + /* XXX: these may be oem specific */ + if (IS_R300_VARIANT) { + save->fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN | R300_FP2_DVO_CLOCK_MODE_SINGLE; +#if 0 + if (mode->Clock > 165000) + save->fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN; +#endif + } if (IsPrimary) { if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) { - save->fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | - RADEON_FP2_DVO_EN | - RADEON_FP2_DVO_RATE_SEL_SDR); - if (mode->Flags & RADEON_USE_RMX) - save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX; + save->fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK; + if (mode->Flags & RADEON_USE_RMX) + save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX; } else { - save->fp2_gen_cntl &= ~(RADEON_FP2_SRC_SEL_CRTC2 | - RADEON_FP2_DVO_RATE_SEL_SDR); - } + save->fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2; + } } else { if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) { - save->fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | - RADEON_FP2_DVO_RATE_SEL_SDR); + save->fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK; save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2; } else { - save->fp2_gen_cntl &= ~(RADEON_FP2_DVO_RATE_SEL_SDR); save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2; } } @@ -807,16 +900,30 @@ static void RADEONInitLVDSRegisters(xf86OutputPtr output, RADEONSavePtr save, ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); - save->lvds_pll_cntl = info->SavedReg.lvds_pll_cntl; + save->lvds_pll_cntl = (info->SavedReg.lvds_pll_cntl | + RADEON_LVDS_PLL_EN); + + save->lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET; save->lvds_gen_cntl = info->SavedReg.lvds_gen_cntl; save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON); - if (IsPrimary) - save->lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2; - else - save->lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2; + if (IS_R300_VARIANT) + save->lvds_pll_cntl &= ~(R300_LVDS_SRC_SEL_MASK); + + if (IsPrimary) { + if (IS_R300_VARIANT) { + if (mode->Flags & RADEON_USE_RMX) + save->lvds_pll_cntl |= R300_LVDS_SRC_SEL_RMX; + } else + save->lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2; + } else { + if (IS_R300_VARIANT) { + save->lvds_pll_cntl |= R300_LVDS_SRC_SEL_CRTC2; + } else + save->lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2; + } } @@ -1018,15 +1125,6 @@ radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode, xf86CrtcPtr crtc = output->crtc; RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; - if (radeon_output->type == OUTPUT_DVI && - radeon_output->TMDSType == TMDS_INT) { - if (radeon_output->tmds_pll_table == TMDS_PLL_BIOS) { - if (!RADEONGetTMDSInfoFromBIOS(output)) - RADEONGetTMDSInfoFromTable(output); - } else - RADEONGetTMDSInfoFromTable(output); - } - RADEONInitOutputRegisters(pScrn, &info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id); if (radeon_crtc->crtc_id == 0) @@ -1043,6 +1141,7 @@ radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode, RADEONRestoreFPRegisters(pScrn, &info->ModeReg); } else { ErrorF("restore FP2\n"); + RADEONRestoreDVOChip(pScrn, output); RADEONRestoreFP2Registers(pScrn, &info->ModeReg); } break; @@ -1641,9 +1740,9 @@ radeon_create_resources(xf86OutputPtr output) if (radeon_output->DACType == DAC_PRIMARY) data = 1; /* primary dac, only drives vga */ - else if (radeon_output->DACType == DAC_TVDAC && + /*else if (radeon_output->DACType == DAC_TVDAC && info->tvdac_use_count < 2) - data = 1; /* only one output with tvdac */ + data = 1;*/ /* only one output with tvdac */ else data = 0; /* shared tvdac between vga/dvi/tv */ @@ -1672,6 +1771,10 @@ radeon_create_resources(xf86OutputPtr output) #else s = "bios"; #endif + if (xf86ReturnOptValBool(info->Options, OPTION_DEFAULT_TMDS_PLL, FALSE)) { + s = "driver"; + } + err = RRChangeOutputProperty(output->randr_output, tmds_pll_atom, XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s, FALSE, FALSE); @@ -1682,7 +1785,7 @@ radeon_create_resources(xf86OutputPtr output) } - /* RMX control - fullscreen, centered, keep ratio */ + /* RMX control - fullscreen, centered, keep ratio, off */ /* actually more of a crtc property as only crtc1 has rmx */ if (radeon_output->type == OUTPUT_LVDS || radeon_output->type == OUTPUT_DVI) { @@ -1695,7 +1798,10 @@ radeon_create_resources(xf86OutputPtr output) "RRConfigureOutputProperty error, %d\n", err); } /* Set the current value of the property */ - s = "full"; + if (radeon_output->type == OUTPUT_LVDS) + s = "full"; + else + s = "off"; err = RRChangeOutputProperty(output->randr_output, rmx_atom, XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s, FALSE, FALSE); @@ -1876,34 +1982,35 @@ radeon_set_property(xf86OutputPtr output, Atom property, radeon_output->load_detection = val; } else if (property == rmx_atom) { - xf86CrtcPtr crtc = output->crtc; - RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; - if (radeon_crtc->crtc_id == 0) { - const char *s; - if (value->type != XA_STRING || value->format != 8) - return FALSE; - s = (char*)value->data; - if (value->size == strlen("full") && !strncmp("full", s, strlen("full"))) { - return TRUE; - } else if (value->size == strlen("aspect") && !strncmp("aspect", s, strlen("aspect"))) { - return TRUE; - } else if (value->size == strlen("center") && !strncmp("center", s, strlen("center"))) { - return TRUE; - } - return FALSE; - } else { - return FALSE; - } + const char *s; + if (value->type != XA_STRING || value->format != 8) + return FALSE; + s = (char*)value->data; + if (value->size == strlen("full") && !strncmp("full", s, strlen("full"))) { + radeon_output->rmx_type = RMX_FULL; + return TRUE; + } else if (value->size == strlen("aspect") && !strncmp("aspect", s, strlen("aspect"))) { + radeon_output->rmx_type = RMX_ASPECT; + return TRUE; + } else if (value->size == strlen("center") && !strncmp("center", s, strlen("center"))) { + radeon_output->rmx_type = RMX_CENTER; + return TRUE; + } else if (value->size == strlen("off") && !strncmp("off", s, strlen("off"))) { + radeon_output->rmx_type = RMX_OFF; + return TRUE; + } + return FALSE; } else if (property == tmds_pll_atom) { const char *s; if (value->type != XA_STRING || value->format != 8) return FALSE; s = (char*)value->data; if (value->size == strlen("bios") && !strncmp("bios", s, strlen("bios"))) { - radeon_output->tmds_pll_table = TMDS_PLL_BIOS; + if (!RADEONGetTMDSInfoFromBIOS(output)) + RADEONGetTMDSInfoFromTable(output); return TRUE; } else if (value->size == strlen("driver") && !strncmp("driver", s, strlen("driver"))) { - radeon_output->tmds_pll_table = TMDS_PLL_DRIVER; + RADEONGetTMDSInfoFromTable(output); return TRUE; } return FALSE; @@ -1973,10 +2080,7 @@ radeon_set_property(xf86OutputPtr output, Atom property, if (value->type != XA_STRING || value->format != 8) return FALSE; s = (char*)value->data; - if (value->size == strlen("default") && !strncmp("default", s, strlen("default"))) { - radeon_output->tvStd = radeon_output->default_tvStd; - return TRUE; - } else if (value->size == strlen("ntsc") && !strncmp("ntsc", s, strlen("ntsc"))) { + if (value->size == strlen("ntsc") && !strncmp("ntsc", s, strlen("ntsc"))) { if (radeon_output->SupportedTVStds & TV_STD_NTSC) { radeon_output->tvStd = TV_STD_NTSC; return TRUE; @@ -2433,7 +2537,6 @@ RADEONGetTVInfo(xf86OutputPtr output) void RADEONInitConnector(xf86OutputPtr output) { ScrnInfoPtr pScrn = output->scrn; - RADEONInfoPtr info = RADEONPTR(pScrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; int DDCReg = 0; char* name = (char*) DDCTypeName[radeon_output->DDCType]; @@ -2449,9 +2552,9 @@ void RADEONInitConnector(xf86OutputPtr output) if (radeon_output->DACType == DAC_PRIMARY) radeon_output->load_detection = 1; /* primary dac, only drives vga */ - else if (radeon_output->DACType == DAC_TVDAC && + /*else if (radeon_output->DACType == DAC_TVDAC && info->tvdac_use_count < 2) - radeon_output->load_detection = 1; /* only one output with tvdac */ + radeon_output->load_detection = 1;*/ /* only one output with tvdac */ else radeon_output->load_detection = 0; /* shared tvdac between vga/dvi/tv */ @@ -2461,11 +2564,32 @@ void RADEONInitConnector(xf86OutputPtr output) } if (radeon_output->type == OUTPUT_LVDS) { + radeon_output->rmx_type = RMX_FULL; RADEONGetLVDSInfo(output); } if (radeon_output->type == OUTPUT_DVI) { - RADEONGetTMDSInfo(output); + I2CBusPtr pDVOBus; + radeon_output->rmx_type = RMX_OFF; + if (radeon_output->TMDSType == TMDS_EXT) { +#if defined(__powerpc__) + radeon_output->dvo_i2c_reg = RADEON_GPIO_MONID; + radeon_output->dvo_i2c_slave_addr = 0x70; +#else + if (!RADEONGetExtTMDSInfoFromBIOS(output)) { + radeon_output->dvo_i2c_reg = RADEON_GPIO_CRT2_DDC; + radeon_output->dvo_i2c_slave_addr = 0x70; + } +#endif + if (RADEONI2CInit(pScrn, &pDVOBus, radeon_output->dvo_i2c_reg, "DVO")) { + radeon_output->DVOChip = + RADEONDVODeviceInit(pDVOBus, + radeon_output->dvo_i2c_slave_addr); + if (!radeon_output->DVOChip) + xfree(pDVOBus); + } + } else + RADEONGetTMDSInfo(output); } if (radeon_output->type == OUTPUT_STV || @@ -2480,9 +2604,104 @@ void RADEONInitConnector(xf86OutputPtr output) } +#if defined(__powerpc__) +static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + + switch (info->MacModel) { + case RADEON_MAC_IBOOK: + info->BiosConnector[0].DDCType = DDC_DVI; + info->BiosConnector[0].DACType = DAC_NONE; + info->BiosConnector[0].TMDSType = TMDS_NONE; + info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY; + info->BiosConnector[0].valid = TRUE; + + info->BiosConnector[1].DDCType = DDC_VGA; + info->BiosConnector[1].DACType = DAC_TVDAC; + info->BiosConnector[1].TMDSType = TMDS_NONE; + info->BiosConnector[1].ConnectorType = CONNECTOR_CRT; + info->BiosConnector[1].valid = TRUE; + + info->BiosConnector[2].ConnectorType = CONNECTOR_STV; + info->BiosConnector[2].DACType = DAC_TVDAC; + info->BiosConnector[2].TMDSType = TMDS_NONE; + info->BiosConnector[2].DDCType = DDC_NONE_DETECTED; + info->BiosConnector[2].valid = TRUE; + return TRUE; + case RADEON_MAC_POWERBOOK_DL: + info->BiosConnector[0].DDCType = DDC_DVI; + info->BiosConnector[0].DACType = DAC_NONE; + info->BiosConnector[0].TMDSType = TMDS_NONE; + info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY; + info->BiosConnector[0].valid = TRUE; + + info->BiosConnector[1].DDCType = DDC_VGA; + info->BiosConnector[1].DACType = DAC_PRIMARY; + info->BiosConnector[1].TMDSType = TMDS_EXT; + info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I; + info->BiosConnector[1].valid = TRUE; + + info->BiosConnector[2].ConnectorType = CONNECTOR_STV; + info->BiosConnector[2].DACType = DAC_TVDAC; + info->BiosConnector[2].TMDSType = TMDS_NONE; + info->BiosConnector[2].DDCType = DDC_NONE_DETECTED; + info->BiosConnector[2].valid = TRUE; + return TRUE; + case RADEON_MAC_POWERBOOK: + info->BiosConnector[0].DDCType = DDC_DVI; + info->BiosConnector[0].DACType = DAC_NONE; + info->BiosConnector[0].TMDSType = TMDS_NONE; + info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY; + info->BiosConnector[0].valid = TRUE; + + info->BiosConnector[1].DDCType = DDC_VGA; + info->BiosConnector[1].DACType = DAC_PRIMARY; + info->BiosConnector[1].TMDSType = TMDS_INT; + info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I; + info->BiosConnector[1].valid = TRUE; + + info->BiosConnector[2].ConnectorType = CONNECTOR_STV; + info->BiosConnector[2].DACType = DAC_TVDAC; + info->BiosConnector[2].TMDSType = TMDS_NONE; + info->BiosConnector[2].DDCType = DDC_NONE_DETECTED; + info->BiosConnector[2].valid = TRUE; + return TRUE; + case RADEON_MAC_MINI: + info->BiosConnector[0].DDCType = DDC_CRT2; + info->BiosConnector[0].DACType = DAC_TVDAC; + info->BiosConnector[0].TMDSType = TMDS_EXT; + info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I; + info->BiosConnector[0].valid = TRUE; + + info->BiosConnector[1].ConnectorType = CONNECTOR_STV; + info->BiosConnector[1].DACType = DAC_TVDAC; + info->BiosConnector[1].TMDSType = TMDS_NONE; + info->BiosConnector[1].DDCType = DDC_NONE_DETECTED; + info->BiosConnector[1].valid = TRUE; + return TRUE; + default: + return FALSE; + } + + return FALSE; +} +#endif + static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + + if (!pRADEONEnt->HasCRTC2) { + info->BiosConnector[0].DDCType = DDC_VGA; + info->BiosConnector[0].DACType = DAC_PRIMARY; + info->BiosConnector[0].TMDSType = TMDS_NONE; + info->BiosConnector[0].ConnectorType = CONNECTOR_CRT; + info->BiosConnector[0].valid = TRUE; + return; + } if (info->IsMobility) { /* Below is the most common setting, but may not be true */ @@ -2515,7 +2734,7 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn) info->BiosConnector[1].DDCType = DDC_VGA; info->BiosConnector[1].DACType = DAC_PRIMARY; - info->BiosConnector[1].TMDSType = TMDS_EXT; + info->BiosConnector[1].TMDSType = TMDS_UNKNOWN; info->BiosConnector[1].ConnectorType = CONNECTOR_CRT; info->BiosConnector[1].valid = TRUE; } @@ -2596,6 +2815,29 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) info->BiosConnector[i].ConnectorType = CONNECTOR_NONE; } +#if defined(__powerpc__) + optstr = (char *)xf86GetOptValString(info->Options, OPTION_MAC_MODEL); + + info->MacModel = 0; + if (optstr) { + if (!strncmp("ibook", optstr, strlen("ibook"))) + info->MacModel = RADEON_MAC_IBOOK; + else if (!strncmp("powerbook-duallink", optstr, strlen("powerbook-duallink"))) + info->MacModel = RADEON_MAC_POWERBOOK_DL; + else if (!strncmp("powerbook", optstr, strlen("powerbook"))) + info->MacModel = RADEON_MAC_POWERBOOK; + else if (!strncmp("mini", optstr, strlen("mini"))) + info->MacModel = RADEON_MAC_MINI; + else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid Mac Model: %s\n", optstr); + return FALSE; + } + + if (!RADEONSetupAppleConnectors(pScrn)) + RADEONSetupGenericConnectors(pScrn); + + } else +#endif if (xf86ReturnOptValBool(info->Options, OPTION_DEFAULT_CONNECTOR_TABLE, FALSE)) { RADEONSetupGenericConnectors(pScrn); } else { diff --git a/src/radeon_probe.c b/src/radeon_probe.c index b7c38ad0..5c7d16ff 100644 --- a/src/radeon_probe.c +++ b/src/radeon_probe.c @@ -316,7 +316,7 @@ RADEONProbe(DriverPtr drv, int flags) DevUnion *pPriv; RADEONEntPtr pRADEONEnt; - xf86SetEntitySharable(usedChips[i]); + /*xf86SetEntitySharable(usedChips[i]);*/ if (gRADEONEntityIndex == -1) gRADEONEntityIndex = xf86AllocateEntityPrivateIndex(); diff --git a/src/radeon_probe.h b/src/radeon_probe.h index b6ef59dd..dbd50d74 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -124,9 +124,11 @@ typedef enum typedef enum { - TMDS_PLL_BIOS, - TMDS_PLL_DRIVER -} RADEONTMDSPllType; + RMX_OFF, + RMX_FULL, + RMX_CENTER, + RMX_ASPECT +} RADEONRMXType; typedef struct { CARD32 freq; @@ -202,7 +204,12 @@ typedef struct _RADEONOutputPrivateRec { int PanelPwrDly; int DotClock; RADEONTMDSPll tmds_pll[4]; - RADEONTMDSPllType tmds_pll_table; + RADEONRMXType rmx_type; + /* dvo */ + I2CDevPtr DVOChip; + int dvo_i2c_reg; + int dvo_i2c_slave_addr; + Bool dvo_duallink; /* TV out */ TVStd default_tvStd; TVStd tvStd; diff --git a/src/radeon_reg.h b/src/radeon_reg.h index af62a692..26533397 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -780,7 +780,7 @@ # define RADEON_FP2_PANEL_FORMAT (1 << 3) # define RADEON_FP2_DETECT_SENSE (1 << 8) # define R200_FP2_SOURCE_SEL_MASK (3 << 10) -# define R200_FP2_SOURCE_SEL_CRTC1 (0 << 10) +# define R200_FP2_SOURCE_SEL_CRTC1 (0 << 10) # define R200_FP2_SOURCE_SEL_CRTC2 (1 << 10) # define R200_FP2_SOURCE_SEL_RMX (2 << 10) # define R200_FP2_SOURCE_SEL_TRANS_UNIT (3 << 10) @@ -796,6 +796,8 @@ # define RADEON_FP2_DVO_EN (1 << 25) # define RADEON_FP2_DVO_RATE_SEL_SDR (1 << 26) # define R200_FP2_DVO_RATE_SEL_SDR (1 << 27) +# define R300_FP2_DVO_CLOCK_MODE_SINGLE (1 << 28) +# define R300_FP2_DVO_DUAL_CHANNEL_EN (1 << 29) #define RADEON_FP_H_SYNC_STRT_WID 0x02c4 #define RADEON_FP_H2_SYNC_STRT_WID 0x03c4 #define RADEON_FP_HORZ_STRETCH 0x028c @@ -924,6 +926,12 @@ #define RADEON_LVDS_PLL_CNTL 0x02d4 # define RADEON_HSYNC_DELAY_SHIFT 28 # define RADEON_HSYNC_DELAY_MASK (0xf << 28) +# define RADEON_LVDS_PLL_EN (1 << 16) +# define RADEON_LVDS_PLL_RESET (1 << 17) +# define R300_LVDS_SRC_SEL_MASK (3 << 18) +# define R300_LVDS_SRC_SEL_CRTC1 (0 << 18) +# define R300_LVDS_SRC_SEL_CRTC2 (1 << 18) +# define R300_LVDS_SRC_SEL_RMX (2 << 18) #define RADEON_MAX_LATENCY 0x0f3f /* PCI */ #define RADEON_MC_AGP_LOCATION 0x014c diff --git a/src/radeon_video.c b/src/radeon_video.c index 271f7fe8..dca96954 100644 --- a/src/radeon_video.c +++ b/src/radeon_video.c @@ -2907,6 +2907,15 @@ RADEONPutImage( clipBoxes, width, height)) return Success; + if (!crtc) { + if (pPriv->videoStatus & CLIENT_VIDEO_ON) { + unsigned char *RADEONMMIO = info->MMIO; + OUTREG(RADEON_OV0_SCALE_CNTL, 0); + pPriv->videoStatus &= ~CLIENT_VIDEO_ON; + } + return Success; + } + dstBox.x1 -= crtc->x; dstBox.x2 -= crtc->x; dstBox.y1 -= crtc->y; @@ -3285,6 +3294,15 @@ RADEONDisplaySurface( surface->width, surface->height)) return Success; + if (!crtc) { + if (pPriv->isOn) { + unsigned char *RADEONMMIO = info->MMIO; + OUTREG(RADEON_OV0_SCALE_CNTL, 0); + pPriv->isOn = FALSE; + } + return Success; + } + dstBox.x1 -= crtc->x; dstBox.x2 -= crtc->x; dstBox.y1 -= crtc->y; @@ -3419,6 +3437,15 @@ RADEONPutVideo( clipBoxes, width, height)) return Success; + if (!crtc) { + if (pPriv->videoStatus & CLIENT_VIDEO_ON) { + unsigned char *RADEONMMIO = info->MMIO; + OUTREG(RADEON_OV0_SCALE_CNTL, 0); + pPriv->videoStatus &= ~CLIENT_VIDEO_ON; + } + return Success; + } + dstBox.x1 -= crtc->x; dstBox.x2 -= crtc->x; dstBox.y1 -= crtc->y; diff --git a/src/radeon_vip.c b/src/radeon_vip.c index abcba06a..7ee4ab5b 100644 --- a/src/radeon_vip.c +++ b/src/radeon_vip.c @@ -331,6 +331,13 @@ void RADEONVIP_reset(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) OUTREG(RADEON_VIPH_BM_CHUNK, 0x0); OUTREG(RADEON_TEST_DEBUG_CNTL, INREG(RADEON_TEST_DEBUG_CNTL) & (~RADEON_TEST_DEBUG_CNTL__TEST_DEBUG_OUT_EN)); break; + case CHIP_FAMILY_RV380: + OUTREG(RADEON_VIPH_CONTROL, 0x003F000D); /* slowest, timeout in 16 phases */ + OUTREG(RADEON_VIPH_TIMEOUT_STAT, (INREG(RADEON_VIPH_TIMEOUT_STAT) & 0xFFFFFF00) | RADEON_VIPH_TIMEOUT_STAT__VIPH_REGR_DIS); + OUTREG(RADEON_VIPH_DV_LAT, 0x444400FF); /* set timeslice */ + OUTREG(RADEON_VIPH_BM_CHUNK, 0x0); + OUTREG(RADEON_TEST_DEBUG_CNTL, INREG(RADEON_TEST_DEBUG_CNTL) & (~RADEON_TEST_DEBUG_CNTL__TEST_DEBUG_OUT_EN)); + break; default: OUTREG(RADEON_VIPH_CONTROL, 0x003F0004); /* slowest, timeout in 16 phases */ OUTREG(RADEON_VIPH_TIMEOUT_STAT, (INREG(RADEON_VIPH_TIMEOUT_STAT) & 0xFFFFFF00) | RADEON_VIPH_TIMEOUT_STAT__VIPH_REGR_DIS); |