kdrive: add MTRR support, add clock support to trident driver

This commit is contained in:
Keith Packard 2000-11-29 08:42:25 +00:00
parent 02568ec5a8
commit 5f8e75f27d
8 changed files with 440 additions and 168 deletions

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.h,v 1.8 2000/09/22 06:25:29 keithp Exp $ */ /* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.h,v 1.10 2000/09/27 20:47:37 keithp Exp $ */
#include <stdio.h> #include <stdio.h>
#include "X.h" #include "X.h"
@ -562,12 +562,22 @@ extern KdKeyboardFuncs VxWorksKeyboardFuncs;
extern KdOsFuncs VxWorksFuncs; extern KdOsFuncs VxWorksFuncs;
/* kmap.c */ /* kmap.c */
#define KD_MAPPED_MODE_REGISTERS 0
#define KD_MAPPED_MODE_FRAMEBUFFER 1
void * void *
KdMapDevice (CARD32 addr, CARD32 size); KdMapDevice (CARD32 addr, CARD32 size);
void void
KdUnmapDevice (void *addr, CARD32 size); KdUnmapDevice (void *addr, CARD32 size);
void
KdSetMappedMode (CARD32 addr, CARD32 size, int mode);
void
KdResetMappedMode (CARD32 addr, CARD32 size, int mode);
/* kmode.c */ /* kmode.c */
const KdMonitorTiming * const KdMonitorTiming *
KdFindMode (KdScreenInfo *screen, KdFindMode (KdScreenInfo *screen,

View File

@ -29,6 +29,7 @@
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <asm/mtrr.h>
#endif #endif
void * void *
@ -90,3 +91,72 @@ KdUnmapDevice (void *addr, CARD32 size)
#endif #endif
} }
#ifdef linux
static int mtrr;
#endif
void
KdSetMappedMode (CARD32 addr, CARD32 size, int mode)
{
#ifdef linux
struct mtrr_sentry sentry;
unsigned long base, bound;
unsigned int type;
if (addr < 0x100000)
return;
if (!mtrr)
mtrr = open ("/proc/mtrr", 2);
if (mtrr > 0)
{
base = addr & ~((1<22)-1);
bound = ((addr + size) + ((1<<22) - 1)) & ~((1<<22) - 1);
switch (mode) {
case KD_MAPPED_MODE_REGISTERS:
type = MTRR_TYPE_UNCACHABLE;
break;
case KD_MAPPED_MODE_FRAMEBUFFER:
type = MTRR_TYPE_WRCOMB;
break;
}
sentry.base = base;
sentry.size = bound - base;
sentry.type = type;
ioctl (mtrr, MTRRIOC_ADD_ENTRY, &sentry);
}
#endif
}
void
KdResetMappedMode (CARD32 addr, CARD32 size, int mode)
{
#ifdef linux
struct mtrr_sentry sentry;
unsigned long base, bound;
unsigned int type;
if (addr < 0x100000)
return;
if (!mtrr)
mtrr = open ("/proc/mtrr", 2);
if (mtrr > 0)
{
base = addr & ~((1<22)-1);
bound = ((addr + size) + ((1<<22) - 1)) & ~((1<<22) - 1);
switch (mode) {
case KD_MAPPED_MODE_REGISTERS:
type = MTRR_TYPE_UNCACHABLE;
break;
case KD_MAPPED_MODE_FRAMEBUFFER:
type = MTRR_TYPE_WRCOMB;
break;
}
sentry.base = base;
sentry.size = bound - base;
sentry.type = type;
ioctl (mtrr, MTRRIOC_DEL_ENTRY, &sentry);
}
#endif
}

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/trident.c,v 1.13 2000/10/11 06:04:40 keithp Exp $ */ /* $XFree86: xc/programs/Xserver/hw/kdrive/trident/trident.c,v 1.14 2000/10/20 00:19:51 keithp Exp $ */
#include "trident.h" #include "trident.h"
#define extern #define extern
@ -30,6 +30,15 @@
#undef TRI_DEBUG #undef TRI_DEBUG
int trident_clk = 0;
int trident_mclk = 0;
#define CLOCK 14318 /* KHz */
#define CLK_N(a,b) (a & 0xff)
#define CLK_M(a,b) ((b) & 0x3f)
#define CLK_K(a,b) (((b) >> 6) & 3)
#define CLK_FREQ(a,b) (((CLK_N(a,b) + 8) * CLOCK) / ((CLK_M(a,b)+2) << CLK_K(a,b)))
Bool Bool
tridentCardInit (KdCardInfo *card) tridentCardInit (KdCardInfo *card)
{ {
@ -45,6 +54,13 @@ tridentCardInit (KdCardInfo *card)
iopl (3); iopl (3);
tridentc->cop_base = (CARD8 *) KdMapDevice (TRIDENT_COP_BASE(card), tridentc->cop_base = (CARD8 *) KdMapDevice (TRIDENT_COP_BASE(card),
TRIDENT_COP_SIZE(card)); TRIDENT_COP_SIZE(card));
if (tridentc->cop_base)
{
KdSetMappedMode (TRIDENT_COP_BASE(card),
TRIDENT_COP_SIZE(card),
KD_MAPPED_MODE_REGISTERS);
}
tridentc->cop = (Cop *) (tridentc->cop_base + TRIDENT_COP_OFF(card)); tridentc->cop = (Cop *) (tridentc->cop_base + TRIDENT_COP_OFF(card));
tridentc->mmio = FALSE; tridentc->mmio = FALSE;
r39 = tridentReadIndex (tridentc, 0x3d4, 0x39); r39 = tridentReadIndex (tridentc, 0x3d4, 0x39);
@ -119,18 +135,16 @@ tridentScreenInit (KdScreenInfo *screen)
else else
tridents->cursor_base = 0; tridents->cursor_base = 0;
memory -= screen_size; memory -= screen_size;
#if 0
if (memory > screen->fb[0].byteStride) if (memory > screen->fb[0].byteStride)
{ {
screen->off_screen = tridents->screen + screen_size; tridents->off_screen = tridents->screen + screen_size;
screen->off_screen_size = memory - screen_size; tridents->off_screen_size = memory;
} }
else else
{ {
screen->off_screen = 0; tridents->off_screen = 0;
screen->off_screen_size = 0; tridents->off_screen_size = 0;
} }
#endif
screen->driver = tridents; screen->driver = tridents;
return TRUE; return TRUE;
} }
@ -178,6 +192,36 @@ tridentWriteIndex (TridentCardInfo *tridentc, CARD16 port, CARD8 index, CARD8 va
} }
} }
CARD8
tridentReadReg (TridentCardInfo *tridentc, CARD16 port)
{
CARD8 value;
if (tridentc->mmio)
{
value = tridentc->cop_base[port];
}
else
{
value = inb (port);
}
return value;
}
void
tridentWriteReg (TridentCardInfo *tridentc, CARD16 port, CARD8 value)
{
if (tridentc->mmio)
{
tridentc->cop_base[port] = value;
}
else
{
outb (value, port);
}
}
void void
tridentPause () tridentPause ()
{ {
@ -204,6 +248,16 @@ tridentPreserve (KdCardInfo *card)
tridentc->save.reg_3d4_39 = tridentReadIndex (tridentc, 0x3d4, 0x39); tridentc->save.reg_3d4_39 = tridentReadIndex (tridentc, 0x3d4, 0x39);
tridentc->save.reg_3d4_62 = tridentReadIndex (tridentc, 0x3d4, 0x62); tridentc->save.reg_3d4_62 = tridentReadIndex (tridentc, 0x3d4, 0x62);
tridentc->save.reg_3ce_21 = tridentReadIndex (tridentc, 0x3ce, 0x21); tridentc->save.reg_3ce_21 = tridentReadIndex (tridentc, 0x3ce, 0x21);
tridentc->save.reg_3c2 = tridentReadReg (tridentc, 0x3cc);
tridentc->save.reg_3c4_16 = tridentReadIndex (tridentc, 0x3c4, 0x16);
tridentc->save.reg_3c4_17 = tridentReadIndex (tridentc, 0x3c4, 0x17);
tridentc->save.reg_3c4_18 = tridentReadIndex (tridentc, 0x3c4, 0x18);
tridentc->save.reg_3c4_19 = tridentReadIndex (tridentc, 0x3c4, 0x19);
ErrorF ("clk low 0x%x high 0x%x freq %d\n",
tridentc->save.reg_3c4_18,
tridentc->save.reg_3c4_19,
CLK_FREQ(tridentc->save.reg_3c4_18,
tridentc->save.reg_3c4_19));
#ifdef TRI_DEBUG #ifdef TRI_DEBUG
fprintf (stderr, "3c4 0e: %02x\n", tridentc->save.reg_3c4_0e); fprintf (stderr, "3c4 0e: %02x\n", tridentc->save.reg_3c4_0e);
fprintf (stderr, "3d4 36: %02x\n", tridentc->save.reg_3d4_36); fprintf (stderr, "3d4 36: %02x\n", tridentc->save.reg_3d4_36);
@ -215,6 +269,98 @@ tridentPreserve (KdCardInfo *card)
tridentPause (); tridentPause ();
} }
void
tridentSetCLK(int clock, CARD8 *a, CARD8 *b)
{
int powerup[4] = { 1,2,4,8 };
int clock_diff = 750;
int freq, ffreq;
int m, n, k;
int p, q, r, s;
int startn, endn;
int endm, endk;
p = q = r = s = 0;
startn = 64;
endn = 255;
endm = 63;
endk = 3;
freq = clock;
for (k=0;k<=endk;k++)
for (n=startn;n<=endn;n++)
for (m=1;m<=endm;m++)
{
ffreq = ( ( ((n + 8) * CLOCK) / ((m + 2) * powerup[k]) ));
if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff))
{
clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq;
p = n; q = m; r = k; s = ffreq;
}
}
ErrorF ("ffreq %d clock %d\n", s, clock);
if (s == 0)
{
FatalError("Unable to set programmable clock.\n"
"Frequency %d is not a valid clock.\n"
"Please modify XF86Config for a new clock.\n",
freq);
}
/* N is all 8bits */
*a = p;
/* M is first 6bits, with K last 2bits */
*b = (q & 0x3F) | (r << 6);
}
void
tridentSetMCLK(int clock, CARD8 *a, CARD8 *b)
{
int powerup[4] = { 1,2,4,8 };
int clock_diff = 750;
int freq, ffreq;
int m,n,k;
int p, q, r, s;
int startn, endn;
int endm, endk;
p = q = r = s = 0;
startn = 64;
endn = 255;
endm = 63;
endk = 3;
freq = clock;
for (k=0;k<=endk;k++)
for (n=startn;n<=endn;n++)
for (m=1;m<=endm;m++) {
ffreq = ((((n+8)*CLOCK)/((m+2)*powerup[k])));
if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff))
{
clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq;
p = n; q = m; r = k; s = ffreq;
}
}
if (s == 0)
{
FatalError("Unable to set memory clock.\n"
"Frequency %d is not a valid clock.\n"
"Please modify XF86Config for a new clock.\n",
freq);
}
/* N is all 8bits */
*a = p;
/* M is first 6bits, with K last 2bits */
*b = (q & 0x3F) | (r << 6);
}
void void
tridentSetMMIO (TridentCardInfo *tridentc) tridentSetMMIO (TridentCardInfo *tridentc)
{ {
@ -255,6 +401,46 @@ tridentSetMMIO (TridentCardInfo *tridentc)
/* reset GE, enable GE, set GE to 0xbff00 */ /* reset GE, enable GE, set GE to 0xbff00 */
tridentWriteIndex (tridentc, 0x3d4, 0x36, 0x92); tridentWriteIndex (tridentc, 0x3d4, 0x36, 0x92);
#endif #endif
/* set clock */
if (trident_clk)
{
CARD8 a, b;
a = tridentReadIndex (tridentc, 0x3c4, 0x18);
b = tridentReadIndex (tridentc, 0x3c4, 0x19);
ErrorF ("old clock 0x%x 0x%x %d\n",
a, b, CLK_FREQ(a,b));
tridentSetCLK (trident_clk, &a, &b);
ErrorF ("clk %d-> 0x%x 0x%x %d\n", trident_clk, a, b,
CLK_FREQ(a,b));
#if 1
tridentWriteIndex (tridentc, 0x3c4, 0x18, a);
tridentWriteIndex (tridentc, 0x3c4, 0x19, b);
#endif
}
if (trident_mclk)
{
CARD8 a, b;
tridentSetMCLK (trident_mclk, &a, &b);
ErrorF ("mclk %d -> 0x%x 0x%x\n", trident_mclk, a, b);
#if 0
tridentWriteIndex (tridentc, 0x3c4, 0x16, a);
tridentWriteIndex (tridentc, 0x3c4, 0x17, b);
#endif
}
if (trident_clk || trident_mclk)
{
CARD8 mode;
mode = tridentReadReg (tridentc, 0x3cc);
ErrorF ("old mode 0x%x\n", mode);
mode = (mode & 0xf3) | 0x08;
ErrorF ("new mode 0x%x\n", mode);
#if 1
tridentWriteReg (tridentc, 0x3c2, mode);
#endif
}
#ifdef TRI_DEBUG #ifdef TRI_DEBUG
fprintf (stderr, "0x36: 0x%02x\n", fprintf (stderr, "0x36: 0x%02x\n",
tridentReadIndex (tridentc, 0x3d4, 0x36)); tridentReadIndex (tridentc, 0x3d4, 0x36));
@ -276,6 +462,14 @@ tridentResetMMIO (TridentCardInfo *tridentc)
fprintf (stderr, "Reset MMIO\n"); fprintf (stderr, "Reset MMIO\n");
#endif #endif
tridentPause (); tridentPause ();
#if 0
tridentWriteIndex (tridentc, 0x3c4, 0x16, tridentc->save.reg_3c4_16);
tridentWriteIndex (tridentc, 0x3c4, 0x17, tridentc->save.reg_3c4_17);
#endif
tridentWriteIndex (tridentc, 0x3c4, 0x18, tridentc->save.reg_3c4_18);
tridentWriteIndex (tridentc, 0x3c4, 0x19, tridentc->save.reg_3c4_19);
tridentWriteReg (tridentc, 0x3c2, tridentc->save.reg_3c2);
tridentPause ();
tridentWriteIndex (tridentc, 0x3ce, 0x21, tridentc->save.reg_3ce_21); tridentWriteIndex (tridentc, 0x3ce, 0x21, tridentc->save.reg_3ce_21);
tridentPause (); tridentPause ();
tridentWriteIndex (tridentc, 0x3d4, 0x62, tridentc->save.reg_3d4_62); tridentWriteIndex (tridentc, 0x3d4, 0x62, tridentc->save.reg_3d4_62);
@ -364,7 +558,12 @@ tridentCardFini (KdCardInfo *card)
TridentCardInfo *tridentc = card->driver; TridentCardInfo *tridentc = card->driver;
if (tridentc->cop_base) if (tridentc->cop_base)
{
KdUnmapDevice ((void *) tridentc->cop_base, TRIDENT_COP_SIZE(card)); KdUnmapDevice ((void *) tridentc->cop_base, TRIDENT_COP_SIZE(card));
KdResetMappedMode (TRIDENT_COP_BASE(card),
TRIDENT_COP_SIZE(card),
KD_MAPPED_MODE_REGISTERS);
}
#ifdef VESA #ifdef VESA
vesaCardFini (card); vesaCardFini (card);
#else #else

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/trident.h,v 1.7 2000/10/11 06:04:40 keithp Exp $ */ /* $XFree86: xc/programs/Xserver/hw/kdrive/trident/trident.h,v 1.8 2000/10/20 00:19:51 keithp Exp $ */
#ifndef _TRIDENT_H_ #ifndef _TRIDENT_H_
#define _TRIDENT_H_ #define _TRIDENT_H_
@ -179,6 +179,11 @@ typedef struct _tridentSave {
CARD8 reg_3d4_39; CARD8 reg_3d4_39;
CARD8 reg_3d4_62; /* GE setup */ CARD8 reg_3d4_62; /* GE setup */
CARD8 reg_3ce_21; /* DPMS */ CARD8 reg_3ce_21; /* DPMS */
CARD8 reg_3c2; /* clock config */
CARD8 reg_3c4_16; /* MCLKLow */
CARD8 reg_3c4_17; /* MCLKHigh */
CARD8 reg_3c4_18; /* ClockLow */
CARD8 reg_3c4_19; /* ClockHigh */
} TridentSave; } TridentSave;
typedef struct _tridentCardInfo { typedef struct _tridentCardInfo {

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/tridentdraw.c,v 1.5 2000/08/26 00:17:50 keithp Exp $ */ /* $XFree86: xc/programs/Xserver/hw/kdrive/trident/tridentdraw.c,v 1.6 2000/10/11 06:04:40 keithp Exp $ */
#include "trident.h" #include "trident.h"
#include "tridentdraw.h" #include "tridentdraw.h"
@ -701,25 +701,37 @@ tridentComposite (CARD8 op,
CARD16 height) CARD16 height)
{ {
SetupTrident (pDst->pDrawable->pScreen); SetupTrident (pDst->pDrawable->pScreen);
RegionRec region; tridentScreenInfo(pScreenPriv);
int n; RegionRec region;
BoxPtr pbox; int n;
BoxPtr pbox;
CARD32 rgb; CARD32 rgb;
CARD8 *msk, *mskLine; CARD8 *msk, *mskLine;
FbBits *mskBits; FbBits *mskBits;
FbStride mskStride; FbStride mskStride;
int mskBpp; int mskBpp;
CARD32 *src, *srcLine; CARD32 *src, *srcLine;
CARD32 *off, *offLine;
FbBits *srcBits; FbBits *srcBits;
FbStride srcStride; FbStride srcStride;
FbStride offStride;
int srcBpp; int srcBpp;
int x_msk, y_msk, x_src, y_src, x_dst, y_dst; int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
int x2; int x2;
int w, h, w_this, h_this, w_remain; int w, h, w_this, h_this, w_remain;
int win_remain; CARD32 *off_screen;
CARD32 *window; int off_size = tridents->off_screen_size >> 2;
int off_width, off_height;
int stride = pScreenPriv->screen->fb[0].pixelStride;
int mskExtra; int mskExtra;
CARD32 off_screen_offset = tridents->off_screen - tridents->screen;
int mode;
#define MODE_NONE 0
#define MODE_IMAGE 1
#define MODE_MASK 2
rgb = *((CARD32 *) ((PixmapPtr) (pSrc->pDrawable))->devPrivate.ptr);
if (pMask && if (pMask &&
!pMask->repeat && !pMask->repeat &&
pMask->format == PICT_a8 && pMask->format == PICT_a8 &&
@ -729,109 +741,11 @@ tridentComposite (CARD8 op,
pSrc->pDrawable->height == 1 && pSrc->pDrawable->height == 1 &&
PICT_FORMAT_BPP(pSrc->format) == 32 && PICT_FORMAT_BPP(pSrc->format) == 32 &&
(PICT_FORMAT_A(pSrc->format) == 0 || (PICT_FORMAT_A(pSrc->format) == 0 ||
((rgb = (*((CARD32 *) ((PixmapPtr) (pSrc->pDrawable))->devPrivate.ptr)) (rgb & 0xff000000) == 0xff000000) &&
& 0xff000000) == 0xff000000)) &&
pDst->pDrawable->bitsPerPixel == 32 && pDst->pDrawable->bitsPerPixel == 32 &&
pDst->pDrawable->type == DRAWABLE_WINDOW) pDst->pDrawable->type == DRAWABLE_WINDOW)
{ {
xDst += pDst->pDrawable->x; mode = MODE_MASK;
yDst += pDst->pDrawable->y;
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
if (pMask)
{
xMask += pMask->pDrawable->x;
yMask += pMask->pDrawable->y;
}
rgb = (*((CARD32 *) ((PixmapPtr) (pSrc->pDrawable))->devPrivate.ptr)
& 0xffffff);
if (!miComputeCompositeRegion (&region,
pSrc,
pMask,
pDst,
xSrc,
ySrc,
xMask,
yMask,
xDst,
yDst,
width,
height))
return;
fbGetDrawable (pMask->pDrawable, mskBits, mskStride, mskBpp);
mskStride = mskStride * sizeof (FbBits) / sizeof (CARD8);
cop->multi = (COP_MULTI_ROP | 0xcc);
cop->multi = (COP_MULTI_ALPHA |
COP_ALPHA_BLEND_ENABLE |
COP_ALPHA_WRITE_ENABLE |
0x7 << 16 |
COP_ALPHA_DST_BLEND_1_SRC_A |
COP_ALPHA_SRC_BLEND_SRC_A);
n = REGION_NUM_RECTS (&region);
pbox = REGION_RECTS (&region);
while (n--)
{
h = pbox->y2 - pbox->y1;
x2 = pbox->x2;
w = x2 - pbox->x1;
cop->multi = COP_MULTI_CLIP_TOP_LEFT | TRI_XY(0,0);
cop->clip_bottom_right = TRI_XY(x2-1, 0xfff);
if (w & 1)
{
x2++;
w++;
}
y_msk = pbox->y1 - yDst + yMask;
y_dst = pbox->y1;
x_msk = pbox->x1 - xDst + xMask;
x_dst = pbox->x1;
mskLine = (CARD8 *) mskBits + y_msk * mskStride + x_msk;
cop->dst_start_xy = TRI_XY(pbox->x1, pbox->y1);
cop->dst_end_xy = TRI_XY(x2-1,pbox->y2-1);
_tridentWaitDone(cop);
cop->command = (COP_OP_BLT | COP_SCL_OPAQUE | COP_CLIP | COP_OP_ROP);
win_remain = 0;
while (h--)
{
w_remain = w;
msk = mskLine;
mskLine += mskStride;
while (w_remain)
{
if (!win_remain)
{
window = tridentc->window;
win_remain = 0x1000 / 4;
}
w_this = w_remain;
if (w_this > win_remain)
w_this = win_remain;
win_remain -= w_this;
w_remain -= w_this;
while (w_this--)
*window++ = rgb | (*msk++ << 24);
}
}
pbox++;
}
cop->multi = TridentAlpha;
cop->clip_bottom_right = 0x0fff0fff;
KdMarkSync (pDst->pDrawable->pScreen);
} }
else if (!pMask && else if (!pMask &&
op == PictOpOver && op == PictOpOver &&
@ -840,15 +754,27 @@ tridentComposite (CARD8 op,
PICT_FORMAT_BPP(pSrc->format) == 32 && PICT_FORMAT_BPP(pSrc->format) == 32 &&
pDst->pDrawable->bitsPerPixel == 32 && pDst->pDrawable->bitsPerPixel == 32 &&
pDst->pDrawable->type == DRAWABLE_WINDOW) pDst->pDrawable->type == DRAWABLE_WINDOW)
{
mode = MODE_IMAGE;
}
else
mode = MODE_NONE;
if (mode != MODE_NONE)
{ {
xDst += pDst->pDrawable->x; xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y; yDst += pDst->pDrawable->y;
xSrc += pSrc->pDrawable->x; xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y; ySrc += pSrc->pDrawable->y;
fbGetDrawable (pSrc->pDrawable, srcBits, srcStride, srcBpp);
if (pMask) if (pMask)
{ {
xMask += pMask->pDrawable->x; xMask += pMask->pDrawable->x;
yMask += pMask->pDrawable->y; yMask += pMask->pDrawable->y;
fbGetDrawable (pMask->pDrawable, mskBits, mskStride, mskBpp);
mskStride = mskStride * sizeof (FbBits) / sizeof (CARD8);
} }
if (!miComputeCompositeRegion (&region, if (!miComputeCompositeRegion (&region,
@ -865,16 +791,30 @@ tridentComposite (CARD8 op,
height)) height))
return; return;
fbGetDrawable (pSrc->pDrawable, srcBits, srcStride, srcBpp); _tridentInit(cop,tridentc);
cop->multi = (COP_MULTI_ROP | 0xcc); cop->multi = COP_MULTI_PATTERN;
cop->src_offset = off_screen_offset;
cop->multi = (COP_MULTI_ALPHA | if (mode == MODE_IMAGE)
COP_ALPHA_BLEND_ENABLE | {
COP_ALPHA_WRITE_ENABLE | cop->multi = (COP_MULTI_ALPHA |
0x7 << 16 | COP_ALPHA_BLEND_ENABLE |
COP_ALPHA_DST_BLEND_1_SRC_A | COP_ALPHA_WRITE_ENABLE |
COP_ALPHA_SRC_BLEND_1); 0x7 << 16 |
COP_ALPHA_DST_BLEND_1_SRC_A |
COP_ALPHA_SRC_BLEND_1);
}
else
{
rgb &= 0xffffff;
cop->multi = (COP_MULTI_ALPHA |
COP_ALPHA_BLEND_ENABLE |
COP_ALPHA_WRITE_ENABLE |
0x7 << 16 |
COP_ALPHA_DST_BLEND_1_SRC_A |
COP_ALPHA_SRC_BLEND_SRC_A);
}
n = REGION_NUM_RECTS (&region); n = REGION_NUM_RECTS (&region);
pbox = REGION_RECTS (&region); pbox = REGION_RECTS (&region);
@ -882,59 +822,79 @@ tridentComposite (CARD8 op,
while (n--) while (n--)
{ {
h = pbox->y2 - pbox->y1; h = pbox->y2 - pbox->y1;
x2 = pbox->x2; w = pbox->x2 - pbox->x1;
w = x2 - pbox->x1;
cop->multi = COP_MULTI_CLIP_TOP_LEFT | TRI_XY(0,0); offStride = (w + 7) & ~7;
cop->clip_bottom_right = TRI_XY(x2-1, 0xfff); off_height = off_size / offStride;
if (w & 1) if (off_height > h)
{ off_height = h;
x2++;
w++; cop->multi = COP_MULTI_STRIDE | (stride << 16) | offStride;
}
y_src = pbox->y1 - yDst + ySrc;
y_dst = pbox->y1; y_dst = pbox->y1;
x_src = pbox->x1 - xDst + xSrc; y_src = y_dst - yDst + ySrc;
y_msk = y_dst - yDst + yMask;
x_dst = pbox->x1; x_dst = pbox->x1;
x_src = x_dst - xDst + xSrc;
x_msk = x_dst - xDst + xMask;
srcLine = srcBits + y_src * srcStride + x_src; if (mode == MODE_IMAGE)
srcLine = (CARD32 *) srcBits + y_src * srcStride + x_src;
cop->dst_start_xy = TRI_XY(pbox->x1, pbox->y1); else
cop->dst_end_xy = TRI_XY(x2-1,pbox->y2-1); mskLine = (CARD8 *) mskBits + y_msk * mskStride + x_msk;
_tridentWaitDone(cop); while (h)
cop->command = (COP_OP_BLT | COP_SCL_OPAQUE | COP_OP_ROP | COP_CLIP);
win_remain = 0;
while (h--)
{ {
w_remain = w; h_this = h;
src = srcLine; if (h_this > off_height)
srcLine += srcStride; h_this = off_height;
while (w_remain) h -= h_this;
offLine = (CARD32 *) tridents->off_screen;
_tridentWaitDone(cop);
cop->dst_start_xy = TRI_XY(x_dst, y_dst);
cop->dst_end_xy = TRI_XY(x_dst + w - 1, y_dst + h_this - 1);
cop->src_start_xy = TRI_XY(0,0);
cop->src_end_xy = TRI_XY(w - 1, h_this - 1);
if (mode == MODE_IMAGE)
{ {
if (!win_remain) while (h_this--)
{ {
window = tridentc->window; w_remain = w;
win_remain = 0x1000 / 4; src = srcLine;
srcLine += srcStride;
off = offLine;
offLine += offStride;
while (w_remain--)
*off++ = *src++;
} }
w_this = w_remain;
if (w_this > win_remain)
w_this = win_remain;
win_remain -= w_this;
w_remain -= w_this;
while (w_this--)
*window++ = *src++;
} }
else
{
while (h_this--)
{
w_remain = w;
msk = mskLine;
mskLine += mskStride;
off = offLine;
offLine += offStride;
while (w_remain--)
*off++ = rgb | (*msk++ << 24);
}
}
cop->command = (COP_OP_BLT |
COP_SCL_OPAQUE |
COP_OP_FB);
} }
pbox++; pbox++;
} }
cop->src_offset = 0;
cop->multi = TridentAlpha;
cop->multi = COP_MULTI_CLIP_TOP_LEFT;
cop->clip_bottom_right = 0x0fff0fff;
KdMarkSync (pDst->pDrawable->pScreen); KdMarkSync (pDst->pDrawable->pScreen);
} }
else else
@ -1057,6 +1017,7 @@ Bool
tridentDrawInit (ScreenPtr pScreen) tridentDrawInit (ScreenPtr pScreen)
{ {
SetupTrident(pScreen); SetupTrident(pScreen);
tridentScreenInfo(pScreenPriv);
PictureScreenPtr ps = GetPictureScreen(pScreen); PictureScreenPtr ps = GetPictureScreen(pScreen);
/* /*
@ -1071,7 +1032,7 @@ tridentDrawInit (ScreenPtr pScreen)
pScreen->PaintWindowBackground = tridentPaintWindow; pScreen->PaintWindowBackground = tridentPaintWindow;
pScreen->PaintWindowBorder = tridentPaintWindow; pScreen->PaintWindowBorder = tridentPaintWindow;
if (ps && tridentc->window) if (ps && tridents->off_screen)
ps->Composite = tridentComposite; ps->Composite = tridentComposite;
return TRUE; return TRUE;

View File

@ -22,10 +22,12 @@
* *
* Author: Keith Packard, SuSE, Inc. * Author: Keith Packard, SuSE, Inc.
*/ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/tridentstub.c,v 1.2 1999/12/30 03:03:18 robin Exp $ */ /* $XFree86: xc/programs/Xserver/hw/kdrive/trident/tridentstub.c,v 1.4 2000/08/29 17:20:15 keithp Exp $ */
#include "trident.h" #include "trident.h"
extern int trident_clk, trident_mclk;
void void
InitCard (char *name) InitCard (char *name)
{ {
@ -52,6 +54,23 @@ ddxProcessArgument (int argc, char **argv, int i)
{ {
int ret; int ret;
if (!strcmp (argv[i], "-clk"))
{
if (i+1 < argc)
trident_clk = atoi (argv[i+1]);
else
UseMsg ();
return 2;
}
if (!strcmp (argv[i], "-mclk"))
{
if (i+1 < argc)
trident_mclk = atoi (argv[i+1]);
else
UseMsg ();
return 2;
}
#ifdef VESA #ifdef VESA
if (!(ret = vesaProcessArgument (argc, argv, i))) if (!(ret = vesaProcessArgument (argc, argv, i)))
#endif #endif

View File

@ -19,7 +19,7 @@ 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
*/ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vbe.c,v 1.6 2000/10/20 00:19:50 keithp Exp $ */ /* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vbe.c,v 1.7 2000/11/19 20:51:12 keithp Exp $ */
#include "vesa.h" #include "vesa.h"
@ -281,6 +281,9 @@ VbeMapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int *ret_size)
return NULL; return NULL;
} }
KdSetMappedMode (vmib.PhysBasePtr - before, before + size + after,
KD_MAPPED_MODE_FRAMEBUFFER);
return fb + before; return fb + before;
} }
@ -307,7 +310,10 @@ VbeUnmapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, void *fb)
after = 0; after = 0;
fb = (void *) ((char *) fb - before); fb = (void *) ((char *) fb - before);
KdUnmapDevice (fb, before + size + after); KdUnmapDevice (fb, before + size + after);
KdResetMappedMode (vmib.PhysBasePtr - before, before + size + after,
KD_MAPPED_MODE_FRAMEBUFFER);
} }
int int

View File

@ -19,7 +19,7 @@ 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
*/ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vesa.c,v 1.6 2000/09/19 23:50:47 keithp Exp $ */ /* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vesa.c,v 1.8 2000/10/20 00:19:50 keithp Exp $ */
#include "vesa.h" #include "vesa.h"
@ -159,6 +159,8 @@ vesaGetModes (Vm86InfoPtr vi, int *ret_nmode)
modes = xalloc (nmode * sizeof (VesaModeRec)); modes = xalloc (nmode * sizeof (VesaModeRec));
memset (modes, '\0', nmode * sizeof (VesaModeRec));
if (nmodeVga) if (nmodeVga)
{ {
code = VgaGetModes (vi, modes, nmodeVga); code = VgaGetModes (vi, modes, nmodeVga);