Пример #1
0
/**
 * intel_mmio_use_pci_bar:
 * @pci_dev: intel gracphis pci device
 *
 * Sets up #igt_global_mmio to point at the mmio bar.
 *
 * @pci_dev can be obtained from intel_get_pci_device().
 */
void
intel_mmio_use_pci_bar(struct pci_device *pci_dev)
{
	uint32_t devid, gen;
	int mmio_bar, mmio_size;
	int error;

	devid = pci_dev->device_id;
	if (IS_GEN2(devid))
		mmio_bar = 1;
	else
		mmio_bar = 0;

	gen = intel_gen(devid);
	if (gen < 3)
		mmio_size = 512*1024;
	else if (gen < 5)
		mmio_size = 512*1024;
	else
		mmio_size = 2*1024*1024;

	error = pci_device_map_range (pci_dev,
				      pci_dev->regions[mmio_bar].base_addr,
				      mmio_size,
				      PCI_DEV_MAP_FLAG_WRITABLE,
				      &igt_global_mmio);

	igt_fail_on_f(error != 0,
		      "Couldn't map MMIO region\n");
}
Пример #2
0
void
intel_get_mmio(struct pci_device *pci_dev)
{
	uint32_t devid;
	int mmio_bar;
	int err;

	devid = pci_dev->device_id;
	if (IS_GEN2(devid))
		mmio_bar = 1;
	else
		mmio_bar = 0;

	err = pci_device_map_range (pci_dev,
				    pci_dev->regions[mmio_bar].base_addr,
				    pci_dev->regions[mmio_bar].size,
				    PCI_DEV_MAP_FLAG_WRITABLE,
				    &mmio);

	if (err != 0) {
		fprintf(stderr, "Couldn't map MMIO region: %s\n",
			strerror(err));
		exit(1);
	}
}
Пример #3
0
Bool
ASTMapMem(ScrnInfoPtr pScrn)
{
   ASTRecPtr pAST = ASTPTR(pScrn);

#ifndef XSERVER_LIBPCIACCESS
   pAST->FBVirtualAddr = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
				 pAST->PciTag,
				 pAST->FBPhysAddr, pAST->FbMapSize);
#else
   {
     void** result = (void**)&pAST->FBVirtualAddr;
     int err = pci_device_map_range(pAST->PciInfo,
				    pAST->FBPhysAddr,
				    pAST->FbMapSize,
				    PCI_DEV_MAP_FLAG_WRITABLE |
				    PCI_DEV_MAP_FLAG_WRITE_COMBINE,
				    result);

     if (err)
			return FALSE;
   }
#endif

   if (!pAST->FBVirtualAddr)
      return FALSE;

   return TRUE;
}
Пример #4
0
/**
 * Map the specified memory range so that it can be accessed by the CPU.
 *
 * Maps the specified memory range for access by the processor.  The pointer
 * to the mapped region is stored in \c addr.  In addition, the
 * \c pci_mem_region::memory pointer for the BAR will be updated.
 *
 * \param dev          Device whose memory region is to be mapped.
 * \param base         Base address of the range to be mapped.
 * \param size         Size of the range to be mapped.
 * \param write_enable Map for writing (non-zero).
 * \param addr         Location to store the mapped address.
 *
 * \return
 * Zero on success or an \c errno value on failure.
 *
 * \sa pci_device_map_range
 */
