--- a/src/ast.h	Wed Nov 12 11:57:06 2014
+++ b/src/ast.h	Wed Nov 12 11:59:37 2014
@@ -33,7 +33,12 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <sys/visual_io.h>
 
+#ifdef __sparc
+#define __sparc__ 1
+#endif
+
 #ifdef HAVE_XAA_H
 #include "xaa.h"
 #endif
@@ -305,10 +310,89 @@
     CreateScreenResourcesProcPtr CreateScreenResources;
 #endif
 
+#if defined(__sparc__)
+    char               *deviceName;
+    int                fd;
+#endif
+
 } ASTRec, *ASTRecPtr, *ASTPtr;
 
 #define ASTPTR(p) ((ASTRecPtr)((p)->driverPrivate))
 
+#if defined(__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)
+
+typedef struct  vis_pci_cfg {
+        uint16_t        VendorID;
+        uint16_t        DeviceID;
+        uint16_t        Command;
+        uint16_t        Status;
+        uint8_t         RevisionID;
+        uint8_t         ProgIF;
+        uint8_t         SubClass;
+        uint8_t         BaseClass;
+
+        uint8_t         CacheLineSize;
+        uint8_t         LatencyTimer;
+        uint8_t         HeaderType;
+        uint8_t         BIST;
+
+        uint32_t        bar[6];
+        uint32_t        CIS;
+        uint16_t        SubVendorID;
+        uint16_t        SubSystemID;
+        uint32_t        ROMBaseAddress;
+
+        uint8_t         CapabilitiesPtr;
+        uint8_t         Reserved_1[3];
+        uint32_t        Reserved_2;
+
+        uint8_t         InterruptLine;
+        uint8_t         InterruptPin;
+        uint8_t         MinimumGrant;
+        uint8_t         MaximumLatency;
+
+       uint8_t         pad[100];
+} vis_pci_cfg_t;
+
+
+#define VIS_SETIOREG                    (VIOC | 17)
+#define VIS_GETIOREG                    (VIOC | 18)
+
+typedef struct vis_io_reg {
+        uchar_t         offset;
+        uchar_t         value;
+} vis_io_reg_t;
+#endif
+
+extern struct pci_device *ASTGetPciInfo(ASTRecPtr);
+extern ScrnInfoPtr        ASTAllocScreen(DriverPtr, GDevPtr);
+extern pointer           ASTMapVidMem(ScrnInfoPtr, unsigned int, PCITAG,
+                                               unsigned long, unsigned long);
+extern void              ASTUnmapVidMem(ScrnInfoPtr, pointer, unsigned long);
+extern void              ASTNotifyModeChanged(ScrnInfoPtr);
+extern void              ASTSaveHW(ScrnInfoPtr);
+extern void              ASTRestoreHW(ScrnInfoPtr);
+
+#endif
+
 /* ast_vgatool.c */
 extern Bool bASTIsVGAEnabled(ScrnInfoPtr pScrn);
 extern Bool ASTGetVGA2EDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer);
--- a/src/ast_tool.c	Wed Nov 12 11:59:48 2014
+++ b/src/ast_tool.c	Wed Nov 12 12:03:43 2014
@@ -50,16 +50,27 @@
 /* Driver specific headers */
 #include "ast.h"
 
+#if defined(__sparc__)
+extern pointer ASTMapVidMem(ScrnInfoPtr, unsigned int, PCITAG,
+                                 unsigned long, unsigned long);
+extern void    ASTUnmapVidMem(ScrnInfoPtr, pointer, unsigned long);
+#endif /* __sparc__ */
+
 Bool
 ASTMapMem(ScrnInfoPtr pScrn)
 {
    ASTRecPtr pAST = ASTPTR(pScrn);
 
-#ifndef XSERVER_LIBPCIACCESS
+#if !defined(XSERVER_LIBPCIACCESS) || defined(__sparc__)
+#if !defined(__sparc__)
    pAST->FBVirtualAddr = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
 				 pAST->PciTag,
 				 pAST->FBPhysAddr, pAST->FbMapSize);
 #else
