diff --git a/src/mga.h b/src/mga.h
index 77406f1..25dcf53 100644
--- a/src/mga.h
+++ b/src/mga.h
@@ -46,6 +46,10 @@
 #include "mga_dri.h"
 #endif
 
+#ifdef __sparc__
+#include <sys/visual_io.h>
+#endif
+
 typedef enum {
     OPTION_SW_CURSOR,
     OPTION_HW_CURSOR,
@@ -200,6 +204,28 @@ void MGAdbg_outreg32(ScrnInfoPtr, int,int, char*);
 #define MGA_MODULE_DATA mgaModuleData
 #define MGA_DRIVER_NAME "mga"
 
+#ifdef __sparc__
+#ifndef VIS_GETPCICONFIG
+
+/*
+ * These definitions will be removed when they are included in the
+ * visual_io.h
+ */
+#define VIS_GETVIDEOMODENAME		(VIOC | 12)
+#define VIS_STOREVIDEOMODENAME		(VIOC | 13)
+#define VIS_MAX_VMODE_LEN		48
+
+typedef struct	vis_video_mode {
+	char		mode_name[VIS_MAX_VMODE_LEN];
+	uint32_t	vRefresh;
+	char		pad[96];
+} vis_video_mode_t;
+
+
+#define VIS_GETPCICONFIG		(VIOC | 14)
+#endif
+#endif
+
 typedef struct {
     unsigned char	ExtVga[6];
     unsigned char 	DacClk[6];
@@ -667,6 +693,9 @@ typedef struct {
                                        if in merged mode */
 /* End of Merged Framebuffer Data */
   int			HALGranularityOffX, HALGranularityOffY;
+#ifdef __sparc__
+    int			fd;
+#endif
 } MGARec, *MGAPtr;
 
 extern CARD32 MGAAtype[16];
diff --git a/src/mga_dacG.c b/src/mga_dacG.c
index b489dea..e549f6c 100644
--- a/src/mga_dacG.c
+++ b/src/mga_dacG.c
@@ -1711,11 +1711,35 @@ MGAGLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
     MGAPtr pMga = MGAPTR(pScrn);
     CARD32 *dst = (CARD32*)(pMga->FbBase + pMga->FbCursorOffset);
     int i = 128;
-    
-    /* swap bytes in each line */
+#ifdef X_BYTE_ORDER != X_LITTLE_ENDIAN
+    MGAFBLayout *pLayout = &pMga->CurrentLayout;
+#endif
+
+    /* 
+     * HW cursor expects image that is both bytes and words swapped
+     * see DAC Registers section of the manual 
+     */
     while( i-- ) {
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+    	/* swap bytes in each line, byte swap happens during explict byte shift */
         *dst++ = (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7];
         *dst++ = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
+#else
+	if (pLayout->depth == 8) {
+	    /* byte swap happens during assembly of word, no explict byte shift */
+            *dst++ = (src[7] << 24) | (src[6] << 16) | (src[5] << 8) | src[4];
+            *dst++ = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
+	} else if (pLayout->depth == 16) {
+	    /* byte swap happens during assembly of word, partial byte shift to
+	       offset effects from HW cursor's double bytes reading */
+	    *dst++ = (src[6] << 24) | (src[7] << 16) | (src[4] << 8) | src[5];
+	    *dst++ = (src[2] << 24) | (src[3] << 16) | (src[0] << 8) | src[1];
+	} else {
+	    /* depth = 32. no byte swap needed, HW cursor's word reading does swap */
+	    *dst++ = ((CARD32 *)src)[1];
+	    *dst++ = ((CARD32 *)src)[0];
+	}
+#endif
         src += 8;
     }
 }
diff --git a/src/mga_driver.c b/src/mga_driver.c
index af005f1..ae4a005 100644
--- a/src/mga_driver.c
+++ b/src/mga_driver.c
@@ -107,6 +107,11 @@
 
 #include <unistd.h>
 
+#ifdef __sparc__
+#include <stdio.h>
+#include <fcntl.h>
+#endif
+
 /*
  * Forward definitions for the functions that make up the driver.
  */
@@ -156,6 +161,10 @@ static Bool	MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
 static void 	MGABlockHandler(int, pointer, pointer, pointer);
 static void	MGAG100BlackMagic(ScrnInfoPtr pScrn);
 
+#ifdef __sparc__
+static void MGANotifyModeChanged(ScrnInfoPtr pScrn);
+#endif
+
 static int MGAEntityIndex = -1;
 
 #include "mga_merge.h"
@@ -455,6 +464,15 @@ static const struct pci_id_match mga_device_match[] = {
 
     { 0, 0, 0 },
 };
+
+#ifdef __sparc__
+/* mimic pci_device_private struct so that define of DEV_PATH becomes valid */
+static struct mga_device_private {
+    struct pci_device  base;
+    const char * device_string;
+};
+#define DEV_PATH(dev)    (((struct mga_device_private *) (dev))->device_string)
+#endif
 #endif
 
 /* Supported chipsets */
@@ -1296,9 +1314,11 @@ MGAdoDDC(ScrnInfoPtr pScrn)
 
     /* Map the VGA memory when the primary video */
     if (pMga->Primary) {
+#if !defined(__sparc__)
 	hwp->MapSize = 0x10000;
 	if (!vgaHWMapMem(pScrn))
 	    return NULL;
+#endif
     } else {
 	/* XXX Need to write an MGA mode ddc1SetSpeed */
 	if (pMga->DDC1SetSpeed == vgaHWddc1SetSpeedWeak()) {
@@ -1341,6 +1361,7 @@ MGAdoDDC(ScrnInfoPtr pScrn)
 					  pMga->ddc1Read ) ;
 		from = "DDC1";
 	    }
+#if !defined(__sparc__)
 	if (!MonInfo){
 	    vbeInfoPtr pVbe;
 	    if (xf86LoadSubModule(pScrn, "vbe")) {
@@ -1350,6 +1371,7 @@ MGAdoDDC(ScrnInfoPtr pScrn)
 		from = "VBE";
 	    }
 	}
+#endif
     }
 
     if (MonInfo) {
@@ -1571,6 +1593,20 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
     pMga->PciInfo = xf86GetPciInfoForEntity(pMga->pEnt->index);
     pMga->PciTag = pciTag(pMga->PciInfo->bus, pMga->PciInfo->device,
 			  pMga->PciInfo->func);
+#else
+#ifdef __sparc__
+    {
+	char        dev[128];
+	if (DEV_PATH(pMga->PciInfo))
+	    snprintf(dev, sizeof (dev), "%s%s", "/devices",
+		DEV_PATH(pMga->PciInfo));
+	else
+	    strcpy (dev, "/dev/fb0");
+
+	if ((pMga->fd = open(dev, O_RDWR)) < 0)
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot open device %s\n", dev);
+    }
+#endif
 #endif
 
     pMga->Primary = xf86IsPrimaryPci(pMga->PciInfo);
@@ -1922,7 +1958,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling KVM\n");
     }
     
