[PATCH video-siliconmotion] Added detection of SM501 on PPC LocalBus.
Marc Scherer
marc.scherer at mp-ndt.de
Tue Sep 14 03:49:08 PDT 2010
Bit-fields are reversed on big-endian PPC :(
Therefore, changed STATUS bit-field operations to bit-masks.
TODO: change all remaining bit fields to bit-masks.
Signed-off-by: Marc Scherer <marc.scherer at mp-ndt.de>
---
src/regsmi.h | 13 ++----
src/smi.h | 7 +++
src/smi_501.c | 10 ++--
src/smi_501.h | 26 +++---------
src/smi_driver.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++-------
5 files changed, 122 insertions(+), 48 deletions(-)
diff --git a/src/regsmi.h b/src/regsmi.h
index 5dd0320..6481850 100644
--- a/src/regsmi.h
+++ b/src/regsmi.h
@@ -217,7 +217,7 @@ VGAOUT8(SMIPtr pSmi, int port, CARD8 data)
\
mem_barrier(); \
if (IS_MSOC(pSmi)) { \
- MSOCCmdStatusRec status; \
+ int32_t status; \
\
/* bit 0: 2d engine idle if *not set*
* bit 1: 2d fifo empty if *set*
@@ -226,14 +226,9 @@ VGAOUT8(SMIPtr pSmi, int port, CARD8 data)
* bit 19: command fifo empty if *set*
* bit 20: 2d memory fifo empty idle if *set*
*/ \
- for (status.value = READ_SCR(pSmi, CMD_STATUS); \
- loop && (status.f.engine || \
- !status.f.cmdfifo || \
- status.f.setup || \
- status.f.csc || \
- !status.f.cmdhif || \
- !status.f.memfifo); \
- status.value = READ_SCR(pSmi, CMD_STATUS), loop--) \
+ for (status = READ_SCR(pSmi, CMD_STATUS); \
+ loop && (status & STATUS_IDLE_MASK) != STATUS_IDLE_VALUE; \
+ status = READ_SCR(pSmi, CMD_STATUS), loop--) \
; \
} \
else { \
diff --git a/src/smi.h b/src/smi.h
index 0f72db9..ba03033 100644
--- a/src/smi.h
+++ b/src/smi.h
@@ -278,6 +278,13 @@ typedef struct
#define SMIPTR(p) ((SMIPtr)((p)->driverPrivate))
/******************************************************************************/
+/* G L O B A L S */
+/******************************************************************************/
+
+/* for PowerPC LocalBus */
+extern Bool ppcLocalBus;
+
+/******************************************************************************/
/* M A C R O S */
/******************************************************************************/
diff --git a/src/smi_501.c b/src/smi_501.c
index a605e0d..33618d3 100644
--- a/src/smi_501.c
+++ b/src/smi_501.c
@@ -610,7 +610,7 @@ SMI501_PrintRegs(ScrnInfoPtr pScrn)
void
SMI501_WaitVSync(SMIPtr pSmi, int vsync_count)
{
- MSOCCmdStatusRec status;
+ int32_t status;
int32_t timeout;
while (vsync_count-- > 0) {
@@ -618,18 +618,18 @@ SMI501_WaitVSync(SMIPtr pSmi, int vsync_count)
timeout = 0;
do {
/* bit 11: vsync active *if set* */
- status.value = READ_SCR(pSmi, CMD_STATUS);
+ status = READ_SCR(pSmi, CMD_STATUS);
if (++timeout == 10000)
break;
- } while (status.f.pvsync);
+ } while (status & STATUS_PVSYNC_MASK);
/* Wait for start of vsync */
timeout = 0;
do {
- status.value = READ_SCR(pSmi, CMD_STATUS);
+ status = READ_SCR(pSmi, CMD_STATUS);
if (++timeout == 10000)
break;
- } while (!status.f.pvsync);
+ } while (!(status & STATUS_PVSYNC_MASK));
}
}
diff --git a/src/smi_501.h b/src/smi_501.h
index 10bcf6c..4995493 100644
--- a/src/smi_501.h
+++ b/src/smi_501.h
@@ -40,6 +40,9 @@ authorization from the XFree86 Project and Silicon Motion.
#define bits(lo, hi) hi + 1 - lo
+#define SMI501_ENDIAN_CTL 0x5C
+#define SMI501_BIG_ENDIAN 0xFFFFFFFF
+#define SMI501_LITTLE_ENDIAN 0x0
#define DRAM_CTL 0x000010
@@ -78,6 +81,9 @@ typedef union _MSOCCmdAddrRec {
#define CMD_RETADDR 0x000020
#define CMD_STATUS 0x000024
+#define STATUS_IDLE_MASK 0x1C0007
+#define STATUS_IDLE_VALUE 0x180002
+#define STATUS_PVSYNC_MASK 0x000800
/* COMMAND LIST STATUS
* Read/Write MMIO_base + 0x000024
* Power-on Default 0b0000.0000.000X.XXXX.XXXX.X000.0000.0XXX
@@ -124,26 +130,6 @@ typedef union _MSOCCmdAddrRec {
* 1: Empty.
* 21:31 Reserved
*/
-typedef union _MSOCCmdStatusRec {
- struct {
- int32_t engine : bits( 0, 0);
- int32_t cmdfifo : bits( 1, 1);
- int32_t setup : bits( 2, 2);
- int32_t u0 : bits( 3, 10);
- int32_t pvsync : bits(11, 11);
- int32_t cvsync : bits(12, 12);
- int32_t player : bits(13, 13);
- int32_t vlayer : bits(14, 14);
- int32_t vfield : bits(15, 15);
- int32_t clayer : bits(16, 16);
- int32_t dma : bits(17, 17);
- int32_t csc : bits(18, 18);
- int32_t cmdhif : bits(19, 19);
- int32_t memfifo : bits(20, 20);
- int32_t u1 : bits(21, 31);
- } f;
- int32_t value;
-} MSOCCmdStatusRec, *MSOCCmdStatusPtr;
/* contents of either power0_clock or power1_clock */
#define CURRENT_CLOCK 0x00003c
diff --git a/src/smi_driver.c b/src/smi_driver.c
index 391efbc..c0d4ded 100644
--- a/src/smi_driver.c
+++ b/src/smi_driver.c
@@ -106,6 +106,10 @@ int smi_indent = 1;
/* for dualhead */
int gSMIEntityIndex = -1;
+/* for PowerPC LocalBus */
+/* tested only on TQM5200 Board with SM501 and MPC5200B */
+Bool ppcLocalBus = FALSE;
+
/*
* This contains the functions needed by the server after loading the
* driver module. It must be supplied, and gets added the driver list by
@@ -319,6 +323,7 @@ SMI_Probe(DriverPtr drv, int flags)
int numDevSections;
int numUsed;
Bool foundScreen = FALSE;
+ Bool pciError = FALSE;
ENTER();
@@ -330,21 +335,46 @@ SMI_Probe(DriverPtr drv, int flags)
#ifndef XSERVER_LIBPCIACCESS
if (xf86GetPciVideoInfo() == NULL)
- LEAVE(FALSE);
+ pciError = TRUE;
#endif
numUsed = xf86MatchPciInstances(SILICONMOTION_NAME, PCI_SMI_VENDOR_ID,
SMIChipsets, SMIPciChipsets, devSections,
numDevSections, drv, &usedChips);
- /* Free it since we don't need that list after this */
- xfree(devSections);
if (numUsed <= 0)
- LEAVE(FALSE);
+ pciError = TRUE;
if (flags & PROBE_DETECT)
foundScreen = TRUE;
- else {
+ else if (pciError) { /* ClaimNoSlot if there is no PCI device */
+ int entity;
+ ScrnInfoPtr pScrn;
+
+ xf86DrvMsg(0, X_WARNING, SILICONMOTION_NAME ": no PCI device found, try LocalBus\n");
+ numUsed = numDevSections;
+ for (i = 0; i < numUsed; i++) {
+ entity = xf86ClaimNoSlot(drv, 0, devSections[i], TRUE);
+ if((pScrn = xf86AllocateScreen(drv, 0)))
+ xf86AddEntityToScreen(pScrn, entity);
+
+ pScrn->driverVersion = SILICONMOTION_DRIVER_VERSION;
+ pScrn->driverName = SILICONMOTION_DRIVER_NAME;
+ pScrn->name = SILICONMOTION_NAME;
+ pScrn->Probe = SMI_Probe;
+ pScrn->PreInit = SMI_PreInit;
+ pScrn->ScreenInit = SMI_ScreenInit;
+ pScrn->SwitchMode = SMI_SwitchMode;
+ pScrn->AdjustFrame = SMI_AdjustFrame;
+ pScrn->EnterVT = SMI_EnterVT;
+ pScrn->LeaveVT = SMI_LeaveVT;
+ pScrn->FreeScreen = SMI_FreeScreen;
+
+ foundScreen = TRUE;
+ ppcLocalBus = TRUE;
+ }
+ }
+ else { /* do PCI setup */
ScrnInfoPtr pScrn;
EntityInfoPtr pEnt;
@@ -371,6 +401,8 @@ SMI_Probe(DriverPtr drv, int flags)
}
}
}
+
+ xfree(devSections);
xfree(usedChips);
LEAVE(foundScreen);
@@ -400,9 +432,13 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags)
/* Find the PCI slot for this screen */
pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if(ppcLocalBus) {
+ pSmi->PciInfo = NULL;
+ pSmi->Chipset = PCI_CHIP_SMI501;
+ } else {
pSmi->PciInfo = xf86GetPciInfoForEntity(pEnt->index);
pSmi->Chipset = PCI_DEV_DEVICE_ID(pSmi->PciInfo);
-
+ }
if (IS_MSOC(pSmi)) {
pSmi->Save = SMI501_Save;
pSmi->save = xnfcalloc(sizeof(MSOCRegRec), 1);
@@ -420,13 +456,14 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags)
LEAVE(TRUE);
}
+ if(!ppcLocalBus) {
if (pEnt->location.type != BUS_PCI) {
xfree(pEnt);
SMI_FreeRec(pScrn);
LEAVE(FALSE);
}
pSmi->PciInfo = xf86GetPciInfoForEntity(pEnt->index);
-
+ }
/* Set pScrn->monitor */
pScrn->monitor = pScrn->confScreen->monitor;
@@ -651,6 +688,9 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags)
}
else {
from = X_PROBED;
+ if(ppcLocalBus)
+ pSmi->Chipset = SMI_MSOC;
+ else
pSmi->Chipset = PCI_DEV_DEVICE_ID(pSmi->PciInfo);
pScrn->chipset = (char *) xf86TokenToString(SMIChipsets, pSmi->Chipset);
}
@@ -660,6 +700,8 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
pSmi->ChipRev);
}
+ else if(ppcLocalBus)
+ pSmi->ChipRev = 0xA0;
else
pSmi->ChipRev = PCI_DEV_REVISION(pSmi->PciInfo);
xfree(pEnt);
@@ -683,6 +725,9 @@ SMI_PreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
#ifndef XSERVER_LIBPCIACCESS
+ if(ppcLocalBus)
+ pSmi->PciTag = NULL;
+ else
pSmi->PciTag = pciTag(pSmi->PciInfo->bus, pSmi->PciInfo->device,
pSmi->PciInfo->func);
#endif
@@ -1219,6 +1264,12 @@ SMI_MapMmio(ScrnInfoPtr pScrn)
SMI_EnableMmio(pScrn);
+ if(ppcLocalBus) {
+ memBase = 0xE3E00000; /* fixed MMIO-Base on TQM5200 */
+ pSmi->MapSize = 0x200000; /* in Bytes */
+ pSmi->MapBase = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, memBase, pSmi->MapSize);
+ }
+ else {
switch (pSmi->Chipset) {
case SMI_COUGAR3DR:
memBase = PCI_REGION_BASE(pSmi->PciInfo, 1, REGION_MEM);
@@ -1263,6 +1314,7 @@ SMI_MapMmio(ScrnInfoPtr pScrn)
return (FALSE);
}
#endif
+ }
if (pSmi->MapBase == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Internal error: could not map "
@@ -1306,13 +1358,13 @@ SMI_MapMmio(ScrnInfoPtr pScrn)
pSmi->DataPortSize = 0x100000;
break;
case SMI_MSOC:
- pSmi->DPRBase = pSmi->MapBase + 0x100000;
- pSmi->VPRBase = pSmi->MapBase + 0x000000;
- pSmi->CPRBase = pSmi->MapBase + 0x090000;
- pSmi->DCRBase = pSmi->MapBase + 0x080000;
- pSmi->SCRBase = pSmi->MapBase + 0x000000;
+ pSmi->DPRBase = pSmi->MapBase + 0x100000; /* 2D drawing engine */
+ pSmi->VPRBase = pSmi->MapBase + 0x000000; /* ??? */
+ pSmi->CPRBase = pSmi->MapBase + 0x090000; /* ZV port */
+ pSmi->DCRBase = pSmi->MapBase + 0x080000; /* Display controller */
+ pSmi->SCRBase = pSmi->MapBase + 0x000000; /* System config */
pSmi->IOBase = 0;
- pSmi->DataPortBase = pSmi->MapBase + 0x110000;
+ pSmi->DataPortBase = pSmi->MapBase + 0x110000; /* 2D drawing engine data port */
pSmi->DataPortSize = 0x10000;
break;
default:
@@ -1337,6 +1389,22 @@ SMI_MapMmio(ScrnInfoPtr pScrn)
"DataPort=%p - %p\n", pSmi->DataPortBase,
pSmi->DataPortBase + pSmi->DataPortSize - 1);
+ if(ppcLocalBus) {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ WRITE_SCR(pSmi, SMI501_ENDIAN_CTL, SMI501_BIG_ENDIAN);
+#else
+ WRITE_SCR(pSmi, SMI501_ENDIAN_CTL, SMI501_LITTLE_ENDIAN);
+#endif
+ /* TODO: make this test more general */
+ if(READ_SCR(pSmi, DEVICE_ID) != 0x050100A0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No SM501 found on PPC LocalBus\n");
+ return (FALSE);
+ }
+ else
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV,
+ "Found Device_ID = %08X\n", READ_SCR(pSmi, DEVICE_ID));
+ }
+
return (TRUE);
}
@@ -1456,6 +1524,9 @@ SMI_MapMem(ScrnInfoPtr pScrn)
if (pSmi->MapBase == NULL && SMI_MapMmio(pScrn) == FALSE)
LEAVE(FALSE);
+ if(ppcLocalBus)
+ pScrn->memPhysBase = 0xE0000000; /* fixed FB-Base on TQM5200 */
+ else
pScrn->memPhysBase = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM);
if (pSmi->Chipset == SMI_LYNX3DM)
@@ -1463,6 +1534,9 @@ SMI_MapMem(ScrnInfoPtr pScrn)
else
pSmi->fbMapOffset = 0x0;
+ if(ppcLocalBus)
+ pSmi->FBBase = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, pScrn->memPhysBase, pSmi->videoRAMBytes);
+ else {
#ifndef XSERVER_LIBPCIACCESS
pSmi->FBBase = xf86MapPciMem(pScrn->scrnIndex,
VIDMEM_FRAMEBUFFER,
@@ -1484,6 +1558,7 @@ SMI_MapMem(ScrnInfoPtr pScrn)
LEAVE(FALSE);
}
#endif
+ }
if (pSmi->FBBase == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -1585,6 +1660,17 @@ SMI_UnmapMem(ScrnInfoPtr pScrn)
SMI_DisableMmio(pScrn);
+ if(ppcLocalBus) {
+ if (pSmi->MapBase) {
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSmi->MapBase, pSmi->MapSize);
+ pSmi->MapBase = NULL;
+ }
+ if (pSmi->FBBase) {
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSmi->FBBase, pSmi->videoRAMBytes);
+ pSmi->FBBase = NULL;
+ }
+ }
+ else {
if (pSmi->MapBase) {
#ifndef XSERVER_LIBPCIACCESS
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSmi->MapBase,
@@ -1606,7 +1692,7 @@ SMI_UnmapMem(ScrnInfoPtr pScrn)
#endif
pSmi->FBBase = NULL;
}
-
+ }
LEAVE();
}
--
1.7.0.4
--------------050004090505010409070805--
More information about the xorg-devel
mailing list