+   pAST->FBVirtualAddr = ASTMapVidMem(pScrn, VIDMEM_FRAMEBUFFER, NULL,
+                                pAST->FBPhysAddr, pAST->FbMapSize);
+#endif /* sparc */
+#else
    {
      void** result = (void**)&pAST->FBVirtualAddr;
      int err = pci_device_map_range(pAST->PciInfo,
@@ -85,10 +96,14 @@
 {
    ASTRecPtr pAST = ASTPTR(pScrn);
 
-#ifndef XSERVER_LIBPCIACCESS
+#if !defined(XSERVER_LIBPCIACCESS) || defined(__sparc__)
+#if !defined(__sparc__)
    xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pAST->FBVirtualAddr,
 		   pAST->FbMapSize);
 #else
+   ASTUnmapVidMem(pScrn, (pointer)pAST->FBVirtualAddr, pAST->FbMapSize);
+#endif
+#else
    pci_device_unmap_range(pAST->PciInfo, pAST->FBVirtualAddr, pAST->FbMapSize);
 #endif
 
@@ -101,7 +116,7 @@
 ASTMapMMIO(ScrnInfoPtr pScrn)
 {
    ASTRecPtr pAST = ASTPTR(pScrn);
-#ifndef XSERVER_LIBPCIACCESS
+#if !defined(XSERVER_LIBPCIACCESS) || defined(__sparc__)
    int mmioFlags;
 
 #if !defined(__alpha__)
@@ -110,12 +125,17 @@
    mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE;
 #endif
 
-
+#if !defined(__sparc__)
    pAST->MMIOVirtualAddr = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
 				         pAST->PciTag,
 				         pAST->MMIOPhysAddr, pAST->MMIOMapSize);
 
 #else
+   pAST->MMIOVirtualAddr = ASTMapVidMem(pScrn,
+                        VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, NULL,
+                        pAST->MMIOPhysAddr, pAST->MMIOMapSize);
+#endif
+#else
    {
      void** result = (void**)&pAST->MMIOVirtualAddr;
      int err = pci_device_map_range(pAST->PciInfo,
@@ -140,10 +160,14 @@
 {
    ASTRecPtr pAST = ASTPTR(pScrn);
 
-#ifndef XSERVER_LIBPCIACCESS
+#if !defined(XSERVER_LIBPCIACCESS) || defined(__sparc__)
+#if !defined(__sparc__)
    xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pAST->MMIOVirtualAddr,
 		   pAST->MMIOMapSize);
 #else
+   ASTUnmapVidMem(pScrn, (pointer)pAST->MMIOVirtualAddr, pAST->MMIOMapSize);
+#endif
+#else
    pci_device_unmap_range(pAST->PciInfo, pAST->MMIOVirtualAddr, pAST->MMIOMapSize);
 #endif
    pAST->MMIOVirtualAddr = 0;
--- a/src/ast_vgatool.h	Wed Nov 12 12:03:58 2014
+++ b/src/ast_vgatool.h	Wed Nov 12 12:06:04 2014
@@ -20,6 +20,12 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifndef ASTVGATOOL_H
+#define ASTVGATOOL_H
+
+#include <unistd.h>
+#include <stropts.h>
+
 /* VRAM Size Definition */
 #define VIDEOMEM_SIZE_08M	0x00800000
 #define VIDEOMEM_SIZE_16M	0x01000000
@@ -40,6 +46,96 @@
 #define DRAMTYPE_2Gx16		6
 #define DRAMTYPE_4Gx16		7
 
+#if defined(__sparc__)
+
+#define SET_IO_REG             0x1000
+#define GET_IO_REG             0x1001
+
+#define AR_PORT_WRITE          0x40
+#define MISC_PORT_WRITE        0x42
+#define VGA_ENABLE_PORT        0x43
+#define SEQ_PORT               0x44
+#define DAC_INDEX_READ         0x47
+#define DAC_INDEX_WRITE        0x48
+#define DAC_DATA               0x49
+#define GR_PORT                0x4E
+#define CRTC_PORT              0x54
+#define INPUT_STATUS1_READ     0x5A
+#define MISC_PORT_READ         0x4C
+
+static inline uchar_t
+_GetRegFromFd(uchar_t off, int fd)
+{
+       struct vis_io_reg   io_reg = {
+              .offset = off
+       };
+       ioctl(fd, VIS_GETIOREG, &io_reg);
+       return io_reg.value;
+}
+
+#define GetReg(off)            _GetRegFromFd(off, pAST->fd)
+
+#define SetReg(off, val)       do {                                    \
+                       struct vis_io_reg   io_reg = {                  \
+                              .offset = off,                           \
+                              .value = val                             \
+                       };                                              \
+                       ioctl(pAST->fd, VIS_SETIOREG, &io_reg);         \
+                       } while (0)
+
+#define GetIndexReg(off, index, val)   do {                            \
+                       struct vis_io_reg   io_reg = {                  \
+                              .offset = off,                           \
+                              .value = index                           \
+                       };                                              \
+                       ioctl(pAST->fd, VIS_SETIOREG, &io_reg);         \
+                       io_reg.offset = off+1;                          \
+                       ioctl(pAST->fd, VIS_GETIOREG, &io_reg);         \
+                       val = io_reg.value;                             \
+                       } while (0)
+
+#define SetIndexReg(off, index, val) do {                              \
+                       struct vis_io_reg   io_reg = {                  \
+                             .offset = off,                           \
+                              .value = index                           \
+                       };                                              \
+                       ioctl(pAST->fd, VIS_SETIOREG, &io_reg);         \
+                       io_reg.offset = off+1;                          \
+                       io_reg.value = val;                             \
+                       ioctl(pAST->fd, VIS_SETIOREG, &io_reg);         \
+                       } while (0)
+
+#define GetIndexRegMask(off, index, and, val) do {                     \
+                       struct vis_io_reg   io_reg = {                  \
+                              .offset = off,                           \
+                              .value = index                           \
+                       };                                              \
+                       ioctl(pAST->fd, VIS_SETIOREG, &io_reg);         \
+                       io_reg.offset = off+1;                          \
+                       ioctl(pAST->fd, VIS_GETIOREG, &io_reg);         \
+                       val = io_reg.value & and;                       \
+                       } while (0)
+
+#define SetIndexRegMask(off, index, and, val) do {                     \
+                       UCHAR __Temp;                                   \
+                       struct vis_io_reg   io_reg = {                  \
+                              .offset = off,                           \
+                              .value = index                           \
+                       };                                              \
+                       ioctl(pAST->fd, VIS_SETIOREG, &io_reg);         \
+                       io_reg.offset = off + 1;                        \
+                       ioctl(pAST->fd, VIS_GETIOREG, &io_reg);         \
+                       __Temp = (io_reg.value & and) | val;            \
+                       io_reg.offset = off;                            \
+                       io_reg.value = index;                           \
+                       ioctl(pAST->fd, VIS_SETIOREG, &io_reg);         \
+                       io_reg.offset = off+1;                          \
+                       io_reg.value = __Temp;                          \
+                       ioctl(pAST->fd, VIS_SETIOREG, &io_reg);         \
+                       } while (0)
+
+#else /* !__sparc__ */
+
 #define AR_PORT_WRITE		(pAST->MMIOVirtualAddr + 0x3c0)
 #define MISC_PORT_WRITE		(pAST->MMIOVirtualAddr + 0x3c2)
 #define VGA_ENABLE_PORT		(pAST->MMIOVirtualAddr + 0x3c3)