int pci_device_map_memory_range(struct pci_device *dev,
				pciaddr_t base, pciaddr_t size,
				int write_enable, void **addr)
{
    return pci_device_map_range(dev, base, size,
				(write_enable) ? PCI_DEV_MAP_FLAG_WRITABLE : 0,
				addr);
}
Пример #5
0
void find_host_mem_read_write(int cnum)
{
	uint32_t signals_real[0x100 * 8] = { 0 };
	uint32_t signals_real_cycles[0x100 * 8] = { 0 };
	struct pci_device *dev = nva_cards[cnum].pci;
	volatile uint8_t *bar1, val;
	int ret, i, e;

	ret = pci_device_map_range(dev, dev->regions[1].base_addr, dev->regions[1].size, PCI_DEV_MAP_FLAG_WRITABLE, (void**)&bar1);
	if (ret) {
		printf("HOST_MEM: Failed to mmap bar1. aborting.\n");
		return;
	}

	printf("<HOST_MEM (1000 rd, 200 wr @bar1[0])> /!\\ no drivers should be loaded!\n");

	/* let's create some activity  */
	for (i = 0; i < 0xff; i+=4) {
		nv40_start_monitoring(cnum, 0, i, i+1, i+2, i+3);
		for (e = 0; e < 1000; e++)
			val = bar1[0];
		for (e = 0; e < 200; e++)
			bar1[0] = val;
		nv40_stop_monitoring(cnum, 0, NULL, signals_real, signals_real_cycles);
	}

	for (i = 0; i < 0xff; i++) {
		uint32_t val = SIGNAL_VALUE(signals_real, 0, i);
		uint32_t cycles = SIGNAL_VALUE(signals_real_cycles, 0, i);
		if (val == 200)
			print_counter_value("HOST_MEM", "WR", 0, i, val, cycles);
		else if (val == 1000)
			print_counter_value("HOST_MEM", "RD", 0, i, val, cycles);
		else if (val == 1200)
			print_counter_value("HOST_MEM", "TRANS", 0, i, val, cycles);
		else if (val == 3000)
			print_counter_value("HOST_MEM", "3_RD", 0, i, val, cycles);
		else if (val >= 10 && val < 10000)
			print_counter_value("UNK", "", 0, i, val, cycles);
	}

	printf("</HOST_MEM>\n\n");
}
Пример #6
0
/**
 * Map the specified BAR so that it can be accessed by the CPU.
 *
 * Maps the specified BAR for access by the processor.  The pointer to the
 * mapped region is stored in the \c pci_mem_region::memory pointer for the
 * BAR.
 *
 * \param dev          Device whose memory region is to be mapped.
 * \param region       Region, on the range [0, 5], that is to be mapped.
 * \param write_enable Map for writing (non-zero).
 *
 * \return
 * Zero on success or an \c errno value on failure.
 *
 * \sa pci_device_map_range, pci_device_unmap_range
 * \deprecated
 */
int
pci_device_map_region(struct pci_device * dev, unsigned region,
                      int write_enable)
{
    const unsigned map_flags =
        (write_enable) ? PCI_DEV_MAP_FLAG_WRITABLE : 0;

    if ((region > 5) || (dev->regions[region].size == 0))  {
        return ENOENT;
    }

    if (dev->regions[region].memory != NULL) {
        return 0;
    }

    return pci_device_map_range(dev, dev->regions[region].base_addr,
                                dev->regions[region].size, map_flags,
                                &dev->regions[region].memory);
}
Пример #7
0
Bool
ASTMapMMIO(ScrnInfoPtr pScrn)
{
   ASTRecPtr pAST = ASTPTR(pScrn);
#ifndef XSERVER_LIBPCIACCESS
   int mmioFlags;

#if !defined(__alpha__)
   mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
#else
   mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE;
#endif


   pAST->MMIOVirtualAddr = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
				         pAST->PciTag,
				         pAST->MMIOPhysAddr, pAST->MMIOMapSize);

#else
   {
     void** result = (void**)&pAST->MMIOVirtualAddr;
     int err = pci_device_map_range(pAST->PciInfo,
				    pAST->MMIOPhysAddr,
				    pAST->MMIOMapSize,
				    PCI_DEV_MAP_FLAG_WRITABLE,
				    result);

     if (err)
			return FALSE;
   }

