2001-06-03 20:48:19 +02:00
|
|
|
|
/*
|
|
|
|
|
* Copyright <EFBFBD> 2001 Keith Packard
|
|
|
|
|
*
|
|
|
|
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
|
|
|
* documentation for any purpose is hereby granted without fee, provided that
|
|
|
|
|
* the above copyright notice appear in all copies and that both that
|
|
|
|
|
* copyright notice and this permission notice appear in supporting
|
|
|
|
|
* documentation, and that the name of Keith Packard not be used in
|
|
|
|
|
* advertising or publicity pertaining to distribution of the software without
|
|
|
|
|
* specific, written prior permission. Keith Packard makes no
|
|
|
|
|
* representations about the suitability of this software for any purpose. It
|
|
|
|
|
* is provided "as is" without express or implied warranty.
|
|
|
|
|
*
|
|
|
|
|
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
|
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
|
|
|
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
|
|
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
|
|
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
|
|
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
|
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
|
*/
|
2001-06-23 05:41:24 +02:00
|
|
|
|
/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64.c,v 1.4 2001/06/19 09:31:47 keithp Exp $ */
|
2001-06-03 20:48:19 +02:00
|
|
|
|
|
|
|
|
|
#include "mach64.h"
|
|
|
|
|
#include <sys/io.h>
|
|
|
|
|
|
|
|
|
|
Bool
|
|
|
|
|
mach64CardInit (KdCardInfo *card)
|
|
|
|
|
{
|
|
|
|
|
Mach64CardInfo *mach64c;
|
|
|
|
|
|
|
|
|
|
mach64c = (Mach64CardInfo *) xalloc (sizeof (Mach64CardInfo));
|
|
|
|
|
if (!mach64c)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
mach64c->reg_base = (CARD8 *) KdMapDevice (MACH64_REG_BASE(card),
|
|
|
|
|
MACH64_REG_SIZE(card));
|
|
|
|
|
|
|
|
|
|
if (mach64c->reg_base)
|
|
|
|
|
{
|
|
|
|
|
KdSetMappedMode (MACH64_REG_BASE(card),
|
|
|
|
|
MACH64_REG_SIZE(card),
|
|
|
|
|
KD_MAPPED_MODE_REGISTERS);
|
|
|
|
|
}
|
|
|
|
|
mach64c->reg = (Reg *) (mach64c->reg_base + MACH64_REG_OFF(card));
|
|
|
|
|
mach64c->media_reg = (MediaReg *) (mach64c->reg_base + MACH64_MEDIA_REG_OFF(card));
|
2001-06-16 07:48:49 +02:00
|
|
|
|
mach64c->lcdEnabled = FALSE;
|
2001-06-03 20:48:19 +02:00
|
|
|
|
|
|
|
|
|
if (!vesaInitialize (card, &mach64c->vesa))
|
|
|
|
|
{
|
|
|
|
|
xfree (mach64c);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
card->driver = mach64c;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool
|
|
|
|
|
mach64ScreenInit (KdScreenInfo *screen)
|
|
|
|
|
{
|
|
|
|
|
Mach64CardInfo *mach64c = screen->card->driver;
|
|
|
|
|
Mach64ScreenInfo *mach64s;
|
|
|
|
|
int screen_size, memory;
|
|
|
|
|
|
|
|
|
|
mach64s = (Mach64ScreenInfo *) xalloc (sizeof (Mach64ScreenInfo));
|
|
|
|
|
if (!mach64s)
|
|
|
|
|
return FALSE;
|
|
|
|
|
memset (mach64s, '\0', sizeof (Mach64ScreenInfo));
|
|
|
|
|
if (!vesaScreenInitialize (screen, &mach64s->vesa))
|
|
|
|
|
{
|
|
|
|
|
xfree (mach64s);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
if (!mach64c->reg)
|
|
|
|
|
screen->dumb = TRUE;
|
|
|
|
|
if (mach64s->vesa.mapping != VESA_LINEAR)
|
|
|
|
|
screen->dumb = TRUE;
|
|
|
|
|
mach64s->screen = mach64s->vesa.fb;
|
2001-06-19 11:31:47 +02:00
|
|
|
|
switch (screen->fb[0].depth) {
|
|
|
|
|
case 8:
|
|
|
|
|
mach64s->colorKey = 0xff;
|
|
|
|
|
break;
|
|
|
|
|
case 15:
|
|
|
|
|
case 16:
|
|
|
|
|
mach64s->colorKey = 0x001e;
|
|
|
|
|
break;
|
|
|
|
|
case 24:
|
|
|
|
|
mach64s->colorKey = 0x0000fe;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
mach64s->colorKey = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-06-03 20:48:19 +02:00
|
|
|
|
memory = mach64s->vesa.fb_size;
|
|
|
|
|
screen_size = screen->fb[0].byteStride * screen->height;
|
|
|
|
|
if (mach64s->screen && memory >= screen_size + 2048)
|
|
|
|
|
{
|
|
|
|
|
memory -= 2048;
|
|
|
|
|
mach64s->cursor_base = mach64s->screen + memory - 2048;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
mach64s->cursor_base = 0;
|
|
|
|
|
screen->softCursor = TRUE; /* XXX for now */
|
|
|
|
|
memory -= screen_size;
|
|
|
|
|
if (memory > screen->fb[0].byteStride)
|
|
|
|
|
{
|
|
|
|
|
mach64s->off_screen = mach64s->screen + screen_size;
|
|
|
|
|
mach64s->off_screen_size = memory;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mach64s->off_screen = 0;
|
|
|
|
|
mach64s->off_screen_size = 0;
|
|
|
|
|
}
|
|
|
|
|
screen->driver = mach64s;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool
|
|
|
|
|
mach64InitScreen (ScreenPtr pScreen)
|
|
|
|
|
{
|
2001-06-16 07:48:49 +02:00
|
|
|
|
#ifdef XV
|
2001-06-19 11:31:47 +02:00
|
|
|
|
KdScreenPriv(pScreen);
|
|
|
|
|
Mach64CardInfo *mach64c = pScreenPriv->screen->card->driver;
|
|
|
|
|
if (mach64c->media_reg && mach64c->reg)
|
|
|
|
|
mach64InitVideo(pScreen);
|
2001-06-16 07:48:49 +02:00
|
|
|
|
#endif
|
2001-06-03 20:48:19 +02:00
|
|
|
|
return vesaInitScreen (pScreen);
|
|
|
|
|
}
|
|
|
|
|
|
2001-06-04 11:45:42 +02:00
|
|
|
|
#ifdef RANDR
|
|
|
|
|
mach64RandRSetConfig (ScreenPtr pScreen,
|
|
|
|
|
Rotation rotation,
|
|
|
|
|
RRScreenSizePtr pSize,
|
|
|
|
|
RRVisualGroupPtr pVisualGroup)
|
|
|
|
|
{
|
|
|
|
|
KdScreenPriv(pScreen);
|
|
|
|
|
|
|
|
|
|
KdCheckSync (pScreen);
|
|
|
|
|
|
|
|
|
|
if (!vesaRandRSetConfig (pScreen, rotation, pSize, pVisualGroup))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
mach64RandRInit (ScreenPtr pScreen)
|
|
|
|
|
{
|
|
|
|
|
rrScrPriv(pScreen);
|
|
|
|
|
|
|
|
|
|
pScrPriv->rrSetConfig = mach64RandRSetConfig;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
Bool
|
|
|
|
|
mach64FinishInitScreen (ScreenPtr pScreen)
|
|
|
|
|
{
|
|
|
|
|
Bool ret;
|
|
|
|
|
ret = vesaFinishInitScreen (pScreen);
|
|
|
|
|
#ifdef RANDR
|
|
|
|
|
mach64RandRInit (pScreen);
|
|
|
|
|
#endif
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2001-06-03 20:48:19 +02:00
|
|
|
|
CARD32
|
|
|
|
|
mach64ReadLCD (Reg *reg, int id)
|
|
|
|
|
{
|
|
|
|
|
CARD32 LCD_INDEX;
|
|
|
|
|
|
|
|
|
|
LCD_INDEX = reg->LCD_INDEX & ~(0x3f);
|
|
|
|
|
reg->LCD_INDEX = (LCD_INDEX | id);
|
|
|
|
|
return reg->LCD_DATA;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
mach64WriteLCD (Reg *reg, int id, CARD32 data)
|
|
|
|
|
{
|
|
|
|
|
CARD32 LCD_INDEX;
|
|
|
|
|
|
|
|
|
|
LCD_INDEX = reg->LCD_INDEX & ~(0x3f);
|
|
|
|
|
reg->LCD_INDEX = (LCD_INDEX | id);
|
|
|
|
|
reg->LCD_DATA = data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
mach64Preserve (KdCardInfo *card)
|
|
|
|
|
{
|
|
|
|
|
Mach64CardInfo *mach64c = card->driver;
|
|
|
|
|
Reg *reg = mach64c->reg;
|
|
|
|
|
|
|
|
|
|
vesaPreserve(card);
|
|
|
|
|
if (reg)
|
2001-06-23 05:41:24 +02:00
|
|
|
|
{
|
2001-06-16 07:48:49 +02:00
|
|
|
|
mach64c->save.LCD_GEN_CTRL = mach64ReadLCD (reg, 1);
|
2001-06-23 05:41:24 +02:00
|
|
|
|
}
|
2001-06-03 20:48:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
mach64SetMMIO (Mach64CardInfo *mach64c)
|
|
|
|
|
{
|
|
|
|
|
if (mach64c->reg->GUI_STAT == 0xffffffff)
|
|
|
|
|
FatalError ("Mach64 REG not visible\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
mach64ResetMMIO (Mach64CardInfo *mach64c)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool
|
|
|
|
|
mach64Enable (ScreenPtr pScreen)
|
|
|
|
|
{
|
|
|
|
|
KdScreenPriv(pScreen);
|
|
|
|
|
Mach64CardInfo *mach64c = pScreenPriv->card->driver;
|
|
|
|
|
|
|
|
|
|
if (!vesaEnable (pScreen))
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
mach64SetMMIO (mach64c);
|
|
|
|
|
mach64DPMS (pScreen, KD_DPMS_NORMAL);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
mach64Disable (ScreenPtr pScreen)
|
|
|
|
|
{
|
|
|
|
|
vesaDisable (pScreen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const CARD8 mach64DPMSModes[4] = {
|
|
|
|
|
0x80, /* KD_DPMS_NORMAL */
|
|
|
|
|
0x8c, /* KD_DPMS_STANDBY */
|
|
|
|
|
0x8c, /* KD_DPMS_STANDBY */
|
|
|
|
|
0x8c, /* KD_DPMS_STANDBY */
|
|
|
|
|
/* 0xb0, /* KD_DPMS_SUSPEND */
|
|
|
|
|
/* 0xbc, /* KD_DPMS_POWERDOWN */
|
|
|
|
|
};
|
|
|
|
|
|
2001-06-16 07:48:49 +02:00
|
|
|
|
#define PWR_MGT_ON (1 << 0)
|
|
|
|
|
#define PWR_MGT_MODE (3 << 1)
|
|
|
|
|
#define PWR_MGT_MODE_PIN (0 << 1)
|
|
|
|
|
#define PWR_MGT_MODE_REG (1 << 1)
|
|
|
|
|
#define PWR_MGT_MODE_TIMER (2 << 1)
|
|
|
|
|
#define PWR_MGR_MODE_PCI (3 << 1)
|
|
|
|
|
#define AUTO_PWRUP_EN (1 << 3)
|
|
|
|
|
#define ACTIVITY_PIN_ON (1 << 4)
|
|
|
|
|
#define STANDBY_POL (1 << 5)
|
|
|
|
|
#define SUSPEND_POL (1 << 6)
|
|
|
|
|
#define SELF_REFRESH (1 << 7)
|
|
|
|
|
#define ACTIVITY_PIN_EN (1 << 8)
|
|
|
|
|
#define KEYBD_SNOOP (1 << 9)
|
|
|
|
|
#define DONT_USE_F32KHZ (1 << 10)
|
|
|
|
|
#define TRISTATE_MEM_EN (1 << 11)
|
|
|
|
|
#define LCDENG_TEST_MODE (0xf << 12)
|
|
|
|
|
#define STANDBY_COUNT (0xf << 16)
|
|
|
|
|
#define SUSPEND_COUNT (0xf << 20)
|
|
|
|
|
#define BIASON (1 << 24)
|
|
|
|
|
#define BLON (1 << 25)
|
|
|
|
|
#define DIGON (1 << 26)
|
|
|
|
|
#define PM_D3_RST_ENB (1 << 27)
|
|
|
|
|
#define STANDBY_NOW (1 << 28)
|
|
|
|
|
#define SUSPEND_NOW (1 << 29)
|
|
|
|
|
#define PWR_MGT_STATUS (3 << 30)
|
|
|
|
|
#define PWR_MGT_STATUS_ON (0 << 30)
|
|
|
|
|
#define PWR_MGT_STATUS_STANDBY (1 << 30)
|
|
|
|
|
#define PWR_MGT_STATUS_SUSPEND (2 << 30)
|
|
|
|
|
#define PWR_MGT_STATUS_TRANSITION (3 << 30)
|
|
|
|
|
|
2001-06-03 20:48:19 +02:00
|
|
|
|
Bool
|
|
|
|
|
mach64DPMS (ScreenPtr pScreen, int mode)
|
|
|
|
|
{
|
|
|
|
|
KdScreenPriv(pScreen);
|
|
|
|
|
Mach64CardInfo *mach64c = pScreenPriv->card->driver;
|
|
|
|
|
int hsync_off, vsync_off, blank;
|
|
|
|
|
CARD32 CRTC_GEN_CNTL;
|
2001-06-16 07:48:49 +02:00
|
|
|
|
CARD32 LCD_GEN_CTRL;
|
2001-06-03 20:48:19 +02:00
|
|
|
|
Reg *reg = mach64c->reg;
|
|
|
|
|
|
|
|
|
|
if (!reg)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
CRTC_GEN_CNTL = reg->CRTC_GEN_CNTL;
|
2001-06-16 07:48:49 +02:00
|
|
|
|
LCD_GEN_CTRL = mach64ReadLCD (reg, 1);
|
|
|
|
|
|
2001-06-03 20:48:19 +02:00
|
|
|
|
switch (mode) {
|
|
|
|
|
case KD_DPMS_NORMAL:
|
|
|
|
|
hsync_off = 0;
|
|
|
|
|
vsync_off = 0;
|
|
|
|
|
blank = 0;
|
|
|
|
|
break;
|
|
|
|
|
case KD_DPMS_STANDBY:
|
|
|
|
|
hsync_off = 1;
|
|
|
|
|
vsync_off = 0;
|
|
|
|
|
blank = 1;
|
|
|
|
|
break;
|
|
|
|
|
case KD_DPMS_SUSPEND:
|
|
|
|
|
hsync_off = 0;
|
|
|
|
|
vsync_off = 1;
|
|
|
|
|
blank = 1;
|
|
|
|
|
break;
|
|
|
|
|
case KD_DPMS_POWERDOWN:
|
|
|
|
|
hsync_off = 1;
|
|
|
|
|
vsync_off = 1;
|
|
|
|
|
blank = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hsync_off)
|
|
|
|
|
CRTC_GEN_CNTL |= (1 << 2);
|
|
|
|
|
else
|
|
|
|
|
CRTC_GEN_CNTL &= ~(1 << 2);
|
|
|
|
|
if (vsync_off)
|
|
|
|
|
CRTC_GEN_CNTL |= (1 << 3);
|
|
|
|
|
else
|
|
|
|
|
CRTC_GEN_CNTL &= ~(1 << 3);
|
|
|
|
|
if (blank)
|
2001-06-16 07:48:49 +02:00
|
|
|
|
{
|
|
|
|
|
mach64c->lcdEnabled = (LCD_GEN_CTRL & (1 << 1)) != 0;
|
|
|
|
|
LCD_GEN_CTRL &= ~(1 << 1);
|
2001-06-03 20:48:19 +02:00
|
|
|
|
CRTC_GEN_CNTL |= (1 << 6);
|
2001-06-16 07:48:49 +02:00
|
|
|
|
|
|
|
|
|
}
|
2001-06-03 20:48:19 +02:00
|
|
|
|
else
|
2001-06-16 07:48:49 +02:00
|
|
|
|
{
|
|
|
|
|
if (!(LCD_GEN_CTRL & 3) || mach64c->lcdEnabled)
|
|
|
|
|
LCD_GEN_CTRL |= (1 << 1);
|
2001-06-03 20:48:19 +02:00
|
|
|
|
CRTC_GEN_CNTL &= ~(1 << 6);
|
2001-06-16 07:48:49 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
KdCheckSync (pScreen);
|
|
|
|
|
|
|
|
|
|
mach64WriteLCD (reg, 1, LCD_GEN_CTRL);
|
2001-06-03 20:48:19 +02:00
|
|
|
|
|
|
|
|
|
reg->CRTC_GEN_CNTL = CRTC_GEN_CNTL;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
mach64Restore (KdCardInfo *card)
|
|
|
|
|
{
|
|
|
|
|
Mach64CardInfo *mach64c = card->driver;
|
|
|
|
|
Reg *reg = mach64c->reg;
|
|
|
|
|
|
|
|
|
|
if (reg)
|
2001-06-23 05:41:24 +02:00
|
|
|
|
{
|
2001-06-16 07:48:49 +02:00
|
|
|
|
mach64WriteLCD (reg, 1, mach64c->save.LCD_GEN_CTRL);
|
2001-06-23 05:41:24 +02:00
|
|
|
|
}
|
2001-06-03 20:48:19 +02:00
|
|
|
|
mach64ResetMMIO (mach64c);
|
|
|
|
|
vesaRestore (card);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
mach64ScreenFini (KdScreenInfo *screen)
|
|
|
|
|
{
|
|
|
|
|
Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
|
|
|
|
|
|
|
|
|
|
vesaScreenFini (screen);
|
|
|
|
|
xfree (mach64s);
|
|
|
|
|
screen->driver = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
mach64CardFini (KdCardInfo *card)
|
|
|
|
|
{
|
|
|
|
|
Mach64CardInfo *mach64c = card->driver;
|
|
|
|
|
|
|
|
|
|
if (mach64c->reg_base)
|
|
|
|
|
{
|
|
|
|
|
KdUnmapDevice ((void *) mach64c->reg_base, MACH64_REG_SIZE(card));
|
|
|
|
|
KdResetMappedMode (MACH64_REG_BASE(card),
|
|
|
|
|
MACH64_REG_SIZE(card),
|
|
|
|
|
KD_MAPPED_MODE_REGISTERS);
|
|
|
|
|
}
|
|
|
|
|
vesaCardFini (card);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define mach64CursorInit 0 /* initCursor */
|
|
|
|
|
#define mach64CursorEnable 0 /* enableCursor */
|
|
|
|
|
#define mach64CursorDisable 0 /* disableCursor */
|
|
|
|
|
#define mach64CursorFini 0 /* finiCursor */
|
|
|
|
|
#define mach64RecolorCursor 0 /* recolorCursor */
|
|
|
|
|
|
|
|
|
|
KdCardFuncs mach64Funcs = {
|
|
|
|
|
mach64CardInit, /* cardinit */
|
|
|
|
|
mach64ScreenInit, /* scrinit */
|
|
|
|
|
mach64InitScreen, /* initScreen */
|
|
|
|
|
mach64Preserve, /* preserve */
|
|
|
|
|
mach64Enable, /* enable */
|
|
|
|
|
mach64DPMS, /* dpms */
|
|
|
|
|
mach64Disable, /* disable */
|
|
|
|
|
mach64Restore, /* restore */
|
|
|
|
|
mach64ScreenFini, /* scrfini */
|
|
|
|
|
mach64CardFini, /* cardfini */
|
|
|
|
|
|
|
|
|
|
mach64CursorInit, /* initCursor */
|
|
|
|
|
mach64CursorEnable, /* enableCursor */
|
|
|
|
|
mach64CursorDisable, /* disableCursor */
|
|
|
|
|
mach64CursorFini, /* finiCursor */
|
|
|
|
|
mach64RecolorCursor, /* recolorCursor */
|
|
|
|
|
|
|
|
|
|
mach64DrawInit, /* initAccel */
|
|
|
|
|
mach64DrawEnable, /* enableAccel */
|
|
|
|
|
mach64DrawSync, /* syncAccel */
|
|
|
|
|
mach64DrawDisable, /* disableAccel */
|
|
|
|
|
mach64DrawFini, /* finiAccel */
|
|
|
|
|
|
|
|
|
|
vesaGetColors, /* getColors */
|
|
|
|
|
vesaPutColors, /* putColors */
|
2001-06-04 11:45:42 +02:00
|
|
|
|
|
|
|
|
|
mach64FinishInitScreen, /* finishInitScreen */
|
2001-06-03 20:48:19 +02:00
|
|
|
|
};
|