@@ -72,6 +168,7 @@
 						__Temp = (MMIO_IN8(base, 1)&(and))|(val);	\
 						SetIndexReg(base,index,__Temp);			\
 						}
+#endif
 
 #define VGA_GET_PALETTE_INDEX(index, red, green, blue) \
 { \
@@ -170,3 +267,5 @@
 /* Delay */
 #define DelayUS(x)		usleep(x)
 #define DelayMS(x)		DelayUS(1000*x)
+
+#endif /* ASTVGATOOL_H */
--- a/src/ast_vgatool.c	Wed Nov 12 12:06:20 2014
+++ b/src/ast_vgatool.c	Wed Nov 12 12:08:08 2014
@@ -864,6 +864,7 @@
 void
 ASTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
 {
+#if !defined(__sparc__)
    ASTRecPtr pAST;
    UCHAR SEQ01, CRB6;
    ULONG ulData, ulTemp;
@@ -923,6 +924,7 @@
    {  /* 3rd Tx */
       if (pAST->jTxChipType == Tx_DP501) SetDP501VideoOutput(pScrn, 1);
    }
+#endif
 }
 
 
@@ -1395,7 +1397,7 @@
     { 0x0030, 0x00000040 },
     { 0x0028, 0x00000003 },
     { 0x000C, 0x00005a21 },
-    { 0x0034, 0x00007c03 },
+    { 0x0034, 0x00007c43 },
     { 0x0120, 0x00004c41 },
     { 0xffff, 0xffffffff },
 };
