Beispiel #1
0
/* Mandatory */
static Bool
VoodooPreInit(ScrnInfoPtr pScrn, int flags)
{
  VoodooPtr pVoo;
  int i;
  ClockRangePtr clockRanges;
  MessageType from;
  int maxwidth;

  if (flags & PROBE_DETECT)
      return FALSE;

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

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

  if (!xf86SetDepthBpp(pScrn, 16, 0, 0, Support32bppFb)) {
    return FALSE;
  }

  /* Check that the returned depth is one we support */
  switch (pScrn->depth) {
  case 16:
  case 24:
  case 32:
    break;
  default:
    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
               "Given depth (%d) is not supported by this driver\n",
               pScrn->depth);
    return FALSE;
  }
  xf86PrintDepthBpp(pScrn);
  
  if(pScrn->depth == 32)
  	pScrn->depth = 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};

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

  /* Set the default visual. */
  if (!xf86SetDefaultVisual(pScrn, -1)) {
    return FALSE;
  }
  /* We don't support DirectColor at > 8bpp */
  if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
               " (%s) is not supported at depth %d\n",
               xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
    return FALSE;
  }

  /* Set default gamma */
  {
    Gamma zeros = {0.0, 0.0, 0.0};

    if (!xf86SetGamma(pScrn, zeros)) {
      return FALSE;
    }
  }

  /* We use a programmable clock */
  pScrn->progClock = TRUE;

  /* Allocate the VoodooRec driverPrivate */
  if (!VoodooGetRec(pScrn)) {
    return FALSE;
  }

  pVoo = VoodooPTR(pScrn);

  /* Get the entity */
  pVoo->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
  
  pVoo->PciInfo = xf86GetPciInfoForEntity(pVoo->pEnt->index);
#ifndef XSERVER_LIBPCIACCESS
  pVoo->PciTag = pciTag(pVoo->PciInfo->bus, pVoo->PciInfo->device, pVoo->PciInfo->func);
#endif

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

  /* Process the options */
  if (!(pVoo->Options = malloc(sizeof(VoodooOptions))))
    return FALSE;
  memcpy(pVoo->Options, VoodooOptions, sizeof(VoodooOptions));
  xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pVoo->Options);

  /* Need to do rotation some day */

  if(pVoo->pEnt->chipset == PCI_CHIP_VOODOO2)
  {
  	pVoo->Voodoo2 = 1;	/* We have 2D accel, interlace, double */
  	pVoo->Accel = 1;
  }
  else
  {
  	pVoo->Voodoo2 = 0;
  	pVoo->ShadowFB = 1;
  	xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Using shadowFB with Voodoo1 hardware.\n");
  }

  from = X_DEFAULT;

  if (xf86ReturnOptValBool(pVoo->Options, OPTION_SHADOW_FB,  FALSE)) {
  	pVoo->ShadowFB = 1;
  	pVoo->Accel = 0;
  }
  
  if (xf86ReturnOptValBool(pVoo->Options, OPTION_PASS_THROUGH,  FALSE))
      pVoo->PassThrough = 1;

  if (xf86ReturnOptValBool(pVoo->Options, OPTION_NOACCEL, FALSE)) {
  	pVoo->ShadowFB = 1;
  	pVoo->Accel = 0;
  }
  
  if(pScrn->depth == 24 && !pVoo->ShadowFB)
  {
      xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "ShadowFB is required for 24/32bit modes.\n");
      pVoo->ShadowFB = 1;
      pVoo->Accel = 0;
  }

  /* MMIO at 0 , FB at 4Mb, Texture at 8Mb */
  pVoo->PhysBase = PCI_REGION_BASE(pVoo->PciInfo, 0, REGION_MEM) + 0x400000;

#ifndef XSERVER_LIBPCIACCESS
  pVoo->MMIO = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVoo->PciTag,
			     pVoo->PciInfo->memBase[0], 0x400000);
  pVoo->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVoo->PciTag,
			       pVoo->PciInfo->memBase[0] + 0x400000, 0x400000);
  		