-#if !defined(__powerpc__)
+#if (!defined(__powerpc__) && !defined(__sparc__))
     pMga->softbooted = FALSE;
     Default = (pMga->chip_attribs->dual_head_possible
 	       && !pMga->Primary && !pMga->SecondCrtc);
@@ -2838,7 +2874,11 @@ MGASave(ScrnInfoPtr pScrn)
     /* Could call it dac2Saved */
 
     /* Only save text mode fonts/text for the primary card */
+#ifdef __sparc__
+    (*pMga->Save)(pScrn, vgaReg, mgaReg, FALSE);
+#else
     (*pMga->Save)(pScrn, vgaReg, mgaReg, pMga->Primary);
+#endif
 }
 
 /*
@@ -2996,6 +3036,10 @@ MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
 #ifdef DEBUG
    MGAG450PrintPLL(pScrn);
 #endif
+
+#ifdef __sparc__
+    MGANotifyModeChanged(pScrn);
+#endif
     return TRUE;
 }
 
@@ -3085,7 +3129,11 @@ MGARestore(ScrnInfoPtr pScrn)
 	vgaHWProtect(pScrn, TRUE);
     }
     if (pMga->Primary) {
+#ifdef __sparc__
+        (*pMga->Restore)(pScrn, vgaReg, mgaReg, FALSE);
+#else
         (*pMga->Restore)(pScrn, vgaReg, mgaReg, TRUE);
+#endif
     } else {
         vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
     }
@@ -3215,9 +3263,11 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     /* Map the VGA memory when the primary video */
     if (!pMga->FBDev) {
 	if (pMga->Primary) {
+#if !defined(__sparc__)
 	    hwp->MapSize = 0x10000;
 	    if (!vgaHWMapMem(pScrn))
 		return FALSE;
+#endif
 	}
 
 	/* Save the current state */
@@ -3473,6 +3523,10 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 
     MGAInitVideo(pScreen);
 
+#ifdef __sparc__
+    MGANotifyModeChanged(pScrn);
+#endif
+
 #ifdef MGADRI
     if (pMga->directRenderingEnabled) {
        /* Now that mi, drm and others have done their thing,
@@ -3792,6 +3846,13 @@ MGACloseScreen(int scrnIndex, ScreenPtr pScreen)
     free(pMga->portPrivate);
     free(pMga->ScratchBuffer);
 
+#ifdef __sparc__
+    MGANotifyModeChanged(pScrn);
+
+    if (pMga->fd)
+	close(pMga->fd);
+#endif
+
     pScrn->vtSema = FALSE;
 
     xf86ClearPrimInitDone(pScrn->entityList[0]);
diff --git a/src/mga_storm.c b/src/mga_storm.c
index 96bb6b9..57fdba5 100644
--- a/src/mga_storm.c
+++ b/src/mga_storm.c
@@ -97,6 +97,7 @@
 static void mgaSubsequentSolidTwoPointLine( ScrnInfoPtr pScrn,	int x1, int y1,
     int x2, int y2, int flags );
 
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
 static void mgaSetupForMono8x8PatternFill( ScrnInfoPtr pScrn, 
     int patx, int paty, int fg, int bg, int rop, unsigned int planemask );
 
@@ -109,6 +110,7 @@
 static void mgaSubsequentMono8x8PatternFillTrap( ScrnInfoPtr pScrn,
     int patx, int paty, int y, int h, int left, int dxL, int dyL, int eL,
     int right, int dxR, int dyR, int eR );
+#endif
 
 static void mgaSetupForScanlineImageWrite( ScrnInfoPtr pScrn, int rop,
     unsigned int planemask, int transparency_color, int bpp, int depth );
@@ -148,10 +150,12 @@
 static void MGAFillSolidSpansDMA(ScrnInfoPtr pScrn, int fg, int rop,
 				unsigned int planemask, int n, DDXPointPtr ppt,
  				int *pwidth, int fSorted);
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
 static void MGAFillMono8x8PatternRectsTwoPass(ScrnInfoPtr pScrn, int fg, int bg,
  				int rop, unsigned int planemask, int nBox,
  				BoxPtr pBox, int pattern0, int pattern1,
 				int xorigin, int yorigin);
+#endif
 static void MGAValidatePolyArc(GCPtr, unsigned long, DrawablePtr);
 static void MGAValidatePolyPoint(GCPtr, unsigned long, DrawablePtr);
 static void MGAFillCacheBltRects(ScrnInfoPtr, int, unsigned int, int, BoxPtr,
@@ -623,7 +627,9 @@
     /* fill out infoPtr here */
     infoPtr->Flags = 	PIXMAP_CACHE |
 			OFFSCREEN_PIXMAPS |
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
 			LINEAR_FRAMEBUFFER |
+#endif
 			MICROSOFT_ZERO_LINE_BIAS;
 
     /* sync */
@@ -652,18 +658,20 @@
     /* clipping */
     infoPtr->SetClippingRectangle = MGASetClippingRectangle;
     infoPtr->DisableClipping = MGADisableClipping;
+#if X_BYTE_ORDER == X_BIG_ENDIAN
     infoPtr->ClippingFlags = 	HARDWARE_CLIP_SOLID_LINE  |
+				HARDWARE_CLIP_SOLID_FILL;
+#else
+    infoPtr->ClippingFlags = 	HARDWARE_CLIP_SOLID_LINE  |
 				HARDWARE_CLIP_DASHED_LINE |
 				HARDWARE_CLIP_SOLID_FILL  |
 				HARDWARE_CLIP_MONO_8x8_FILL;
 
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
     /* dashed lines */
     infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED;
     infoPtr->SetupForDashedLine = mgaSetupForDashedLine;
     infoPtr->SubsequentDashedTwoPointLine = mgaSubsequentDashedTwoPointLine;
     infoPtr->DashPatternMaxLength = 128;
-#endif
 
     /* 8x8 mono patterns */
     infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_BITS |
@@ -675,6 +683,7 @@
 		mgaSubsequentMono8x8PatternFillRect;
     infoPtr->SubsequentMono8x8PatternFillTrap =
 		mgaSubsequentMono8x8PatternFillTrap;
+#endif
 
     /* cpu to screen color expansion */
     infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
@@ -748,11 +757,13 @@
 	infoPtr->FillSolidSpans = MGAFillSolidSpansDMA;
     }
 
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
     if(pMga->AccelFlags & TWO_PASS_COLOR_EXPAND) {
 	if(infoPtr->SetupForMono8x8PatternFill)
 	    infoPtr->FillMono8x8PatternRects =
 				MGAFillMono8x8PatternRectsTwoPass;
     }
+#endif
 
     if(infoPtr->SetupForSolidFill) {
 	infoPtr->ValidatePolyArc = MGAValidatePolyArc;
@@ -769,12 +780,14 @@
 	infoPtr->SolidLineFlags |= NO_PLANEMASK;
 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
 	infoPtr->DashedLineFlags |= NO_PLANEMASK;
-#endif
 	infoPtr->Mono8x8PatternFillFlags |= NO_PLANEMASK;
+#endif
 	infoPtr->ScreenToScreenColorExpandFillFlags |= NO_PLANEMASK;
 	infoPtr->FillSolidRectsFlags |= NO_PLANEMASK;
 	infoPtr->FillSolidSpansFlags |= NO_PLANEMASK;
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
 	infoPtr->FillMono8x8PatternRectsFlags |= NO_PLANEMASK;
+#endif
 	infoPtr->FillCacheBltRectsFlags |= NO_PLANEMASK;
     }
 
@@ -989,7 +1002,12 @@
 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
    OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT );
 #else