#endif
   if (!pAST->MMIOVirtualAddr)
      return FALSE;

   return TRUE;
}
Пример #8
0
int main(int argc, char **argv)
{
	struct pci_device *dev;
	I830Rec i830;
	I830Ptr pI830 = &i830;
	ScrnInfoRec scrn;
	int err, mmio_bar;
	void *mmio;
	int i;

	err = pci_system_init();
	if (err != 0) {
		fprintf(stderr, "Couldn't initialize PCI system: %s\n",
			strerror(err));
		exit(1);
	}

	/* Grab the graphics card */
	dev = pci_device_find_by_slot(0, 0, 2, 0);
	if (dev == NULL)
		errx(1, "Couldn't find graphics card");

	err = pci_device_probe(dev);
	if (err != 0) {
		fprintf(stderr, "Couldn't probe graphics card: %s\n",
			strerror(err));
		exit(1);
	}

	if (dev->vendor_id != 0x8086)
		errx(1, "Graphics card is non-intel");

	i830.PciInfo = dev;

	mmio_bar = IS_I9XX((&i830)) ? 0 : 1;

	err = pci_device_map_range(dev,
				   dev->regions[mmio_bar].base_addr,
				   dev->regions[mmio_bar].size,
				   PCI_DEV_MAP_FLAG_WRITABLE, &mmio);

	if (err != 0) {
		fprintf(stderr, "Couldn't map MMIO region: %s\n",
			strerror(err));
		exit(1);
	}
	i830.mmio = mmio;

	scrn.scrnIndex = 0;
	scrn.pI830 = &i830;

	OUTREG(SDVOB, (0x0 << 10));
	OUTREG(SDVOC, (0x0 << 10));

	OUTREG(PORT_HOTPLUG_EN,
	       (1 << 29) |
	       (1 << 28) |
	       (1 << 27) |
	       SDVOB_HOTPLUG_INT_EN |
	       SDVOC_HOTPLUG_INT_EN |
	       (1 << 24) |
	       CRT_HOTPLUG_INT_EN | TV_HOTPLUG_INT_EN | CRT_HOTPLUG_INT_EN);

	for (i = 0;; i++) {
		OUTREG(PORT_HOTPLUG_STAT,
		       (1 << 20) |
		       (1 << 19) |
		       (1 << 18) |
		       (1 << 17) |
		       CRT_HOTPLUG_INT_STATUS |
		       TV_HOTPLUG_INT_STATUS |
		       SDVOC_HOTPLUG_INT_STATUS | SDVOB_HOTPLUG_INT_STATUS);
		INREG(PORT_HOTPLUG_STAT);

		usleep(500 * 1000);

		printf("%5d: 0x%08x\n", i, INREG(PORT_HOTPLUG_STAT));
		sleep(1);
	}

	return 0;
}
Пример #9
0
int nva_init() {
	int ret;
	ret = pci_system_init();
	if (ret)
		return -1;
	struct pci_id_match nv_match = {0x10de, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0x30000, 0xffff0000};
	struct pci_device_iterator* it = pci_id_match_iterator_create(&nv_match);
	if (!it) {
		pci_system_cleanup();
		return -1;
	}

	struct pci_device *dev;
	while (dev = pci_device_next(it)) {
		struct nva_card c = { 0 };
		ret = pci_device_probe(dev);
		if (ret) {
			fprintf (stderr, "WARN: Can't probe %04x:%02x:%02x.%x\n", dev->domain, dev->bus, dev->dev, dev->func);
			continue;
		}
		c.pci = dev;
		ADDARRAY(nva_cards, c);
	}
	pci_iterator_destroy(it);

	struct pci_id_match nv_sgs_match = {0x12d2, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0x30000, 0xffff0000};
	it = pci_id_match_iterator_create(&nv_sgs_match);
	if (!it) {
		pci_system_cleanup();
		return -1;
	}

	while (dev = pci_device_next(it)) {
		struct nva_card c = { 0 };
		ret = pci_device_probe(dev);
		if (ret) {
			fprintf (stderr, "WARN: Can't probe %04x:%02x:%02x.%x\n", dev->domain, dev->bus, dev->dev, dev->func);
			continue;
		}
		c.pci = dev;
		ADDARRAY(nva_cards, c);
	}
	pci_iterator_destroy(it);

	int i;
	for (i = 0; i < nva_cardsnum; i++) {
		dev = nva_cards[i].pci;
		ret = pci_device_map_range(dev, dev->regions[0].base_addr, dev->regions[0].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar0);
		if (ret)
			return -1;
		nva_cards[i].boot0 = nva_rd32(i, 0);
		nva_cards[i].chipset = nva_cards[i].boot0 >> 20 & 0xff;
		if (nva_cards[i].chipset < 0x10) {
			if (nva_cards[i].boot0 & 0xf000) {
				if (nva_cards[i].boot0 & 0xf00000)
					nva_cards[i].chipset = 5;
				else
					nva_cards[i].chipset = 4;
			} else {
				nva_cards[i].chipset = nva_cards[i].boot0 >> 16 & 0xf;
				if ((nva_cards[i].boot0 & 0xff) >= 0x20)
					nva_cards[i].is_nv03p = 1;
			}
		}

		if (nva_cards[i].chipset < 0x04)
			nva_cards[i].card_type = nva_cards[i].chipset;
		else if (nva_cards[i].chipset < 0x10)
			nva_cards[i].card_type = 0x04;
		else if (nva_cards[i].chipset < 0x20)
			nva_cards[i].card_type = 0x10;
		else if (nva_cards[i].chipset < 0x30)
			nva_cards[i].card_type = 0x20;
		else if (nva_cards[i].chipset < 0x40)
			nva_cards[i].card_type = 0x30;
		else if (nva_cards[i].chipset < 0x50 ||
			nva_cards[i].chipset & 0xf0 == 0x60)
			nva_cards[i].card_type = 0x40;
		else if (nva_cards[i].chipset < 0xc0)
			nva_cards[i].card_type = 0x50;
		else
			nva_cards[i].card_type = 0xc0;
	}
	return 0;
}
Пример #10
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;
}
int
Permedia3MemorySizeDetect(ScrnInfoPtr pScrn)
{
    GLINTPtr pGlint = GLINTPTR (pScrn);
    CARD32 size = 0, temp, temp1, temp2, i;

    /* We can map 64MB, as that's the size of the Permedia3 aperture 
     * regardless of memory configuration */
    pGlint->FbMapSize = 64*1024*1024;

#ifndef XSERVER_LIBPCIACCESS    
    /* Mark as VIDMEM_MMIO to avoid write-combining while detecting memory */
    pGlint->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
			pGlint->PciTag, pGlint->FbAddress, pGlint->FbMapSize);
