diff options
Diffstat (limited to 'src/radeon_driver.c')
-rw-r--r-- | src/radeon_driver.c | 1409 |
1 files changed, 349 insertions, 1060 deletions
diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 1efa07ac..4f568275 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v 1.117 2004/02/19 22:38:12 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v 1.104 2003/08/23 15:02:54 dawes Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. @@ -61,6 +61,7 @@ /* Driver data structures */ #include "radeon.h" #include "radeon_macros.h" +#include "radeon_pci.h" #include "radeon_probe.h" #include "radeon_reg.h" #include "radeon_version.h" @@ -80,7 +81,6 @@ /* X and server generic header files */ #include "xf86.h" #include "xf86_OSproc.h" -#include "xf86PciInfo.h" #include "xf86RAC.h" #include "xf86Resources.h" #include "xf86cmap.h" @@ -93,9 +93,6 @@ #ifndef MAX #define MAX(a,b) ((a)>(b)?(a):(b)) #endif -#ifndef MIN -#define MIN(a,b) ((a)>(b)?(b):(a)) -#endif /* Forward definitions for driver functions */ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen); @@ -106,7 +103,6 @@ static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); -static void RADEONInitDispBandwidth(ScrnInfoPtr pScrn); typedef enum { OPTION_NOACCEL, @@ -115,7 +111,6 @@ typedef enum { OPTION_DAC_8BIT, #ifdef XF86DRI OPTION_IS_PCI, - OPTION_BUS_TYPE, OPTION_CP_PIO, OPTION_USEC_TIMEOUT, OPTION_AGP_MODE, @@ -136,10 +131,7 @@ typedef enum { OPTION_CLONE_HSYNC, OPTION_CLONE_VREFRESH, OPTION_FBDEV, - OPTION_VIDEO_KEY, - OPTION_DISP_PRIORITY, - OPTION_PANEL_SIZE, - OPTION_MIN_DOTCLOCK + OPTION_VIDEO_KEY } RADEONOpts; const OptionInfoRec RADEONOptions[] = { @@ -149,12 +141,10 @@ const OptionInfoRec RADEONOptions[] = { { OPTION_DAC_8BIT, "Dac8Bit", OPTV_BOOLEAN, {0}, TRUE }, #ifdef XF86DRI { OPTION_IS_PCI, "ForcePCIMode", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_BUS_TYPE, "BusType", OPTV_ANYSTR, {0}, FALSE }, { OPTION_CP_PIO, "CPPIOMode", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_USEC_TIMEOUT, "CPusecTimeout", OPTV_INTEGER, {0}, FALSE }, { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE }, { OPTION_AGP_FW, "AGPFastWrite", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_GART_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, { OPTION_GART_SIZE, "GARTSize", OPTV_INTEGER, {0}, FALSE }, { OPTION_RING_SIZE, "RingSize", OPTV_INTEGER, {0}, FALSE }, { OPTION_BUFFER_SIZE, "BufferSize", OPTV_INTEGER, {0}, FALSE }, @@ -172,12 +162,15 @@ const OptionInfoRec RADEONOptions[] = { { OPTION_CLONE_VREFRESH, "CloneVRefresh", OPTV_ANYSTR, {0}, FALSE }, { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, - { OPTION_DISP_PRIORITY, "DisplayPriority", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_PANEL_SIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_MIN_DOTCLOCK, "ForceMinDotClock", OPTV_FREQ, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; +RADEONRAMRec RADEONRAM[] = { /* Memory Specifications + From Radeon Manual */ + { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SDRAM" }, + { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SDRAM" }, +}; + static const char *vgahwSymbols[] = { "vgaHWFreeHWRec", "vgaHWGetHWRec", @@ -377,7 +370,7 @@ static struct {1024, 768, 87}, {832, 624, 75}, {800, 600, 75}, - {800, 600, 72}, + {800, 600, 72}, {800, 600, 60}, {800, 600, 56}, {640, 480, 75}, @@ -388,24 +381,6 @@ static struct {720, 400, 70}, }; -static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] = -{ - {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_UNKNOW*/ - {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_LEGACY*/ - {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RADEON*/ - {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV100*/ - {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS100*/ - {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV200*/ - {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS200*/ - {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R200*/ - {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV250*/ - {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS300*/ - {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x400f7/*0x40111*/}, {0, 0}}, /*CHIP_FAMILY_RV280*/ - {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R300*/ - {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R350*/ - {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV350*/ -}; - extern int gRADEONEntityIndex; struct RADEONInt10Save { @@ -439,7 +414,7 @@ RADEONPreInt10Save(ScrnInfoPtr pScrn, void **pPtr) SaveStruct.MEMSIZE = INREG(RADEON_CONFIG_MEMSIZE); SaveStruct.MPP_TB_CONFIG = INREG(RADEON_MPP_TB_CONFIG); - /* + /* * Zap MEM_CNTL and set MPP_TB_CONFIG<31:24> to 4 */ OUTREG(RADEON_MEM_CNTL, 0); @@ -468,20 +443,20 @@ RADEONPostInt10Check(ScrnInfoPtr pScrn, void *ptr) * the saved registers. */ CardTmp = INREG(RADEON_MEM_CNTL); - if (!CardTmp || - ((CardTmp & 1) && + if (!CardTmp || + ((CardTmp & 1) && (((CardTmp >> 8) & 0xff) != ((CardTmp >> 24) & 0xff)))) { /* Restore the saved registers */ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Restoring MEM_CNTL (%08lx), setting to %08lx\n", - (unsigned long)CardTmp, (unsigned long)pSave->MEM_CNTL); + "Restoring MEM_CNTL (%08x), setting to %08x\n", + CardTmp, pSave->MEM_CNTL); OUTREG(RADEON_MEM_CNTL, pSave->MEM_CNTL); CardTmp = INREG(RADEON_CONFIG_MEMSIZE); if (CardTmp != pSave->MEMSIZE) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Restoring CONFIG_MEMSIZE (%08lx), setting to %08lx\n", - (unsigned long)CardTmp, (unsigned long)pSave->MEMSIZE); + "Restoring CONFIG_MEMSIZE (%08x), setting to %08x\n", + CardTmp, pSave->MEMSIZE); OUTREG(RADEON_CONFIG_MEMSIZE, pSave->MEMSIZE); } } @@ -489,9 +464,8 @@ RADEONPostInt10Check(ScrnInfoPtr pScrn, void *ptr) CardTmp = INREG(RADEON_MPP_TB_CONFIG); if ((CardTmp & 0xff000000u) != (pSave->MPP_TB_CONFIG & 0xff000000u)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Restoring MPP_TB_CONFIG<31:24> (%02lx), setting to %02lx\n", - (unsigned long)CardTmp >> 24, - (unsigned long)pSave->MPP_TB_CONFIG >> 24); + "Restoring MPP_TB_CONFIG<31:24> (%02x), setting to %02x\n", + CardTmp >> 24, pSave->MPP_TB_CONFIG >> 24); CardTmp &= 0x00ffffffu; CardTmp |= (pSave->MPP_TB_CONFIG & 0xff000000u); OUTREG(RADEON_MPP_TB_CONFIG, CardTmp); @@ -811,7 +785,7 @@ static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCT OUTREG(info->DDCReg, INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1)); - for (i = 0; i < 10; i++) { + for (i = 0; i < 3; i++) { usleep(15000); if (INREG(info->DDCReg) & RADEON_GPIO_Y_1) break; @@ -864,7 +838,7 @@ static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCT info->DDCReg = DDCReg; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Type: %d, Detected Type: %d\n", DDCType, MonType); return MonType; @@ -875,7 +849,7 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - int bConnected = 0; + int bConnected = 0; /* the monitor either wasn't connected or it is a non-DDC CRT. * try to probe it @@ -901,7 +875,7 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac) ulData = ulOrigCRTC_EXT_CNTL; ulData |= RADEON_CRTC_CRT_ON; OUTREG(RADEON_CRTC_EXT_CNTL, ulData); - + ulOrigDAC_EXT_CNTL = INREG(RADEON_DAC_EXT_CNTL); ulData = ulOrigDAC_EXT_CNTL; ulData &= ~RADEON_DAC_FORCE_DATA_MASK; @@ -928,7 +902,7 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac) ulData = INREG(RADEON_DAC_CNTL); bConnected = (RADEON_DAC_CMP_OUTPUT & ulData)?1:0; - + ulData = ulOrigVCLK_ECP_CNTL; ulMask = 0xFFFFFFFFL; OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask); @@ -938,10 +912,10 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac) OUTREG(RADEON_CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL); } else { /* TV DAC */ - /* This doesn't seem to work reliably (maybe worse on some OEM cards), - for now we always return false. If one wants to connected a - non-DDC monitor on the DVI port when CRT port is also connected, - he will need to explicitly tell the driver in the config file + /* This doesn't seem to work reliably (maybe worse on some OEM cards), + for now we always return false. If one wants to connected a + non-DDC monitor on the DVI port when CRT port is also connected, + he will need to explicitly tell the driver in the config file with Option MonitorLayout. */ bConnected = FALSE; @@ -1005,7 +979,7 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac) ulData = INREG(RADEON_GPIO_MONID); bConnected = (ulData & RADEON_GPIO_Y_0)?1:0; if (!bConnected) break; - + usleep(1000); } @@ -1031,7 +1005,7 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac) unsigned long ulOrigDAC_CNTL2; unsigned long ulData; unsigned long ulMask; - + ulOrigPIXCLKSDATA = INPLL(pScrn, RADEON_PIXCLKS_CNTL); ulData = ulOrigPIXCLKSDATA; @@ -1047,10 +1021,10 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac) OUTREG(RADEON_TV_MASTER_CNTL, ulData); ulOrigDAC_CNTL2 = INREG(RADEON_DAC_CNTL2); - ulData = ulOrigDAC_CNTL2; + ulData = ulOrigDAC_CNTL2; ulData &= ~RADEON_DAC2_DAC2_CLK_SEL; OUTREG(RADEON_DAC_CNTL2, ulData); - + ulOrigTV_DAC_CNTL = INREG(RADEON_TV_DAC_CNTL); ulData = 0x00880213; @@ -1075,12 +1049,12 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac) usleep(1000); ulData = INREG(RADEON_TV_DAC_CNTL); - bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0; + bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0; ulData = ulOrigPIXCLKSDATA; ulMask = 0xFFFFFFFFL; OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask); - + OUTREG(RADEON_TV_MASTER_CNTL, ulOrigTV_MASTER_CNTL); OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2); OUTREG(RADEON_TV_DAC_CNTL, ulOrigTV_DAC_CNTL); @@ -1088,7 +1062,7 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac) } #endif } - + return(bConnected ? MT_CRT : MT_NONE); } @@ -1107,7 +1081,7 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pIn (info->VBIOS[(v) + 1] << 8) | \ (info->VBIOS[(v) + 2] << 16) | \ (info->VBIOS[(v) + 3] << 24)) - + pRADEONEnt->MonType1 = MT_NONE; pRADEONEnt->MonType2 = MT_NONE; pRADEONEnt->MonInfo1 = NULL; @@ -1121,16 +1095,16 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pIn */ if (xf86GetOptValBool(info->Options, OPTION_IGNORE_EDID, &ignore_edid)) { if (ignore_edid) - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "IgnoreEDID is specified, EDID data will be ignored\n"); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "IgnoreEDID is specified, EDID data will be ignored\n"); } - /* + /* * MonitorLayout option takes a string for two monitors connected in following format: * Option "MonitorLayout" "primary-port-display, secondary-port-display" - * primary and secondary port displays can have one of following: - * NONE, CRT, LVDS, TMDS - * With this option, driver will bring up monitors as specified, + * primary and secondary port displays can have one of following: + * NONE, CRT, LVDS, TMDS + * With this option, driver will bring up monitors as specified, * not using auto-detection routines to probe monitors. */ @@ -1149,7 +1123,7 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pIn * CRTC1 -> FP/TMDS -> DVI port -> TMDS panel --> Primary or * CRTC1 -> FP/LVDS -> Int. LCD -> LVDS panel --> Primary or * CRTC1 -> TV DAC -> DVI port -> CRT monitor --> Primary - * + * * Only VGA (can be DVI on some dual-DVI boards) connected: * CRTC1 -> CRT DAC -> VGA port -> CRT monitor --> Primary or * CRTC1 -> FP2/Ext. -> DVI port -> TMDS panel --> Primary (not supported) @@ -1159,19 +1133,19 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pIn * otherwise, VGA port will be treated as 1st port * * Here we always treat DVI port as primary if both ports are connected. - * When only one port is connected, it will be treated as - * primary regardless which port or what type of display is involved. + * When only one port is connected, it will be treated as + * primary regardless which port or what type of display is involved. */ if ((s = xf86GetOptValString(info->Options, OPTION_MONITOR_LAYOUT))) { char s1[5], s2[5]; int i = 0, second = 0; - + /* When using user specified monitor types, we will not do DDC detection - * + * */ do { - switch(*s) + switch(*s) { case ',': s1[i] = '\0'; @@ -1202,9 +1176,9 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pIn pRADEONEnt->MonType1 = MT_DFP; else if (strcmp(s1, "LVDS") == 0) pRADEONEnt->MonType1 = MT_LCD; - else - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Invalid Monitor type specified for 1st port \n"); + else + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Invalid Monitor type specified for 1st port \n"); if (strcmp(s2, "NONE") == 0) pRADEONEnt->MonType2 = MT_NONE; else if (strcmp(s2, "CRT") == 0) @@ -1213,20 +1187,20 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pIn pRADEONEnt->MonType2 = MT_DFP; else if (strcmp(s2, "LVDS") == 0) pRADEONEnt->MonType2 = MT_LCD; - else - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Invalid Monitor type specified for 2nd port \n"); + else + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Invalid Monitor type specified for 2nd port \n"); if (!ignore_edid) { if (pRADEONEnt->MonType1) /* assuming the first port using DDC_DVI */ - if(!RADEONDisplayDDCConnected(pScrn, DDC_DVI, &pRADEONEnt->MonInfo1)) { + if(!RADEONDisplayDDCConnected(pScrn, DDC_DVI, &pRADEONEnt->MonInfo1)) { RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo1); ddc_crt2_used = TRUE; - } + } if (pRADEONEnt->MonType2) { /* assuming the second port using DDC_VGA/DDC_CRT2 */ if(!RADEONDisplayDDCConnected(pScrn, DDC_VGA, &pRADEONEnt->MonInfo2)) if (!ddc_crt2_used) - RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo2); + RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo2); } } @@ -1236,8 +1210,8 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pIn pRADEONEnt->MonInfo1 = pRADEONEnt->MonInfo2; } else { pRADEONEnt->MonType1 = MT_CRT; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "No valid monitor specified, force to CRT on 1st port\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "No valid monitor specified, force to CRT on 1st port\n"); } pRADEONEnt->MonType2 = MT_NONE; pRADEONEnt->MonInfo2 = NULL; @@ -1284,8 +1258,8 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pIn * If that's the case, we need also reverse the port arrangement. * BIOS settings are supposed report this correctly, work fine for all cards tested. * But there may be some exceptions, in that case, user can reverse their monitor - * definition in config file to correct the problem. - */ + * definition in config file to correct the problem. + */ if (info->VBIOS && (tmp = RADEON_BIOS16(info->FPBIOSstart + 0x50))) { for (i = 1; i < 4; i++) { unsigned int tmp0; @@ -1297,7 +1271,7 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pIn } if ((((tmp0 >> 8) & 0x0f) == DDC_DVI ) && ((tmp0 >> 4) & 0x1)) { pRADEONEnt->ReversedTMDS = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Reversed TMDS detected\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Reversed TMDS detected\n"); } } } @@ -1305,10 +1279,10 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pIn /* Primary Head (DVI or Laptop Int. panel)*/ /* A ddc capable display connected on DVI port */ if((pRADEONEnt->MonType1 = RADEONDisplayDDCConnected(pScrn, DDC_DVI, &pRADEONEnt->MonInfo1))); - else if((pRADEONEnt->MonType1 = + else if((pRADEONEnt->MonType1 = RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo1))) { ddc_crt2_used = TRUE; - } else if ((info->IsMobility) && + } else if ((info->IsMobility) && (info->VBIOS && (INREG(RADEON_BIOS_4_SCRATCH) & 4))) { /* non-DDC laptop panel connected on primary */ pRADEONEnt->MonType1 = MT_LCD; @@ -1319,17 +1293,30 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pIn } /* Secondary Head (mostly VGA, can be DVI on some OEM boards)*/ - if((pRADEONEnt->MonType2 = + if((pRADEONEnt->MonType2 = RADEONDisplayDDCConnected(pScrn, DDC_VGA, &pRADEONEnt->MonInfo2))); - else if(!ddc_crt2_used) - pRADEONEnt->MonType2 = + else if(!ddc_crt2_used) + pRADEONEnt->MonType2 = RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &pRADEONEnt->MonInfo2); if (!pRADEONEnt->MonType2) pRADEONEnt->MonType2 = RADEONCrtIsPhysicallyConnected(pScrn, !pRADEONEnt->ReversedDAC); + /* no display detected on DVI port*/ + if (pRADEONEnt->MonType1 == MT_NONE) { + if (pRADEONEnt->MonType2 != MT_NONE) { + /* Only one detected on VGA, let it to be primary */ + pRADEONEnt->MonType1 = pRADEONEnt->MonType2; + pRADEONEnt->MonInfo1 = pRADEONEnt->MonInfo2; + pRADEONEnt->MonType2 = MT_NONE; + } else { + /* Non detected, Default to a CRT connected */ + pRADEONEnt->MonType1 = MT_CRT; + } + } + if(pRADEONEnt->ReversedTMDS) { /* always keep internal TMDS as primary head */ - if (pRADEONEnt->MonType1 == MT_DFP || + if (pRADEONEnt->MonType1 == MT_DFP || pRADEONEnt->MonType2 == MT_DFP) { int tmp1 = pRADEONEnt->MonType1; xf86MonPtr MonInfo = pRADEONEnt->MonInfo1; @@ -1337,35 +1324,21 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pIn pRADEONEnt->MonInfo2 = MonInfo; pRADEONEnt->MonType1 = pRADEONEnt->MonType2; pRADEONEnt->MonType2 = tmp1; - if ((pRADEONEnt->MonType1 == MT_CRT) || + if ((pRADEONEnt->MonType1 == MT_CRT) || (pRADEONEnt->MonType2 == MT_CRT)) { pRADEONEnt->ReversedDAC ^= 1; } } } - - /* no display detected on DVI port*/ - if (pRADEONEnt->MonType1 == MT_NONE) { - if (pRADEONEnt->MonType2 != MT_NONE) { - /* Only one detected on VGA, let it to be primary */ - pRADEONEnt->MonType1 = pRADEONEnt->MonType2; - pRADEONEnt->MonInfo1 = pRADEONEnt->MonInfo2; - pRADEONEnt->MonType2 = MT_NONE; - pRADEONEnt->MonInfo2 = NULL; - } else { - /* Non detected, Default to a CRT connected */ - pRADEONEnt->MonType1 = MT_CRT; - } - } } if(s) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Displays Configured by MonitorLayout: \n\tMonitor1--Type %d, Monitor2--Type %d\n\n", + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Displays Configured by MonitorLayout: \n\tMonitor1--Type %d, Monitor2--Type %d\n\n", pRADEONEnt->MonType1, pRADEONEnt->MonType2); } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Displays Detected: Monitor1--Type %d, Monitor2--Type %d\n\n", + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Displays Detected: Monitor1--Type %d, Monitor2--Type %d\n\n", pRADEONEnt->MonType1, pRADEONEnt->MonType2); } @@ -1386,7 +1359,7 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pIn xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of Monitor2 EDID data --------------------\n"); } } - + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\n"); info->OverlayOnCRTC2 = FALSE; @@ -1394,7 +1367,7 @@ static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn, xf86Int10InfoPtr pIn info->OverlayOnCRTC2 = TRUE; } - if (pRADEONEnt->MonType2 == MT_NONE) + if (pRADEONEnt->MonType2 == MT_NONE) pRADEONEnt->HasSecondary = FALSE; } @@ -1404,6 +1377,7 @@ static Bool RADEONGetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned long tmp, i; + unsigned char *RADEONMMIO; if (!(info->VBIOS = xalloc(RADEON_VBIOS_SIZE))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -1445,35 +1419,34 @@ static Bool RADEONGetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) { RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + RADEONMMIO = info->MMIO; info->Clone = FALSE; info->CloneType = MT_NONE; - if(info->HasCRTC2) { - if(info->IsSecondary) { - info->DisplayType = (RADEONMonitorType)pRADEONEnt->MonType2; - if(info->DisplayType == MT_NONE) return FALSE; + if(info->HasCRTC2) { + if(info->IsSecondary) { + if(!(info->DisplayType = pRADEONEnt->MonType2)) return FALSE; } else { - info->DisplayType = (RADEONMonitorType)pRADEONEnt->MonType1; + info->DisplayType = pRADEONEnt->MonType1; if(!pRADEONEnt->HasSecondary) { - info->CloneType = (RADEONMonitorType)pRADEONEnt->MonType2; - if (info->CloneType != MT_NONE) + if ((info->CloneType = pRADEONEnt->MonType2)) info->Clone = TRUE; - } + } } } else { - info->DisplayType = (RADEONMonitorType)pRADEONEnt->MonType1; + info->DisplayType = pRADEONEnt->MonType1; } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s Display == Type %d\n", - (info->IsSecondary ? "Secondary" : "Primary"), + (info->IsSecondary ? "Secondary" : "Primary"), info->DisplayType); if (info->Clone) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clone Display == Type %d\n", info->CloneType); - + info->HBlank = 0; info->HOverPlus = 0; info->HSyncWidth = 0; @@ -1483,8 +1456,7 @@ static Bool RADEONGetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) info->DotClock = 0; info->UseBiosDividers = FALSE; - if (info->DisplayType == MT_LCD && info->VBIOS && - !(xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) { + if (info->DisplayType == MT_LCD && info->VBIOS) { tmp = RADEON_BIOS16(info->FPBIOSstart + 0x40); if (!tmp) { info->PanelPwrDly = 200; @@ -1505,7 +1477,7 @@ static Bool RADEONGetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) info->PanelYRes = RADEON_BIOS16(tmp+27); xf86DrvMsg(0, X_INFO, "Panel Size from BIOS: %dx%d\n", info->PanelXRes, info->PanelYRes); - + info->PanelPwrDly = RADEON_BIOS16(tmp+44); if (info->PanelPwrDly > 2000 || info->PanelPwrDly < 0) info->PanelPwrDly = 2000; @@ -1515,18 +1487,14 @@ static Bool RADEONGetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) info->RefDivider = RADEON_BIOS16(tmp+46); info->PostDivider = RADEON_BIOS8(tmp+48); info->FeedbackDivider = RADEON_BIOS16(tmp+49); - if ((info->RefDivider != 0) && + if ((info->RefDivider != 0) && (info->FeedbackDivider > 3)) { info->UseBiosDividers = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "BIOS provided dividers will be used.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "BIOS provided dividers will be used."); } - /* We don't use a while loop here just in case we have a corrupted BIOS image. - The max number of table entries is 23 at present, but may grow in future. - To ensure it works with future revisions we loop it to 32. - */ - for (i = 0; i < 32; i++) { + for (i = 0; i < 20; i++) { tmp0 = RADEON_BIOS16(tmp+64+i*2); if (tmp0 == 0) break; if ((RADEON_BIOS16(tmp0) == info->PanelXRes) && @@ -1545,60 +1513,9 @@ static Bool RADEONGetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) info->Flags = 0; } } - - if (info->DotClock == 0) { - DisplayModePtr tmp_mode = NULL; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "No valid timing info from BIOS.\n"); - /* No timing information for the native mode, - use whatever specified in the Modeline. - If no Modeline specified, we'll just pick - the VESA mode at 60Hz refresh rate which - is likely to be the best for a flat panel. - */ - tmp_mode = pScrn->monitor->Modes; - while(tmp_mode) { - if ((tmp_mode->HDisplay == info->PanelXRes) && - (tmp_mode->VDisplay == info->PanelYRes)) { - - float refresh = - (float)tmp_mode->Clock * 1000.0 / tmp_mode->HTotal / tmp_mode->VTotal; - if ((abs(60.0 - refresh) < 1.0) || - (tmp_mode->type == 0)) { - info->HBlank = tmp_mode->HTotal - tmp_mode->HDisplay; - info->HOverPlus = tmp_mode->HSyncStart - tmp_mode->HDisplay; - info->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart; - info->VBlank = tmp_mode->VTotal - tmp_mode->VDisplay; - info->VOverPlus = tmp_mode->VSyncStart - tmp_mode->VDisplay; - info->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart; - info->DotClock = tmp_mode->Clock; - info->Flags = 0; - break; - } - tmp_mode = tmp_mode->next; - } - } - if ((info->DotClock == 0) && !pRADEONEnt->MonInfo1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Panel size is not correctly detected.\n" - "Please try to use PanelSize option for correct settings.\n"); - return FALSE; - } - } } - } - } - - if (info->VBIOS) { - tmp = RADEON_BIOS16(info->FPBIOSstart + 0x30); - info->sclk = RADEON_BIOS16(tmp + 8) / 100.0; - info->mclk = RADEON_BIOS16(tmp + 10) / 100.0; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No valid info for SCLK/MCLK for display bandwidth calculation.\n"); - info->sclk = 200.00; - info->mclk = 200.00; - } - + } + } return TRUE; } @@ -1615,25 +1532,27 @@ static Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn) long start_secs, start_usecs, stop_secs, stop_usecs, total_usecs; int i; + tmp = INREG(RADEON_DEVICE_ID); + for(i=0; i<1000000; i++) if (((INREG(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) == 0) break; - + xf86getsecs(&start_secs, &start_usecs); - + for(i=0; i<1000000; i++) if (((INREG(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) != 0) break; - + for(i=0; i<1000000; i++) if (((INREG(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) == 0) break; - + xf86getsecs(&stop_secs, &stop_usecs); - + total_usecs = abs(stop_usecs - start_usecs); hz = 1000000/total_usecs; - + hTotal = ((INREG(RADEON_CRTC_H_TOTAL_DISP) & 0x1ff) + 1) * 8; vTotal = ((INREG(RADEON_CRTC_V_TOTAL_DISP) & 0x3ff) + 1); vclk = (float)(hTotal * (float)(vTotal * hz)); @@ -1657,7 +1576,7 @@ static Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn) denom = 2*m; break; } - + OUTREG(RADEON_CLOCK_CNTL_INDEX, 1); ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_DATA + 1) & 0x3; @@ -1666,7 +1585,7 @@ static Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn) num *= n; denom *= m; - + switch ((INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel) >> 16) & 0x7) { case 1: denom *= 2; @@ -1681,7 +1600,7 @@ static Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn) denom *= 3; break; case 6: - denom *= 6; + denom *= 6; break; case 7: denom *= 12; @@ -1714,56 +1633,6 @@ static Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn) return TRUE; } -static void RADEONGetTMDSInfo(ScrnInfoPtr pScrn) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - CARD32 tmp; - int i, n; - - for (i=0; i<4; i++) { - info->tmds_pll[i].value = 0; - info->tmds_pll[i].freq = 0; - } - - if (info->VBIOS) { - tmp = RADEON_BIOS16(info->FPBIOSstart + 0x34); - if (tmp) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "DFP table revision: %d\n", RADEON_BIOS8(tmp)); - if (RADEON_BIOS8(tmp) == 3) { - n = RADEON_BIOS8(tmp + 5) + 1; - if (n > 4) n = 4; - for (i=0; i<n; i++) { - info->tmds_pll[i].value = RADEON_BIOS32(tmp+i*10+0x08); - info->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*10+0x10); - } - return; - } - - /* revision 4 has some problem as it appears in RV280, - comment it off for new, use default instead */ - /* - else if (RADEON_BIOS8(tmp) == 4) { - int stride = 0; - n = RADEON_BIOS8(tmp + 5) + 1; - if (n > 4) n = 4; - for (i=0; i<n; i++) { - info->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08); - info->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10); - if (i == 0) stride += 10; - else stride += 6; - } - return; - } - */ - } - } - - for (i=0; i<4; i++) { - info->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value; - info->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq; - } -} /* Read PLL parameters from BIOS block. Default to typical values if * there is no BIOS. @@ -1774,22 +1643,22 @@ static Bool RADEONGetPLLParameters(ScrnInfoPtr pScrn) RADEONPLLPtr pll = &info->pll; CARD16 bios_header; CARD16 pll_info_block; - double min_dotclock; if (!info->VBIOS) { pll->min_pll_freq = 12500; pll->max_pll_freq = 35000; - + if (!RADEONProbePLLParameters(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Video BIOS not detected, using default PLL parameters!\n"); + "Video BIOS not detected, using default PLL parameters!\n"); switch (info->Chipset) { case PCI_CHIP_R200_QL: case PCI_CHIP_R200_QN: case PCI_CHIP_R200_QO: + case PCI_CHIP_R200_Ql: case PCI_CHIP_R200_BB: pll->reference_freq = 2700; pll->reference_div = 12; @@ -1811,7 +1680,7 @@ static Bool RADEONGetPLLParameters(ScrnInfoPtr pScrn) default: pll->reference_freq = 2700; pll->reference_div = 67; - pll->xclk = 16615; + pll->xclk = 16615; break; } } @@ -1828,26 +1697,6 @@ static Bool RADEONGetPLLParameters(ScrnInfoPtr pScrn) pll->xclk = RADEON_BIOS16(pll_info_block + 0x08); } - /* (Some?) Radeon BIOSes seem too lie about their minimum dot - * clocks. Allow users to override the detected minimum dot clock - * value (e.g., and allow it to be suitable for TV sets). - */ - if (xf86GetOptValFreq(info->Options, OPTION_MIN_DOTCLOCK, - OPTUNITS_MHZ, &min_dotclock)) { - if (min_dotclock < 12 || min_dotclock*100 >= pll->max_pll_freq) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Illegal minimum dotclock specified %.2f MHz " - "(option ignored)\n", - min_dotclock); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Forced minimum dotclock to %.2f MHz " - "(instead of detected %.2f MHz)\n", - min_dotclock, ((double)pll->min_pll_freq/1000)); - pll->min_pll_freq = min_dotclock * 1000; - } - } - return TRUE; } @@ -1940,44 +1789,6 @@ static Bool RADEONPreInitWeight(ScrnInfoPtr pScrn) return TRUE; } -static void RADEONGetVRamType(ScrnInfoPtr pScrn) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - CARD32 tmp; - - if (info->IsIGP || (info->ChipFamily >= CHIP_FAMILY_R300) || - (INREG(RADEON_MEM_SDRAM_MODE_REG) & (1<<30))) - info->IsDDR = TRUE; - else - info->IsDDR = FALSE; - - tmp = INREG(RADEON_MEM_CNTL); - if ((info->ChipFamily == CHIP_FAMILY_R300) || - (info->ChipFamily == CHIP_FAMILY_R350) || - (info->ChipFamily == CHIP_FAMILY_RV350)) { - tmp &= R300_MEM_NUM_CHANNELS_MASK; - switch (tmp) { - case 0: info->RamWidth = 64; break; - case 1: info->RamWidth = 128; break; - case 2: info->RamWidth = 256; break; - default: info->RamWidth = 128; break; - } - } else if ((info->ChipFamily == CHIP_FAMILY_RV100) || - (info->ChipFamily == CHIP_FAMILY_RS100) || - (info->ChipFamily == CHIP_FAMILY_RS200)){ - if (tmp & RV100_HALF_MODE) info->RamWidth = 32; - else info->RamWidth = 64; - } else { - if (tmp & RADEON_MEM_NUM_CHANNELS_MASK) info->RamWidth = 128; - else info->RamWidth = 64; - } - - /* This may not be correct, as some cards can have half of channel disabled - * ToDo: identify these cases - */ -} - /* This is called by RADEONPreInit to handle config file overrides for * things like chipset and memory regions. Also determine memory size * and type. If memory type ever needs an override, put it in this @@ -1988,12 +1799,9 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) RADEONInfoPtr info = RADEONPTR(pScrn); EntityInfoPtr pEnt = info->pEnt; GDevPtr dev = pEnt->device; + int offset = 0; /* RAM Type */ MessageType from; unsigned char *RADEONMMIO = info->MMIO; -#ifdef XF86DRI - const char *s; - CARD32 agpCommand; -#endif /* Chipset */ from = X_PROBED; @@ -2060,27 +1868,45 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) break; case PCI_CHIP_R200_BB: - case PCI_CHIP_R200_BC: case PCI_CHIP_R200_QH: + case PCI_CHIP_R200_QI: + case PCI_CHIP_R200_QJ: + case PCI_CHIP_R200_QK: case PCI_CHIP_R200_QL: case PCI_CHIP_R200_QM: + case PCI_CHIP_R200_QN: + case PCI_CHIP_R200_QO: + case PCI_CHIP_R200_Qh: + case PCI_CHIP_R200_Qi: + case PCI_CHIP_R200_Qj: + case PCI_CHIP_R200_Qk: + case PCI_CHIP_R200_Ql: info->ChipFamily = CHIP_FAMILY_R200; break; + case PCI_CHIP_RV200_QW: /* RV200 desktop */ + case PCI_CHIP_RV200_QX: + info->ChipFamily = CHIP_FAMILY_RV200; + break; + case PCI_CHIP_RADEON_LW: case PCI_CHIP_RADEON_LX: info->IsMobility = TRUE; - case PCI_CHIP_RV200_QW: /* RV200 desktop */ - case PCI_CHIP_RV200_QX: info->ChipFamily = CHIP_FAMILY_RV200; break; + case PCI_CHIP_RV250_Id: + case PCI_CHIP_RV250_Ie: + case PCI_CHIP_RV250_If: + case PCI_CHIP_RV250_Ig: + info->ChipFamily = CHIP_FAMILY_RV250; + break; + case PCI_CHIP_RV250_Ld: + case PCI_CHIP_RV250_Le: case PCI_CHIP_RV250_Lf: case PCI_CHIP_RV250_Lg: info->IsMobility = TRUE; - case PCI_CHIP_RV250_If: - case PCI_CHIP_RV250_Ig: info->ChipFamily = CHIP_FAMILY_RV250; break; @@ -2091,13 +1917,18 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) info->IsIGP = TRUE; break; - case PCI_CHIP_RV280_5C61: - case PCI_CHIP_RV280_5C63: - info->IsMobility = TRUE; case PCI_CHIP_RV280_5960: case PCI_CHIP_RV280_5961: case PCI_CHIP_RV280_5962: - case PCI_CHIP_RV280_5964: + case PCI_CHIP_RV280_5963: + info->ChipFamily = CHIP_FAMILY_RV280; + break; + + case PCI_CHIP_RV280_5968: + case PCI_CHIP_RV280_5969: + case PCI_CHIP_RV280_596A: + case PCI_CHIP_RV280_596B: + info->IsMobility = TRUE; info->ChipFamily = CHIP_FAMILY_RV280; break; @@ -2113,29 +1944,15 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) break; case PCI_CHIP_RV350_NP: - case PCI_CHIP_RV350_NQ: - case PCI_CHIP_RV350_NR: - case PCI_CHIP_RV350_NS: - case PCI_CHIP_RV350_NT: - case PCI_CHIP_RV350_NV: info->IsMobility = TRUE; case PCI_CHIP_RV350_AP: - case PCI_CHIP_RV350_AQ: - case PCI_CHIP_RV360_AR: - case PCI_CHIP_RV350_AS: - case PCI_CHIP_RV350_AT: - case PCI_CHIP_RV350_AV: + case PCI_CHIP_RV350_AR: info->ChipFamily = CHIP_FAMILY_RV350; break; - case PCI_CHIP_R350_AH: - case PCI_CHIP_R350_AI: - case PCI_CHIP_R350_AJ: case PCI_CHIP_R350_AK: case PCI_CHIP_R350_NH: - case PCI_CHIP_R350_NI: case PCI_CHIP_R350_NK: - case PCI_CHIP_R360_NJ: info->ChipFamily = CHIP_FAMILY_R350; break; @@ -2152,7 +1969,7 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) pScrn->memPhysBase = info->LinearAddr; if (dev->MemBase) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Linear address override, using 0x%08lx instead of 0x%08lx\n", + "Linear address override, using 0x%08x instead of 0x%08x\n", dev->MemBase, info->LinearAddr); info->LinearAddr = dev->MemBase; @@ -2170,7 +1987,7 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) info->BIOSAddr = info->PciInfo->biosBase & 0xfffe0000; if (dev->BiosBase) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "BIOS address override, using 0x%08lx instead of 0x%08lx\n", + "BIOS address override, using 0x%08x instead of 0x%08x\n", dev->BiosBase, info->BIOSAddr); info->BIOSAddr = dev->BiosBase; @@ -2181,15 +1998,15 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) "BIOS at 0x%08lx\n", info->BIOSAddr); } - /* Read registers used to determine options */ + /* Read registers used to determine options */ from = X_PROBED; if (info->FBDev) pScrn->videoRam = fbdevHWGetVidmem(pScrn) / 1024; - else if ((info->ChipFamily == CHIP_FAMILY_RS100) || + else if ((info->ChipFamily == CHIP_FAMILY_RS100) || (info->ChipFamily == CHIP_FAMILY_RS200) || (info->ChipFamily == CHIP_FAMILY_RS300)) { CARD32 tom = INREG(RADEON_NB_TOM); - pScrn->videoRam = (((tom >> 16) - + pScrn->videoRam = (((tom >> 16) - (tom & 0xffff) + 1) << 6); OUTREG(RADEON_MC_FB_LOCATION, tom); OUTREG(RADEON_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); @@ -2198,10 +2015,10 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) /* This is supposed to fix the crtc2 noise problem. */ - OUTREG(RADEON_GRPH2_BUFFER_CNTL, + OUTREG(RADEON_GRPH2_BUFFER_CNTL, INREG(RADEON_GRPH2_BUFFER_CNTL) & ~0x7f0000); - if ((info->ChipFamily == CHIP_FAMILY_RS100) || + if ((info->ChipFamily == CHIP_FAMILY_RS100) || (info->ChipFamily == CHIP_FAMILY_RS200)) { /* This is to workaround the asic bug for RMX, some versions of BIOS dosen't have this register initialized correctly. @@ -2241,7 +2058,13 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) info->MemCntl = INREG(RADEON_SDRAM_MODE_REG); info->BusCntl = INREG(RADEON_BUS_CNTL); - RADEONGetVRamType(pScrn); + /* RAM */ + switch (info->MemCntl >> 30) { + case 0: offset = 0; break; /* 64-bit SDR SDRAM */ + case 1: offset = 1; break; /* 64-bit DDR SDRAM */ + default: offset = 0; + } + info->ram = &RADEONRAM[offset]; if (dev->videoRam) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -2254,92 +2077,70 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) pScrn->videoRam &= ~1023; info->FbMapSize = pScrn->videoRam * 1024; xf86DrvMsg(pScrn->scrnIndex, from, - "VideoRAM: %d kByte (%d bit %s SDRAM)\n", pScrn->videoRam, info->RamWidth, info->IsDDR?"DDR":"SDR"); + "VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name); #ifdef XF86DRI /* AGP/PCI */ - /* Proper autodetection of an AGP capable device requires examining - * PCI config registers to determine if the device implements extended - * PCI capabilities, and then walking the capability list as indicated - * in the PCI 2.2 and AGP 2.0 specifications, to determine if AGP - * capability is present. The procedure is outlined as follows: - * - * 1) Test bit 4 (CAP_LIST) of the PCI status register of the device - * to determine wether or not this device implements any extended - * capabilities. If this bit is zero, then the device is a PCI 2.1 - * or earlier device and is not AGP capable, and we can conclude it - * to be a PCI device. - * - * 2) If bit 4 of the status register is set, then the device implements - * extended capabilities. There is an 8 bit wide capabilities pointer - * register located at offset 0x34 in PCI config space which points to - * the first capability in a linked list of extended capabilities that - * this device implements. The lower two bits of this register are - * reserved and MBZ so must be masked out. - * - * 3) The extended capabilities list is formed by one or more extended - * capabilities structures which are aligned on DWORD boundaries. - * The first byte of the structure is the capability ID (CAP_ID) - * indicating what extended capability this structure refers to. The - * second byte of the structure is an offset from the beginning of - * PCI config space pointing to the next capability in the linked - * list (NEXT_PTR) or NULL (0x00) at the end of the list. The lower - * two bits of this pointer are reserved and MBZ. By examining the - * CAP_ID of each capability and walking through the list, we will - * either find the AGP_CAP_ID (0x02) indicating this device is an - * AGP device, or we'll reach the end of the list, indicating it is - * a PCI device. - * - * Mike A. Harris <mharris@redhat.com> - * - * References: - * - PCI Local Bus Specification Revision 2.2, Chapter 6 - * - AGP Interface Specification Revision 2.0, Section 6.1.5 - */ - - info->IsPCI = TRUE; - - if (pciReadLong(info->PciTag, PCI_CMD_STAT_REG) & RADEON_CAP_LIST) { - CARD32 cap_ptr, cap_id; - - cap_ptr = pciReadLong(info->PciTag, - RADEON_CAPABILITIES_PTR_PCI_CONFIG) - & RADEON_CAP_PTR_MASK; - - while(cap_ptr != RADEON_CAP_ID_NULL) { - cap_id = pciReadLong(info->PciTag, cap_ptr); - if ((cap_id & 0xff)== RADEON_CAP_ID_AGP) { - info->IsPCI = FALSE; - break; - } - cap_ptr = (cap_id >> 8) & RADEON_CAP_PTR_MASK; - } - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s card detected\n", - (info->IsPCI) ? "PCI" : "AGP"); - - if ((s = xf86GetOptValString(info->Options, OPTION_BUS_TYPE))) { - if (strcmp(s, "AGP") == 0) { - info->IsPCI = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into AGP mode\n"); - } else if (strcmp(s, "PCI") == 0) { - info->IsPCI = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI mode\n"); - } else if (strcmp(s, "PCIE") == 0) { - info->IsPCI = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "PCI Express not supported yet, using PCI mode\n"); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Invalid BusType option, using detected type\n"); - } - } else if (xf86ReturnOptValBool(info->Options, OPTION_IS_PCI, FALSE)) { + if (xf86ReturnOptValBool(info->Options, OPTION_IS_PCI, FALSE)) { info->IsPCI = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI mode\n"); - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "ForcePCIMode is deprecated -- " - "use BusType option instead\n"); + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI-only mode\n"); + } else { + switch (info->Chipset) { +#if 0 + case PCI_CHIP_RADEON_XX: info->IsPCI = TRUE; break; +#endif + case PCI_CHIP_RV100_QY: + case PCI_CHIP_RV100_QZ: + case PCI_CHIP_RADEON_LW: + case PCI_CHIP_RADEON_LX: + case PCI_CHIP_RADEON_LY: + case PCI_CHIP_RADEON_LZ: + case PCI_CHIP_RADEON_QD: + case PCI_CHIP_RADEON_QE: + case PCI_CHIP_RADEON_QF: + case PCI_CHIP_RADEON_QG: + case PCI_CHIP_R200_BB: + case PCI_CHIP_R200_QH: + case PCI_CHIP_R200_QI: + case PCI_CHIP_R200_QJ: + case PCI_CHIP_R200_QK: + case PCI_CHIP_R200_QL: + case PCI_CHIP_R200_QM: + case PCI_CHIP_R200_QN: + case PCI_CHIP_R200_QO: + case PCI_CHIP_R200_Qh: + case PCI_CHIP_R200_Qi: + case PCI_CHIP_R200_Qj: + case PCI_CHIP_R200_Qk: + case PCI_CHIP_R200_Ql: + case PCI_CHIP_RV200_QW: + case PCI_CHIP_RV200_QX: + case PCI_CHIP_RV250_Id: + case PCI_CHIP_RV250_Ie: + case PCI_CHIP_RV250_If: + case PCI_CHIP_RV250_Ig: + case PCI_CHIP_RV250_Ld: + case PCI_CHIP_RV250_Le: + case PCI_CHIP_RV250_Lf: + case PCI_CHIP_RV250_Lg: + case PCI_CHIP_RV280_5960: + case PCI_CHIP_RV280_5961: + case PCI_CHIP_RV280_5962: + case PCI_CHIP_RV280_5963: + case PCI_CHIP_RV280_5968: + case PCI_CHIP_RV280_5969: + case PCI_CHIP_RV280_596A: + case PCI_CHIP_RV280_596B: + case PCI_CHIP_R300_AD: + case PCI_CHIP_R300_AE: + case PCI_CHIP_R300_AF: + case PCI_CHIP_R300_AG: + case PCI_CHIP_R300_ND: + case PCI_CHIP_R300_NE: + case PCI_CHIP_R300_NF: + case PCI_CHIP_R300_NG: + default: info->IsPCI = FALSE; break; + } } #endif @@ -2371,9 +2172,6 @@ static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data) val |= (Clock ? 0:RADEON_GPIO_EN_1); val |= (data ? 0:RADEON_GPIO_EN_0); OUTREG(info->DDCReg, val); - - /* read back to improve reliability on some cards. */ - val = INREG(info->DDCReg); } static Bool RADEONI2cInit(ScrnInfoPtr pScrn) @@ -2503,7 +2301,7 @@ static void RADEONSortModes(DisplayModePtr *new, DisplayModePtr *first, p = *last; while (p) { - if ((((*new)->HDisplay < p->HDisplay) && + if ((((*new)->HDisplay < p->HDisplay) && ((*new)->VDisplay < p->VDisplay)) || (((*new)->HDisplay == p->HDisplay) && ((*new)->VDisplay == p->VDisplay) && @@ -2522,7 +2320,7 @@ static void RADEONSortModes(DisplayModePtr *new, DisplayModePtr *first, p->prev = *new; *first = *new; break; - } + } p = p->prev; } @@ -2548,7 +2346,7 @@ static void RADEONSetPitch (ScrnInfoPtr pScrn) pScrn->displayWidth = dummy; } -/* When no mode provided in config file, this will add all modes supported in +/* When no mode provided in config file, this will add all modes supported in * DDC date the pScrn->modes list */ static DisplayModePtr RADEONDDCModes(ScrnInfoPtr pScrn) @@ -2658,7 +2456,7 @@ static DisplayModePtr RADEONDDCModes(ScrnInfoPtr pScrn) strcpy(new->name, p->name); new->status = MODE_OK; new->type = M_T_DEFAULT; - + count++; xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -2786,7 +2584,7 @@ static int RADEONValidateDDCModes(ScrnInfoPtr pScrn, char **ppModeName, } } - /* + /* * Add remaining DDC modes if they're smaller than the user * specified modes */ @@ -2939,7 +2737,7 @@ static int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName) new->HSyncEnd = new->HSyncStart + info->HSyncWidth; new->VTotal = info->PanelYRes + info->VBlank; new->VSyncStart = info->PanelYRes + info->VOverPlus; - new->VSyncEnd = new->VSyncStart + info->VSyncWidth; + new->VSyncEnd = new->VSyncStart + info->VSyncWidth; new->Clock = info->DotClock; new->Flags |= RADEON_USE_RMX; @@ -2990,7 +2788,7 @@ static int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName) new->HSyncEnd = new->HSyncStart + info->HSyncWidth; new->VTotal = info->PanelYRes + info->VBlank; new->VSyncStart = info->PanelYRes + info->VOverPlus; - new->VSyncEnd = new->VSyncStart + info->VSyncWidth; + new->VSyncEnd = new->VSyncStart + info->VSyncWidth; new->Clock = info->DotClock; new->Flags |= RADEON_USE_RMX; @@ -3168,12 +2966,12 @@ static int RADEONValidateCloneModes(ScrnInfoPtr pScrn) else count++; clone_mode_names[0] = xnfalloc(strlen(s)+1); sprintf(clone_mode_names[0], "%dx%d", tmp_hdisplay, tmp_vdisplay); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clone mode %s in config file is used\n", clone_mode_names[0]); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clone mode %s in config file is used\n"); } } for (i = 0; i < count; i++) { - if (sscanf(clone_mode_names[i], "%dx%d", + if (sscanf(clone_mode_names[i], "%dx%d", &tmp_hdisplay, &tmp_vdisplay) == 2) { if (pScrn->display->virtualX < tmp_hdisplay) pScrn->display->virtualX = tmp_hdisplay; @@ -3230,8 +3028,8 @@ static int RADEONValidateCloneModes(ScrnInfoPtr pScrn) if (info->CloneType == MT_CRT && !ddc_mode) { modesFound = - xf86ValidateModes(pScrn, pScrn->monitor->Modes, - clone_mode_names, + xf86ValidateModes(pScrn, pScrn->monitor->Modes, + clone_mode_names, clockRanges, NULL, /* linePitches */ 8 * 64, /* minPitch */ @@ -3241,7 +3039,7 @@ static int RADEONValidateCloneModes(ScrnInfoPtr pScrn) 2048, /* maxHeight */ pScrn->display->virtualX, pScrn->display->virtualY, - info->FbMapSize, + info->FbMapSize, LOOKUP_BEST_REFRESH); } else { /* Try to add DDC modes */ @@ -3255,8 +3053,8 @@ static int RADEONValidateCloneModes(ScrnInfoPtr pScrn) */ if (modesFound < 1 && info->CloneType != MT_CRT) { modesFound = - xf86ValidateModes(pScrn, pScrn->monitor->Modes, - clone_mode_names, + xf86ValidateModes(pScrn, pScrn->monitor->Modes, + clone_mode_names, clockRanges, NULL, /* linePitches */ 8 * 64, /* minPitch */ @@ -3266,7 +3064,7 @@ static int RADEONValidateCloneModes(ScrnInfoPtr pScrn) 2048, /* maxHeight */ pScrn->display->virtualX, pScrn->display->virtualY, - info->FbMapSize, + info->FbMapSize, LOOKUP_BEST_REFRESH); } } @@ -3300,7 +3098,7 @@ static int RADEONValidateCloneModes(ScrnInfoPtr pScrn) clone_mode->prev->next = clone_mode; } valid++; - + tmp_mode = clone_mode; clone_mode->next = NULL; } @@ -3362,7 +3160,6 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) ClockRangePtr clockRanges; int modesFound; RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - char *s; /* This option has two purposes: * @@ -3434,7 +3231,7 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) } xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Validating modes on %s head ---------\n", + "Validating modes on %s head ---------\n", info->IsSecondary ? "Secondary" : "Primary"); if (info->IsSecondary) @@ -3448,59 +3245,6 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) "No DDC data available, DDCMode option is dismissed\n"); } - if ((info->DisplayType == MT_DFP) || - (info->DisplayType == MT_LCD)) { - if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) { - int PanelX, PanelY; - DisplayModePtr tmp_mode = NULL; - if (sscanf(s, "%dx%d", &PanelX, &PanelY) == 2) { - info->PanelXRes = PanelX; - info->PanelYRes = PanelY; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Panel size is forced to: %s\n", s); - - /* We can't trust BIOS or DDC timings anymore, - Use whatever specified in the Modeline. - If no Modeline specified, we'll just pick the VESA mode at - 60Hz refresh rate which is likely to be the best for a flat panel. - */ - info->ddc_mode = FALSE; - pScrn->monitor->DDC = NULL; - tmp_mode = pScrn->monitor->Modes; - while(tmp_mode) { - if ((tmp_mode->HDisplay == PanelX) && - (tmp_mode->VDisplay == PanelY)) { - - float refresh = - (float)tmp_mode->Clock * 1000.0 / tmp_mode->HTotal / tmp_mode->VTotal; - if ((abs(60.0 - refresh) < 1.0) || - (tmp_mode->type == 0)) { - info->HBlank = tmp_mode->HTotal - tmp_mode->HDisplay; - info->HOverPlus = tmp_mode->HSyncStart - tmp_mode->HDisplay; - info->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart; - info->VBlank = tmp_mode->VTotal - tmp_mode->VDisplay; - info->VOverPlus = tmp_mode->VSyncStart - tmp_mode->VDisplay; - info->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart; - info->DotClock = tmp_mode->Clock; - info->Flags = 0; - break; - } - } - tmp_mode = tmp_mode->next; - } - if (info->DotClock == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid timing info for specified panel size.\n" - "Please specify the Modeline for this panel\n"); - return FALSE; - } - } else { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Invalid PanelSize value: %s\n", s); - } - } - } - if (pScrn->monitor->DDC) { /* If we still don't know sync range yet, let's try EDID. * @@ -3579,14 +3323,14 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) * add the flat panel modes */ if (info->DisplayType != MT_CRT) { - + /* some panels have DDC, but don't have internal scaler. * in this case, we need to validate additional modes * by using on-chip RMX. */ int user_modes_asked = 0, user_modes_found = 0, i; DisplayModePtr tmp_mode = pScrn->modes; - while (pScrn->display->modes[user_modes_asked]) user_modes_asked++; + while (pScrn->display->modes[user_modes_asked]) user_modes_asked++; if (tmp_mode) { for (i = 0; i < modesFound; i++) { if (tmp_mode->type & M_T_USERDEF) user_modes_found++; @@ -3594,8 +3338,8 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) } } - if ((modesFound <= 1) || (user_modes_found < user_modes_asked)) { - /* when panel size is not valid, try to validate + if ((modesFound <= 1) || (user_modes_found < user_modes_asked)) { + /* when panel size is not valid, try to validate * mode using xf86ValidateModes routine * This can happen when DDC is disabled. */ @@ -3617,7 +3361,7 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) LOOKUP_BEST_REFRESH); else if (!info->IsSecondary) modesFound = RADEONValidateFPModes(pScrn, pScrn->display->modes); - } + } } /* Setup the screen's clockRanges for the VidMode extension */ @@ -3653,9 +3397,9 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) if ((clone_mode->HDisplay > pScrn->virtualX) || (clone_mode->VDisplay > pScrn->virtualY)) { pScrn->virtualX = - pScrn->display->virtualX = clone_mode->HDisplay; + pScrn->display->virtualX = clone_mode->HDisplay; pScrn->virtualY = - pScrn->display->virtualY = clone_mode->VDisplay; + pScrn->display->virtualY = clone_mode->VDisplay; RADEONSetPitch(pScrn); } if (!clone_mode->next) break; @@ -3774,7 +3518,7 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling AGP Fast Write\n"); } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "AGP Fast Write disabled by default\n"); } } @@ -3853,7 +3597,7 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) * for dedicated 3d rendering boxes */ info->noBackBuffer = xf86ReturnOptValBool(info->Options, - OPTION_NO_BACKBUFFER, + OPTION_NO_BACKBUFFER, FALSE); if (info->noBackBuffer) { @@ -3894,7 +3638,6 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) RADEONInfoPtr info; xf86Int10InfoPtr pInt10 = NULL; void *int10_save = NULL; - const char *s; RADEONTRACE(("RADEONPreInit\n")); if (pScrn->numEntities != 1) return FALSE; @@ -3919,7 +3662,7 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) info->MMIOAddr = info->PciInfo->memBase[2] & 0xffffff00; if (info->pEnt->device->IOBase) { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "MMIO address override, using 0x%08lx instead of 0x%08lx\n", + "MMIO address override, using 0x%08x instead of 0x%08x\n", info->pEnt->device->IOBase, info->MMIOAddr); info->MMIOAddr = info->pEnt->device->IOBase; @@ -3931,7 +3674,7 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) "MMIO registers at 0x%08lx\n", info->MMIOAddr); if(!RADEONMapMMIO(pScrn)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Memory map the MMIO region failed\n"); goto fail1; } @@ -3945,7 +3688,7 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) * going to run it again - so make sure to "fix up" the card * so that (1) we can read the BIOS ROM and (2) the BIOS will * get the memory config right. - */ + */ RADEONPreInt10Save(pScrn, &int10_save); #endif @@ -4027,18 +3770,6 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) info->videoKey = 0x1E; } - info->DispPriority = 1; - if ((s = xf86GetOptValString(info->Options, OPTION_DISP_PRIORITY))) { - if (strcmp(s, "AUTO") == 0) { - info->DispPriority = 1; - } else if (strcmp(s, "BIOS") == 0) { - info->DispPriority = 0; - } else if (strcmp(s, "HIGH") == 0) { - info->DispPriority = 2; - } else - info->DispPriority = 1; - } - if (xf86ReturnOptValBool(info->Options, OPTION_FBDEV, FALSE)) { /* check for Linux framebuffer device */ @@ -4074,9 +3805,6 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) if (!RADEONGetBIOSParameters(pScrn, pInt10)) goto fail; - if (info->DisplayType == MT_DFP) - RADEONGetTMDSInfo(pScrn); - if (!RADEONGetPLLParameters(pScrn)) goto fail; if (!RADEONPreInitGamma(pScrn)) goto fail; @@ -4101,7 +3829,7 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) if (pInt10) xf86FreeInt10(pInt10); - if(info->MMIO) RADEONUnmapMMIO(pScrn); + if(info->MMIO) RADEONUnmapMMIO(pScrn); info->MMIO = NULL; xf86DrvMsg(pScrn->scrnIndex, X_NOTICE, @@ -4129,7 +3857,7 @@ fail: vgaHWFreeHWRec(pScrn); fail2: - if(info->MMIO) RADEONUnmapMMIO(pScrn); + if(info->MMIO) RADEONUnmapMMIO(pScrn); info->MMIO = NULL; fail1: RADEONFreeRec(pScrn); @@ -4236,7 +3964,7 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors, g = colors[idx].green; b = colors[idx / 2].blue; OUTPAL(idx * 4, r, g, b); - + /* AH - Added to write extra green data - How come * this isn't needed on R128? We didn't load the * extra green data in the other routine. @@ -4392,7 +4120,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Xinerama has sync problem with DRI, disable it for now */ if (xf86IsEntityShared(info->pEnt->index)) { info->directRenderingEnabled = FALSE; - xf86DrvMsg(scrnIndex, X_WARNING, + xf86DrvMsg(scrnIndex, X_WARNING, "Direct Rendering Disabled -- " "Dual-head configuration is not working with " "DRI at present.\n" @@ -4503,7 +4231,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) info->textureSize = info->FbMapSize - 4 * bufferSize - depthSize; } if (info->textureSize < (int)info->FbMapSize / 2) { - info->textureSize = info->FbMapSize - 3 * bufferSize - depthSize; + info->textureSize = info->FbMapSize - 3 * bufferSize - depthSize; } /* If there's still no space for textures, try without pixmap cache */ if (info->textureSize < 0) { @@ -4734,7 +4462,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) int width, height; xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using hardware cursor (scanline %ld)\n", + "Using hardware cursor (scanline %d)\n", info->cursor_start / pScrn->displayWidth / info->CurrentLayout.pixel_bytes); if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, @@ -4788,10 +4516,6 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) info->directRenderingEnabled = RADEONDRIFinishScreenInit(pScreen); } if (info->directRenderingEnabled) { - if ((info->DispPriority == 1) && (!info->IsPCI)) { - /* we need to re-calculate bandwidth because of AGPMode difference. */ - RADEONInitDispBandwidth(pScrn); - } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering disabled\n"); @@ -4898,7 +4622,6 @@ static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn, OUTREG(RADEON_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl); OUTREG(RADEON_CRTC_PITCH, restore->crtc_pitch); OUTREG(RADEON_DISP_MERGE_CNTL, restore->disp_merge_cntl); - OUTREG(RADEON_CRTC_MORE_CNTL, restore->crtc_more_cntl); } /* Write CRTC2 registers */ @@ -4935,8 +4658,8 @@ static void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn, OUTREG(RADEON_CRTC2_PITCH, restore->crtc2_pitch); OUTREG(RADEON_DISP2_MERGE_CNTL, restore->disp2_merge_cntl); - if ((info->DisplayType == MT_DFP && info->IsSecondary) || - info->CloneType == MT_DFP) { + if ((info->DisplayType == MT_DFP && info->IsSecondary) || + info->CloneType == MT_DFP) { OUTREG(RADEON_FP_H2_SYNC_STRT_WID, restore->fp2_h_sync_strt_wid); OUTREG(RADEON_FP_V2_SYNC_STRT_WID, restore->fp2_v_sync_strt_wid); OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl); @@ -4964,11 +4687,11 @@ static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) OUTREG(RADEON_FP_VERT_STRETCH, restore->fp_vert_stretch); OUTREG(RADEON_FP_GEN_CNTL, restore->fp_gen_cntl); - /* old AIW Radeon has some BIOS initialization problem + /* old AIW Radeon has some BIOS initialization problem * with display buffer underflow, only occurs to DFP - */ + */ if (!info->HasCRTC2) - OUTREG(RADEON_GRPH_BUFFER_CNTL, + OUTREG(RADEON_GRPH_BUFFER_CNTL, INREG(RADEON_GRPH_BUFFER_CNTL) & ~0x7f0000); if (info->DisplayType != MT_DFP) { @@ -4981,7 +4704,7 @@ static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) */ if (!(restore->lvds_gen_cntl & RADEON_LVDS_ON)) { OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); - } + } } tmp = INREG(RADEON_LVDS_GEN_CNTL); @@ -5068,10 +4791,10 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, unsigned char *RADEONMMIO = info->MMIO; if (info->IsMobility) { - /* A temporal workaround for the occational blanking on certain laptop panels. - This appears to related to the PLL divider registers (fail to lock?). - It occurs even when all dividers are the same with their old settings. - In this case we really don't need to fiddle with PLL registers. + /* A temporal workaround for the occational blanking on certain laptop panels. + This appears to related to the PLL divider registers (fail to lock?). + It occurs even when all dividers are the same with their old settings. + In this case we really don't need to fiddle with PLL registers. By doing this we can avoid the blanking problem with some panels. */ if ((restore->ppll_ref_div == (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_REF_DIV_MASK)) && @@ -5097,7 +4820,6 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, ~(RADEON_PLL_DIV_SEL)); if ((info->ChipFamily == CHIP_FAMILY_R300) || - (info->ChipFamily == CHIP_FAMILY_RS300) || (info->ChipFamily == CHIP_FAMILY_R350) || (info->ChipFamily == CHIP_FAMILY_RV350)) { if (restore->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) { @@ -5110,7 +4832,7 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, } else { /* R300 uses ref_div_acc field as real ref divider */ OUTPLLP(pScrn, RADEON_PPLL_REF_DIV, - (restore->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT), + (restore->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT), ~R300_PPLL_REF_DIV_ACC_MASK); } } else { @@ -5339,8 +5061,6 @@ static void RADEONSaveCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) save->cap1_trig_cntl = INREG(RADEON_CAP1_TRIG_CNTL); save->bus_cntl = INREG(RADEON_BUS_CNTL); save->surface_cntl = INREG(RADEON_SURFACE_CNTL); - save->grph_buffer_cntl = INREG(RADEON_GRPH_BUFFER_CNTL); - save->grph2_buffer_cntl = INREG(RADEON_GRPH2_BUFFER_CNTL); } /* Read miscellaneous registers which might be destroyed by an fbdevHW call */ @@ -5382,7 +5102,6 @@ static void RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL); save->crtc_pitch = INREG(RADEON_CRTC_PITCH); save->disp_merge_cntl = INREG(RADEON_DISP_MERGE_CNTL); - save->crtc_more_cntl = INREG(RADEON_CRTC_MORE_CNTL); } /* Read flat panel registers */ @@ -5403,11 +5122,6 @@ static void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) save->tmds_pll_cntl = INREG(RADEON_TMDS_PLL_CNTL); save->tmds_transmitter_cntl= INREG(RADEON_TMDS_TRANSMITTER_CNTL); save->bios_5_scratch = INREG(RADEON_BIOS_5_SCRATCH); - - if (info->ChipFamily == CHIP_FAMILY_RV280) { - /* bit 22 of TMDS_PLL_CNTL is read-back inverted */ - save->tmds_pll_cntl ^= (1 << 22); - } } /* Read CRTC2 registers */ @@ -5495,12 +5209,12 @@ static void RADEONSaveMode(ScrnInfoPtr pScrn, RADEONSavePtr save) RADEONInfoPtr info = RADEONPTR(pScrn); RADEONTRACE(("RADEONSaveMode(%p)\n", save)); - RADEONSaveCommonRegisters(pScrn, save); if (info->IsSecondary) { RADEONSaveCrtc2Registers(pScrn, save); RADEONSavePLL2Registers(pScrn, save); } else { RADEONSavePLLRegisters(pScrn, save); + RADEONSaveCommonRegisters(pScrn, save); RADEONSaveCrtcRegisters(pScrn, save); RADEONSaveFPRegisters(pScrn, save); @@ -5576,8 +5290,6 @@ static void RADEONRestore(ScrnInfoPtr pScrn) if (info->R300CGWorkaround) R300CGWorkaround(pScrn); OUTREG(RADEON_RBBM_SOFT_RESET, restore->rbbm_soft_reset); OUTREG(RADEON_DP_DATATYPE, restore->dp_datatype); - 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. @@ -5650,322 +5362,6 @@ static void RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info) save->bus_cntl |= RADEON_BUS_RD_DISCARD_EN; } -/* Calculate display buffer watermark to prevent buffer underflow */ -static void RADEONInitDispBandwidth(ScrnInfoPtr pScrn) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - RADEONInfoPtr info2 = NULL; - - DisplayModePtr mode1, mode2; - - CARD32 temp, data, mem_trcd, mem_trp, mem_tras, mem_trbs=0; - float mem_tcas; - int k1, c; - CARD32 MemTrcdExtMemCntl[4] = {1, 2, 3, 4}; - CARD32 MemTrpExtMemCntl[4] = {1, 2, 3, 4}; - CARD32 MemTrasExtMemCntl[8] = {1, 2, 3, 4, 5, 6, 7, 8}; - - CARD32 MemTrcdMemTimingCntl[8] = {1, 2, 3, 4, 5, 6, 7, 8}; - CARD32 MemTrpMemTimingCntl[8] = {1, 2, 3, 4, 5, 6, 7, 8}; - CARD32 MemTrasMemTimingCntl[16] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; - - float MemTcas[8] = {0, 1, 2, 3, 0, 1.5, 2.5, 0}; - float MemTcas2[8] = {0, 1, 2, 3, 4, 5, 6, 7}; - float MemTrbs[8] = {1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5}; - - float mem_bw, peak_disp_bw; - float min_mem_eff = 0.8; - float sclk_eff, sclk_delay; - float mc_latency_mclk, mc_latency_sclk, cur_latency_mclk, cur_latency_sclk; - float disp_latency, disp_latency_overhead, disp_drain_rate, disp_drain_rate2; - float pix_clk, pix_clk2; /* in MHz */ - int cur_size = 16; /* in octawords */ - int critical_point, critical_point2; - int stop_req, max_stop_req; - float read_return_rate, time_disp1_drop_priority; - - if (pRADEONEnt->pSecondaryScrn) { - if (info->IsSecondary) return; - info2 = RADEONPTR(pRADEONEnt->pSecondaryScrn); - } else if (info->Clone) info2 = info; - - /* - * Determine if there is enough bandwidth for current display mode - */ - mem_bw = info->mclk * (info->RamWidth / 8) * (info->IsDDR ? 2 : 1); - - mode1 = info->CurrentLayout.mode; - if (info->Clone) - mode2 = info->CurCloneMode; - else if ((pRADEONEnt->HasSecondary) && info2) - mode2 = info2->CurrentLayout.mode; - else - mode2 = NULL; - - pix_clk = mode1->Clock/1000.0; - if (mode2) - pix_clk2 = mode2->Clock/1000.0; - else - pix_clk2 = 0; - - peak_disp_bw = (pix_clk * info->CurrentLayout.pixel_bytes); - if (info2) - peak_disp_bw += (pix_clk2 * info2->CurrentLayout.pixel_bytes); - - if (peak_disp_bw >= mem_bw * min_mem_eff) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "You may not have enough display bandwidth for current mode\n" - "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n"); - } - - /* CRTC1 - Set GRPH_BUFFER_CNTL register using h/w defined optimal values. - GRPH_STOP_REQ <= MIN[ 0x7C, (CRTC_H_DISP + 1) * (bit depth) / 0x10 ] - */ - stop_req = mode1->HDisplay * info->CurrentLayout.pixel_bytes / 16; - - /* setup Max GRPH_STOP_REQ default value */ - if ((info->ChipFamily == CHIP_FAMILY_RV100) || - (info->ChipFamily == CHIP_FAMILY_RV200) || - (info->ChipFamily == CHIP_FAMILY_RV250) || - (info->ChipFamily == CHIP_FAMILY_RV280) || - (info->ChipFamily == CHIP_FAMILY_RS100) || - (info->ChipFamily == CHIP_FAMILY_RS200) || - (info->ChipFamily == CHIP_FAMILY_RS300)) - max_stop_req = 0x5c; - else - max_stop_req = 0x7c; - if (stop_req > max_stop_req) - stop_req = max_stop_req; - - /* Get values from the EXT_MEM_CNTL register...converting its contents. */ - temp = INREG(RADEON_MEM_TIMING_CNTL); - if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */ - mem_trcd = MemTrcdExtMemCntl[(temp & 0x0c) >> 2]; - mem_trp = MemTrpExtMemCntl[ (temp & 0x03) >> 0]; - mem_tras = MemTrasExtMemCntl[(temp & 0x70) >> 4]; - } else { /* RV200 and later */ - mem_trcd = MemTrcdMemTimingCntl[(temp & 0x07) >> 0]; - mem_trp = MemTrpMemTimingCntl[ (temp & 0x700) >> 8]; - mem_tras = MemTrasMemTimingCntl[(temp & 0xf000) >> 12]; - } - - /* Get values from the MEM_SDRAM_MODE_REG register...converting its */ - temp = INREG(RADEON_MEM_SDRAM_MODE_REG); - data = (temp & (7<<20)) >> 20; - if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */ - mem_tcas = MemTcas [data]; - } else { - mem_tcas = MemTcas2 [data]; - } - - if ((info->ChipFamily == CHIP_FAMILY_R300) || - (info->ChipFamily == CHIP_FAMILY_R350) || - (info->ChipFamily == CHIP_FAMILY_RV350)) { - - /* on the R300, Tcas is included in Trbs. - */ - temp = INREG(RADEON_MEM_CNTL); - data = (R300_MEM_NUM_CHANNELS_MASK & temp); - if (data == 2) { - if (R300_MEM_USE_CD_CH_ONLY & temp) { - temp = INREG(R300_MC_IND_INDEX); - temp &= ~R300_MC_IND_ADDR_MASK; - temp |= R300_MC_READ_CNTL_CD_mcind; - OUTREG(R300_MC_IND_INDEX, temp); - temp = INREG(R300_MC_IND_DATA); - data = (R300_MEM_RBS_POSITION_C_MASK & temp); - } else { - temp = INREG(R300_MC_READ_CNTL_AB); - data = (R300_MEM_RBS_POSITION_A_MASK & temp); - } - } else { - temp = INREG(R300_MC_READ_CNTL_AB); - data = (R300_MEM_RBS_POSITION_A_MASK & temp); - } - - mem_trbs = MemTrbs[data]; - mem_tcas += mem_trbs; - } - - if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */ - /* DDR64 SCLK_EFF = SCLK for analysis */ - sclk_eff = info->sclk; - } else { -#ifdef XF86DRI - if (info->directRenderingEnabled) - sclk_eff = info->sclk - (info->agpMode * 50.0 / 3.0); - else -#endif - sclk_eff = info->sclk; - } - - /* Find the memory controller latency for the display client. - */ - if ((info->ChipFamily == CHIP_FAMILY_R300) || - (info->ChipFamily == CHIP_FAMILY_R350) || - (info->ChipFamily == CHIP_FAMILY_RV350)) { - /*not enough for R350 ???*/ - /* - if (!mode2) sclk_delay = 150; - else { - if (info->RamWidth == 256) sclk_delay = 87; - else sclk_delay = 97; - } - */ - sclk_delay = 250; - } else { - if ((info->ChipFamily == CHIP_FAMILY_RV100) || - info->IsIGP) { - if (info->IsDDR) sclk_delay = 41; - else sclk_delay = 33; - } else { - if (info->RamWidth == 128) sclk_delay = 57; - else sclk_delay = 41; - } - } - - mc_latency_sclk = sclk_delay / sclk_eff; - - if (info->IsDDR) { - if (info->RamWidth == 32) { - k1 = 40; - c = 3; - } else { - k1 = 20; - c = 1; - } - } else { - k1 = 40; - c = 3; - } - mc_latency_mclk = ((2.0*mem_trcd + mem_tcas*c + 4.0*mem_tras + 4.0*mem_trp + k1) / - info->mclk) + (4.0 / sclk_eff); - - /* - HW cursor time assuming worst case of full size colour cursor. - */ - cur_latency_mclk = (mem_trp + MAX(mem_tras, (mem_trcd + 2*(cur_size - (info->IsDDR+1))))) / info->mclk; - cur_latency_sclk = cur_size / sclk_eff; - - /* - Find the total latency for the display data. - */ - disp_latency_overhead = 8.0 / info->sclk; - mc_latency_mclk = mc_latency_mclk + disp_latency_overhead + cur_latency_mclk; - mc_latency_sclk = mc_latency_sclk + disp_latency_overhead + cur_latency_sclk; - disp_latency = MAX(mc_latency_mclk, mc_latency_sclk); - - /* - Find the drain rate of the display buffer. - */ - disp_drain_rate = pix_clk / (16.0/info->CurrentLayout.pixel_bytes); - if (info2) - disp_drain_rate2 = pix_clk2 / (16.0/info2->CurrentLayout.pixel_bytes); - else - disp_drain_rate2 = 0; - - /* - Find the critical point of the display buffer. - */ - critical_point= (CARD32)(disp_drain_rate * disp_latency + 0.5); - - /* ???? */ - /* - temp = (info->SavedReg.grph_buffer_cntl & RADEON_GRPH_CRITICAL_POINT_MASK) >> RADEON_GRPH_CRITICAL_POINT_SHIFT; - if (critical_point < temp) critical_point = temp; - */ - if (info->DispPriority == 2) { - if (mode2) { - /*??some R300 cards have problem with this set to 0, when CRTC2 is enabled.*/ - if (info->ChipFamily == CHIP_FAMILY_R300) - critical_point += 0x10; - else - critical_point = 0; - } - else - critical_point = 0; - } - - /* - The critical point should never be above max_stop_req-4. Setting - GRPH_CRITICAL_CNTL = 0 will thus force high priority all the time. - */ - if (max_stop_req - critical_point < 4) critical_point = 0; - - temp = info->SavedReg.grph_buffer_cntl; - temp &= ~(RADEON_GRPH_STOP_REQ_MASK); - temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT); - temp &= ~(RADEON_GRPH_START_REQ_MASK); - if ((info->ChipFamily == CHIP_FAMILY_R350) && - (stop_req > 0x15)) { - stop_req -= 0x10; - } - temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT); - - temp |= RADEON_GRPH_BUFFER_SIZE; - temp &= ~(RADEON_GRPH_CRITICAL_CNTL | - RADEON_GRPH_CRITICAL_AT_SOF | - RADEON_GRPH_STOP_CNTL); - /* - Write the result into the register. - */ - OUTREG(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) | - (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT))); - - RADEONTRACE(("GRPH_BUFFER_CNTL from %x to %x\n", - info->SavedReg.grph_buffer_cntl, INREG(RADEON_GRPH_BUFFER_CNTL))); - - if (mode2) { - stop_req = mode2->HDisplay * info2->CurrentLayout.pixel_bytes / 16; - - if (stop_req > max_stop_req) stop_req = max_stop_req; - - temp = info->SavedReg.grph2_buffer_cntl; - temp &= ~(RADEON_GRPH_STOP_REQ_MASK); - temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT); - temp &= ~(RADEON_GRPH_START_REQ_MASK); - if ((info->ChipFamily == CHIP_FAMILY_R350) && - (stop_req > 0x15)) { - stop_req -= 0x10; - } - temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT); - temp |= RADEON_GRPH_BUFFER_SIZE; - temp &= ~(RADEON_GRPH_CRITICAL_CNTL | - RADEON_GRPH_CRITICAL_AT_SOF | - RADEON_GRPH_STOP_CNTL); - - if ((info->ChipFamily == CHIP_FAMILY_RS100) || - (info->ChipFamily == CHIP_FAMILY_RS200)) - critical_point2 = 0; - else { - read_return_rate = MIN(info->sclk, info->mclk*(info->RamWidth*(info->IsDDR+1)/128)); - time_disp1_drop_priority = critical_point / (read_return_rate - disp_drain_rate); - - critical_point2 = (CARD32)((disp_latency + time_disp1_drop_priority + - disp_latency) * disp_drain_rate2 + 0.5); - - if (info->DispPriority == 2) { - if (info->ChipFamily == CHIP_FAMILY_R300) - critical_point2 += 0x10; - else - critical_point2 = 0; - } - - if (max_stop_req - critical_point2 < 4) critical_point2 = 0; - - } - - OUTREG(RADEON_GRPH2_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) | - (critical_point2 << RADEON_GRPH_CRITICAL_POINT_SHIFT))); - - RADEONTRACE(("GRPH2_BUFFER_CNTL from %x to %x\n", - info->SavedReg.grph2_buffer_cntl, INREG(RADEON_GRPH2_BUFFER_CNTL))); - } -} - /* Define CRTC registers for requested video mode */ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, RADEONInfoPtr info) @@ -5977,22 +5373,24 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, int hsync_wid; int hsync_fudge; int vsync_wid; + int bytpp; int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 }; int hsync_fudge_fp[] = { 0x02, 0x02, 0x00, 0x00, 0x05, 0x05 }; switch (info->CurrentLayout.pixel_code) { - case 4: format = 1; break; - case 8: format = 2; break; - case 15: format = 3; break; /* 555 */ - case 16: format = 4; break; /* 565 */ - case 24: format = 5; break; /* RGB */ - case 32: format = 6; break; /* xRGB */ + case 4: format = 1; bytpp = 0; break; + case 8: format = 2; bytpp = 1; break; + case 15: format = 3; bytpp = 2; break; /* 555 */ + case 16: format = 4; bytpp = 2; break; /* 565 */ + case 24: format = 5; bytpp = 3; break; /* RGB */ + case 32: format = 6; bytpp = 4; break; /* xRGB */ default: xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unsupported pixel depth (%d)\n", info->CurrentLayout.bitsPerPixel); return FALSE; } + RADEONTRACE(("Format = %d (%d bytes per pixel)\n", format, bytpp)); if ((info->DisplayType == MT_DFP) || (info->DisplayType == MT_LCD)) { @@ -6089,31 +5487,18 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, (pScrn->bitsPerPixel * 8)); save->crtc_pitch |= save->crtc_pitch << 16; - /* Some versions of BIOS setup CRTC_MORE_CNTL for a DFP, if we - have a CRT here, it should be cleared to avoild a blank screen. - */ - if (info->DisplayType == MT_CRT) - save->crtc_more_cntl = (info->SavedReg.crtc_more_cntl & - ~(RADEON_CRTC_H_CUTOFF_ACTIVE_EN | - RADEON_CRTC_V_CUTOFF_ACTIVE_EN)); - else - save->crtc_more_cntl = info->SavedReg.crtc_more_cntl; - save->surface_cntl = 0; save->disp_merge_cntl = info->SavedReg.disp_merge_cntl; save->disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN; #if X_BYTE_ORDER == X_BIG_ENDIAN - /* Alhought we current onlu use aperture 0, also setting aperture 1 should not harm -ReneR */ switch (pScrn->bitsPerPixel) { case 16: save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP; - save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP; break; case 32: save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP; - save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP; break; } #endif @@ -6136,21 +5521,23 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, int hsync_wid; int hsync_fudge; int vsync_wid; + int bytpp; int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 }; switch (info->CurrentLayout.pixel_code) { - case 4: format = 1; break; - case 8: format = 2; break; - case 15: format = 3; break; /* 555 */ - case 16: format = 4; break; /* 565 */ - case 24: format = 5; break; /* RGB */ - case 32: format = 6; break; /* xRGB */ + case 4: format = 1; bytpp = 0; break; + case 8: format = 2; bytpp = 1; break; + case 15: format = 3; bytpp = 2; break; /* 555 */ + case 16: format = 4; bytpp = 2; break; /* 565 */ + case 24: format = 5; bytpp = 3; break; /* RGB */ + case 32: format = 6; bytpp = 4; break; /* xRGB */ default: xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unsupported pixel depth (%d)\n", info->CurrentLayout.bitsPerPixel); return FALSE; } + RADEONTRACE(("Format = %d (%d bytes per pixel)\n", format, bytpp)); hsync_fudge = hsync_fudge_default[format-1]; @@ -6180,10 +5567,10 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, save->disp_output_cntl &= ~(RADEON_DISP_DAC_SOURCE_MASK | RADEON_DISP_DAC2_SOURCE_MASK); if (pRADEONEnt->MonType1 != MT_CRT) { - save->disp_output_cntl |= (RADEON_DISP_DAC_SOURCE_CRTC2 | + save->disp_output_cntl |= (RADEON_DISP_DAC_SOURCE_CRTC2 | RADEON_DISP_DAC2_SOURCE_CRTC2); } else { - if (pRADEONEnt->ReversedDAC) { + if (pRADEONEnt->ReversedDAC) { save->disp_output_cntl |= RADEON_DISP_DAC2_SOURCE_CRTC2; } else { save->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2; @@ -6201,7 +5588,7 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, save->disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL; save->dac2_cntl |= RADEON_DAC2_DAC_CLK_SEL; } else { - if (pRADEONEnt->ReversedDAC) { + if (pRADEONEnt->ReversedDAC) { save->disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL; save->dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL; } else { @@ -6258,7 +5645,7 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, save->disp2_merge_cntl = info->SavedReg.disp2_merge_cntl; save->disp2_merge_cntl &= ~(RADEON_DISP2_RGB_OFFSET_EN); - if ((info->DisplayType == MT_DFP && info->IsSecondary) || + if ((info->DisplayType == MT_DFP && info->IsSecondary) || info->CloneType == MT_DFP) { save->crtc2_gen_cntl = (RADEON_CRTC2_EN | (format << 8)); save->fp2_h_sync_strt_wid = save->crtc2_h_sync_strt_wid; @@ -6280,15 +5667,23 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2; } - if (pScrn->rgbBits == 8) + if (pScrn->rgbBits == 8) save->fp2_gen_cntl |= RADEON_FP2_PANEL_FORMAT; /* 24 bit format */ else save->fp2_gen_cntl &= ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format */ /* FIXME: When there are two DFPs, the 2nd DFP is driven by the * external TMDS transmitter. It may have a problem at - * high dot clock for certain panels. + * high dot clock for certain panels. Since we don't + * know how to control the external TMDS transmitter, not + * much we can do here. */ +#if 0 + if (save->dot_clock_freq > 15000) + save->tmds_pll_cntl = 0xA3F; + else if(save->tmds_pll_cntl != 0xA3F) + save->tmds_pll_cntl = info->SavedReg.tmds_pll_cntl; +#endif /* If BIOS has not turned it on, we'll keep it on so that we'll * have a valid VGA screen even after X quits or VT is switched @@ -6313,8 +5708,8 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, int yres = mode->VDisplay; float Hratio, Vratio; - /* If the FP registers have been initialized before for a panel, - * but the primary port is a CRT, we need to reinitialize + /* If the FP registers have been initialized before for a panel, + * but the primary port is a CRT, we need to reinitialize * FP registers in order for CRT to work properly */ @@ -6352,7 +5747,7 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, if (Hratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) { save->fp_horz_stretch = orig->fp_horz_stretch; save->fp_horz_stretch &= ~(RADEON_HORZ_STRETCH_BLEND | - RADEON_HORZ_STRETCH_ENABLE); + RADEON_HORZ_STRETCH_ENABLE); save->fp_horz_stretch &= ~(RADEON_HORZ_AUTO_RATIO | RADEON_HORZ_PANEL_SIZE); save->fp_horz_stretch |= ((xres/8-1)<<16); @@ -6407,7 +5802,7 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, save->fp_gen_cntl |= (RADEON_FP_CRTC_DONT_SHADOW_VPAR | RADEON_FP_CRTC_DONT_SHADOW_HEND ); - if (pScrn->rgbBits == 8) + if (pScrn->rgbBits == 8) save->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */ else save->fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */ @@ -6415,6 +5810,16 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, save->lvds_gen_cntl = orig->lvds_gen_cntl; save->lvds_pll_cntl = orig->lvds_pll_cntl; + /* This is needed for some panel at high resolution (>=1600x1200) + */ + if ((save->dot_clock_freq > 15000) && + (info->ChipFamily != CHIP_FAMILY_R300) && + (info->ChipFamily != CHIP_FAMILY_R350) && + (info->ChipFamily != CHIP_FAMILY_RV350)) + save->tmds_pll_cntl = 0xA3F; + else + save->tmds_pll_cntl = orig->tmds_pll_cntl; + info->PanelOff = FALSE; /* This option is used to force the ONLY DEVICE in XFConfig to use * CRT port, instead of default DVI port. @@ -6423,7 +5828,6 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, info->PanelOff = TRUE; } - save->tmds_pll_cntl = orig->tmds_pll_cntl; save->tmds_transmitter_cntl= orig->tmds_transmitter_cntl; if (info->PanelOff && info->Clone) { info->OverlayOnCRTC2 = TRUE; @@ -6452,28 +5856,13 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); } else if (info->DisplayType == MT_DFP) { - int i; - CARD32 tmp = orig->tmds_pll_cntl & 0xfffff; - for (i=0; i<4; i++) { - if (info->tmds_pll[i].freq == 0) break; - if (save->dot_clock_freq < info->tmds_pll[i].freq) { - tmp = info->tmds_pll[i].value ; - break; - } - } - if ((info->ChipFamily == CHIP_FAMILY_R300) || - (info->ChipFamily == CHIP_FAMILY_R350) || - (info->ChipFamily == CHIP_FAMILY_RV350) || - (info->ChipFamily == CHIP_FAMILY_RV280)) { - if (tmp & 0xfff00000) - save->tmds_pll_cntl = tmp; - else - save->tmds_pll_cntl = (orig->tmds_pll_cntl & 0xfff00000) | tmp; - } else save->tmds_pll_cntl = tmp; - - RADEONTRACE(("TMDS_PLL from %x to %x\n", - orig->tmds_pll_cntl, - save->tmds_pll_cntl)); + /* This is needed for some panel at high resolution (>=1600x1200) + */ + if ((save->dot_clock_freq > 15000) && + (info->ChipFamily != CHIP_FAMILY_R300) && + (info->ChipFamily != CHIP_FAMILY_R350) && + (info->ChipFamily != CHIP_FAMILY_RV350)) + save->tmds_pll_cntl = 0xA3F; save->tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLRST); if ((info->ChipFamily == CHIP_FAMILY_R300) || @@ -6484,7 +5873,7 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, else /* weird, RV chips got this bit reversed? */ save->tmds_transmitter_cntl |= (RADEON_TMDS_TRANSMITTER_PLLEN); - save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); + save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); } } @@ -6677,12 +6066,12 @@ static Bool RADEONInit(ScrnInfoPtr pScrn, DisplayModePtr mode, info->Flags = mode->Flags; - RADEONInitCommonRegisters(save, info); if (info->IsSecondary) { if (!RADEONInitCrtc2Registers(pScrn, save, mode, info)) return FALSE; RADEONInitPLL2Registers(save, &info->pll, dot_clock); } else { + RADEONInitCommonRegisters(save, info); if (!RADEONInitCrtcRegisters(pScrn, save, mode, info)) return FALSE; dot_clock = mode->Clock/1000.0; @@ -6728,10 +6117,6 @@ static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) RADEONUnblank(pScrn); info->CurrentLayout.mode = mode; - - if (info->DispPriority) - RADEONInitDispBandwidth(pScrn); - return TRUE; } @@ -6777,7 +6162,7 @@ Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) if (info->Clone && info->CloneModes) { DisplayModePtr clone_mode = info->CloneModes; - /* Try to match a mode on primary head + /* Try to match a mode on primary head * FIXME: This may not be good if both heads don't have * exactly the same list of mode. */ @@ -6854,8 +6239,8 @@ Bool RADEONHandleMessage(int scrnIndex, const char* msgtype, #endif /* Used to disallow modes that are not supported by the hardware */ -ModeStatus RADEONValidMode(int scrnIndex, DisplayModePtr mode, - Bool verbose, int flag) +int RADEONValidMode(int scrnIndex, DisplayModePtr mode, + Bool verbose, int flag) { /* There are problems with double scan mode at high clocks * They're likely related PLL and display buffer settings. @@ -6899,7 +6284,7 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int clone) #ifdef XF86DRI if (info->directRenderingEnabled) { - pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); + pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); if (clone || info->IsSecondary) { pSAREAPriv->crtc2_base = Base; @@ -6962,7 +6347,7 @@ Bool RADEONEnterVT(int scrnIndex, int flags) RADEONDRIResume(pScrn->pScreen); } #endif - /* this will get XVideo going again, but only if XVideo was initialised + /* this will get XVideo going again, but only if XVideo was initialised during server startup (hence the info->adaptor if). */ if (info->adaptor) RADEONResetVideo(pScrn); @@ -7070,79 +6455,12 @@ void RADEONFreeScreen(int scrnIndex, int flags) RADEONFreeRec(pScrn); } -/* - * Powering done DAC, needed for DPMS problem with ViewSonic P817 (or its variant). - * - * Note for current DAC mapping when calling this function: - * For most of cards: - * single CRT: Driver doesn't change the existing CRTC->DAC mapping, - * CRTC1 could be driving either DAC or both DACs. - * CRT+CRT: CRTC1->TV DAC, CRTC2->Primary DAC - * DFP/LCD+CRT: CRTC2->TV DAC, CRTC2->Primary DAC. - * Some boards have two DACs reversed or don't even have a primary DAC, - * this is reflected in pRADEONEnt->ReversedDAC. And radeon 7200 doesn't - * have a second DAC. - * It's kind of messy, we'll need to redo DAC mapping part some day. - */ -static void RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC) -{ - RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - - if (IsPrimaryDAC) { - CARD32 dac_cntl; - CARD32 dac_macro_cntl = 0; - dac_cntl = INREG(RADEON_DAC_CNTL); - if ((!info->IsMobility) || (info->ChipFamily == CHIP_FAMILY_RV350)) - dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL); - if (IsOn) { - dac_cntl &= ~RADEON_DAC_PDWN; - dac_macro_cntl &= ~(RADEON_DAC_PDWN_R | - RADEON_DAC_PDWN_G | - RADEON_DAC_PDWN_B); - } else { - dac_cntl |= RADEON_DAC_PDWN; - dac_macro_cntl |= (RADEON_DAC_PDWN_R | - RADEON_DAC_PDWN_G | - RADEON_DAC_PDWN_B); - } - OUTREG(RADEON_DAC_CNTL, dac_cntl); - if ((!info->IsMobility) || (info->ChipFamily == CHIP_FAMILY_RV350)) - OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); - } else { - if (info->ChipFamily != CHIP_FAMILY_R200) { - CARD32 tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL); - if (IsOn) { - tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD | - RADEON_TV_DAC_GDACPD | - RADEON_TV_DAC_BDACPD | - RADEON_TV_DAC_BGSLEEP); - } else { - tv_dac_cntl |= (RADEON_TV_DAC_RDACPD | - RADEON_TV_DAC_GDACPD | - RADEON_TV_DAC_BDACPD | - RADEON_TV_DAC_BGSLEEP); - } - OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl); - } else { - CARD32 fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL); - if (IsOn) { - fp2_gen_cntl |= RADEON_FP2_DV0_EN; - } else { - fp2_gen_cntl &= ~RADEON_FP2_DV0_EN; - } - OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); - } - } -} - /* Sets VESA Display Power Management Signaling (DPMS) Mode */ static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) { RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); unsigned char *RADEONMMIO = info->MMIO; #ifdef XF86DRI @@ -7161,6 +6479,8 @@ static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS); + /* TODO: additional handling for LCD ? */ + switch (PowerManagementMode) { case DPMSModeOn: /* Screen: On; HSync: On, VSync: On */ @@ -7227,37 +6547,23 @@ static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, if (info->ChipFamily >= CHIP_FAMILY_R200) { OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_DV0_EN, ~RADEON_FP2_DV0_EN); } - } else if (info->DisplayType == MT_CRT) { - RADEONDacPowerSet(pScrn, TRUE, !pRADEONEnt->ReversedDAC); } } else { - if (info->Clone) { - if (info->CloneType == MT_DFP) { - OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); - OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_ON, ~RADEON_FP2_ON); - if (info->ChipFamily >= CHIP_FAMILY_R200) { - OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_DV0_EN, ~RADEON_FP2_DV0_EN); - } - } else if (info->CloneType == MT_CRT) { - RADEONDacPowerSet(pScrn, TRUE, !pRADEONEnt->ReversedDAC); + if ((info->Clone) && (info->CloneType == MT_DFP)) { + OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); + OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_ON, ~RADEON_FP2_ON); + if (info->ChipFamily >= CHIP_FAMILY_R200) { + OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_DV0_EN, ~RADEON_FP2_DV0_EN); } } if (info->DisplayType == MT_DFP) { - OUTREGP (RADEON_FP_GEN_CNTL, (RADEON_FP_FPON | RADEON_FP_TMDS_EN), + OUTREGP (RADEON_FP_GEN_CNTL, (RADEON_FP_FPON | RADEON_FP_TMDS_EN), ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN)); } else if (info->DisplayType == MT_LCD) { OUTREGP (RADEON_LVDS_GEN_CNTL, RADEON_LVDS_BLON, ~RADEON_LVDS_BLON); usleep (info->PanelPwrDly * 1000); OUTREGP (RADEON_LVDS_GEN_CNTL, RADEON_LVDS_ON, ~RADEON_LVDS_ON); - } else if (info->DisplayType == MT_CRT) { - if ((pRADEONEnt->HasSecondary) || info->Clone) { - RADEONDacPowerSet(pScrn, TRUE, pRADEONEnt->ReversedDAC); - } else { - RADEONDacPowerSet(pScrn, TRUE, TRUE); - if (info->HasCRTC2) - RADEONDacPowerSet(pScrn, TRUE, FALSE); - } } } } else if ((PowerManagementMode == DPMSModeOff) || @@ -7270,19 +6576,13 @@ static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, if (info->ChipFamily >= CHIP_FAMILY_R200) { OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DV0_EN); } - } else if (info->DisplayType == MT_CRT) { - RADEONDacPowerSet(pScrn, FALSE, !pRADEONEnt->ReversedDAC); } } else { - if (info->Clone) { - if(info->CloneType == MT_DFP) { - OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); - OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_ON); - if (info->ChipFamily >= CHIP_FAMILY_R200) { - OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DV0_EN); - } - } else if (info->CloneType == MT_CRT) { - RADEONDacPowerSet(pScrn, FALSE, !pRADEONEnt->ReversedDAC); + if ((info->Clone) && (info->CloneType == MT_DFP)) { + OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); + OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_ON); + if (info->ChipFamily >= CHIP_FAMILY_R200) { + OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DV0_EN); } } if (info->DisplayType == MT_DFP) { @@ -7297,23 +6597,12 @@ static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); } - OUTREGP (RADEON_LVDS_GEN_CNTL, 0, + OUTREGP (RADEON_LVDS_GEN_CNTL, 0, ~(RADEON_LVDS_BLON | RADEON_LVDS_ON)); if (info->IsMobility || info->IsIGP) { OUTPLL(RADEON_PIXCLKS_CNTL, tmpPixclksCntl); } - } else if (info->DisplayType == MT_CRT) { - if ((pRADEONEnt->HasSecondary) || info->Clone) { - RADEONDacPowerSet(pScrn, FALSE, pRADEONEnt->ReversedDAC); - } else { - /* single CRT, turning both DACs off, we don't really know - * which DAC is actually connected. - */ - RADEONDacPowerSet(pScrn, FALSE, TRUE); - if (info->HasCRTC2) /* don't apply this to old radeon (singel CRTC) card */ - RADEONDacPowerSet(pScrn, FALSE, FALSE); - } } } } |