示例#1
0
/* Mandatory */
Bool
LgPreInit(ScrnInfoPtr pScrn, int flags)
{
	CirPtr pCir;
	vgaHWPtr hwp;
	MessageType from;
	int i;
	ClockRangePtr clockRanges;
	int fbPCIReg, ioPCIReg;
	char *s;

	if (flags & PROBE_DETECT)  {
	  cirProbeDDC( pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index );
	  return TRUE;
	}
	
#ifdef LG_DEBUG
	ErrorF("LgPreInit\n");
#endif

	/* Check the number of entities, and fail if it isn't one. */
	if (pScrn->numEntities != 1)
		return FALSE;

	/* The vgahw module should be loaded here when needed */
	if (!xf86LoadSubModule(pScrn, "vgahw"))
		return FALSE;

	xf86LoaderReqSymLists(vgahwSymbols, NULL);

	/*
	 * Allocate a vgaHWRec
	 */
	if (!vgaHWGetHWRec(pScrn))
		return FALSE;

	hwp = VGAHWPTR(pScrn);
	vgaHWGetIOBase(hwp);

	/* Allocate the LgRec driverPrivate */
	if (!LgGetRec(pScrn))
		return FALSE;

	pCir = CIRPTR(pScrn);
	pCir->pScrn = pScrn;
	pCir->PIOReg = hwp->PIOOffset + 0x3CE;

	/* Get the entity, and make sure it is PCI. */
	pCir->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
	if (pCir->pEnt->location.type != BUS_PCI)
		return FALSE;
	pCir->Chipset = pCir->pEnt->chipset;

	/* Find the PCI info for this screen */
	pCir->PciInfo = xf86GetPciInfoForEntity(pCir->pEnt->index);
	pCir->PciTag = pciTag(pCir->PciInfo->bus,
								pCir->PciInfo->device,
								pCir->PciInfo->func);

	if (xf86LoadSubModule(pScrn, "int10")) {
	    xf86Int10InfoPtr int10InfoPtr;
	    xf86LoaderReqSymLists(int10Symbols, NULL);
	    
	    int10InfoPtr = xf86InitInt10(pCir->pEnt->index);

	    if (int10InfoPtr)
		xf86FreeInt10(int10InfoPtr);
	}

	/* Set pScrn->monitor */
	pScrn->monitor = pScrn->confScreen->monitor;

	/*
	 * The first thing we should figure out is the depth, bpp, etc.
	 * We support both 24bpp and 32bpp layouts, so indicate that.
	 */
	if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb |
							SupportConvert32to24 | PreferConvert32to24)) {
		return FALSE;
    }
	/* Check that the returned depth is one we support */
	switch (pScrn->depth) {
	case 8:
	case 15:
	case 16:
	case 24:
	case 32:
		/* OK */
		break;
	default:
		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			"Given depth (%d) is not supported by this driver\n", pScrn->depth);
		return FALSE;
	}
	xf86PrintDepthBpp(pScrn);

	/* Get the depth24 pixmap format */
	if (pScrn->depth == 24 && pix24bpp == 0)
		pix24bpp = xf86GetBppFromDepth(pScrn, 24);

	/*
	 * This must happen after pScrn->display has been set because
	 * xf86SetWeight references it.
	 */
	if (pScrn->depth > 8) {
		/* The defaults are OK for us */
		rgb zeros = {0, 0, 0};

		/* !!! I think we can force 5-6-5 weight for 16bpp here for
		   the 5462. */

		if (!xf86SetWeight(pScrn, zeros, zeros)) {
			return FALSE;
		} else {
			/* XXX check that weight returned is supported */
			;
		}
	}

	if (!xf86SetDefaultVisual(pScrn, -1))
		return FALSE;


	/* Collect all of the relevant option flags (fill in pScrn->options) */
	xf86CollectOptions(pScrn, NULL);

	/* Process the options */
	if (!(pCir->Options = xalloc(sizeof(LgOptions))))
		return FALSE;
	memcpy(pCir->Options, LgOptions, sizeof(LgOptions));
	xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCir->Options);

	pScrn->rgbBits = 6; 
	from = X_DEFAULT;
	pCir->HWCursor = FALSE;
	if (xf86GetOptValBool(pCir->Options, OPTION_HW_CURSOR, &pCir->HWCursor))
		from = X_CONFIG;

	xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
		pCir->HWCursor ? "HW" : "SW");
	if (xf86ReturnOptValBool(pCir->Options, OPTION_NOACCEL, FALSE)) {
		pCir->NoAccel = TRUE;
		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
	}
	if (pScrn->bitsPerPixel < 8) {
		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			"Cannot use in less than 8 bpp\n");
		return FALSE;
	}
	/*
	 * Set the ChipRev, allowing config file entries to
	 * override.
	 */
	if (pCir->pEnt->device->chipRev >= 0) {
		pCir->ChipRev = pCir->pEnt->device->chipRev;
		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
			pCir->ChipRev);
	} else {
		pCir->ChipRev = pCir->PciInfo->chipRev;
	}

	/* Cirrus swapped the FB and IO registers in the 5465 (by design). */
	if (PCI_CHIP_GD5465 == pCir->Chipset) {
		fbPCIReg = 0;
		ioPCIReg = 1;
	} else {
		fbPCIReg = 1;
		ioPCIReg = 0;
	}

	/* Find the frame buffer base address */
	if (pCir->pEnt->device->MemBase != 0) {
		/* Require that the config file value matches one of the PCI values. */
		if (!xf86CheckPciMemBase(pCir->PciInfo, pCir->pEnt->device->MemBase)) {
			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
				"MemBase 0x%08lX doesn't match any PCI base register.\n",
				pCir->pEnt->device->MemBase);
			return FALSE;
		}
		pCir->FbAddress = pCir->pEnt->device->MemBase;
		from = X_CONFIG;
	} else {
		if (pCir->PciInfo->memBase[fbPCIReg] != 0) {
			pCir->FbAddress = pCir->PciInfo->memBase[fbPCIReg] & 0xff000000;
			from = X_PROBED;
		} else {
			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
				"No valid FB address in PCI config space\n");
			LgFreeRec(pScrn);
			return FALSE;
		}
	}
	xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
		(unsigned long)pCir->FbAddress);

	/* Find the MMIO base address */
	if (pCir->pEnt->device->IOBase != 0) {
		/* Require that the config file value matches one of the PCI values. */
		if (!xf86CheckPciMemBase(pCir->PciInfo, pCir->pEnt->device->IOBase)) {
			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
				"IOBase 0x%08lX doesn't match any PCI base register.\n",
				pCir->pEnt->device->IOBase);
			return FALSE;
		}
		pCir->IOAddress = pCir->pEnt->device->IOBase;
		from = X_CONFIG;
	} else {
		if (pCir->PciInfo->memBase[ioPCIReg] != 0) {
			pCir->IOAddress = pCir->PciInfo->memBase[ioPCIReg] & 0xfffff000;
			from = X_PROBED;
		} else {
			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			"No valid MMIO address in PCI config space\n");
		}
	}
	xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
		(unsigned long)pCir->IOAddress);

	/*
	 * If the user has specified the amount of memory in the XF86Config
	 * file, we respect that setting.
	 */
	if (pCir->pEnt->device->videoRam != 0) {
		pScrn->videoRam = pCir->pEnt->device->videoRam;
		from = X_CONFIG;
	} else {
		pScrn->videoRam = LgCountRam(pScrn);
		from = X_PROBED;
	}
	if (2048 == pScrn->videoRam) {
		/* Two-way interleaving */
		pCir->chip.lg->memInterleave = 0x40;
	} else if (4096 == pScrn->videoRam || 8192 == pScrn->videoRam) {
		/* Four-way interleaving */
		pCir->chip.lg->memInterleave = 0x80;
	} else {
		/* One-way interleaving */
		pCir->chip.lg->memInterleave = 0x00;
	}

	xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
				pScrn->videoRam);

	pCir->FbMapSize = pScrn->videoRam * 1024;
	pCir->IoMapSize = 0x4000;	/* 16K for moment,  will increase */

	pScrn->racIoFlags =   RAC_COLORMAP 