#else
  {
    void** result = (void**)&pVoo->MMIO;
    int err = pci_device_map_range(pVoo->PciInfo,
				   PCI_REGION_BASE(pVoo->PciInfo, 0, REGION_MEM),
				   0x400000,
				   PCI_DEV_MAP_FLAG_WRITABLE,
				   result);
    if (err)
      return FALSE;
  }

  {
    void** result = (void**)&pVoo->FBBase;
    int err = pci_device_map_range(pVoo->PciInfo,
				   PCI_REGION_BASE(pVoo->PciInfo, 0, REGION_MEM) + 0x400000,
				   0x400000,
				   PCI_DEV_MAP_FLAG_WRITABLE|
				   PCI_DEV_MAP_FLAG_WRITE_COMBINE,
				   result);
    if (err)
      return FALSE;
  }
#endif  		
  VoodooHardwareInit(pVoo);
  
  /*
   * If the user has specified the amount of memory in the XF86Config
   * file, we respect that setting.
   */
  if (pVoo->pEnt->device->videoRam != 0) {
    pScrn->videoRam = pVoo->pEnt->device->videoRam;
    from = X_CONFIG;
  } else {
    pScrn->videoRam = VoodooMemorySize(pVoo) * 1024 ;	/* Sizer reports Mbytes */
    from = X_PROBED;
  }
  xf86DrvMsg(pScrn->scrnIndex, from, "Video RAM: %d kB\n",
             pScrn->videoRam);

  /* Set up clock ranges so that the xf86ValidateModes() function will not fail a mode because of the clock
     requirement (because we don't use the clock value anyway) */
  clockRanges = xnfcalloc(sizeof(ClockRange), 1);
  clockRanges->next = NULL;
  clockRanges->minClock = 10000;
  clockRanges->maxClock = 250000;	/* 250MHz DAC */
  clockRanges->clockIndex = -1;		/* programmable */
  
  if(pVoo->Voodoo2)
  {
    clockRanges->interlaceAllowed = TRUE;
    clockRanges->doubleScanAllowed = TRUE;
    maxwidth = min(1024, pScrn->display->virtualX);
  }
  else
  {
    clockRanges->interlaceAllowed = FALSE;
    clockRanges->doubleScanAllowed = FALSE;
    maxwidth = min(800, pScrn->display->virtualX);
  }

  /* Select valid modes from those available */
  i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
                        pScrn->display->modes, clockRanges,
                        NULL, 256, 2048,
                        pScrn->bitsPerPixel, 128, 768,
                        pScrn->display->virtualX,
                        pScrn->display->virtualY,
                        pScrn->videoRam * 1024,
                        LOOKUP_BEST_REFRESH);
    
  if (i == -1) {
    VoodooFreeRec(pScrn);
    return FALSE;
  }

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

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

  /* Set the current mode to the first in the list */
  xf86SetCrtcForModes(pScrn, 0);
  pScrn->currentMode = pScrn->modes;

  /* Do some checking, we will not support a virtual framebuffer larger than
     the visible screen. */
  if (pScrn->currentMode->HDisplay != pScrn->virtualX || 
      pScrn->currentMode->VDisplay != pScrn->virtualY ||
      pScrn->displayWidth != pScrn->virtualX)
  {
    /* FIXME: In this case we could use shadowfb and clip the drawing into
       the physical buffer */
    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
               "Virtual size doesn't equal display size. Forcing virtual size to equal display size.\n");
    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
               "(Virtual size: %dx%d, Display size: %dx%d)\n", pScrn->virtualX, pScrn->virtualY,
               pScrn->currentMode->HDisplay, pScrn->currentMode->VDisplay);
    /* I'm not entirely sure this is "legal" but I hope so. */
    pScrn->virtualX = pScrn->currentMode->HDisplay;
    pScrn->virtualY = pScrn->currentMode->VDisplay;
    pScrn->displayWidth = pScrn->virtualX;
  }

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

  /* Set display resolution */
  xf86SetDpi(pScrn, 0, 0);
    
  /* Load fb */
  if (xf86LoadSubModule(pScrn, "fb") == NULL) {
    VoodooFreeRec(pScrn);
    return FALSE;
  }

  if (!xf86LoadSubModule(pScrn, "xaa")) {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Falling back to shadowfb\n");
      pVoo->Accel = 0;
      pVoo->ShadowFB = 1;
  }
  
  if(pVoo->ShadowFB)
  {
    /* Load the shadow framebuffer */
    if (!xf86LoadSubModule(pScrn, "shadowfb")) {
      VoodooFreeRec(pScrn);
      return FALSE;
    }
  }
  return TRUE;
}
Bool
Permedia3Init(ScrnInfoPtr pScrn, DisplayModePtr mode, GLINTRegPtr pReg)
{
    GLINTPtr pGlint = GLINTPTR(pScrn);
    CARD32 temp1, temp2, temp3, temp4;

    if ((pGlint->numMultiDevices == 2) || (IS_J2000)) {
	STOREREG(GCSRAperture, GCSRSecondaryGLINTMapEn);
    }

    if (pGlint->MultiAperture) {
	STOREREG(GMultGLINTAperture, pGlint->realWidth);
	STOREREG(GMultGLINT1, PCI_REGION_BASE(pGlint->MultiPciInfo[0], 2, REGION_MEM) & 0xFF800000);
	STOREREG(GMultGLINT2, PCI_REGION_BASE(pGlint->MultiPciInfo[1], 2, REGION_MEM) & 0xFF800000);
    }

    STOREREG(PM3MemBypassWriteMask, 	0xffffffff);
    STOREREG(Aperture0,		 	0x00000000);
    STOREREG(Aperture1,		 	0x00000000);

    if (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)
    	STOREREG(DFIFODis,			0x00000001);

    STOREREG(FIFODis,			0x00000007);

    temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay;
    temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay;
    temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart;
    temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;

    STOREREG(PMHTotal,	Shiftbpp(pScrn, mode->CrtcHTotal) - 1);
    STOREREG(PMHsEnd,	Shiftbpp(pScrn, temp1 + temp3));
    STOREREG(PMHsStart,	Shiftbpp(pScrn, temp1));
    STOREREG(PMHbEnd,	Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay));
    STOREREG(PMHgEnd,	Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay));
    STOREREG(PMScreenStride, Shiftbpp(pScrn, pScrn->displayWidth));

    STOREREG(PMVTotal,	mode->CrtcVTotal - 1);
    STOREREG(PMVsEnd,	temp2 + temp4 - 1);
    STOREREG(PMVsStart,	temp2 - 1);
    STOREREG(PMVbEnd,	mode->CrtcVTotal - mode->CrtcVDisplay);

    switch (pScrn->bitsPerPixel)
    {
	case 8:
	    STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_8BIT);
	    STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_8BIT);
	    STOREREG(PMVideoControl,	 1 | (1 << 3) | (1 << 5) | (0 << 19));
	    break;
	case 16:
#if X_BYTE_ORDER != X_BIG_ENDIAN
	    STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_16BIT);
	    STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_16BIT);
#else
	    STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_16BIT |
					 PM3ByApertureMode_BYTESWAP_BADC);
	    STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_16BIT |
					 PM3ByApertureMode_BYTESWAP_BADC);
#endif
	    STOREREG(PMVideoControl,	 1 | (1 << 3) | (1 << 5) | (1 << 19));
	    break;
	case 32:
#if X_BYTE_ORDER != X_BIG_ENDIAN
	    STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_32BIT);
	    STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_32BIT);
#else
	    STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_32BIT |
					 PM3ByApertureMode_BYTESWAP_DCBA);
	    STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_32BIT |
					 PM3ByApertureMode_BYTESWAP_DCBA);
#endif
	    STOREREG(PMVideoControl,	 1 | (1 << 3) | (1 << 5) | (2 << 19));
	    break;
    }

    STOREREG(VClkCtl, GLINT_READ_REG(VClkCtl) & 0xFFFFFFFC);
    STOREREG(PMScreenBase, 0x00000000);
    STOREREG(ChipConfig, GLINT_READ_REG(ChipConfig) & 0xFFFFFFFD);

    {
	/* Get the programmable clock values */
    	unsigned char m,n,p;
	
	/* Let's program the dot clock */
	switch (pGlint->Chipset) {
	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4:
	case PCI_VENDOR_3DLABS_CHIP_R4:
	  (void) PM4DAC_CalculateClock(mode->Clock, pGlint->RefClock, &m,&n,&p);
	  break;
	case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3:
	  (void) PM3DAC_CalculateClock(mode->Clock, pGlint->RefClock, &m,&n,&p);
	  break;
	case PCI_VENDOR_3DLABS_CHIP_GAMMA:
	  switch (pGlint->MultiChip) {
	    case PCI_CHIP_3DLABS_PERMEDIA3:
		(void) PM3DAC_CalculateClock(mode->Clock,
					    pGlint->RefClock, &m,&n,&p);
		break;
	    case PCI_CHIP_3DLABS_R4:
		(void) PM4DAC_CalculateClock(mode->Clock,
					    pGlint->RefClock, &m,&n,&p);
		break;
	  }
	  break;
	}
	STOREDAC(PM3RD_DClk0PreScale, m);
	STOREDAC(PM3RD_DClk0FeedbackScale, n);
	STOREDAC(PM3RD_DClk0PostScale, p);
    }

    temp1 = 0;
    temp2 = 0;
    temp3 = 0;

    if (pGlint->UseFlatPanel) {
    	temp2 |= PM3RD_DACControl_BLANK_PEDESTAL_ENABLE;
    	temp3 |= PM3RD_MiscControl_VSB_OUTPUT_ENABLE;
    	STOREREG(VSConfiguration, 0x06); 
    	STOREREG(VSBBase, 1<<14);
    }

    if (mode->Flags & V_PHSYNC) temp1 |= PM3RD_SyncControl_HSYNC_ACTIVE_HIGH;
    if (mode->Flags & V_PVSYNC) temp1 |= PM3RD_SyncControl_VSYNC_ACTIVE_HIGH;

    STOREREG(PM2VDACRDIndexControl, 0x00);
    STOREDAC(PM2VDACRDSyncControl, temp1);
    STOREDAC(PM2VDACRDDACControl, temp2);

    if (pScrn->rgbBits == 8)
	temp3 |= 0x01; /* 8bit DAC */

    switch (pScrn->bitsPerPixel)
    {
    case 8:
	STOREDAC(PM2VDACRDPixelSize, 0x00);
	STOREDAC(PM2VDACRDColorFormat, 0x2E);
    	break;
    case 16:
    	temp3 |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE;
	STOREDAC(PM2VDACRDPixelSize, 0x01);
	if (pScrn->depth == 15) {
	    STOREDAC(PM2VDACRDColorFormat, 0x61);
	} else {
	    STOREDAC(PM2VDACRDColorFormat, 0x70);
	}
    	break;
    case 24:
    	temp3 |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE;
	STOREDAC(PM2VDACRDPixelSize, 0x04);
	STOREDAC(PM2VDACRDColorFormat, 0x20);
    	break;
    case 32:
    	temp3 |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE;
	if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
	    temp3 |= 0x18;
	    STOREDAC(PM2VDACRDOverlayKey, pScrn->colorKey);
	}
	STOREDAC(PM2VDACRDPixelSize, 0x02);
	STOREDAC(PM2VDACRDColorFormat, 0x20);
    	break;
    }
    STOREDAC(PM2VDACRDMiscControl, temp3);

    STOREREG(PM3FifoControl, 0x905); /* Lower the default fifo threshold */

    return(TRUE);
}