@@ -1448,7 +1450,7 @@
     { 0x0030, 0x00000040 },
     { 0x0028, 0x00000003 },
     { 0x000C, 0x00005a21 },
-    { 0x0034, 0x00007c03 },
+    { 0x0034, 0x00007c43 },
     { 0x0120, 0x00005061 },
     { 0xffff, 0xffffffff },
 };
@@ -3061,9 +3063,11 @@
 
    {
        /* Enable PCI */
+#if !defined(__sparc__)
        PCI_READ_LONG(pAST->PciInfo, &ulData, 0x04);
        ulData |= 0x03;
        PCI_WRITE_LONG(pAST->PciInfo, ulData, 0x04);
+#endif
 
        /* Enable VGA */
        vEnableVGA(pScrn);
@@ -3357,9 +3361,11 @@
     pAST = ASTPTR(pScrn);
 
     /* Enable PCI */
+#if    !defined(__sparc__)
     PCI_READ_LONG(pAST->PciInfo, &ulData, 0x04);
     ulData |= 0x03;
     PCI_WRITE_LONG(pAST->PciInfo, ulData, 0x04);
+#endif
 
     /* init DRAM if no F/W */
     /* TODO */
@@ -3451,9 +3457,11 @@
     if (jReg != 0x01)
     {
        /* Enable PCI */
+#if !defined(__sparc__)
        PCI_READ_LONG(pAST->PciInfo, &ulData, 0x04);
        ulData |= 0x03;
        PCI_WRITE_LONG(pAST->PciInfo, ulData, 0x04);
+#endif
 
        outb(pAST->RelocateIO + 0x43, 0x01);
        outb(pAST->RelocateIO + 0x42, 0x01);
--- a/src/ast_driver.c	Wed Nov 12 12:08:21 2014
+++ b/src/ast_driver.c	Wed Nov 12 12:30:17 2014
@@ -74,7 +74,7 @@
 static ModeStatus ASTValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags);
 
 /* Internally used functions */
-static Bool ASTGetRec(ScrnInfoPtr pScrn);
+extern Bool ASTGetRec(ScrnInfoPtr pScrn);
 static void ASTFreeRec(ScrnInfoPtr pScrn);
 static Bool ASTSaveScreen(ScreenPtr pScreen, Bool unblack);
 static Bool ASTCloseScreen(CLOSE_SCREEN_ARGS_DECL);
@@ -244,7 +244,7 @@
       return FALSE;
     }
 
-#ifndef XSERVER_LIBPCIACCESS
+#if !defined(XSERVER_LIBPCIACCESS) && !defined(__sparc__)
    /*
     * This probing is just checking the PCI data the server already
     * collected.
@@ -254,6 +254,8 @@
     }
 #endif
 
+#if !defined(__sparc__)
+
     numUsed = xf86MatchPciInstances(AST_NAME, PCI_VENDOR_AST,
 				   ASTChipsets, ASTPciChipsets,
 				   devSections, numDevSections,
@@ -322,7 +324,37 @@
 
     free(devSections);
     free(usedChips);
+#else
+    if (flags & PROBE_DETECT) {
+        foundScreen = TRUE;
+    } else {
+        for (i = 0; i < numDevSections; i++) {
 
+           ScrnInfoPtr pScrn = NULL;
+
+           /* Allocate new ScrnInfoRec and claim the slot */
+           if (pScrn = ASTAllocScreen(drv, devSections[i])) {
+               pScrn->driverVersion = AST_VERSION;
+               pScrn->driverName = AST_DRIVER_NAME;
+               pScrn->name = AST_NAME;
+
+               pScrn->Probe = ASTProbe;
+               pScrn->PreInit = ASTPreInit;
+               pScrn->ScreenInit = ASTScreenInit;
+               pScrn->SwitchMode = ASTSwitchMode;
+               pScrn->AdjustFrame = ASTAdjustFrame;
+               pScrn->EnterVT = ASTEnterVT;
+               pScrn->LeaveVT = ASTLeaveVT;
+               pScrn->FreeScreen = ASTFreeScreen;
+               pScrn->ValidMode = ASTValidMode;
+
+               foundScreen = TRUE;
+           }
+       }
+    }
+    free(devSections);
+#endif
+
     return foundScreen;
 }
 
