[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