-   OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT | 0x10000);
+   if (pLayout->depth == 8)
+	OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT);
+   else if (pLayout->depth == 16)
+	OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT | 0x10000);
+   else
+	OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT | 0x20000);
 #endif
    OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */
    OUTREG(MGAREG_YTOP, 0x00000000);    /* minPixelPointer */
@@ -1077,9 +1095,9 @@
         maccess |= (1 << 31);
     }
 
-    opmode |= opmode_table[ pLayout->bitsPerPixel / 8 ];
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
     opmode &= ~0x30000;
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+    opmode |= opmode_table[ pLayout->bitsPerPixel / 8 ];
 #endif
 
     pMga->SetupForSolidFill = mgaSetupForSolidFill;
@@ -1601,6 +1619,7 @@
     OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD);
 }
 
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
 
 	/***************************\
 	|   8x8 Mono Pattern Fills  |
@@ -1689,6 +1708,7 @@
     OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
     OUTREG(MGAREG_DWGCTL, pMga->PatternRectCMD);
 }
+#endif /* X_BYTE_ORDER == X_LITTLE_ENDIAN */
 
 	/***********************\
 	|   Color Expand Rect   |
@@ -2280,6 +2300,8 @@
 }
 
 
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+
 static void
 MGAFillMono8x8PatternRectsTwoPass(
     ScrnInfoPtr pScrn,
@@ -2331,6 +2353,7 @@
 
     SET_SYNC_FLAG(infoRec);
 }
+#endif /* X_BYTE_ORDER == X_LITTLE_ENDIAN */
 
 
 static void
--- a/src/mga_driver.c	Thu Oct 18 14:08:08 2012
+++ b/src/mga_driver.c	Thu Oct 18 14:11:07 2012
@@ -2890,6 +2890,25 @@
 #endif
 }
 
+#ifdef __sparc__
+static void
+MGANotifyModeChanged(ScrnInfoPtr pScrn)
+{
+    struct vis_video_mode mode;
+    MGAPtr pMga = MGAPTR(pScrn);
+
+    if (pScrn->currentMode->name != NULL) {
+      strlcpy(mode.mode_name, pScrn->currentMode->name, VIS_MAX_VMODE_LEN);
+    } else {
+      strlcpy(mode.mode_name, " ", VIS_MAX_VMODE_LEN);
+    }
+    mode.vRefresh = pScrn->currentMode->VRefresh;
+
+    ioctl(pMga->fd, VIS_STOREVIDEOMODENAME, &mode);
+
+}
+#endif
+
 /*
  * Initialise a new mode.  This is currently still using the old
  * "initialise struct, restore/write struct to HW" model.  That could