@@ -393,6 +425,10 @@
 
    pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
 
+#if defined(__sparc__)
+   pEnt->location.type = BUS_PCI;
+#endif
+
    if (flags & PROBE_DETECT) {
        ASTProbeDDC(pScrn, pEnt->index);
        return TRUE;
@@ -495,7 +531,11 @@
    /* Fill AST Info */
    pAST = ASTPTR(pScrn);
    pAST->pEnt    = xf86GetEntityInfo(pScrn->entityList[0]);
+#if !defined(__sparc__)
    pAST->PciInfo = xf86GetPciInfoForEntity(pAST->pEnt->index);
+#else
+   pAST->PciInfo = ASTGetPciInfo(pAST);
+#endif
 #ifndef XSERVER_LIBPCIACCESS
    pAST->PciTag  = pciTag(pAST->PciInfo->bus, pAST->PciInfo->device,
 			  pAST->PciInfo->func);
@@ -540,7 +580,7 @@
    xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n",
 	      (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown ast");
 
-
+#if !(defined(__sparc__))
 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
     /* "Patch" the PIOOffset inside vgaHW in order to force
      * the vgaHW module to use our relocated i/o ports.
@@ -547,15 +587,13 @@
      */
     VGAHWPTR(pScrn)->PIOOffset =
 	pScrn->domainIOBase + PCI_REGION_BASE(pAST->PciInfo, 2, REGION_IO) - 0x380;
-
     pAST->RelocateIO = pScrn->domainIOBase +
 	    PCI_REGION_BASE(pAST->PciInfo, 2, REGION_IO);
 #else
+#endif
     pAST->RelocateIO = (PCI_REGION_BASE(pAST->PciInfo, 2, REGION_IO));
-
 #endif
 
-
    if (pAST->pEnt->device->MemBase != 0) {
       pAST->FBPhysAddr = pAST->pEnt->device->MemBase;
       from = X_CONFIG;
@@ -620,8 +658,10 @@
    }
    else
    {
+#if !(defined(__sparc__))
        /* Enable VGA MMIO Access */
        vASTEnableVGAMMIO(pScrn);
+#endif
 
        /* Init VGA Adapter */
        if (!xf86IsPrimaryPci(pAST->PciInfo))
@@ -866,6 +906,10 @@
 
    vFillASTModeInfo (pScrn);
 
+#if (defined(__sparc__))
+   ASTNotifyModeChanged(pScrn);
+#endif
+
    ASTSave(pScrn);
    if (!ASTModeInit(pScrn, pScrn->currentMode)) {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Mode Init Failed \n");
@@ -1243,7 +1287,7 @@
  * These two functions create and destroy that private data.
  *
  */
-static Bool
+Bool
 ASTGetRec(ScrnInfoPtr pScrn)
 {
    if (pScrn->driverPrivate)
--- a/src/Makefile.am	Wed Nov 12 12:30:37 2014
+++ b/src/Makefile.am	Wed Nov 12 12:31:00 2014
@@ -44,4 +44,5 @@
 	ast_vgatool.c 	\
 	ast_vgatool.h   \
 	ast_dp501fw.h	\
+	ast_sparc_driver.c \
         compat-api.h
--- a/src/ast_cursor.c	Wed Nov 12 12:31:12 2014
+++ b/src/ast_cursor.c	Wed Nov 12 12:31:38 2014
@@ -82,7 +82,11 @@
 
     infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
                      HARDWARE_CURSOR_INVERT_MASK |
+#if     !defined(__sparc__)
                      HARDWARE_CURSOR_BIT_ORDER_MSBFIRST;
+#else
+                    0;
+#endif
 
     infoPtr->MaxWidth  = MAX_HWC_WIDTH;
     infoPtr->MaxHeight = MAX_HWC_HEIGHT;
