Module Name: xsrc Committed By: macallan Date: Fri Nov 12 18:58:14 UTC 2021
Added Files: xsrc/external/mit/xf86-video-mgx/dist: configure xsrc/external/mit/xf86-video-mgx/dist/src: compat-api.h mgx.h mgx_accel.c mgx_cursor.c mgx_driver.c Log Message: crude beginnings of a driver for the Southland Media / Quantum 3D MGX basic acceleration mostly works in 24bit colour needs native hw cursor code windowmaker produces visible artifacts, but it's good enough to run amiwm and a few xterms To generate a diff of this commit: cvs rdiff -u -r0 -r1.1 xsrc/external/mit/xf86-video-mgx/dist/configure cvs rdiff -u -r0 -r1.1 xsrc/external/mit/xf86-video-mgx/dist/src/compat-api.h \ xsrc/external/mit/xf86-video-mgx/dist/src/mgx.h \ xsrc/external/mit/xf86-video-mgx/dist/src/mgx_accel.c \ xsrc/external/mit/xf86-video-mgx/dist/src/mgx_cursor.c \ xsrc/external/mit/xf86-video-mgx/dist/src/mgx_driver.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Added files: Index: xsrc/external/mit/xf86-video-mgx/dist/configure diff -u /dev/null xsrc/external/mit/xf86-video-mgx/dist/configure:1.1 --- /dev/null Fri Nov 12 18:58:14 2021 +++ xsrc/external/mit/xf86-video-mgx/dist/configure Fri Nov 12 18:58:14 2021 @@ -0,0 +1,8 @@ +#! /bin/sh + +# Identity of this package. +PACKAGE_NAME='xf86-video-mgx' +PACKAGE_TARNAME='xf86-video-mgx' +PACKAGE_VERSION='0.0.1' +PACKAGE_STRING='xf86-video-mgx 0.0.1' +PACKAGE_BUGREPORT='https://bugs.freedesktop.org/enter_bug.cgi?product=xorg' Index: xsrc/external/mit/xf86-video-mgx/dist/src/compat-api.h diff -u /dev/null xsrc/external/mit/xf86-video-mgx/dist/src/compat-api.h:1.1 --- /dev/null Fri Nov 12 18:58:14 2021 +++ xsrc/external/mit/xf86-video-mgx/dist/src/compat-api.h Fri Nov 12 18:58:14 2021 @@ -0,0 +1,99 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * 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. + * + * Author: Dave Airlie <airl...@redhat.com> + */ + +/* this file provides API compat between server post 1.13 and pre it, + it should be reused inside as many drivers as possible */ +#ifndef COMPAT_API_H +#define COMPAT_API_H + +#ifndef GLYPH_HAS_GLYPH_PICTURE_ACCESSOR +#define GetGlyphPicture(g, s) GlyphPicture((g))[(s)->myNum] +#define SetGlyphPicture(g, s, p) GlyphPicture((g))[(s)->myNum] = p +#endif + +#ifndef XF86_HAS_SCRN_CONV +#define xf86ScreenToScrn(s) xf86Screens[(s)->myNum] +#define xf86ScrnToScreen(s) screenInfo.screens[(s)->scrnIndex] +#endif + +#ifndef XF86_SCRN_INTERFACE + +#define SCRN_ARG_TYPE int +#define SCRN_INFO_PTR(arg1) ScrnInfoPtr pScrn = xf86Screens[(arg1)] + +#define SCREEN_ARG_TYPE int +#define SCREEN_PTR(arg1) ScreenPtr pScreen = screenInfo.screens[(arg1)] + +#define SCREEN_INIT_ARGS_DECL int i, ScreenPtr pScreen, int argc, char **argv + +#define BLOCKHANDLER_ARGS_DECL int arg, pointer blockData, pointer pTimeout, pointer pReadmask +#define BLOCKHANDLER_ARGS arg, blockData, pTimeout, pReadmask + +#define CLOSE_SCREEN_ARGS_DECL int scrnIndex, ScreenPtr pScreen +#define CLOSE_SCREEN_ARGS scrnIndex, pScreen + +#define ADJUST_FRAME_ARGS_DECL int arg, int x, int y, int flags +#define ADJUST_FRAME_ARGS(arg, x, y) (arg)->scrnIndex, x, y, 0 + +#define SWITCH_MODE_ARGS_DECL int arg, DisplayModePtr mode, int flags +#define SWITCH_MODE_ARGS(arg, m) (arg)->scrnIndex, m, 0 + +#define FREE_SCREEN_ARGS_DECL int arg, int flags + +#define VT_FUNC_ARGS_DECL int arg, int flags +#define VT_FUNC_ARGS pScrn->scrnIndex, 0 + +#define XF86_SCRN_ARG(x) ((x)->scrnIndex) +#else +#define SCRN_ARG_TYPE ScrnInfoPtr +#define SCRN_INFO_PTR(arg1) ScrnInfoPtr pScrn = (arg1) + +#define SCREEN_ARG_TYPE ScreenPtr +#define SCREEN_PTR(arg1) ScreenPtr pScreen = (arg1) + +#define SCREEN_INIT_ARGS_DECL ScreenPtr pScreen, int argc, char **argv + +#define BLOCKHANDLER_ARGS_DECL ScreenPtr arg, pointer pTimeout, pointer pReadmask +#define BLOCKHANDLER_ARGS arg, pTimeout, pReadmask + +#define CLOSE_SCREEN_ARGS_DECL ScreenPtr pScreen +#define CLOSE_SCREEN_ARGS pScreen + +#define ADJUST_FRAME_ARGS_DECL ScrnInfoPtr arg, int x, int y +#define ADJUST_FRAME_ARGS(arg, x, y) arg, x, y + +#define SWITCH_MODE_ARGS_DECL ScrnInfoPtr arg, DisplayModePtr mode +#define SWITCH_MODE_ARGS(arg, m) arg, m + +#define FREE_SCREEN_ARGS_DECL ScrnInfoPtr arg + +#define VT_FUNC_ARGS_DECL ScrnInfoPtr arg +#define VT_FUNC_ARGS pScrn + +#define XF86_SCRN_ARG(x) (x) + +#endif + +#endif Index: xsrc/external/mit/xf86-video-mgx/dist/src/mgx.h diff -u /dev/null xsrc/external/mit/xf86-video-mgx/dist/src/mgx.h:1.1 --- /dev/null Fri Nov 12 18:58:14 2021 +++ xsrc/external/mit/xf86-video-mgx/dist/src/mgx.h Fri Nov 12 18:58:14 2021 @@ -0,0 +1,91 @@ +/* + * TCX framebuffer - defines. + * + * Copyright (C) 2000 Jakub Jelinek (ja...@redhat.com) + * + * 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 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 + * JAKUB JELINEK 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. + */ + +#ifndef MGX_H +#define MGX_H + +#define MMIO_IS_BE + +#include "xorg-server.h" +#include "xf86.h" +#include "xf86_OSproc.h" +#include "compiler.h" +#include "xf86RamDac.h" +#include <X11/Xmd.h> +#include "gcstruct.h" +#include "xf86sbusBus.h" +#include "exa.h" + +#include <dev/wscons/wsconsio.h> + +#include "compat-api.h" + +typedef struct { + uint8_t *fb; + uint8_t *blt; + sbusDevicePtr psdp; + CloseScreenProcPtr CloseScreen; + struct wsdisplay_cursor cursor; + Bool HWCursor, NoAccel; + int vramsize; /* size of the fb */ + int maskoffset; + xf86CursorInfoPtr CursorInfoRec; + OptionInfoPtr Options; + ExaDriverPtr pExa; + uint32_t dec; + int offset; +} MgxRec, *MgxPtr; + +Bool MgxInitAccel(ScreenPtr); +Bool MgxSetupCursor(ScreenPtr); + +#define GET_MGX_FROM_SCRN(p) ((MgxPtr)((p)->driverPrivate)) + +static inline void MgxWrite1(MgxPtr pMgx, int offset, uint8_t val) +{ + MMIO_OUT8(pMgx->blt, offset ^ 3, val); +} + +static inline void MgxWrite2(MgxPtr pMgx, int offset, uint16_t val) +{ + MMIO_OUT16(pMgx->blt, offset ^ 2, val); +} + +static inline void MgxWrite4(MgxPtr pMgx, int offset, uint32_t val) +{ + MMIO_OUT32(pMgx->blt, offset, val); +} + +static inline uint8_t MgxRead1(MgxPtr pMgx, int offset) +{ + uint8_t val = MMIO_IN8(pMgx->blt, offset ^ 3); + return val; +} + +static inline uint32_t MgxRead4(MgxPtr pMgx, int offset) +{ + uint32_t val = MMIO_IN32(pMgx->blt, offset); + return val; +} + +#endif /* MGX_H */ Index: xsrc/external/mit/xf86-video-mgx/dist/src/mgx_accel.c diff -u /dev/null xsrc/external/mit/xf86-video-mgx/dist/src/mgx_accel.c:1.1 --- /dev/null Fri Nov 12 18:58:14 2021 +++ xsrc/external/mit/xf86-video-mgx/dist/src/mgx_accel.c Fri Nov 12 18:58:14 2021 @@ -0,0 +1,393 @@ +/* + * Southland Media MGX - hardware acceleration. + * + * Copyright (C) 2021 Michael Lorenz + * + * 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 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 + * MICHAEL LORENZ 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. + */ + +/* $NetBSD: mgx_accel.c,v 1.1 2021/11/12 18:58:14 macallan Exp $ */ + +#include <sys/types.h> + +#include "mgx.h" +#include <dev/sbus/mgxreg.h> + +//#define DEBUG + +#ifdef DEBUG +#define ENTER xf86Msg(X_ERROR, "%s\n", __func__) +#define LEAVE xf86Msg(X_ERROR, "%s done\n", __func__) +#define DBGMSG xf86Msg +#else +#define ENTER +#define DBGMSG if (0) xf86Msg +#define LEAVE +#endif + +/* Translation from X ROP's to APM ROP's. */ +static unsigned char apmROP[] = { + 0, + 0x88, + 0x44, + 0xCC, + 0x22, + 0xAA, + 0x66, + 0xEE, + 0x11, + 0x99, + 0x55, + 0xDD, + 0x33, + 0xBB, + 0x77, + 0xFF +}; + +static void +MgxWaitMarker(ScreenPtr pScreen, int Marker) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + int bail = 0x0fffffff; + uint8_t stat; + + ENTER; + do { + stat = MgxRead1(pMgx, ATR_BLT_STATUS); + if ((stat & (BLT_HOST_BUSY | BLT_ENGINE_BUSY)) == 0) + break; + bail--; + } while (bail < 0); + if (bail == 0) DBGMSG(X_ERROR, "%s timed out\n", __func__); + LEAVE; +} + +static void +MgxWait(MgxPtr pMgx) +{ + int bail = 10000; + uint8_t stat; + + ENTER; + do { + stat = MgxRead1(pMgx, ATR_BLT_STATUS); + if ((stat & (BLT_HOST_BUSY | BLT_ENGINE_BUSY)) == 0) + break; + bail--; + } while (bail < 0); + if (bail == 0) DBGMSG(X_ERROR, "%s timed out\n", __func__); + LEAVE; +} + +static void +MgxWaitFifo(MgxPtr pMgx, int depth) +{ + unsigned int i; + uint8_t stat; + + ENTER; + + for (i = 100000; i != 0; i--) { + stat = MgxRead1(pMgx, ATR_FIFO_STATUS); + stat = (stat & FIFO_MASK) >> FIFO_SHIFT; + DBGMSG(X_ERROR, "%s %x\n", __func__, stat); + if (stat >= depth) + break; + MgxWrite1(pMgx, ATR_FIFO_STATUS, 0); + } + if (i == 0) xf86Msg(X_ERROR, "%s timed out\n", __func__); + LEAVE; +} + +static Bool +MgxPrepareCopy +( + PixmapPtr pSrcPixmap, + PixmapPtr pDstPixmap, + int xdir, + int ydir, + int alu, + Pixel planemask +) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + int srcpitch = exaGetPixmapPitch(pSrcPixmap); + int srcoff = exaGetPixmapOffset(pSrcPixmap); + + ENTER; + + DBGMSG(X_ERROR, "%s %d %d\n", __func__, srcoff, srcpitch); + pMgx->offset = srcoff / srcpitch; + + MgxWaitFifo(pMgx, 1); + MgxWrite1(pMgx, ATR_ROP, apmROP[alu]); + LEAVE; + return TRUE; +} + +static void +MgxCopy +( + PixmapPtr pDstPixmap, + int xs, + int ys, + int xd, + int yd, + int wi, + int he +) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + int dstpitch = exaGetPixmapPitch(pDstPixmap); + int dstoff = exaGetPixmapOffset(pDstPixmap); + uint32_t dec = pMgx->dec; + + ENTER; + + if (dstoff > 0 || 1) { + DBGMSG(X_ERROR, "%s %d %d\n", __func__, dstoff, dstpitch); + yd += dstoff / dstpitch; + } + ys += pMgx->offset; + + dec |= (DEC_COMMAND_BLT << DEC_COMMAND_SHIFT) | + (DEC_START_DIMX << DEC_START_SHIFT); + + if ((xs < xd) && (ys == yd) && ((xd - xs) < wi)) { + xs += wi - 1; + xd += wi - 1; + dec |= DEC_DIR_X_REVERSE; + } + if (ys < yd) { + ys += he - 1; + yd += he - 1; + dec |= DEC_DIR_Y_REVERSE; + } + + DBGMSG(X_ERROR, "%s %d %d %d %d -> %d %d\n", __func__, xs, ys, wi, he, xd, yd); + MgxWaitFifo(pMgx, 4); + MgxWrite4(pMgx, ATR_DEC, dec); + MgxWrite4(pMgx, ATR_SRC_XY, (ys << 16) | xs); + MgxWrite4(pMgx, ATR_DST_XY, (yd << 16) | xd); + MgxWrite4(pMgx, ATR_WH, (he << 16) | wi); + + exaMarkSync(pDstPixmap->drawable.pScreen); + LEAVE; +} + +static void +MgxDoneCopy(PixmapPtr pDstPixmap) +{ + ENTER; + LEAVE; +} + +static Bool +MgxPrepareSolid( + PixmapPtr pPixmap, + int alu, + Pixel planemask, + Pixel fg) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + uint32_t dec; + + ENTER; + dec = pMgx->dec; + dec |= (DEC_COMMAND_RECT << DEC_COMMAND_SHIFT) | + (DEC_START_DIMX << DEC_START_SHIFT); + MgxWaitFifo(pMgx, 3); + MgxWrite1(pMgx, ATR_ROP, apmROP[alu]); + MgxWrite4(pMgx, ATR_FG, /*bswap32*/(fg)); + MgxWrite4(pMgx, ATR_DEC, dec); + LEAVE; + return TRUE; +} + +static void +MgxSolid( + PixmapPtr pPixmap, + int x1, + int y1, + int x2, + int y2) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + int w = x2 - x1, h = y2 - y1, dstoff, dstpitch; + int pitch = exaGetPixmapPitch(pPixmap); + int offset = exaGetPixmapOffset(pPixmap); + + ENTER; + if (offset > 0) { + DBGMSG(X_ERROR, "%s %d %d\n", __func__, offset, pitch); + y1 += offset / pitch; + } + DBGMSG(X_ERROR, "%s %d %d %d %d\n", __func__, x1, y1, w, h); + + MgxWaitFifo(pMgx, 2); + MgxWrite4(pMgx, ATR_DST_XY, (y1 << 16) | x1); + MgxWrite4(pMgx, ATR_WH, (h << 16) | w); + exaMarkSync(pPixmap->drawable.pScreen); + LEAVE; +} + +/* + * Memcpy-based UTS. + */ +static Bool +MgxUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, + char *srcc, int src_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + uint32_t *dst = (uint32_t *)(pMgx->fb + exaGetPixmapOffset(pDst)); + uint32_t *src = (uint32_t *)srcc; + int i, dst_pitch = exaGetPixmapPitch(pDst) >> 2; + + ENTER; + dst += x + (y * dst_pitch); + + MgxWait(pMgx); + + while (h--) { + for (i = 0; i < w; i++) dst[i] = /*bswap32*/(src[i]); + src += src_pitch >> 2; + dst += dst_pitch; + LEAVE; + } + return TRUE; +} + +/* + * Memcpy-based DFS. + */ +static Bool +MgxDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, + char *dstt, int dst_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + uint32_t *src = (uint32_t *)(pMgx->fb + exaGetPixmapOffset(pSrc)); + uint32_t *dst = (uint32_t *)dstt; + int i, src_pitch = exaGetPixmapPitch(pSrc) >> 2; + + ENTER; + src += x + (y * src_pitch); + + MgxWait(pMgx); + + while (h--) { + for (i = 0; i < w; i++) dst[i] = /*bswap32*/(src[i]); + src += src_pitch; + dst += dst_pitch >> 2; + } + LEAVE; + return TRUE; +} + +Bool +MgxInitAccel(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + ExaDriverPtr pExa; + int lines; + uint32_t ap; + uint8_t reg; + + pExa = exaDriverAlloc(); + if (!pExa) + return FALSE; + + pMgx->pExa = pExa; + + pExa->exa_major = EXA_VERSION_MAJOR; + pExa->exa_minor = EXA_VERSION_MINOR; + + pExa->memoryBase = pMgx->fb; + lines = (pMgx->vramsize - 0x1000) / (pScrn->displayWidth * 4); + DBGMSG(X_ERROR, "lines %d\n", lines); + pExa->memorySize = lines * pScrn->displayWidth * 4; + pExa->offScreenBase = pScrn->displayWidth * pScrn->virtualY * 4; + pExa->pixmapOffsetAlign = pScrn->displayWidth * 4; + pExa->pixmapPitchAlign = pScrn->displayWidth * 4; + + pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_MIXED_PIXMAPS; + + pExa->maxX = 2048; + pExa->maxY = 2048; + + pExa->WaitMarker = MgxWaitMarker; + pExa->PrepareSolid = MgxPrepareSolid; + pExa->Solid = MgxSolid; + pExa->DoneSolid = MgxDoneCopy; + pExa->PrepareCopy = MgxPrepareCopy; + pExa->Copy = MgxCopy; + pExa->DoneCopy = MgxDoneCopy; + + MgxWait(pMgx); + + /* XXX support other colour depths */ + reg = MgxRead1(pMgx, ATR_PIXEL); + DBGMSG(X_ERROR, "pixel %x\n", reg); + reg &= ~PIXEL_DEPTH_MASK; + reg |= PIXEL_32; + MgxWrite1(pMgx, ATR_PIXEL, reg); + pMgx->dec = DEC_DEPTH_32 << DEC_DEPTH_SHIFT; + + ap = MgxRead4(pMgx, ATR_APERTURE); + MgxWrite2(pMgx, ATR_APERTURE, 0xffff); + ap = MgxRead4(pMgx, ATR_APERTURE); + + switch (pScrn->displayWidth) { + case 640: + pMgx->dec |= DEC_WIDTH_640 << DEC_WIDTH_SHIFT; + break; + case 800: + pMgx->dec |= DEC_WIDTH_800 << DEC_WIDTH_SHIFT; + break; + case 1024: + pMgx->dec |= DEC_WIDTH_1024 << DEC_WIDTH_SHIFT; + break; + case 1152: + pMgx->dec |= DEC_WIDTH_1152 << DEC_WIDTH_SHIFT; + break; + case 1280: + pMgx->dec |= DEC_WIDTH_1280 << DEC_WIDTH_SHIFT; + break; + case 1600: + pMgx->dec |= DEC_WIDTH_1600 << DEC_WIDTH_SHIFT; + break; + default: + return FALSE; /* not supported */ + } + + /* + * the fb is endian-twiddled and we don't know how to turn it off, + * so we convert data when copying stuff in and out + */ + pExa->UploadToScreen = MgxUploadToScreen; + pExa->DownloadFromScreen = MgxDownloadFromScreen; + return exaDriverInit(pScreen, pExa); +} Index: xsrc/external/mit/xf86-video-mgx/dist/src/mgx_cursor.c diff -u /dev/null xsrc/external/mit/xf86-video-mgx/dist/src/mgx_cursor.c:1.1 --- /dev/null Fri Nov 12 18:58:14 2021 +++ xsrc/external/mit/xf86-video-mgx/dist/src/mgx_cursor.c Fri Nov 12 18:58:14 2021 @@ -0,0 +1,183 @@ +/* $NetBSD: mgx_cursor.c,v 1.1 2021/11/12 18:58:14 macallan Exp $ */ +/* + * Copyright (c) 2005 Michael Lorenz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * fugly copypasta for now + * the mgx at sbus driver lets us run wsdisplay ioctl()s on the fb device + * will replace with direct hw access eventually + */ + +#include <fcntl.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/endian.h> +#include <dev/wscons/wsconsio.h> +#include <sys/ioctl.h> +#include <errno.h> + +#include "mgx.h" + +static void MgxLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src); +static void MgxSetCursorPosition(ScrnInfoPtr pScrn, int x, int y); +static void MgxSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); + +static void +MgxLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) +{ + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + int err, i; + + pMgx->cursor.which = WSDISPLAY_CURSOR_DOALL; + pMgx->cursor.image = src; + pMgx->cursor.mask = src + pMgx->maskoffset; + if(ioctl(pMgx->psdp->fd, WSDISPLAYIO_SCURSOR, &pMgx->cursor) == -1) + xf86Msg(X_ERROR, "MgxLoadCursorImage: %d\n", errno); +} + +void +MgxShowCursor(ScrnInfoPtr pScrn) +{ + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + + pMgx->cursor.which = WSDISPLAY_CURSOR_DOCUR; + pMgx->cursor.enable = 1; + if(ioctl(pMgx->psdp->fd, WSDISPLAYIO_SCURSOR, &pMgx->cursor) == -1) + xf86Msg(X_ERROR, "MgxShowCursor: %d\n", errno); +} + +void +MgxHideCursor(ScrnInfoPtr pScrn) +{ + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + + pMgx->cursor.which = WSDISPLAY_CURSOR_DOCUR; + pMgx->cursor.enable = 0; + if(ioctl(pMgx->psdp->fd, WSDISPLAYIO_SCURSOR, &pMgx->cursor) == -1) + xf86Msg(X_ERROR, "MgxHideCursor: %d\n", errno); +} + +static void +MgxSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + int xoff = 0, yoff = 0; + + pMgx->cursor.which = WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT; + + if (x < 0) { + xoff = -x; + x = 0; + } + if (y < 0) { + yoff = -y; + y = 0; + } + + pMgx->cursor.pos.x = x; + pMgx->cursor.hot.x = xoff; + pMgx->cursor.pos.y = y; + pMgx->cursor.hot.y = yoff; + + if(ioctl(pMgx->psdp->fd, WSDISPLAYIO_SCURSOR, &pMgx->cursor) == -1) + xf86Msg(X_ERROR, "MgxSetCursorPosition: %d\n", errno); +} + +static void +MgxSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +{ + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + u_char r[4], g[4], b[4]; + + pMgx->cursor.which = WSDISPLAY_CURSOR_DOCMAP; + pMgx->cursor.cmap.red = r; + pMgx->cursor.cmap.green = g; + pMgx->cursor.cmap.blue = b; + r[1] = fg & 0xff; + g[1] = (fg & 0xff00) >> 8; + b[1] = (fg & 0xff0000) >> 16; + r[0] = bg & 0xff; + g[0] = (bg & 0xff00) >> 8; + b[0] = (bg & 0xff0000) >> 16; + pMgx->cursor.cmap.index = 0; + pMgx->cursor.cmap.count = 2; + if(ioctl(pMgx->psdp->fd, WSDISPLAYIO_SCURSOR, &pMgx->cursor) == -1) + xf86Msg(X_ERROR, "MgxSetCursorColors: %d\n", errno); +} + +Bool +MgxSetupCursor(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + xf86CursorInfoPtr infoPtr; + + pMgx->cursor.pos.x = 0; + pMgx->cursor.pos.y = 0; + pMgx->cursor.enable = 0; + + infoPtr = xf86CreateCursorInfoRec(); + if(!infoPtr) return FALSE; + + pMgx->CursorInfoRec = infoPtr; + if(ioctl(pMgx->psdp->fd, WSDISPLAYIO_GCURMAX, &pMgx->cursor.size) == -1) { + xf86Msg(X_WARNING, "No HW cursor support found\n"); + return FALSE; + } + + xf86Msg(X_INFO, "HW cursor enabled\n"); + + infoPtr->MaxWidth = pMgx->cursor.size.x; + infoPtr->MaxHeight = pMgx->cursor.size.y; + pMgx->maskoffset = ( pMgx->cursor.size.x >> 3) * pMgx->cursor.size.y; + + pMgx->cursor.hot.x = 0; + pMgx->cursor.hot.y = 0; + pMgx->cursor.which = WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOCUR | + WSDISPLAY_CURSOR_DOPOS; + if(ioctl(pMgx->psdp->fd, WSDISPLAYIO_SCURSOR, &pMgx->cursor) == -1) + xf86Msg(X_ERROR, "WSDISPLAYIO_SCURSOR: %d\n", errno); + + infoPtr->Flags = HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | + HARDWARE_CURSOR_TRUECOLOR_AT_8BPP +/* XXX not sure why exactly we need this */ +#if BYTE_ORDER == BIG_ENDIAN + | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST +#endif + ; + infoPtr->SetCursorColors = MgxSetCursorColors; + infoPtr->SetCursorPosition = MgxSetCursorPosition; + infoPtr->LoadCursorImage = MgxLoadCursorImage; + infoPtr->HideCursor = MgxHideCursor; + infoPtr->ShowCursor = MgxShowCursor; + infoPtr->UseHWCursor = NULL; + + return xf86InitCursor(pScreen, infoPtr); +} Index: xsrc/external/mit/xf86-video-mgx/dist/src/mgx_driver.c diff -u /dev/null xsrc/external/mit/xf86-video-mgx/dist/src/mgx_driver.c:1.1 --- /dev/null Fri Nov 12 18:58:14 2021 +++ xsrc/external/mit/xf86-video-mgx/dist/src/mgx_driver.c Fri Nov 12 18:58:14 2021 @@ -0,0 +1,796 @@ +/* + * Southland Media MGX framebuffer driver. + * + * Copyright (C) 2021 Michael Lorenz + * + * 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 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 + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <fcntl.h> +#include <sys/types.h> +#include <sys/time.h> +#include <string.h> +#include <sys/ioctl.h> +#include <dev/sun/fbio.h> +#include <dev/wscons/wsconsio.h> + +#include "mgx.h" + +#include "mipointer.h" +#include "micmap.h" + +#include "fb.h" + +#include <dev/sbus/mgxreg.h> + +static const OptionInfoRec * MgxAvailableOptions(int chipid, int busid); +static void MgxIdentify(int flags); +static Bool MgxProbe(DriverPtr drv, int flags); +static Bool MgxPreInit(ScrnInfoPtr pScrn, int flags); +static Bool MgxScreenInit(SCREEN_INIT_ARGS_DECL); +static Bool MgxEnterVT(VT_FUNC_ARGS_DECL); +static void MgxLeaveVT(VT_FUNC_ARGS_DECL); +static Bool MgxCloseScreen(CLOSE_SCREEN_ARGS_DECL); +static Bool MgxSaveScreen(ScreenPtr pScreen, int mode); + +/* Required if the driver supports mode switching */ +static Bool MgxSwitchMode(SWITCH_MODE_ARGS_DECL); +/* Required if the driver supports moving the viewport */ +static void MgxAdjustFrame(ADJUST_FRAME_ARGS_DECL); + +/* Optional functions */ +static void MgxFreeScreen(FREE_SCREEN_ARGS_DECL); +static ModeStatus MgxValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, + Bool verbose, int flags); + +void MgxSync(ScrnInfoPtr pScrn); + +static Bool MgxDriverFunc(ScrnInfoPtr, xorgDriverFuncOp, pointer); + + +#define MGX_VERSION 0001 +#define MGX_NAME "MGX" +#define MGX_DRIVER_NAME "mgx" +#define MGX_MAJOR_VERSION PACKAGE_VERSION_MAJOR +#define MGX_MINOR_VERSION PACKAGE_VERSION_MINOR +#define MGX_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL + +/* + * This contains the functions needed by the server after loading the driver + * module. It must be supplied, and gets passed back by the SetupProc + * function in the dynamic case. In the static case, a reference to this + * is compiled in, and this requires that the name of this DriverRec be + * an upper-case version of the driver name. + */ + +_X_EXPORT DriverRec MGX = { + MGX_VERSION, + MGX_DRIVER_NAME, + MgxIdentify, + MgxProbe, + MgxAvailableOptions, + NULL, + 0, + MgxDriverFunc +}; + +typedef enum { + OPTION_SW_CURSOR, + OPTION_HW_CURSOR, + OPTION_NOACCEL +} TCXOpts; + +static const OptionInfoRec MgxOptions[] = { + { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, TRUE }, + { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +static MODULESETUPPROTO(MgxSetup); + +static XF86ModuleVersionInfo mgxVersRec = +{ + "mgx", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + MGX_MAJOR_VERSION, MGX_MINOR_VERSION, MGX_PATCHLEVEL, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0,0,0,0} +}; + +_X_EXPORT XF86ModuleData mgxModuleData = { &mgxVersRec, MgxSetup, NULL }; + +pointer +MgxSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = FALSE; + + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&MGX, module, HaveDriverFuncs); + + /* + * Modules that this driver always requires can be loaded here + * by calling LoadSubModule(). + */ + + /* + * The return value must be non-NULL on success even though there + * is no TearDownProc. + */ + return (pointer)TRUE; + } else { + if (errmaj) *errmaj = LDR_ONCEONLY; + return NULL; + } +} + +static Bool +MgxGetRec(ScrnInfoPtr pScrn) +{ + /* + * Allocate an MgxRec, and hook it into pScrn->driverPrivate. + * pScrn->driverPrivate is initialised to NULL, so we can check if + * the allocation has already been done. + */ + if (pScrn->driverPrivate != NULL) + return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(MgxRec), 1); + return TRUE; +} + +static void +MgxFreeRec(ScrnInfoPtr pScrn) +{ + MgxPtr pMgx; + + if (pScrn->driverPrivate == NULL) + return; + + pMgx = GET_MGX_FROM_SCRN(pScrn); + + free(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; + + return; +} + +static const OptionInfoRec * +MgxAvailableOptions(int chipid, int busid) +{ + return MgxOptions; +} + +/* Mandatory */ +static void +MgxIdentify(int flags) +{ + xf86Msg(X_INFO, "%s: driver for Southland Media MGX\n", MGX_NAME); +} + + +/* Mandatory */ +static Bool +MgxProbe(DriverPtr drv, int flags) +{ + int i; + GDevPtr *devSections; + int *usedChips; + int numDevSections; + int numUsed; + Bool foundScreen = FALSE; + EntityInfoPtr pEnt; + + /* + * The aim here is to find all cards that this driver can handle, + * and for the ones not already claimed by another driver, claim the + * slot, and allocate a ScrnInfoRec. + * + * This should be a minimal probe, and it should under no circumstances + * change the state of the hardware. Because a device is found, don't + * assume that it will be used. Don't do any initialisations other than + * the required ScrnInfoRec initialisations. Don't allocate any new + * data structures. + */ + + /* + * Next we check, if there has been a chipset override in the config file. + * For this we must find out if there is an active device section which + * is relevant, i.e., which has no driver specified or has THIS driver + * specified. + */ + + if ((numDevSections = xf86MatchDevice(MGX_DRIVER_NAME, + &devSections)) <= 0) { + /* + * There's no matching device section in the config file, so quit + * now. + */ + return FALSE; + } + + /* + * We need to probe the hardware first. We then need to see how this + * fits in with what is given in the config file, and allow the config + * file info to override any contradictions. + */ + + numUsed = xf86MatchSbusInstances(MGX_NAME, SBUS_DEVICE_MGX, + devSections, numDevSections, + drv, &usedChips); + + free(devSections); + if (numUsed <= 0) + return FALSE; + + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else for (i = 0; i < numUsed; i++) { + pEnt = xf86GetEntityInfo(usedChips[i]); + + /* + * Check that nothing else has claimed the slots. + */ + if(pEnt->active) { + ScrnInfoPtr pScrn; + + /* Allocate a ScrnInfoRec and claim the slot */ + pScrn = xf86AllocateScreen(drv, 0); + + /* Fill in what we can of the ScrnInfoRec */ + pScrn->driverVersion = MGX_VERSION; + pScrn->driverName = MGX_DRIVER_NAME; + pScrn->name = MGX_NAME; + pScrn->Probe = MgxProbe; + pScrn->PreInit = MgxPreInit; + pScrn->ScreenInit = MgxScreenInit; + pScrn->SwitchMode = MgxSwitchMode; + pScrn->AdjustFrame = MgxAdjustFrame; + pScrn->EnterVT = MgxEnterVT; + pScrn->LeaveVT = MgxLeaveVT; + pScrn->FreeScreen = MgxFreeScreen; + pScrn->ValidMode = MgxValidMode; + xf86AddEntityToScreen(pScrn, pEnt->index); + foundScreen = TRUE; + } + free(pEnt); + } + free(usedChips); + return foundScreen; +} + +/* Mandatory */ +static Bool +MgxPreInit(ScrnInfoPtr pScrn, int flags) +{ + MgxPtr pMgx; + sbusDevicePtr psdp = NULL; + MessageType from; + int i, prom; + int hwCursor; + + if (flags & PROBE_DETECT) return FALSE; + + /* + * Note: This function is only called once at server startup, and + * not at the start of each server generation. This means that + * only things that are persistent across server generations can + * be initialised here. xf86Screens[] is (pScrn is a pointer to one + * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() + * are too, and should be used for data that must persist across + * server generations. + * + * Per-generation data should be allocated with + * AllocateScreenPrivateIndex() from the ScreenInit() function. + */ + + /* Allocate the TcxRec driverPrivate */ + if (!MgxGetRec(pScrn)) { + return FALSE; + } + pMgx = GET_MGX_FROM_SCRN(pScrn); + + /* Set pScrn->monitor */ + pScrn->monitor = pScrn->confScreen->monitor; + + /* This driver doesn't expect more than one entity per screen */ + if (pScrn->numEntities > 1) + return FALSE; + /* This is the general case */ + for (i = 0; i < pScrn->numEntities; i++) { + EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[i]); + + if (pEnt->location.type == BUS_SBUS) { + psdp = xf86GetSbusInfoForEntity(pEnt->index); + pMgx->psdp = psdp; + } else + return FALSE; + } + if (psdp == NULL) + return FALSE; + + /********************** + check card capabilities + **********************/ + hwCursor = 1; + + prom = sparcPromInit(); + char *b; + int len = 4, v = 0; + + /* see if we have more than 1MB vram */ + pMgx->vramsize = 0x400000; + if (((b = sparcPromGetProperty(&psdp->node, "fb_size", &len)) != NULL) && + (len == 4)) { + memcpy(&v, b, 4); + pMgx->vramsize = v; + } + xf86Msg(X_PROBED, "found %d KB video memory\n", v >> 10); + + if (prom) + sparcPromClose(); + + xf86Msg(X_PROBED, "hardware cursor support %s\n", + hwCursor ? "found" : "not found"); + + /********************* + deal with depth + *********************/ + + if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) { + return FALSE; + } else { + /* Check that the returned depth is one we support */ + switch (pScrn->depth) { + case 8: + case 32: + case 24: + /* OK */ + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by this driver\n", + pScrn->depth); + return FALSE; + } + } + + /* Collect all of the relevant option flags (fill in pScrn->options) */ + xf86CollectOptions(pScrn, NULL); + /* Process the options */ + if (!(pMgx->Options = malloc(sizeof(MgxOptions)))) + return FALSE; + memcpy(pMgx->Options, MgxOptions, sizeof(MgxOptions)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pMgx->Options); + + /* + * This must happen after pScrn->display has been set because + * xf86SetWeight references it. + */ + if (pScrn->depth > 8) { + rgb weight = {0, 0, 0}; + rgb mask = {0xff0000, 0xff00, 0xff}; + + if (!xf86SetWeight(pScrn, weight, mask)) { + return FALSE; + } + } + + if (!xf86SetDefaultVisual(pScrn, -1)) + return FALSE; + else if (pScrn->depth > 8) { + /* We don't currently support DirectColor */ + if (pScrn->defaultVisual != TrueColor) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" + " (%s) is not supported\n", + xf86GetVisualName(pScrn->defaultVisual)); + return FALSE; + } + } + + /* + * The new cmap code requires this to be initialised. + */ + + { + Gamma zeros = {0.0, 0.0, 0.0}; + + if (!xf86SetGamma(pScrn, zeros)) { + return FALSE; + } + } + + /* determine whether we use hardware or software cursor */ + + from = X_PROBED; + pMgx->HWCursor = FALSE; + if (hwCursor) { + from = X_DEFAULT; + pMgx->HWCursor = TRUE; + if (xf86GetOptValBool(pMgx->Options, OPTION_HW_CURSOR, &pMgx->HWCursor)) + from = X_CONFIG; + if (xf86ReturnOptValBool(pMgx->Options, OPTION_SW_CURSOR, FALSE)) { + from = X_CONFIG; + pMgx->HWCursor = FALSE; + } + } + + pMgx->NoAccel = FALSE; + if (xf86ReturnOptValBool(pMgx->Options, OPTION_NOACCEL, FALSE)) { + pMgx->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); + } + + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", + pMgx->HWCursor ? "HW" : "SW"); + + if (xf86LoadSubModule(pScrn, "fb") == NULL) { + MgxFreeRec(pScrn); + return FALSE; + } + + /********************* + set up clock and mode stuff + *********************/ + + pScrn->progClock = TRUE; + + if(pScrn->display->virtualX || pScrn->display->virtualY) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "MGX does not support a virtual desktop\n"); + pScrn->display->virtualX = 0; + pScrn->display->virtualY = 0; + } + + xf86SbusUseBuiltinMode(pScrn, pMgx->psdp); + pScrn->currentMode = pScrn->modes; + pScrn->displayWidth = pScrn->virtualX; + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + return TRUE; +} + +/* Mandatory */ + +/* This gets called at the start of each server generation */ + +static Bool +MgxScreenInit(SCREEN_INIT_ARGS_DECL) +{ + ScrnInfoPtr pScrn; + MgxPtr pMgx; + VisualPtr visual; + int ret; + + /* + * First get the ScrnInfoRec + */ + pScrn = xf86ScreenToScrn(pScreen); + + pMgx = GET_MGX_FROM_SCRN(pScrn); + + /* Map the fb */ + pMgx->fb = xf86MapSbusMem (pMgx->psdp, MGX_FLIPOFFSET, pMgx->vramsize); + pMgx->blt = xf86MapSbusMem (pMgx->psdp, MGX_BLTOFFSET, 0x1000); + + if (!pMgx->blt) { + xf86Msg(X_ERROR, "failed to map blitter space\n"); + return FALSE; + } + + if (!pMgx->fb) { + xf86Msg(X_ERROR, "failed to map framebuffer\n"); + return FALSE; + } + + /* Darken the screen for aesthetic reasons and set the viewport */ + MgxSaveScreen(pScreen, SCREEN_SAVER_ON); + + /* + * The next step is to setup the screen's visuals, and initialise the + * framebuffer code. In cases where the framebuffer's default + * choices for things like visual layouts and bits per RGB are OK, + * this may be as simple as calling the framebuffer's ScreenInit() + * function. If not, the visuals will need to be setup before calling + * a fb ScreenInit() function and fixed up after. + */ + + /* + * Reset visual list. + */ + miClearVisualTypes(); + + if (pScrn->depth == 8) + /* Set the bits per RGB for 8bpp mode */ + pScrn->rgbBits = 8; + + /* Setup the visuals we support. */ + + if (!miSetVisualTypes(pScrn->depth, + pScrn->depth != 8 ? TrueColorMask : + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + + miSetPixmapDepths (); + + /* + * Call the framebuffer layer's ScreenInit function, and fill in other + * pScreen fields. + */ + + ret = fbScreenInit(pScreen, pMgx->fb, pScrn->virtualX, + pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, + pScrn->virtualX, pScrn->bitsPerPixel); + + if (!ret) + return FALSE; + + xf86SetBlackWhitePixels(pScreen); + + if (pScrn->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } + +#ifdef RENDER + /* must be after RGB ordering fixed */ + fbPictureInit (pScreen, 0, 0); +#endif + + if (!pMgx->NoAccel) { + XF86ModReqInfo req; + int errmaj, errmin; + + memset(&req, 0, sizeof(XF86ModReqInfo)); + req.majorversion = 2; + req.minorversion = 0; + if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req, + &errmaj, &errmin)) + { + LoaderErrorMsg(NULL, "exa", errmaj, errmin); + return FALSE; + } + if (!MgxInitAccel(pScreen)) + return FALSE; + } + + xf86SetBackingStore(pScreen); + xf86SetSilkenMouse(pScreen); + + /* Initialise cursor functions */ + miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); + + /* Initialize HW cursor layer. + Must follow software cursor initialization*/ + if (pMgx->HWCursor) { + + if(!MgxSetupCursor(pScreen)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + return(FALSE); + } + } + + /* Initialise default colourmap */ + if (!miCreateDefColormap(pScreen)) + return FALSE; + + if(pScrn->depth == 8 && !xf86SbusHandleColormaps(pScreen, pMgx->psdp)) + return FALSE; + + pMgx->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = MgxCloseScreen; + pScreen->SaveScreen = MgxSaveScreen; + + /* Report any unused options (only for the first generation) */ + if (serverGeneration == 1) { + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + } + + /* unblank the screen */ + MgxSaveScreen(pScreen, SCREEN_SAVER_OFF); + + /* Done */ + return TRUE; +} + + +/* Usually mandatory */ +static Bool +MgxSwitchMode(SWITCH_MODE_ARGS_DECL) +{ + return TRUE; +} + + +/* + * This function is used to initialize the Start Address - the first + * displayed location in the video memory. + */ +/* Usually mandatory */ +static void +MgxAdjustFrame(ADJUST_FRAME_ARGS_DECL) +{ + /* we don't support virtual desktops */ + return; +} + +/* + * This is called when VT switching back to the X server. Its job is + * to reinitialise the video mode. + */ + +/* Mandatory */ +static Bool +MgxEnterVT(VT_FUNC_ARGS_DECL) +{ + SCRN_INFO_PTR(arg); + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + + if (pMgx->HWCursor) { + xf86SbusHideOsHwCursor (pMgx->psdp); + } + return TRUE; +} + + +/* + * This is called when VT switching away from the X server. + */ + +/* Mandatory */ +static void +MgxLeaveVT(VT_FUNC_ARGS_DECL) +{ + return; +} + + +/* + * This is called at the end of each server generation. It restores the + * original (text) mode. It should really also unmap the video memory too. + */ + +/* Mandatory */ +static Bool +MgxCloseScreen(CLOSE_SCREEN_ARGS_DECL) +{ + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + + pScrn->vtSema = FALSE; + xf86UnmapSbusMem(pMgx->psdp, pMgx->fb, pMgx->vramsize); + if (pMgx->blt) + xf86UnmapSbusMem(pMgx->psdp, pMgx->blt, 0x1000); + + if (pMgx->HWCursor) + xf86SbusHideOsHwCursor (pMgx->psdp); + + pScreen->CloseScreen = pMgx->CloseScreen; + return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); +} + + +/* Free up any per-generation data structures */ + +/* Optional */ +static void +MgxFreeScreen(FREE_SCREEN_ARGS_DECL) +{ + SCRN_INFO_PTR(arg); + MgxFreeRec(pScrn); +} + + +/* Checks if a mode is suitable for the selected chipset. */ + +/* Optional */ +static ModeStatus +MgxValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) +{ + if (mode->Flags & V_INTERLACE) + return(MODE_BAD); + + return(MODE_OK); +} + +/* Do screen blanking */ + +/* Mandatory */ +static Bool +MgxSaveScreen(ScreenPtr pScreen, int mode) + /* this function should blank the screen when unblank is FALSE and + unblank it when unblank is TRUE -- it doesn't actually seem to be + used for much though */ +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MgxPtr pMgx = GET_MGX_FROM_SCRN(pScrn); + int fd = pMgx->psdp->fd, state; + + switch(mode) + { + case SCREEN_SAVER_ON: + case SCREEN_SAVER_CYCLE: + state = 0; + if(ioctl(fd, FBIOSVIDEO, &state) == -1) + { + /* complain */ + } + break; + case SCREEN_SAVER_OFF: + case SCREEN_SAVER_FORCER: + state = 1; + if(ioctl(fd, FBIOSVIDEO, &state) == -1) + { + /* complain */ + } + break; + default: + return FALSE; + } + + return TRUE; +} + +/* + * This is the implementation of the Sync() function. + */ +void +MgxSync(ScrnInfoPtr pScrn) +{ + return; +} + +static Bool +MgxDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, + pointer ptr) +{ + xorgHWFlags *flag; + + switch (op) { + case GET_REQUIRED_HW_INTERFACES: + flag = (CARD32*)ptr; + (*flag) = HW_MMIO; + return TRUE; + default: + return FALSE; + } +}