#else
    {
      void** result = (void**)&pGlint->FbBase;
      int err = pci_device_map_range(pGlint->PciInfo,
				     pGlint->FbAddress,
				     pGlint->FbMapSize,
				     PCI_DEV_MAP_FLAG_WRITABLE,
				     result);
      
      if (err) 
	return FALSE;
    }

#endif
    if (pGlint->FbBase == NULL) 
	return 0;

    temp = GLINT_READ_REG(PM3MemBypassWriteMask);
    GLINT_SLOW_WRITE_REG(0xffffffff, PM3MemBypassWriteMask);

    /* The Permedia3 splits up memory, and even replicates it. Grrr.
     * So that each 32MB appears at offset 0, and offset 32, unless
     * there's really 64MB attached to the chip.
     * So, 16MB appears at offset 0, nothing between 16-32, then it re-appears
     * at offset 32.
     * This below is to detect the cases of memory combinations
     */

    /* Test first 32MB */
    for(i=0;i<32;i++) {
    	/* write test pattern */
	MMIO_OUT32(pGlint->FbBase, i*1024*1024, i*0x00345678);
	mem_barrier();
	temp1 = MMIO_IN32(pGlint->FbBase, i*1024*1024);
    	/* Let's check for wrapover, write will fail at 16MB boundary */
	if (temp1 == (i*0x00345678)) 
	    size = i;
	else 
	    break;
    }

    /* Ok, we're satisfied we've got 32MB, let's test the second lot */
    if ((size + 1) == i) {
	for(i=0;i<32;i++) {
	    /* Clear first 32MB */
	    MMIO_OUT32(pGlint->FbBase, i*1024*1024, 0);
	}
	mem_barrier();

        for(i=32;i<64;i++) {
    	    /* write test pattern */
	    MMIO_OUT32(pGlint->FbBase, i*1024*1024, i*0x00345678);
	    mem_barrier();
	    temp1 = MMIO_IN32(pGlint->FbBase, i*1024*1024);
	    temp2 = MMIO_IN32(pGlint->FbBase, (i-32)*1024*1024);
    	    /* Let's check for wrapover */
	    if ( (temp1 == (i*0x00345678)) && (temp2 == 0) )
	        size = i;
	    else 
	        break;
	}
    }

    GLINT_SLOW_WRITE_REG(temp, PM3MemBypassWriteMask);

#ifndef XSERVER_LIBPCIACCESS
    xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pGlint->FbBase, 
							pGlint->FbMapSize);
#else
    pci_device_unmap_range(pGlint->PciInfo, pGlint->FbBase, pGlint->FbMapSize);
