diff options
-rw-r--r-- | configure.ac | 12 | ||||
-rw-r--r-- | src/smi.h | 4 | ||||
-rw-r--r-- | src/smi_driver.c | 50 | ||||
-rw-r--r-- | src/smi_pcirename.h | 122 |
4 files changed, 179 insertions, 9 deletions
diff --git a/configure.ac b/configure.ac index a5fde7a..ad1ba4c 100644 --- a/configure.ac +++ b/configure.ac @@ -58,10 +58,22 @@ PKG_CHECK_MODULES(XORG, [xorg-server >= 1.0.99.901 xproto fontsproto $REQUIRED_M sdkdir=$(pkg-config --variable=sdkdir xorg-server) # Checks for libraries. +SAVE_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $XORG_CFLAGS" +AC_CHECK_DECL(XSERVER_LIBPCIACCESS, + [XSERVER_LIBPCIACCESS=yes],[XSERVER_LIBPCIACCESS=no], + [#include "xorg-server.h"]) +CPPFLAGS="$SAVE_CPPFLAGS" # Checks for header files. AC_HEADER_STDC +if test "x$XSERVER_LIBPCIACCESS" = xyes; then + PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.8.0]) + XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS" +fi +AM_CONDITIONAL(XSERVER_LIBPCIACCESS, test "x$XSERVER_LIBPCIACCESS" = xyes) + AC_SUBST([XORG_CFLAGS]) AC_SUBST([moduledir]) @@ -31,6 +31,8 @@ authorization from the XFree86 Project and Silicon Motion. #ifndef _SMI_H #define _SMI_H +#include "smi_pcirename.h" + #include <string.h> #include <stdio.h> @@ -187,7 +189,9 @@ typedef struct Bool useEXA; /* enable exa acceleration */ pciVideoPtr PciInfo; /* PCI info vars */ +#ifndef XSERVER_LIBPCIACCESS PCITAG PciTag; +#endif int Chipset; /* Chip info, set using PCI above */ int ChipRev; diff --git a/src/smi_driver.c b/src/smi_driver.c index 118228f..11a3ef4 100644 --- a/src/smi_driver.c +++ b/src/smi_driver.c @@ -447,10 +447,12 @@ SMI_Probe(DriverPtr drv, int flags) return FALSE; } +#ifndef XSERVER_LIBPCIACCESS if (xf86GetPciVideoInfo() == NULL) { LEAVE_PROC("SMI_Probe"); return FALSE; } +#endif numUsed = xf86MatchPciInstances(SILICONMOTION_NAME, PCI_SMI_VENDOR_ID, SMIChipsets, SMIPciChipsets, devSections, @@ -821,7 +823,7 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) pSmi->Chipset); } else { from = X_PROBED; - pSmi->Chipset = pSmi->PciInfo->chipType; + pSmi->Chipset = PCI_DEV_DEVICE_ID(pSmi->PciInfo); pScrn->chipset = (char *) xf86TokenToString(SMIChipsets, pSmi->Chipset); } @@ -830,7 +832,7 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", pSmi->ChipRev); } else { - pSmi->ChipRev = pSmi->PciInfo->chipRev; + pSmi->ChipRev = PCI_DEV_REVISION(pSmi->PciInfo); } xfree(pEnt); @@ -854,8 +856,10 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); +#ifndef XSERVER_LIBPCIACCESS pSmi->PciTag = pciTag(pSmi->PciInfo->bus, pSmi->PciInfo->device, pSmi->PciInfo->func); +#endif pSmi->Dualhead = FALSE; if (xf86ReturnOptValBool(pSmi->Options, OPTION_DUALHEAD, FALSE) && @@ -1785,30 +1789,43 @@ SMI_MapMem(ScrnInfoPtr pScrn) /* Map the Lynx register space */ switch (pSmi->Chipset) { default: - memBase = pSmi->PciInfo->memBase[0] + 0x400000; + memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + 0x400000; pSmi->MapSize = 0x10000; break; case SMI_COUGAR3DR: - memBase = pSmi->PciInfo->memBase[1]; + memBase = PCI_REGION_BASE(pSmi->PciInfo, 1, REGION_MEM); pSmi->MapSize = 0x200000; break; case SMI_LYNX3D: - memBase = pSmi->PciInfo->memBase[0] + 0x680000; + memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + 0x680000; pSmi->MapSize = 0x180000; break; case SMI_LYNXEM: case SMI_LYNXEMplus: - memBase = pSmi->PciInfo->memBase[0] + 0x400000; + memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + 0x400000; pSmi->MapSize = 0x400000; break; case SMI_LYNX3DM: - memBase = pSmi->PciInfo->memBase[0]; + memBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM); pSmi->MapSize = 0x200000; break; } +#ifndef XSERVER_LIBPCIACCESS pSmi->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pSmi->PciTag, memBase, pSmi->MapSize); - +#else + { + void** result = (void**)&pSmi->MapBase; + int err = pci_device_map_range(pSmi->PciInfo, + memBase, + pSmi->MapSize, + PCI_DEV_MAP_FLAG_WRITABLE, + result); + + if (err) + return FALSE; + } +#endif if (pSmi->MapBase == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Internal error: could not map " "MMIO registers.\n"); @@ -1872,7 +1889,7 @@ SMI_MapMem(ScrnInfoPtr pScrn) "DataPort=%p - %p\n", pSmi->DataPortBase, pSmi->DataPortBase + pSmi->DataPortSize - 1); - pScrn->memPhysBase = pSmi->PciInfo->memBase[0]; + pScrn->memPhysBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM); SMI_EnableMmio(pScrn); @@ -1887,11 +1904,26 @@ SMI_MapMem(ScrnInfoPtr pScrn) pScrn->fbOffset = pSmi->FBOffset + pSmi->fbMapOffset; +#ifndef XSERVER_LIBPCIACCESS pSmi->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, pSmi->PciTag, pScrn->memPhysBase + pSmi->fbMapOffset, pSmi->videoRAMBytes); +#else + { + void** result = (void**)&pSmi->FBBase; + int err = pci_device_map_range(pSmi->PciInfo, + pScrn->memPhysBase + pSmi->fbMapOffset, + pSmi->videoRAMBytes, + PCI_DEV_MAP_FLAG_WRITABLE | + PCI_DEV_MAP_FLAG_WRITE_COMBINE, + result); + + if (err) + return FALSE; + } +#endif if (pSmi->FBBase == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Internal error: could not " diff --git a/src/smi_pcirename.h b/src/smi_pcirename.h new file mode 100644 index 0000000..9321046 --- /dev/null +++ b/src/smi_pcirename.h @@ -0,0 +1,122 @@ +/* + * Copyright 2007 George Sapountzis + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * Macros for porting drivers from legacy xfree86 PCI code to the pciaccess + * library. The main purpose being to facilitate source code compatibility. + */ + +#ifndef S3PCIRENAME_H +#define S3PCIRENAME_H + +enum region_type { + REGION_MEM, + REGION_IO +}; + +#ifndef XSERVER_LIBPCIACCESS + +/* pciVideoPtr */ +#define PCI_DEV_VENDOR_ID(_pcidev) ((_pcidev)->vendor) +#define PCI_DEV_DEVICE_ID(_pcidev) ((_pcidev)->chipType) +#define PCI_DEV_REVISION(_pcidev) ((_pcidev)->chipRev) + +#define PCI_SUB_VENDOR_ID(_pcidev) ((_pcidev)->subsysVendor) +#define PCI_SUB_DEVICE_ID(_pcidev) ((_pcidev)->subsysCard) + +#define PCI_DEV_TAG(_pcidev) pciTag((_pcidev)->bus, \ + (_pcidev)->device, \ + (_pcidev)->func) +#define PCI_DEV_BUS(_pcidev) ((_pcidev)->bus) +#define PCI_DEV_DEV(_pcidev) ((_pcidev)->device) +#define PCI_DEV_FUNC(_pcidev) ((_pcidev)->func) + +/* pciConfigPtr */ +#define PCI_CFG_TAG(_pcidev) (((pciConfigPtr)(_pcidev)->thisCard)->tag) +#define PCI_CFG_BUS(_pcidev) (((pciConfigPtr)(_pcidev)->thisCard)->busnum) +#define PCI_CFG_DEV(_pcidev) (((pciConfigPtr)(_pcidev)->thisCard)->devnum) +#define PCI_CFG_FUNC(_pcidev) (((pciConfigPtr)(_pcidev)->thisCard)->funcnum) + +/* region addr: xfree86 uses different fields for memory regions and I/O ports */ +#define PCI_REGION_BASE(_pcidev, _b, _type) \ + (((_type) == REGION_MEM) ? (_pcidev)->memBase[(_b)] \ + : (_pcidev)->ioBase[(_b)]) + +/* region size: xfree86 uses the log2 of the region size, + * but with zero meaning no region, not size of one XXX */ +#define PCI_REGION_SIZE(_pcidev, _b) \ + (((_pcidev)->size[(_b)] > 0) ? (1 << (_pcidev)->size[(_b)]) : 0) + +/* read/write PCI configuration space */ +#define PCI_READ_BYTE(_pcidev, _value_ptr, _offset) \ + *(_value_ptr) = pciReadByte(PCI_CFG_TAG(_pcidev), (_offset)) + +#define PCI_READ_LONG(_pcidev, _value_ptr, _offset) \ + *(_value_ptr) = pciReadLong(PCI_CFG_TAG(_pcidev), (_offset)) + +#define PCI_WRITE_LONG(_pcidev, _value, _offset) \ + pciWriteLong(PCI_CFG_TAG(_pcidev), (_offset), (_value)) + +#else /* XSERVER_LIBPCIACCESS */ + +typedef struct pci_device *pciVideoPtr; + +#define PCI_DEV_VENDOR_ID(_pcidev) ((_pcidev)->vendor_id) +#define PCI_DEV_DEVICE_ID(_pcidev) ((_pcidev)->device_id) +#define PCI_DEV_REVISION(_pcidev) ((_pcidev)->revision) + +#define PCI_SUB_VENDOR_ID(_pcidev) ((_pcidev)->subvendor_id) +#define PCI_SUB_DEVICE_ID(_pcidev) ((_pcidev)->subdevice_id) + +/* pci-rework functions take a 'pci_device' parameter instead of a tag */ +#define PCI_DEV_TAG(_pcidev) (_pcidev) + +/* PCI_DEV macros, typically used in printf's, add domain ? XXX */ +#define PCI_DEV_BUS(_pcidev) ((_pcidev)->bus) +#define PCI_DEV_DEV(_pcidev) ((_pcidev)->dev) +#define PCI_DEV_FUNC(_pcidev) ((_pcidev)->func) + +/* pci-rework functions take a 'pci_device' parameter instead of a tag */ +#define PCI_CFG_TAG(_pcidev) (_pcidev) + +/* PCI_CFG macros, typically used in DRI init, contain the domain */ +#define PCI_CFG_BUS(_pcidev) (((_pcidev)->domain << 8) | \ + (_pcidev)->bus) +#define PCI_CFG_DEV(_pcidev) ((_pcidev)->dev) +#define PCI_CFG_FUNC(_pcidev) ((_pcidev)->func) + +#define PCI_REGION_BASE(_pcidev, _b, _type) ((_pcidev)->regions[(_b)].base_addr) +#define PCI_REGION_SIZE(_pcidev, _b) ((_pcidev)->regions[(_b)].size) + +#define PCI_READ_BYTE(_pcidev, _value_ptr, _offset) \ + pci_device_cfg_read_u8((_pcidev), (_value_ptr), (_offset)) + +#define PCI_READ_LONG(_pcidev, _value_ptr, _offset) \ + pci_device_cfg_read_u32((_pcidev), (_value_ptr), (_offset)) + +#define PCI_WRITE_LONG(_pcidev, _value, _offset) \ + pci_device_cfg_write_u32((_pcidev), (_value), (_offset)) + +#endif /* XSERVER_LIBPCIACCESS */ + +#endif /* CIRPCIRENAME_H */ |