diff options
-rw-r--r-- | src/i810_driver.c | 244 |
1 files changed, 239 insertions, 5 deletions
diff --git a/src/i810_driver.c b/src/i810_driver.c index 972b6d50..e55f9425 100644 --- a/src/i810_driver.c +++ b/src/i810_driver.c @@ -94,7 +94,16 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* Required Functions: */ static void I810Identify(int flags); + +#if XSERVER_LIBPCIACCESS +static Bool intel_pci_probe (DriverPtr drv, + int entity_num, + struct pci_device *dev, + intptr_t match_data); +#else static Bool I810Probe(DriverPtr drv, int flags); +#endif + #ifndef I830_ONLY static Bool I810PreInit(ScrnInfoPtr pScrn, int flags); static Bool I810ScreenInit(int Index, ScreenPtr pScreen, int argc, @@ -112,14 +121,59 @@ static ModeStatus I810ValidMode(int scrnIndex, DisplayModePtr mode, #endif /* I830_ONLY */ +#if XSERVER_LIBPCIACCESS + +#define INTEL_DEVICE_MATCH(d,i) \ + { 0x8086, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) } + +static const struct pci_id_match intel_device_match[] = { +#ifndef I830_ONLY + INTEL_DEVICE_MATCH (PCI_CHIP_I810, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I810_DC100, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I810_E, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I815, 0 ), +#endif + INTEL_DEVICE_MATCH (PCI_CHIP_I830_M, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_845_G, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I855_GM, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I865_G, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I915_G, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_E7221_G, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I915_GM, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I945_G, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I945_GM, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I945_GME, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I965_G, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I965_G_1, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I965_Q, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I946_GZ, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I965_GM, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_I965_GME, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_G33_G, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_Q35_G, 0 ), + INTEL_DEVICE_MATCH (PCI_CHIP_Q33_G, 0 ), + { 0, 0, 0 }, +}; + +#endif /* XSERVER_LIBPCIACCESS */ + _X_EXPORT DriverRec I810 = { I810_VERSION, I810_DRIVER_NAME, I810Identify, +#if XSERVER_LIBPCIACCESS + NULL, +#else I810Probe, +#endif I810AvailableOptions, NULL, - 0 + 0, + NULL, +#if XSERVER_LIBPCIACCESS + intel_device_match, + intel_pci_probe +#endif }; /* *INDENT-OFF* */ @@ -429,7 +483,13 @@ i810Setup(pointer module, pointer opts, int *errmaj, int *errmin) */ if (!setupDone) { setupDone = 1; - xf86AddDriver(&I810, module, 0); + xf86AddDriver(&I810, module, +#if XSERVER_LIBPCIACCESS + HaveDriverFuncs +#else + 0 +#endif + ); /* * Tell the loader about symbols from other modules that this module @@ -517,6 +577,113 @@ I810AvailableOptions(int chipid, int busid) #endif } +#if XSERVER_LIBPCIACCESS +struct pci_device * +intel_host_bridge (void) +{ + static const struct pci_slot_match bridge_match = { + 0, 0, 0, PCI_MATCH_ANY, 0 + }; + struct pci_device_iterator *slot_iterator; + struct pci_device *bridge; + + slot_iterator = pci_slot_match_iterator_create (&bridge_match); + bridge = pci_device_next (slot_iterator); + pci_iterator_destroy (slot_iterator); + return bridge; +} + +/* + * intel_pci_probe -- + * + * Look through the PCI bus to find cards that are intel boards. + * Setup the dispatch table for the rest of the driver functions. + * + */ +static Bool intel_pci_probe (DriverPtr driver, + int entity_num, + struct pci_device *device, + intptr_t match_data) +{ + ScrnInfoPtr scrn = NULL; + EntityInfoPtr entity; + I830EntPtr i830_ent = NULL; + DevUnion *private; + + scrn = xf86ConfigPciEntity (scrn, 0, entity_num, I810PciChipsets, + NULL, + NULL, NULL, NULL, NULL); + if (scrn != NULL) + { + scrn->driverVersion = I810_VERSION; + scrn->driverName = I810_DRIVER_NAME; + scrn->name = I810_NAME; + scrn->Probe = NULL; + + entity = xf86GetEntityInfo (entity_num); + + switch (DEVICE_ID(device)) { +#ifndef I830_ONLY + case PCI_CHIP_I810: + case PCI_CHIP_I810_DC100: + case PCI_CHIP_I810_E: + case PCI_CHIP_I815: + scrn->PreInit = I810PreInit; + scrn->ScreenInit = I810ScreenInit; + scrn->SwitchMode = I810SwitchMode; + scrn->AdjustFrame = I810AdjustFrame; + scrn->EnterVT = I810EnterVT; + scrn->LeaveVT = I810LeaveVT; + scrn->FreeScreen = I810FreeScreen; + scrn->ValidMode = I810ValidMode; + break; +#endif + case PCI_CHIP_845_G: + case PCI_CHIP_I865_G: + /* + * These two chips have only one pipe, and + * cannot do dual-head + */ + I830InitpScrn(scrn); + break; + default: + /* + * Everything else is an i830-ish dual-pipe chip + */ + xf86SetEntitySharable(entity_num); + + /* Allocate an entity private if necessary */ + if (I830EntityIndex < 0) + I830EntityIndex = xf86AllocateEntityPrivateIndex(); + + private = xf86GetEntityPrivate(scrn->entityList[0], + I830EntityIndex); + i830_ent = private->ptr; + if (!i830_ent) + { + private->ptr = xnfcalloc(sizeof(I830EntRec), 1); + i830_ent = private->ptr; + i830_ent->lastInstance = -1; + } + + /* + * Set the entity instance for this instance of the driver. + * For dual head per card, instance 0 is the "master" + * instance, driving the primary head, and instance 1 is + * the "slave". + */ + i830_ent->lastInstance++; + xf86SetEntityInstanceForScreen(scrn, + scrn->entityList[0], + i830_ent->lastInstance); + I830InitpScrn(scrn); + break; + } + } + return scrn != NULL; +} +#else /* XSERVER_LIBPCIACCESS */ + /* * I810Probe -- * @@ -678,6 +845,7 @@ I810Probe(DriverPtr drv, int flags) return foundScreen; } +#endif /* else XSERVER_LIBPCIACCESS */ #ifndef I830_ONLY static void @@ -769,8 +937,10 @@ I810PreInit(ScrnInfoPtr pScrn, int flags) pI810->ioBase = hwp->PIOOffset; pI810->PciInfo = xf86GetPciInfoForEntity(pI810->pEnt->index); +#if !XSERVER_LIBPCIACCESS pI810->PciTag = pciTag(pI810->PciInfo->bus, pI810->PciInfo->device, pI810->PciInfo->func); +#endif if (xf86RegisterResources(pI810->pEnt->index, NULL, ResNone)) return FALSE; @@ -899,7 +1069,7 @@ I810PreInit(ScrnInfoPtr pScrn, int flags) } else { from = X_PROBED; pScrn->chipset = (char *)xf86TokenToString(I810Chipsets, - pI810->PciInfo->chipType); + DEVICE_ID(pI810->PciInfo)); } if (pI810->pEnt->device->chipRev >= 0) { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", @@ -909,6 +1079,10 @@ I810PreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i810"); +#if XSERVER_LIBPCIACCESS + pI810->fb_bar = 0; + pI810->LinearAddr = pI810->PciInfo->regions[pI810->fb_bar].base_addr; +#else if (pI810->pEnt->device->MemBase != 0) { pI810->LinearAddr = pI810->pEnt->device->MemBase; from = X_CONFIG; @@ -923,9 +1097,14 @@ I810PreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } } +#endif xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", (unsigned long)pI810->LinearAddr); +#if XSERVER_LIBPCIACCESS + pI810->mmio_bar = 1; + pI810->MMIOAddr = pI810->PciInfo->regions[pI810->mmio_bar].base_addr; +#else if (pI810->pEnt->device->IOBase != 0) { pI810->MMIOAddr = pI810->pEnt->device->IOBase; from = X_CONFIG; @@ -940,6 +1119,7 @@ I810PreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } } +#endif xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n", (unsigned long)pI810->MMIOAddr); @@ -956,8 +1136,13 @@ I810PreInit(ScrnInfoPtr pScrn, int flags) /* Find out memory bus frequency. */ { - unsigned long whtcfg_pamr_drp = pciReadLong(pI810->PciTag, - WHTCFG_PAMR_DRP); + uint32_t whtcfg_pamr_drp; + +#if XSERVER_LIBPCIACCESS + pci_device_cfg_read_u32(pI810->PciInfo, & whtcfg_pamr_drp, WHTCFG_PAMR_DRP); +#else + whtcfg_pamr_drp = pciReadLong(pI810->PciTag, WHTCFG_PAMR_DRP); +#endif /* Need this for choosing watermarks. */ @@ -1010,11 +1195,19 @@ I810PreInit(ScrnInfoPtr pScrn, int flags) /* Calculate Fixed Offsets depending on graphics aperture size */ { +#if XSERVER_LIBPCIACCESS + struct pci_device *bridge = intel_host_bridge (); + uint32_t smram_miscc; + + pci_device_cfg_read_u32 (bridge, & smram_miscc, SMRAM_MISCC); +#else PCITAG bridge; long smram_miscc; bridge = pciTag(0, 0, 0); /* This is always the host bridge */ smram_miscc = pciReadLong(bridge, SMRAM_MISCC); +#endif + if ((smram_miscc & GFX_MEM_WIN_SIZE) == GFX_MEM_WIN_32M) { pI810->FbMapSize = 0x1000000; pI810->DepthOffset = 0x1000000; @@ -1204,6 +1397,10 @@ I810MapMMIO(ScrnInfoPtr pScrn) { int mmioFlags; I810Ptr pI810 = I810PTR(pScrn); +#if XSERVER_LIBPCIACCESS + struct pci_device *const device = pI810->PciInfo; + int err; +#endif #if !defined(__alpha__) mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT; @@ -1211,11 +1408,23 @@ I810MapMMIO(ScrnInfoPtr pScrn) mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE; #endif +#if XSERVER_LIBPCIACCESS + err = pci_device_map_region (device, pI810->mmio_bar, TRUE); + if (err) + { + xf86DrvMsg (pScrn->scrnIndex, X_ERROR, + "Unable to map mmio BAR. %s (%d)\n", + strerror (err), err); + return FALSE; + } + pI810->MMIOBase = device->regions[pI810->mmio_bar].memory; +#else pI810->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pI810->PciTag, pI810->MMIOAddr, I810_REG_SIZE); if (!pI810->MMIOBase) return FALSE; +#endif return TRUE; } @@ -1224,17 +1433,34 @@ I810MapMem(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); long i; +#if XSERVER_LIBPCIACCESS + struct pci_device *const device = pI810->PciInfo; + int err; +#endif for (i = 2; i < pI810->FbMapSize; i <<= 1) ; if (!I810MapMMIO(pScrn)) return FALSE; +#if XSERVER_LIBPCIACCESS + err = pci_device_map_region (device, pI810->fb_bar, TRUE); + if (err) + { + xf86DrvMsg (pScrn->scrnIndex, X_ERROR, + "Unable to map frame buffer BAR. %s (%d)\n", + strerror (err), err); + return FALSE; + } + pI810->FbBase = device->regions[pI810->fb_bar].memory; + pI810->FbMapSize = device->regions[pI810->fb_bar].size; +#else pI810->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, pI810->PciTag, pI810->LinearAddr, i); if (!pI810->FbBase) return FALSE; +#endif pI810->LpRing->virtual_start = pI810->FbBase + pI810->LpRing->mem.Start; @@ -1246,8 +1472,12 @@ I810UnmapMMIO(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); +#if XSERVER_LIBPCIACCESS + pci_device_unmap_region (pI810->PciInfo, pI810->mmio_bar); +#else xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI810->MMIOBase, I810_REG_SIZE); +#endif pI810->MMIOBase = NULL; } @@ -1256,8 +1486,12 @@ I810UnmapMem(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); +#if XSERVER_LIBPCIACCESS + pci_device_unmap_region (pI810->PciInfo, pI810->fb_bar); +#else xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI810->FbBase, pI810->FbMapSize); +#endif pI810->FbBase = NULL; I810UnmapMMIO(pScrn); return TRUE; |