#endif

    pGlint->FbBase = NULL;
    pGlint->FbMapSize = 0;

    return ( (size+1) * 1024 );
}
Пример #12
0
int nva_init() {
	int ret;
	ret = pci_system_init();
	if (ret)
		return -1;
	int i;

	for (i = 0; i < ARRAY_SIZE(nv_match); i++) {
		struct pci_device_iterator* it = pci_id_match_iterator_create(&nv_match[i]);
		if (!it) {
			pci_system_cleanup();
			return -1;
		}

		struct pci_device *dev;
		while ((dev = pci_device_next(it))) {
			struct nva_card c = { 0 };
			ret = pci_device_probe(dev);
			if (ret) {
				fprintf (stderr, "WARN: Can't probe %04x:%02x:%02x.%x\n", dev->domain, dev->bus, dev->dev, dev->func);
				continue;
			}
			c.pci = dev;
			ADDARRAY(nva_cards, c);
		}
		pci_iterator_destroy(it);
	}

	for (i = 0; i < nva_cardsnum; i++) {
		struct pci_device *dev;
		dev = nva_cards[i].pci;
		ret = pci_device_map_range(dev, dev->regions[0].base_addr, dev->regions[0].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar0);
		if (ret) {
			fprintf (stderr, "WARN: Can't probe %04x:%02x:%02x.%x\n", dev->domain, dev->bus, dev->dev, dev->func);
			int j;
			for (j = i + 1; j < nva_cardsnum; j++) {
				nva_cards[j-1] = nva_cards[j];
			}
			nva_cardsnum--;
			i--;
			continue;
		}
		nva_cards[i].bar0len = dev->regions[0].size;
		if (dev->regions[1].size) {
			nva_cards[i].hasbar1 = 1;
			nva_cards[i].bar1len = dev->regions[1].size;
			ret = pci_device_map_range(dev, dev->regions[1].base_addr, dev->regions[1].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar1);
			if (ret) {
				nva_cards[i].bar1 = 0;
			}
		}
		if (dev->regions[2].size) {
			nva_cards[i].hasbar2 = 1;
			nva_cards[i].bar2len = dev->regions[2].size;
			ret = pci_device_map_range(dev, dev->regions[2].base_addr, dev->regions[2].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar2);
			if (ret) {
				nva_cards[i].bar2 = 0;
			}
		} else if (dev->regions[3].size) {
			nva_cards[i].hasbar2 = 1;
			nva_cards[i].bar2len = dev->regions[3].size;
			ret = pci_device_map_range(dev, dev->regions[3].base_addr, dev->regions[3].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar2);
			if (ret) {
				nva_cards[i].bar2 = 0;
			}
		}
		uint32_t pmc_id = nva_rd32(i, 0);
		parse_pmc_id(pmc_id, &nva_cards[i].chipset);
	}
	return (nva_cardsnum == 0);
}
static Bool
VIAMapFB(ScrnInfoPtr pScrn)
{
    VIAPtr pVia = VIAPTR(pScrn);

#ifdef HAVE_PCIACCESS
    if (pVia->Chipset == VIA_VX900) {
        pVia->FrameBufferBase = pVia->PciInfo->regions[2].base_addr;
    } else {
        pVia->FrameBufferBase = pVia->PciInfo->regions[0].base_addr;
    }
    int err;
#else
    if (pVia->Chipset == VIA_VX900) {
        pVia->FrameBufferBase = pVia->PciInfo->memBase[2];
    } else {
        pVia->FrameBufferBase = pVia->PciInfo->memBase[0];
    }
#endif

    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapFB\n"));
    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
               "mapping framebuffer @ 0x%lx with size 0x%lx\n",
               pVia->FrameBufferBase, pVia->videoRambytes);

    if (pVia->videoRambytes) {

#ifndef HAVE_PCIACCESS
        /*
         * FIXME: This is a hack to get rid of offending wrongly sized
         * MTRR regions set up by the VIA BIOS. Should be taken care of
         * in the OS support layer.
         */
        unsigned char *tmp;

        tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
                            pVia->FrameBufferBase, pVia->videoRambytes);
        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) tmp, pVia->videoRambytes);

        /*
         * And, as if this wasn't enough, 2.6 series kernels don't
         * remove MTRR regions on the first attempt. So try again.
         */

        tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
                            pVia->FrameBufferBase, pVia->videoRambytes);
        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) tmp, pVia->videoRambytes);

        /*
         * End of hack.
         */
#endif

