i810_driver.c changes for libpciaccess.

This includes new probe code (intel_pci_probe) and changes for i810 to
use BAR indices to refer to suitable portions of the device mappings.
This commit is contained in:
Keith Packard 2007-08-26 23:06:57 -07:00
parent 2c79419205
commit 387fed6daa
1 changed files with 239 additions and 5 deletions

View File

@ -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;