summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/i810_driver.c244
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;