#ifndef EXPERIMENTAL
	  | RAC_VIEWPORT
#endif
;
 	xf86SetOperatingState(resVgaMem, pCir->pEnt->index, ResUnusedOpr);
	
	/* Register the PCI-assigned resources. */
	if (xf86RegisterResources(pCir->pEnt->index, NULL, ResExclusive)) {
		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			"xf86RegisterResources() found resource conflicts\n");
		return FALSE;
	}

	if (!xf86LoadSubModule(pScrn, "ddc")) {
		LgFreeRec(pScrn);
		return FALSE;
	}
	xf86LoaderReqSymLists(ddcSymbols, NULL);

#if LGuseI2C
	if (!xf86LoadSubModule(pScrn, "i2c")) {
		LgFreeRec(pScrn);
		return FALSE;
	}
	xf86LoaderReqSymLists(i2cSymbols, NULL);
#endif

	/* Read and print the monitor DDC information */
	pScrn->monitor->DDC = LgDoDDC(pScrn);

	/* The gamma fields must be initialised when using the new cmap code */
	if (pScrn->depth > 1) {
		Gamma zeros = {0.0, 0.0, 0.0};

		if (!xf86SetGamma(pScrn, zeros))
			return FALSE;
	}
	if (xf86GetOptValBool(pCir->Options,
			      OPTION_SHADOW_FB,&pCir->shadowFB))
	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB %s.\n",
		       pCir->shadowFB ? "enabled" : "disabled");
	    
	if ((s = xf86GetOptValString(pCir->Options, OPTION_ROTATE))) {
	    if(!xf86NameCmp(s, "CW")) {
		/* accel is disabled below for shadowFB */
		pCir->shadowFB = TRUE;
		pCir->rotate = 1;
		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
			   "Rotating screen clockwise - acceleration disabled\n");
	    } else if(!xf86NameCmp(s, "CCW")) {
		pCir->shadowFB = TRUE;
		pCir->rotate = -1;
		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,  "Rotating screen"
			   "counter clockwise - acceleration disabled\n");
	    } else {
		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid"
			   "value for Option \"Rotate\"\n", s);
		xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
			   "Valid options are \"CW\" or \"CCW\"\n");
	    }
	}

	if (pCir->shadowFB && !pCir->NoAccel) {
	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
		       "HW acceleration not supported with \"shadowFB\".\n");
	    pCir->NoAccel = TRUE;
	}
	
	if (pCir->rotate && pCir->HWCursor) {
	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
		       "HW cursor not supported with \"rotate\".\n");
	    pCir->HWCursor = FALSE;
	}
	
	/* We use a programmable clock */
	pScrn->progClock = TRUE;

	/* XXX Set HW cursor use */

	/* Set the min pixel clock */
	pCir->MinClock = 12000;	/* XXX Guess, need to check this */
	xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
				pCir->MinClock / 1000);
	/*
	 * If the user has specified ramdac speed in the XF86Config
	 * file, we respect that setting.
	 */
	if (pCir->pEnt->device->dacSpeeds[0]) {
		ErrorF("Do not specify a Clocks line for Cirrus chips\n");
		return FALSE;
	} else {
		int speed;
		int *p;
		switch (pCir->Chipset) {
		case PCI_CHIP_GD5462:
			p = gd5462_MaxClocks;
			break;
		case PCI_CHIP_GD5464:
		case PCI_CHIP_GD5464BD:
			p = gd5464_MaxClocks;
			break;
		case PCI_CHIP_GD5465:
			p = gd5465_MaxClocks;
			break;
		default:
			ErrorF("???\n");
			return FALSE;
		}
		switch (pScrn->bitsPerPixel) {
		case 8:
			speed = p[1];
			break;
		case 15:
		case 16:
			speed = p[2];
			break;
		case 24:
			speed = p[3];
			break;
		case 32:
			speed = p[4];
			break;
		default:
			/* Should not get here */
			speed = 0;
			break;
		}
		pCir->MaxClock = speed;
		from = X_PROBED;
	}
	xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
				pCir->MaxClock / 1000);

	/*
	 * Setup the ClockRanges, which describe what clock ranges are available,
	 * and what sort of modes they can be used for.
	 */
	clockRanges = xnfcalloc(sizeof(ClockRange), 1);
	clockRanges->next = NULL;
	clockRanges->minClock = pCir->MinClock;
	clockRanges->maxClock = pCir->MaxClock;
	clockRanges->clockIndex = -1;		/* programmable */
	clockRanges->interlaceAllowed = FALSE;	/* XXX check this */
	clockRanges->doubleScanAllowed = FALSE;	/* XXX check this */
	clockRanges->doubleScanAllowed = FALSE;	/* XXX check this */
	clockRanges->doubleScanAllowed = FALSE;	/* XXX check this */
	clockRanges->ClockMulFactor = 1;
	clockRanges->ClockDivFactor = 1;
	clockRanges->PrivFlags = 0;

	/* Depending upon what sized tiles used, either 128 or 256. */
	/* Aw, heck.  Just say 128. */
	pCir->Rounding = 128 >> pCir->BppShift;

	/*
	 * xf86ValidateModes will check that the mode HTotal and VTotal values
	 * don't exceed the chipset's limit if pScrn->maxHValue and
	 * pScrn->maxVValue are set.  Since our CIRValidMode() already takes
	 * care of this, we don't worry about setting them here.
	 */

	i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes,
							clockRanges,
							LgLinePitches[pScrn->bitsPerPixel / 8 - 1],
							0, 0, 128 * 8,
							0, 0, /* Any virtual height is allowed. */
							pScrn->display->virtualX,
							pScrn->display->virtualY,
							pCir->FbMapSize,
							LOOKUP_BEST_REFRESH);

	pCir->chip.lg->lineDataIndex = LgFindLineData(pScrn->displayWidth,
										pScrn->bitsPerPixel);

	if (i == -1) {
		LgFreeRec(pScrn);
		return FALSE;
	}

	/* Prune the modes marked as invalid */
	xf86PruneDriverModes(pScrn);

	if (i == 0 || pScrn->modes == NULL) {
		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
		LgFreeRec(pScrn);
		return FALSE;
	}

	/*
	 * Set the CRTC parameters for all of the modes based on the type
	 * of mode, and the chipset's interlace requirements.
	 *
	 * Calling this is required if the mode->Crtc* values are used by the
	 * driver and if the driver doesn't provide code to set them.  They
	 * are not pre-initialised at all.
	 */
	xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);

	/* Set the current mode to the first in the list */
	pScrn->currentMode = pScrn->modes;

	/* Print the list of modes being used */
	xf86PrintModes(pScrn);

	/* Set display resolution */
	xf86SetDpi(pScrn, 0, 0);

	/* Load bpp-specific modules */
	switch (pScrn->bitsPerPixel) {
	case 8:
	case 16:
	case 24:
	case 32: 
	    if (xf86LoadSubModule(pScrn, "fb") == NULL) {
	         LgFreeRec(pScrn);
		 return FALSE;
	    }
	    xf86LoaderReqSymLists(fbSymbols, NULL);
	    break;
	}

	/* Load XAA if needed */
	if (!pCir->NoAccel) {
		if (!xf86LoadSubModule(pScrn, "xaa")) {
			LgFreeRec(pScrn);
			return FALSE;
		}
		xf86LoaderReqSymLists(xaaSymbols, NULL);
	}

	/* Load ramdac if needed */
	if (pCir->HWCursor) {
		if (!xf86LoadSubModule(pScrn, "ramdac")) {
			LgFreeRec(pScrn);
			return FALSE;
		}
		xf86LoaderReqSymLists(ramdacSymbols, NULL);
	}

	if (pCir->shadowFB) {
	    if (!xf86LoadSubModule(pScrn, "shadowfb")) {
		LgFreeRec(pScrn);
		return FALSE;
	    }
	    xf86LoaderReqSymLists(shadowSymbols, NULL);
	}
	
	return TRUE;
}
void
Permedia3PreInit(ScrnInfoPtr pScrn)
{
    GLINTPtr pGlint = GLINTPTR(pScrn);
    CARD32 LocalMemCaps;

    TRACE_ENTER("Permedia3PreInit");

    if (IS_J2000) {
    	unsigned char m,n,p;

	if (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)
	    GLINT_SLOW_WRITE_REG(GCSRSecondaryGLINTMapEn, GCSRAperture);

	/* Memory timings for the Appian J2000 board.
	 * This is needed for the second head which is left un-initialized
	 * by the bios, thus freezing the machine. */
	GLINT_SLOW_WRITE_REG(0x02e311B8, PM3LocalMemCaps);
	GLINT_SLOW_WRITE_REG(0x07424905, PM3LocalMemTimings);
	GLINT_SLOW_WRITE_REG(0x0c000003, PM3LocalMemControl);
	GLINT_SLOW_WRITE_REG(0x00000061, PM3LocalMemRefresh);
	GLINT_SLOW_WRITE_REG(0x00000000, PM3LocalMemPowerDown);
	
	/* Let's program the K, M and S Clocks to the same values as the bios
	 * does for first head :
	 *   - KClk and MClk are 105Mhz.
	 *   - S Clock is set to PClk.
	 * Note 1 : pGlint->RefClock is not set yet, so use 14318 instead.
	 * Note 2 : KClk gets internally halved, so we need to double it.
	 */
	(void) PM3DAC_CalculateClock(2*105000, 14318, &m,&n,&p);
        Permedia2vOutIndReg(pScrn, PM3RD_KClkPreScale, 0x00, m);
        Permedia2vOutIndReg(pScrn, PM3RD_KClkFeedbackScale, 0x00, n);
        Permedia2vOutIndReg(pScrn, PM3RD_KClkPostScale, 0x00, p);
        Permedia2vOutIndReg(pScrn, PM3RD_KClkControl, 0x00,
	    PM3RD_KClkControl_STATE_RUN |
	    PM3RD_KClkControl_SOURCE_PLL |
	    PM3RD_KClkControl_ENABLE);
        Permedia2vOutIndReg(pScrn, PM3RD_MClkControl, 0x00,
	    PM3RD_MClkControl_STATE_RUN |
	    PM3RD_MClkControl_SOURCE_KCLK |
	    PM3RD_MClkControl_ENABLE);
        Permedia2vOutIndReg(pScrn, PM3RD_SClkControl, 0x00,
	    PM3RD_SClkControl_STATE_RUN |
	    PM3RD_SClkControl_SOURCE_PCLK |
	    PM3RD_SClkControl_ENABLE);
    }

#if defined(__alpha__)
    /*
     * On Alpha, we have to "int10" secondary VX1 cards early;
     * otherwise, some information taken from registers, like
     * memory size, is incorrect.
     */
    if (!xf86IsPrimaryPci(pGlint->PciInfo)) {
        if ( IS_QVX1 ) {

	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		       "VX1 secondary enabling VGA before int10\n");

	    /* Enable VGA on the current card. */
	    PCI_WRITE_BYTE(pGlint->PciInfo, 0, 0xf8);
	    PCI_WRITE_BYTE(pGlint->PciInfo, 0, 0xf4);
	    PCI_WRITE_BYTE(pGlint->PciInfo, 0, 0xfc);

	    /* The card we are on should be VGA-enabled now, so run int10. */
	    if (xf86LoadSubModule(pScrn, "int10")) {
	        xf86Int10InfoPtr pInt;

		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n");
		pInt = xf86InitInt10(pGlint->pEnt->index);
		xf86FreeInt10(pInt);
	    }

	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		       "VX1 secondary disabling VGA after int10\n");

	    /* Finally, disable VGA on the current card. */
	    PCI_WRITE_BYTE(pGlint->PciInfo, 0x70, 0xf8);
	    PCI_WRITE_BYTE(pGlint->PciInfo, 0x01, 0xf4);
	    PCI_WRITE_BYTE(pGlint->PciInfo, 0x00, 0xfc);
	}
    }
#endif /* __alpha__ */

    /* If we have SDRAM instead of SGRAM, we have to do some things
       differently in the FillRectSolid code. */       
    LocalMemCaps = GLINT_READ_REG(PM3LocalMemCaps);
    pGlint->PM3_UsingSGRAM = !(LocalMemCaps & PM3LocalMemCaps_NoWriteMask);
    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %s memory\n", 
	       pGlint->PM3_UsingSGRAM ? "SGRAM" : "SDRAM");

    TRACE_EXIT("Permedia3PreInit");
}