#ifdef HAVE_PCIACCESS
        err = pci_device_map_range(pVia->PciInfo, pVia->FrameBufferBase,
                                   pVia->videoRambytes,
                                   (PCI_DEV_MAP_FLAG_WRITABLE |
                                    PCI_DEV_MAP_FLAG_WRITE_COMBINE),
                                   (void **)&pVia->FBBase);
        if (err) {
            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                       "Unable to map mmio BAR. %s (%d)\n", strerror(err), err);
            return FALSE;
        }
#else
        pVia->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
                                     pVia->PciTag, pVia->FrameBufferBase,
                                     pVia->videoRambytes);

        if (!pVia->FBBase) {
            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                       "Internal error: could not map framebuffer\n");
            return FALSE;
        }
#endif

        pVia->FBFreeStart = 0;
        pVia->FBFreeEnd = pVia->videoRambytes;

        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
                   "Frame buffer start: %p, free start: 0x%x end: 0x%x\n",
                   pVia->FBBase, pVia->FBFreeStart, pVia->FBFreeEnd);
    }

#ifdef HAVE_PCIACCESS
    pScrn->memPhysBase = pVia->PciInfo->regions[0].base_addr;
#else
    pScrn->memPhysBase = pVia->PciInfo->memBase[0];
#endif
    pScrn->fbOffset = 0;
    if (pVia->IsSecondary)
        pScrn->fbOffset = pScrn->videoRam << 10;

    return TRUE;
}
static Bool
VIAMapMMIO(ScrnInfoPtr pScrn)
{
    VIAPtr pVia = VIAPTR(pScrn);

#ifdef HAVE_PCIACCESS
    pVia->MmioBase = pVia->PciInfo->regions[1].base_addr;
    int err;
#else
    pVia->MmioBase = pVia->PciInfo->memBase[1];
#endif

    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapMMIO\n"));

    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
               "mapping MMIO @ 0x%lx with size 0x%x\n",
               pVia->MmioBase, VIA_MMIO_REGSIZE);

#ifdef HAVE_PCIACCESS
    err = pci_device_map_range(pVia->PciInfo,
                               pVia->MmioBase,
                               VIA_MMIO_REGSIZE,
                               PCI_DEV_MAP_FLAG_WRITABLE,
                               (void **)&pVia->MapBase);

    if (err) {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                   "Unable to map mmio BAR. %s (%d)\n", strerror(err), err);
        return FALSE;
    }
#else
    pVia->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
                                  pVia->MmioBase, VIA_MMIO_REGSIZE);
    if (!pVia->MapBase)
        return FALSE;
#endif

    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
               "mapping BitBlt MMIO @ 0x%lx with size 0x%x\n",
               pVia->MmioBase + VIA_MMIO_BLTBASE, VIA_MMIO_BLTSIZE);

#ifdef HAVE_PCIACCESS
    err = pci_device_map_range(pVia->PciInfo,
                               pVia->MmioBase + VIA_MMIO_BLTBASE,
                               VIA_MMIO_BLTSIZE,
                               PCI_DEV_MAP_FLAG_WRITABLE,
                               (void **)&pVia->BltBase);

    if (err) {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                   "Unable to map blt BAR. %s (%d)\n", strerror(err), err);
        return FALSE;
    }
#else
    pVia->BltBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
                                  pVia->MmioBase + VIA_MMIO_BLTBASE,
                                  VIA_MMIO_BLTSIZE);
    if (!pVia->BltBase)
        return FALSE;
#endif

    if (!pVia->MapBase || !pVia->BltBase) {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                   "BitBlit could not be mapped.\n");
        return FALSE;
    }

    /* Memory mapped IO for mpeg engine. */
    pVia->MpegMapBase = pVia->MapBase + 0xc00;

    /* Set up MMIO vgaHW. */
    {
        vgaHWPtr hwp = VGAHWPTR(pScrn);
        CARD8 val;

        vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000);

        val = hwp->readEnable(hwp);
        hwp->writeEnable(hwp, val | 0x01);

        val = hwp->readMiscOut(hwp);
        hwp->writeMiscOut(hwp, val | 0x01);

        /* Unlock extended IO space. */
        ViaSeqMask(hwp, 0x10, 0x01, 0x01);

        ViaMMIOEnable(pScrn);

        vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000);

        /* Unlock CRTC. */
        ViaCrtcMask(hwp, 0x47, 0x00, 0x01);

        vgaHWGetIOBase(hwp);
    }
    return TRUE;
}