xfree86: drivers: cirrus: copy over xf86-video-cirrus tree

Since this driver doesn't receive much functional changes, except fixups
for server ABI changes, it's a good candidate to move it back into the
main Xserver tree.

As the first step to move back this driver into the Xserver tree,
copy over the source from last release tag. Skipped files we don't need
here (eg. gitlab pipeline, automake files, ...)

repo: git@github.com:X11Libre/xf86-video-cirrus.git
git tag: xlibre-xf86-video-cirrus-1.6.0.1

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult
2025-07-21 17:53:29 +02:00
parent 9f03501c8f
commit f8a7c34953
19 changed files with 6964 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved.
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 fur-
nished 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, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the XFree86 Project shall not
be used in advertising or otherwise to promote the sale, use or other deal-
ings in this Software without prior written authorization from the XFree86
Project.
Copyright 2000 by Egbert Eich
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 Alan Hourihane not be used in
advertising or publicity pertaining to distribution of the software without
specific, written prior permission. Alan Hourihane makes no representations
about the suitability of this software for any purpose. It is provided
"as is" without express or implied warranty.
EGBERT EICH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
EVENT SHALL ALAN HOURIHANE 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.
Copyright 2007 George Sapountzis
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.

View File

@@ -0,0 +1,18 @@
xf86-video-cirrus - Cirrus Logic video driver for the Xorg X server
-------------------------------------------------------------------
All questions regarding this software should be directed at the
Xorg mailing list:
https://lists.x.org/mailman/listinfo/xorg
The primary development code repository can be found at:
https://gitlab.freedesktop.org/xorg/driver/xf86-video-cirrus
Please submit bug reports and requests to merge patches there.
For patch submission instructions, see:
https://www.x.org/wiki/Development/Documentation/SubmittingPatches

View File

@@ -0,0 +1,70 @@
WARNING:
On exit XFree86 restores the old mode but it
does not disable the secondary card. As a result
the second card (which has some randonm CRTC timing)
may produce synch pulses which are wrong for your
monitor.
If your monitor does not tolerate bad timing I would
recommend that you don't try Multi-head yet, or at
least, turn it off *before* leaving X.
3.9Nl notice: There is a problem with releasing
of LBX colormap privates which may cause a seg.
fault when the server exits. I got a patch from
Mark Vojkovich which fixes it.
If you have a CL-GD5480 or CL-GD5446 ver. B you
should be able to try Multi-Head with that
card as a secondary. The primary card should not
have any special feature. Some MainBoards may
not do it right too. I tried it with a 5465 (AGP)
as a primary and 5446B (PCI) secondary on an
ABIT LX6 upgraded to the latest bios.
Version A of the 5446 cannot be pure MMIO (The driver
requires that it is the primary display adapter).
You can distinguish between the rel A and rel B by
running "scanpci -v". Version 1 does not report a
valid BASE1 address.
The bios upgrade lets me chose if the primary
display adapter is on PCI on AGP (I chose
the AGP card as primary). Warning - this setup
will *NOT* work with XFree86 3.3.2.
The only problem that I found so far is with
memory configuration initialization. My bios
does not initialize the secondary display adapter.
This results in a corrupted display.
Here are the options:
1. warm booting from Windows 98 may work. I have
not tried that.
2. Take out the other card and leave the 5446
(or 5480) as the primary card. Start the server
and watch it's output. Look for lines like:
(--) CIRRUS(0): Memory Config reg 1 is 0x1B
(--) CIRRUS(0): Memory Config reg 2 is 0x21
Remember these values. Now edit XF86Config
and add to the proper device section the lines:
Option "MemCFG1" "0x1B"
Option "MemCFG2" "0x21"
These values are the contents of registers SR0F
and SR17. (notice: the 5480 driver does not use
and will not print MemCFG2).
Now you can reinstall the other card (which
must me set as the the primary display adaptor).
A note about configuring multi-head:
There should be a separate section for each
adapter (device), Monitor and Screen. A "ServerLayout"
section is optional (and recommended). To make it
easier for XFree86 to relate device sections to
actual cards, use a BusId line in each device
section. XFree86 3.9N works properly if the config
file is for Multi-head but it finds only one
display adapter.

View File

@@ -0,0 +1,34 @@
.\" shorthand for double quote that works everywhere.
.ds q \N'34'
.TH CIRRUS __drivermansuffix__ 2009-05-07 __vendorversion__
.SH NAME
cirrus \- Cirrus Logic video driver for Xorg
.SH SYNOPSIS
.nf
.B "Section \*qDevice\*q"
.BI " Identifier \*q" devname \*q
.B " Driver \*qcirrus\*q"
\ \ ...
.B EndSection
.fi
.SH DESCRIPTION
.B cirrus
is an Xorg driver for Cirrus Logic video chips.
THIS MAN PAGE NEEDS TO BE FILLED IN.
.SH SUPPORTED HARDWARE
The
.B cirrus
driver supports...
.SH CONFIGURATION DETAILS
Please refer to
.BR xorg.conf (__filemansuffix__)
for general configuration details.
This section only covers configuration details specific to this driver.
.SH "SEE ALSO"
.BR Xorg (1),
.BR xorg.conf (__filemansuffix__),
.BR Xserver (1),
.BR X (__miscmansuffix__)
.SH AUTHORS
Authors include: Corin Anderson, Egbert Eich, Derek Fawcus, Koen Gadeyne,
Harm Hanemaayer, David Monniaux, Itai Nahshon

View File

@@ -0,0 +1,146 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/*
* Programming of the built-in Cirrus clock generator.
* Harm Hanemaayer <hhanemaa@cs.ruu.nl>
*
* VCO stability criterion code added by Koen Gadeyne (koen.gadeyne@barco.com)
* Max clock specification added by Harm Hanemaayer (H.Hanemaayer@inter.nl.net)
*
* Minor changes and cleanup Itai Nahshon.
*
* Made this completely chipset independent, and moved chipset dependent parts
* into the specific sub-drivers. Derek Fawcus <derek@spider.com>
*/
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86Pci.h"
#include "cir.h"
/* CLOCK_FACTOR is double the osc freq in kHz (osc = 14.31818 MHz) */
#define CLOCK_FACTOR 28636
/* Stability constraints for internal VCO -- MAX_VCO also determines
* the maximum Video pixel clock
*/
#define MIN_VCO CLOCK_FACTOR
#define MAX_VCO 111000
/* clock in kHz is (numer * CLOCK_FACTOR / (denom & 0x3E)) >> (denom & 1) */
#define VCOVAL(n, d) \
((((n) & 0x7F) * CLOCK_FACTOR / ((d) & 0x3E)) )
#define CLOCKVAL(n, d) \
(VCOVAL(n, d) >> ((d) & 1))
typedef struct {
unsigned char numer;
unsigned char denom;
} cirrusClockRec;
static cirrusClockRec cirrusClockTab[] = {
{ 0x2C, 0x33 }, /* 12.599 */
{ 0x4A, 0x2B }, /* 25.227 */
{ 0x5B, 0x2F }, /* 28.325 */
{ 0x45, 0x30 }, /* 41.164 */
{ 0x7E, 0x33 }, /* 36.082 */
{ 0x42, 0x1F }, /* 31.500 */
{ 0x51, 0x3A }, /* 39.992 */
{ 0x55, 0x36 }, /* 45.076 */
{ 0x65, 0x3A }, /* 49.867 */
{ 0x76, 0x34 }, /* 64.983 */
{ 0x7E, 0x32 }, /* 72.163 */
{ 0x6E, 0x2A }, /* 75.000 */
{ 0x5F, 0x22 }, /* 80.013 */
{ 0x7D, 0x2A }, /* 85.226 */
{ 0x58, 0x1C }, /* 89.998 */
{ 0x49, 0x16 }, /* 95.019 */
{ 0x46, 0x14 }, /* 100.226 */
{ 0x53, 0x16 }, /* 108.035 */
{ 0x5C, 0x18 }, /* 110.248 */
{ 0x6D, 0x1A }, /* 120.050 */
{ 0x58, 0x14 }, /* 125.998 */
{ 0x6D, 0x18 }, /* 130.055 */
{ 0x42, 0x0E }, /* 134.998 */
{ 0x69, 0x14 }, /* 150.341 */
{ 0x5E, 0x10 }, /* 168.239 */
{ 0x5C, 0x0E }, /* 188.182 */
{ 0x67, 0x0E }, /* 210.682 */
{ 0x60, 0x0C }, /* 229.091 */
};
#define NU_FIXED_CLOCKS (sizeof(cirrusClockTab)/sizeof(cirrusClockTab[0]))
/*
* This function returns the 7-bit numerator and 6-bit denominator/post-scalar
* value that corresponds to the closest clock found.
* If a frequency close to one of the tested clock values is found,
* use the tested clock since others can be unstable.
*/
_X_EXPORT Bool
CirrusFindClock(int *rfreq, int max_clock, int *num_out, int *den_out)
{
int n, i;
int num = 0, den = 0;
int freq, ffreq = 0, mindiff = 0;
freq = *rfreq;
/* Prefer a tested value if it matches within 0.1%. */
for (i = 0; i < NU_FIXED_CLOCKS; i++) {
int diff;
diff = abs(CLOCKVAL(cirrusClockTab[i].numer,
cirrusClockTab[i].denom) - freq);
if (diff < freq / 1000) {
num = cirrusClockTab[i].numer;
den = cirrusClockTab[i].denom;
ffreq = CLOCKVAL(num, den);
goto foundclock;
}
}
/*
* If max_clock is greater than the MAX_VCO default, ignore
* MAX_VCO. On the other hand, if MAX_VCO is higher than max_clock,
* make use of the higher MAX_VCO value.
*/
if (MAX_VCO > max_clock)
max_clock = MAX_VCO;
mindiff = freq;
for (n = 0x10; n < 0x7f; n++) {
int d;
for (d = 0x14; d < 0x3f; d++) {
int c, diff;
/* Avoid combinations that can be unstable. */
if ((VCOVAL(n, d) < MIN_VCO) || (VCOVAL(n, d) > max_clock))
continue;
c = CLOCKVAL(n, d);
diff = abs(c - freq);
if (diff < mindiff) {
mindiff = diff;
num = n;
den = d;
ffreq = c;
}
}
}
if (0 == num || 0 == den)
return FALSE;
foundclock:
*num_out = num;
*den_out = den;
*rfreq = ffreq;
return TRUE;
}

View File

@@ -0,0 +1,83 @@
/* (c) Itai Nahshon */
#ifndef ALP_H
#define ALP_H
extern ScrnInfoPtr AlpProbe(int entity);
extern const OptionInfoRec * AlpAvailableOptions(int chipid);
# ifdef _ALP_PRIVATE_
/* Saved registers that are not part of the core VGA */
/* CRTC >= 0x19; Sequencer >= 0x05; Graphics >= 0x09; Attribute >= 0x15 */
enum {
/* CR regs */
CR1A,
CR1B,
CR1D,
/* SR regs */
SR07,
SR0E,
SR12,
SR13,
SR17,
SR1E,
SR21,
SR2D,
/* GR regs */
GR17,
GR18,
/* HDR */
HDR,
/* Must be last! */
CIR_NSAVED
};
typedef enum {LCD_NONE, LCD_DUAL_MONO, LCD_UNKNOWN, LCD_DSTN, LCD_TFT} LCDType;
typedef struct {
unsigned char ExtVga[CIR_NSAVED];
} AlpRegRec, *AlpRegPtr;
extern Bool AlpHWCursorInit(ScreenPtr pScreen, int size);
extern Bool AlpDGAInit(ScreenPtr pScreen);
extern Bool AlpI2CInit(ScrnInfoPtr pScrn);
/* Card-specific driver information */
#define ALPPTR(p) ((AlpPtr)((p)->chip.alp))
typedef struct alpRec {
unsigned char * HWCursorBits;
unsigned char * CursorBits;
AlpRegRec SavedReg;
AlpRegRec ModeReg;
LCDType lcdType;
int lcdWidth, lcdHeight;
int CursorWidth;
int CursorHeight;
int waitMsk;
int scanlineDest;
int scanlineCount;
int scanlineWidth;
int SubsequentColorExpandScanlineDest;
int SubsequentColorExpandScanlineByteWidth;
int SubsequentColorExpandScanlineDWordWidth;
/* Offset into framebuffer of a 8-byte scratch area for fills */
CARD32 monoPattern8x8;
Bool autoStart;
/* MMIO Base for BitBLT operation. This is
IOBase for 5446 and 7548, IOBase+0x100 for 5480 */
unsigned char * BLTBase;
CARD32 transRop;
/* XXX For XF86Config based mem configuration */
CARD32 sr0f, sr17;
} AlpRec, *AlpPtr;
# endif /* _ALP_PRIVATE_ */
#endif /* ALP_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,258 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* (c) Itai Nahshon */
#include "xf86.h"
#include "xf86_OSproc.h"
#include "compiler.h"
#include "xf86Pci.h"
#include "vgaHW.h"
#include "cir.h"
#define _ALP_PRIVATE_
#include "alp.h"
#define CURSORWIDTH pAlp->CursorWidth
#define CURSORHEIGHT pAlp->CursorHeight
#define CURSORSIZE (CURSORWIDTH*CURSORHEIGHT/8)
#define MAXCURSORSIZE (64*64>>3)
static void
AlpSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
const AlpPtr pAlp = ALPPTR(CIRPTR(pScrn));
vgaHWPtr hwp = VGAHWPTR(pScrn);
#ifdef ALP_DEBUG
ErrorF("AlpSetCursorColors\n");
#endif
hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]|0x02);
hwp->writeDacWriteAddr(hwp, 0x00);
hwp->writeDacData(hwp, 0x3f & (bg >> 18));
hwp->writeDacData(hwp, 0x3f & (bg >> 10));
hwp->writeDacData(hwp, 0x3f & (bg >> 2));
hwp->writeDacWriteAddr(hwp, 0x0F);
hwp->writeDacData(hwp, 0x3F & (fg >> 18));
hwp->writeDacData(hwp, 0x3F & (fg >> 10));
hwp->writeDacData(hwp, 0x3F & (fg >> 2));
hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]);
}
static void
AlpLoadSkewedCursor(CirPtr pCir, int x, int y) {
const AlpPtr pAlp = ALPPTR(pCir);
unsigned char *memx = pAlp->HWCursorBits;
unsigned char *CursorBits = pAlp->CursorBits;
unsigned char mem[2*MAXCURSORSIZE];
unsigned char *p1, *p2;
int i, a, b;
Bool cur64 = (CURSORWIDTH == 64);
int shift = (cur64? 1 : 0);
if (x > 0) x = 0; else x = -x;
if (y > 0) y = 0; else y = -y;
a = ((y*CURSORWIDTH<<shift)+x)>>3;
b = x & 7;
/* Copy the skewed mask bits */
p1 = mem;
p2 = CursorBits + a;
for (i = 0; i < (CURSORSIZE << shift)-a-1; i++) {
*p1++ = (p2[0] << b) | (p2[1] >> (8-b));
p2++;
}
/* last mask byte */
*p1++ = (p2[0] << b);
/* Clear to end (bottom) of mask. */
for (i = i+1; i < (CURSORSIZE << shift); i++)
*p1++ = 0;
if (!cur64) {
/* Now copy the cursor bits */
/* p1 is already right */
p2 = CursorBits+CURSORSIZE+a;
for (i = 0; i < CURSORSIZE-a-1; i++) {
*p1++ = (p2[0] << b) | (p2[1] >> (8-b));
p2++;
}
/* last cursor byte */
*p1++ = (p2[0] << b);
}
/* Clear to end (bottom) of cursor. */
for (i = i+1; i < CURSORSIZE; i++)
*p1++ = 0;
/* Clear the right unused area of the mask
and cyrsor bits. */
p2 = mem + CURSORWIDTH/8 - (x>>3) - 1;
for (i = 0; i < 2*CURSORHEIGHT; i++) {
int m = (-1)<<(x&7);
p1 = p2;
p2 += CURSORWIDTH/8;
for (int j = x>>3; j >= 0; j--) {
*p1 &= m;
m = 0;
p1++;
}
}
memcpy(memx, mem, 2*CURSORSIZE);
}
static void
AlpSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
const CirPtr pCir = CIRPTR(pScrn);
const AlpPtr pAlp = ALPPTR(pCir);
vgaHWPtr hwp = VGAHWPTR(pScrn);
#if 0
#ifdef ALP_DEBUG
ErrorF("AlpSetCursorPosition %d %d\n", x, y);
#endif
#endif
if (x < 0 || y < 0) {
if (x+CURSORWIDTH <= 0 || y+CURSORHEIGHT <= 0) {
hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12] & ~0x01);
return;
}
AlpLoadSkewedCursor(pCir, x, y);
pCir->CursorIsSkewed = TRUE;
if (x < 0) x = 0;
if (y < 0) y = 0;
} else if (pCir->CursorIsSkewed) {
memcpy(pAlp->HWCursorBits, pAlp->CursorBits, 2*CURSORSIZE);
pCir->CursorIsSkewed = FALSE;
}
hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]);
hwp->writeSeq(hwp, ((x << 5)|0x10)&0xff, x >> 3);
hwp->writeSeq(hwp, ((y << 5)|0x11)&0xff, y >> 3);
}
static void
AlpLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits)
{
const AlpPtr pAlp = ALPPTR(CIRPTR(pScrn));
vgaHWPtr hwp = VGAHWPTR(pScrn);
#ifdef ALP_DEBUG
ErrorF("AlpLoadCursorImage\n");
#endif
pAlp->CursorBits = bits;
memcpy(pAlp->HWCursorBits, bits, 2*CURSORSIZE);
/* this should work for both 64 and 32 bit cursors */
pAlp->ModeReg.ExtVga[SR13] = 0x3f;
hwp->writeSeq(hwp, 0x13, pAlp->ModeReg.ExtVga[SR13]);
}
static void
AlpHideCursor(ScrnInfoPtr pScrn)
{
AlpPtr pAlp = ALPPTR(CIRPTR(pScrn));
vgaHWPtr hwp = VGAHWPTR(pScrn);
#ifdef ALP_DEBUG
ErrorF("AlpHideCursor\n");
#endif
pAlp->ModeReg.ExtVga[SR12] &= ~0x01;
hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]);
}
static void
AlpShowCursor(ScrnInfoPtr pScrn)
{
AlpPtr pAlp = ALPPTR(CIRPTR(pScrn));
vgaHWPtr hwp = VGAHWPTR(pScrn);
#ifdef ALP_DEBUG
ErrorF("AlpShowCursor\n");
#endif
pAlp->ModeReg.ExtVga[SR12] |= 0x01;
hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]);
}
static Bool
AlpUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
#ifdef ALP_DEBUG
ErrorF("AlpUseHWCursor\n");
#endif
if (pScrn->bitsPerPixel < 8)
return FALSE;
return TRUE;
}
Bool
AlpHWCursorInit(ScreenPtr pScreen, int size)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
const CirPtr pCir = CIRPTR(pScrn);
const AlpPtr pAlp = ALPPTR(pCir);
xf86CursorInfoPtr infoPtr;
#ifdef ALP_DEBUG
ErrorF("AlpHWCursorInit\n");
#endif
if (!size) return FALSE;
infoPtr = xf86CreateCursorInfoRec();
if (!infoPtr) return FALSE;
pCir->CursorInfoRec = infoPtr;
pCir->CursorIsSkewed = FALSE;
pAlp->CursorBits = NULL;
if (size == 64)
CURSORWIDTH = CURSORHEIGHT = 64;
else
CURSORWIDTH = CURSORHEIGHT = 32;
pAlp->HWCursorBits = pCir->FbBase + 1024*pScrn->videoRam - 2*CURSORSIZE;
infoPtr->MaxWidth = CURSORWIDTH;
infoPtr->MaxHeight = CURSORHEIGHT;
if (CURSORWIDTH == 64)
infoPtr->Flags =
#if X_BYTE_ORDER == X_LITTLE_ENDIAN
HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
#endif
HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
else
infoPtr->Flags =
#if X_BYTE_ORDER == X_LITTLE_ENDIAN
HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
#endif
HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
infoPtr->SetCursorColors = AlpSetCursorColors;
infoPtr->SetCursorPosition = AlpSetCursorPosition;
infoPtr->LoadCursorImage = AlpLoadCursorImage;
infoPtr->HideCursor = AlpHideCursor;
infoPtr->ShowCursor = AlpShowCursor;
infoPtr->UseHWCursor = AlpUseHWCursor;
#ifdef ALP_DEBUG
ErrorF("AlpHWCursorInit before xf86InitCursor\n");
#endif
xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Hardware cursor: %ix%i\n",
CURSORWIDTH,CURSORHEIGHT);
return(xf86InitCursor(pScreen, infoPtr));
}

View File

@@ -0,0 +1,131 @@
/* (c) Itai Nahshon */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86.h"
#include "xf86_OSproc.h"
#include "compiler.h"
#include "xf86Pci.h"
#include "vgaHW.h"
#include "cir.h"
#define _ALP_PRIVATE_
#include "alp.h"
static char strI2CBus1[] = "I2C bus 1";
static char strI2CBus2[] = "I2C bus 2";
/*
* Switch between internal I2C bus and external (DDC) bus.
* There is one I2C port controlled bu SR08 and the programmable
* outputs control a multiplexer.
*/
static Bool
AlpI2CSwitchToBus(I2CBusPtr b)
{
CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr);
vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);
CARD8 reg = hwp->readGr(hwp, 0x17);
if (b == pCir->I2CPtr1) {
if ((reg & 0x60) == 0)
return TRUE;
reg &= ~0x60;
}
else if(b == pCir->I2CPtr2) {
if ((reg & 0x60) != 0)
return TRUE;
reg |= 0x60;
} else return FALSE;
/* ErrorF("AlpI2CSwitchToBus: \"%s\"\n", b->BusName); */
hwp->writeGr(hwp, 0x17, reg);
return TRUE;
}
static void
AlpI2CPutBits(I2CBusPtr b, int clock, int data)
{
unsigned int reg = 0xfc;
CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr);
vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);
if (!AlpI2CSwitchToBus(b))
return;
if (clock) reg |= 1;
if (data) reg |= 2;
hwp->writeSeq(hwp, 0x08, reg);
/* ErrorF("AlpI2CPutBits: %d %d\n", clock, data); */
}
static void
AlpI2CGetBits(I2CBusPtr b, int *clock, int *data)
{
unsigned int reg;
CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr);
vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);
if (!AlpI2CSwitchToBus(b))
return;
reg = hwp->readSeq(hwp, 0x08);
*clock = (reg & 0x04) != 0;
*data = (reg & 0x80) != 0;
/* ErrorF("AlpI2CGetBits: %d %d\n", *clock, *data); */
}
Bool
AlpI2CInit(ScrnInfoPtr pScrn)
{
CirPtr pCir = CIRPTR(pScrn);
I2CBusPtr I2CPtr;
#ifdef ALP_DEBUG
ErrorF("AlpI2CInit\n");
#endif
switch(pCir->Chipset) {
case PCI_CHIP_GD5446:
case PCI_CHIP_GD5480:
break;
default:
return FALSE;
}
I2CPtr = xf86CreateI2CBusRec();
if (!I2CPtr) return FALSE;
pCir->I2CPtr1 = I2CPtr;
I2CPtr->BusName = strI2CBus1;
I2CPtr->scrnIndex = pScrn->scrnIndex;
I2CPtr->I2CPutBits = AlpI2CPutBits;
I2CPtr->I2CGetBits = AlpI2CGetBits;
I2CPtr->DriverPrivate.ptr = pCir;
if (!xf86I2CBusInit(I2CPtr))
return FALSE;
I2CPtr = xf86CreateI2CBusRec();
if (!I2CPtr) return FALSE;
pCir->I2CPtr2 = I2CPtr;
I2CPtr->BusName = strI2CBus2;
I2CPtr->scrnIndex = pScrn->scrnIndex;
I2CPtr->I2CPutBits = AlpI2CPutBits;
I2CPtr->I2CGetBits = AlpI2CGetBits;
I2CPtr->DriverPrivate.ptr = pCir;
if (!xf86I2CBusInit(I2CPtr))
return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,99 @@
/* (c) Itai Nahshon */
#ifndef CIR_H
#define CIR_H
#include "xf86Cursor.h"
#include "xf86i2c.h"
#include <string.h>
#include <stdlib.h>
#include "cir_pcirename.h"
/* Card-specific driver information */
#define CIRPTR(p) ((CirPtr)((p)->driverPrivate))
struct lgRec;
struct alpRec;
typedef struct {
ScrnInfoPtr pScrn;
CARD32 properties;
pciVideoPtr PciInfo;
#ifndef XSERVER_LIBPCIACCESS
PCITAG PciTag;
#endif
unsigned long PIOReg;
union {
struct lgRec *lg;
struct alpRec *alp;
} chip;
EntityInfoPtr pEnt;
int Chipset;
int ChipRev;
int Rounding;
int BppShift;
Bool HasFBitBlt;
CARD32 IOAddress;
CARD32 FbAddress;
unsigned char *IOBase;
unsigned char *FbBase;
long FbMapSize;
long IoMapSize;
int MinClock;
int MaxClock;
Bool NoAccel;
Bool HWCursor;
Bool UseMMIO;
xf86CursorInfoPtr CursorInfoRec;
int DGAnumModes;
DGAModePtr DGAModes;
Bool DGAactive;
Bool (*DGAModeInit)(ScrnInfoPtr, DisplayModePtr);
int DGAViewportStatus;
I2CBusPtr I2CPtr1;
I2CBusPtr I2CPtr2;
CloseScreenProcPtr CloseScreen;
Bool CursorIsSkewed;
Bool shadowFB;
int rotate;
int ShadowPitch;
unsigned char * ShadowPtr;
void (*PointerMoved)(ScrnInfoPtr arg, int x, int y);
int pitch;
unsigned char ** ScanlineColorExpandBuffers;
void (*InitAccel)(ScrnInfoPtr);
int offscreen_size;
int offscreen_offset;
OptionInfoPtr Options;
} CirRec, *CirPtr;
/* CirrusClk.c */
extern Bool
CirrusFindClock(int *rfreq, int max_clock, int *num_out, int *den_out);
/* cir_driver.c */
extern SymTabRec CIRChipsets[];
extern PciChipsets CIRPciChipsets[];
extern Bool CirMapMem(CirPtr pCir, int scrnIndex);
extern Bool CirUnmapMem(CirPtr pCir, int scrnIndex);
extern void cirProbeDDC(ScrnInfoPtr pScrn, int index);
/* cir_dga.c */
extern Bool CirDGAInit(ScreenPtr pScreen);
/* in cir_shadow.c */
void cirPointerMoved(ScrnInfoPtr arg, int x, int y);
void cirRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void cirRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void cirRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void cirRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void cirRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
/* properties */
#define HWCUR64 0x1
#define ACCEL_AUTOSTART 0x2
#endif /* CIR_H */

View File

@@ -0,0 +1,198 @@
/*
* Copyright 2000 by Egbert Eich
*
* 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 Alan Hourihane not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Alan Hourihane makes no representations
* about the suitability of this software for any purpose. It is provided
* "as is" without express or implied warranty.
*
* EGBERT EICH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL ALAN HOURIHANE 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.
*
* Authors: Adapted from: Alan Hourihane, <alanh@fairlite.demon.co.uk>
* by: Egbert Eich
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86Pci.h"
#include "vgaHW.h"
#include "cir.h"
#include "dgaproc.h"
static Bool Cir_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
int *, int *, int *);
static Bool Cir_SetMode(ScrnInfoPtr, DGAModePtr);
static int Cir_GetViewport(ScrnInfoPtr);
static void Cir_SetViewport(ScrnInfoPtr, int, int, int);
static
DGAFunctionRec CirDGAFuncs = {
Cir_OpenFramebuffer,
NULL, /* Cir_CloseFramebuffer */
Cir_SetMode,
Cir_SetViewport,
Cir_GetViewport,
NULL, NULL, NULL,
NULL /* Cir_BlitTransRect */
};
_X_EXPORT Bool
CirDGAInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
CirPtr pCir = CIRPTR(pScrn);
DGAModePtr modes = NULL, newmodes = NULL, currentMode;
DisplayModePtr pMode, firstMode;
int Bpp = pScrn->bitsPerPixel >> 3;
int num = 0;
int imlines = (pScrn->videoRam * 1024) /
(pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
if (!pCir->DGAnumModes) {
pMode = firstMode = pScrn->modes;
while (pMode) {
newmodes = realloc(modes, (num + 1) * sizeof (DGAModeRec));
if (!newmodes) {
free(modes);
return FALSE;
}
modes = newmodes;
currentMode = modes + num;
num++;
(void)memset(currentMode, 1, sizeof(DGAModeRec));
currentMode->mode = pMode;
currentMode->flags = DGA_PIXMAP_AVAILABLE
| ((!pCir->NoAccel) ? (DGA_FILL_RECT | DGA_BLIT_RECT) : 0);
if (pMode->Flags & V_DBLSCAN)
currentMode->flags |= DGA_DOUBLESCAN;
if(pMode->Flags & V_INTERLACE)
currentMode->flags |= DGA_INTERLACED;
currentMode->byteOrder = pScrn->imageByteOrder;
currentMode->depth = pScrn->depth;
currentMode->bitsPerPixel = pScrn->bitsPerPixel;
currentMode->red_mask = pScrn->mask.red;
currentMode->green_mask = pScrn->mask.green;
currentMode->blue_mask = pScrn->mask.blue;
currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
currentMode->viewportWidth = pMode->HDisplay;
currentMode->viewportHeight = pMode->VDisplay;
currentMode->xViewportStep = 1; /* The granularity of x and y pos. */
currentMode->yViewportStep = 1;
currentMode->viewportFlags = 0 /*DGA_FLIP_RETRACE*/;
currentMode->offset = 0;
currentMode->address = pCir->FbBase;
currentMode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L;
currentMode->pixmapWidth = currentMode->imageWidth
= pScrn->displayWidth;
currentMode->pixmapHeight = currentMode->imageHeight = imlines;
currentMode->maxViewportX = currentMode->imageWidth -
currentMode->viewportWidth;
/* this might need to get clamped to some maximum */
currentMode->maxViewportY = currentMode->imageHeight -
currentMode->viewportHeight;
pMode = pMode->next;
if(pMode == firstMode)
break;
}
pCir->DGAnumModes = num;
pCir->DGAModes = modes;
}
return DGAInit(pScreen, &CirDGAFuncs, pCir->DGAModes, pCir->DGAnumModes);
}
static Bool
Cir_OpenFramebuffer(
ScrnInfoPtr pScrn,
char **name,
unsigned char **mem,
int *size,
int *offset,
int *flags
){
CirPtr pCir = CIRPTR(pScrn);
*name = NULL; /* no special device */
*mem = (unsigned char*)(long)pCir->FbAddress;
*size = pCir->FbMapSize;
*offset = 0; /* Always */
*flags = 0; /* Root permissions OS-dependent */
return TRUE;
}
static Bool
Cir_SetMode(
ScrnInfoPtr pScrn,
DGAModePtr pMode
){
CirPtr pCir = CIRPTR(pScrn);
static int OldDisplayWidth[MAXSCREENS];
int index = pScrn->pScreen->myNum;
Bool ret = FALSE;
if(!pMode) { /* restore the original mode */
/* put the ScreenParameters back */
pScrn->displayWidth = OldDisplayWidth[index];
ret = pCir->DGAModeInit(xf86Screens[index], pScrn->currentMode);
pCir->DGAactive = FALSE;
} else {
if(!pCir->DGAactive) { /* save the old parameters */
OldDisplayWidth[index] = pScrn->displayWidth;
pCir->DGAactive = TRUE;
}
pScrn->displayWidth = pMode->bytesPerScanline /
(pMode->bitsPerPixel >> 3);
ret = pCir->DGAModeInit(xf86Screens[index], pMode->mode);
}
return ret;
}
static void
Cir_SetViewport(
ScrnInfoPtr pScrn,
int x, int y,
int flags
){
CirPtr pCir = CIRPTR(pScrn);
vgaHWPtr hwp = VGAHWPTR(pScrn);
pScrn->AdjustFrame(pScrn, x, y);
while((hwp->readST01(hwp) & 0x08));
while(!(hwp->readST01(hwp) & 0x08));
pCir->DGAViewportStatus = 0; /* AdjustFrame loops until finished */
}
static int
Cir_GetViewport(
ScrnInfoPtr pScrn
){
CirPtr pCir = CIRPTR(pScrn);
return pCir->DGAViewportStatus;
}

View File

@@ -0,0 +1,387 @@
/*
* Driver for CL-GD5480.
* Itai Nahshon.
*
* Support for the CL-GD7548: David Monniaux
*
* This is mainly a cut & paste from the MGA driver.
* Original authors and contributors list include:
* Radoslaw Kapitan, Andrew Vanderstock, Dirk Hohndel,
* David Dawes, Andrew E. Mileski, Leonard N. Zubkoff,
* Guy DESBIEF
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* All drivers should typically include these */
#include "xf86.h"
#include "xf86_OSproc.h"
/* Drivers that need to access the PCI config space directly need this */
#include "xf86Pci.h"
#include "cir.h"
#include "alp.h"
#include "lg.h"
#include "vbe.h"
/*
* Forward definitions for the functions that make up the driver.
*/
/* Mandatory functions */
static const OptionInfoRec * CIRAvailableOptions(int chipid, int busid);
static void CIRIdentify(int flags);
static Bool CIRProbe(DriverPtr drv, int flags);
#define CIR_VERSION 4000
#define CIR_NAME "CIRRUS"
#define CIR_DRIVER_NAME "cirrus"
#define CIR_MAJOR_VERSION PACKAGE_VERSION_MAJOR
#define CIR_MINOR_VERSION PACKAGE_VERSION_MINOR
#define CIR_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL
/*
* This contains the functions needed by the server after loading the
* driver module. It must be supplied, and gets added to the driver list by
* the Module Setup 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 CIRRUS = {
CIR_VERSION,
CIR_DRIVER_NAME,
CIRIdentify,
CIRProbe,
CIRAvailableOptions,
NULL,
0
};
/* Supported chipsets */
SymTabRec CIRChipsets[] = {
{ PCI_CHIP_GD5430, "CLGD5430" },
{ PCI_CHIP_GD5434_4, "CLGD5434-4" },
{ PCI_CHIP_GD5434_8, "CLGD5434-8" },
{ PCI_CHIP_GD5436, "CLGD5436" },
/* { PCI_CHIP_GD5440, "CLGD5440" }, */
{ PCI_CHIP_GD5446, "CLGD5446" },
{ PCI_CHIP_GD5480, "CLGD5480" },
{ PCI_CHIP_GD5462, "CL-GD5462" },
{ PCI_CHIP_GD5464, "CL-GD5464" },
{ PCI_CHIP_GD5464BD, "CL-GD5464BD" },
{ PCI_CHIP_GD5465, "CL-GD5465" },
{ PCI_CHIP_GD7548, "CL-GD7548" },
{ PCI_CHIP_GD7555, "CL-GD7555" },
{ PCI_CHIP_GD7556, "CL-GD7556" },
{-1, NULL }
};
/* List of PCI chipset names */
_X_EXPORT PciChipsets CIRPciChipsets[] = {
{ PCI_CHIP_GD5430, PCI_CHIP_GD5430, RES_SHARED_VGA },
{ PCI_CHIP_GD5434_4,PCI_CHIP_GD5434_4, RES_SHARED_VGA },
{ PCI_CHIP_GD5434_8,PCI_CHIP_GD5434_8, RES_SHARED_VGA },
{ PCI_CHIP_GD5436, PCI_CHIP_GD5436, RES_SHARED_VGA },
/* { PCI_CHIP_GD5440, PCI_CHIP_GD5440, RES_SHARED_VGA }, */
{ PCI_CHIP_GD5446, PCI_CHIP_GD5446, RES_SHARED_VGA },
{ PCI_CHIP_GD5480, PCI_CHIP_GD5480, RES_SHARED_VGA },
{ PCI_CHIP_GD5462, PCI_CHIP_GD5462, RES_SHARED_VGA },
{ PCI_CHIP_GD5464, PCI_CHIP_GD5464, RES_SHARED_VGA },
{ PCI_CHIP_GD5464BD,PCI_CHIP_GD5464BD, RES_SHARED_VGA },
{ PCI_CHIP_GD5465, PCI_CHIP_GD5465, RES_SHARED_VGA },
{ PCI_CHIP_GD7548, PCI_CHIP_GD7548, RES_SHARED_VGA },
{ PCI_CHIP_GD7555, PCI_CHIP_GD7555, RES_SHARED_VGA },
{ PCI_CHIP_GD7556, PCI_CHIP_GD7556, RES_SHARED_VGA },
{ -1, -1, RES_UNDEFINED}
};
#ifdef XFree86LOADER
static MODULESETUPPROTO(cirSetup);
static XF86ModuleVersionInfo cirVersRec =
{
"cirrus",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XORG_VERSION_CURRENT,
CIR_MAJOR_VERSION, CIR_MINOR_VERSION, CIR_PATCHLEVEL,
ABI_CLASS_VIDEODRV, /* This is a video driver */
ABI_VIDEODRV_VERSION,
MOD_CLASS_VIDEODRV,
{0,0,0,0}
};
/*
* This is the module init data.
* Its name has to be the driver name followed by ModuleData.
*/
_X_EXPORT XF86ModuleData cirrusModuleData = { &cirVersRec, cirSetup, NULL };
static pointer
cirSetup(pointer module, pointer opts, int *errmaj, int *errmin)
{
static Bool setupDone = FALSE;
/* This module should be loaded only once, but check to be sure. */
if (!setupDone) {
setupDone = TRUE;
xf86AddDriver(&CIRRUS, module, 0);
return (pointer)1;
}
if (errmaj) *errmaj = LDR_ONCEONLY;
return NULL;
}
#endif /* XFree86LOADER */
/* Mandatory */
static void
CIRIdentify(int flags)
{
xf86PrintChipsets(CIR_NAME, "driver for Cirrus chipsets", CIRChipsets);
}
static const OptionInfoRec *
CIRAvailableOptions(int chipid, int busid)
{
int chip = chipid & 0xffff;
switch (chip)
{
case PCI_CHIP_GD5462:
case PCI_CHIP_GD5464:
case PCI_CHIP_GD5464BD:
case PCI_CHIP_GD5465:
return LgAvailableOptions(chipid);
default:
return AlpAvailableOptions(chipid);
}
}
static Bool
CIRProbe(DriverPtr drv, int flags)
{
int i;
GDevPtr *devSections;
pciVideoPtr pPci;
int *usedChips;
int numDevSections;
int numUsed;
Bool foundScreen = FALSE;
ScrnInfoPtr pScrn;
#ifdef CIR_DEBUG
ErrorF("CirProbe\n");
#endif
if ((numDevSections = xf86MatchDevice(CIR_DRIVER_NAME,
&devSections)) <= 0) {
return FALSE;
}
#ifndef XSERVER_LIBPCIACCESS
if (xf86GetPciVideoInfo() == NULL) {
/*
* We won't let anything in the config file override finding no
* PCI video cards at all. This seems reasonable now, but we'll see.
*/
return FALSE;
}
#endif
numUsed = xf86MatchPciInstances(CIR_NAME, PCI_VENDOR_CIRRUS,
CIRChipsets, CIRPciChipsets, devSections,
numDevSections, drv, &usedChips);
/* Free it since we don't need that list after this */
if (numUsed <= 0) {
free(devSections);
return FALSE;
}
if (flags & PROBE_DETECT)
foundScreen = TRUE;
else for (i = 0; i < numUsed; i++) {
/* The Laguna family of chips is so different from the Alpine
family that we won't share even the highest-level of
functions. But, the Laguna chips /are/ Cirrus chips, so
they should be handled in this driver (as opposed to their
own driver). */
pPci = xf86GetPciInfoForEntity(usedChips[i]);
#ifdef XSERVER_LIBPCIACCESS
if (pci_device_has_kernel_driver(pPci)) {
xf86DrvMsg(0, X_ERROR,
"cirrus: The PCI device 0x%x at %2.2d@%2.2d:%2.2d:%1.1d has a kernel module claiming it.\n",
pPci->device_id, pPci->bus, pPci->domain, pPci->dev, pPci->func);
xf86DrvMsg(0, X_ERROR,
"cirrus: This driver cannot operate until it has been unloaded.\n");
xf86UnclaimPciSlot(pPci, devSections[0]);
free(devSections);
return FALSE;
}
#endif
pScrn = NULL;
if (pPci && (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5462 ||
PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464 ||
PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464BD ||
PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5465)) {
pScrn = LgProbe(usedChips[i]);
} else {
pScrn = AlpProbe(usedChips[i]);
}
if (pScrn) {
foundScreen = TRUE;
/* Fill in what we can of the ScrnInfoRec */
pScrn->driverVersion = CIR_VERSION;
pScrn->driverName = CIR_DRIVER_NAME;
pScrn->name = CIR_NAME;
pScrn->Probe = NULL;
}
}
free(devSections);
free(usedChips);
return foundScreen;
}
/*
* Map the framebuffer and MMIO memory.
*/
_X_EXPORT Bool
CirMapMem(CirPtr pCir, int scrnIndex)
{
#ifdef CIR_DEBUG
ErrorF("CirMapMem\n");
#endif
/*
* Map the frame buffer.
*/
if (pCir->FbMapSize) {
#ifndef XSERVER_LIBPCIACCESS
pCir->FbBase = xf86MapPciMem(scrnIndex, VIDMEM_FRAMEBUFFER,
pCir->PciTag, pCir->FbAddress,
pCir->FbMapSize);
if (pCir->FbBase == NULL)
return FALSE;
#else
void** result = (void**)&pCir->FbBase;
int err = pci_device_map_range(pCir->PciInfo,
pCir->FbAddress,
pCir->FbMapSize,
PCI_DEV_MAP_FLAG_WRITABLE |
PCI_DEV_MAP_FLAG_WRITE_COMBINE,
result);
if (err)
return FALSE;
#endif
}
#ifdef CIR_DEBUG
ErrorF("CirMapMem pCir->FbBase=0x%08x\n", pCir->FbBase);
#endif
/*
* Map IO registers to virtual address space
*/
if (pCir->IOAddress == 0) {
pCir->IOBase = NULL; /* Until we are ready to use MMIO */
} else {
#ifndef XSERVER_LIBPCIACCESS
/*
* For Alpha, we need to map SPARSE memory, since we need
* byte/short access. Common-level will automatically use
* sparse mapping for MMIO.
*/
pCir->IOBase =
xf86MapPciMem(scrnIndex, VIDMEM_MMIO, pCir->PciTag,
pCir->IOAddress, pCir->IoMapSize);
if (pCir->IOBase == NULL)
return FALSE;
#else
void** result = (void**)&pCir->IOBase;
int err = pci_device_map_range(pCir->PciInfo,
pCir->IOAddress,
pCir->IoMapSize,
PCI_DEV_MAP_FLAG_WRITABLE,
result);
if (err)
return FALSE;
#endif
}
#ifdef CIR_DEBUG
ErrorF("CirMapMem pCir->IOBase=0x%08x [length=%08x] from PCI=%08x\n",
pCir->IOBase, pCir->IoMapSize, pCir->IOAddress);
ErrorF("MMIO[GR31] = %2X\n", (int)
((volatile unsigned char*) pCir->IOBase)[0x40]);
#endif
return TRUE;
}
/*
* Unmap the framebuffer and MMIO memory.
*/
_X_EXPORT Bool
CirUnmapMem(CirPtr pCir, int scrnIndex)
{
#ifdef CIR_DEBUG
ErrorF("CirUnmapMem\n");
#endif
if (pCir->IOBase != NULL) {
/*
* Unmap IO registers to virtual address space
*/
#ifndef XSERVER_LIBPCIACCESS
xf86UnMapVidMem(scrnIndex, (pointer)pCir->IOBase, pCir->IoMapSize);
#else
pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->IOBase, pCir->IoMapSize);
#endif
pCir->IOBase = NULL;
}
#ifndef XSERVER_LIBPCIACCESS
xf86UnMapVidMem(scrnIndex, (pointer)pCir->FbBase, pCir->FbMapSize);
#else
pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->FbBase, pCir->FbMapSize);
#endif
pCir->FbBase = NULL;
return TRUE;
}
_X_EXPORT void
cirProbeDDC(ScrnInfoPtr pScrn, int index)
{
vbeInfoPtr pVbe;
if (xf86LoadSubModule(pScrn, "vbe")) {
pVbe = VBEInit(NULL,index);
ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
vbeFree(pVbe);
}
}

View File

@@ -0,0 +1,148 @@
/*
* Copyright 2007 George Sapountzis
*
* 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.
*/
/**
* Macros for porting drivers from legacy xfree86 PCI code to the pciaccess
* library. The main purpose being to facilitate source code compatibility.
*/
#ifndef CIRPCIRENAME_H
#define CIRPCIRENAME_H
enum region_type {
REGION_MEM,
REGION_IO
};
#include "xf86Module.h"
#ifndef XSERVER_LIBPCIACCESS
/* pciVideoPtr */
#define PCI_DEV_VENDOR_ID(_pcidev) ((_pcidev)->vendor)
#define PCI_DEV_DEVICE_ID(_pcidev) ((_pcidev)->chipType)
#define PCI_DEV_REVISION(_pcidev) ((_pcidev)->chipRev)
#define PCI_SUB_VENDOR_ID(_pcidev) ((_pcidev)->subsysVendor)
#define PCI_SUB_DEVICE_ID(_pcidev) ((_pcidev)->subsysCard)
#define PCI_DEV_TAG(_pcidev) pciTag((_pcidev)->bus, \
(_pcidev)->device, \
(_pcidev)->func)
#define PCI_DEV_BUS(_pcidev) ((_pcidev)->bus)
#define PCI_DEV_DEV(_pcidev) ((_pcidev)->device)
#define PCI_DEV_FUNC(_pcidev) ((_pcidev)->func)
/* pciConfigPtr */
#define PCI_CFG_TAG(_pcidev) (((pciConfigPtr)(_pcidev)->thisCard)->tag)
#define PCI_CFG_BUS(_pcidev) (((pciConfigPtr)(_pcidev)->thisCard)->busnum)
#define PCI_CFG_DEV(_pcidev) (((pciConfigPtr)(_pcidev)->thisCard)->devnum)
#define PCI_CFG_FUNC(_pcidev) (((pciConfigPtr)(_pcidev)->thisCard)->funcnum)
/* region addr: xfree86 uses different fields for memory regions and I/O ports */
#define PCI_REGION_BASE(_pcidev, _b, _type) \
(((_type) == REGION_MEM) ? (_pcidev)->memBase[(_b)] \
: (_pcidev)->ioBase[(_b)])
/* region size: xfree86 uses the log2 of the region size,
* but with zero meaning no region, not size of one XXX */
#define PCI_REGION_SIZE(_pcidev, _b) \
(((_pcidev)->size[(_b)] > 0) ? (1 << (_pcidev)->size[(_b)]) : 0)
/* read/write PCI configuration space */
#define PCI_READ_BYTE(_pcidev, _value_ptr, _offset) \
*(_value_ptr) = pciReadByte(PCI_CFG_TAG(_pcidev), (_offset))
#define PCI_READ_LONG(_pcidev, _value_ptr, _offset) \
*(_value_ptr) = pciReadLong(PCI_CFG_TAG(_pcidev), (_offset))
#define PCI_WRITE_LONG(_pcidev, _value, _offset) \
pciWriteLong(PCI_CFG_TAG(_pcidev), (_offset), (_value))
#else /* XSERVER_LIBPCIACCESS */
typedef struct pci_device *pciVideoPtr;
#define PCI_DEV_VENDOR_ID(_pcidev) ((_pcidev)->vendor_id)
#define PCI_DEV_DEVICE_ID(_pcidev) ((_pcidev)->device_id)
#define PCI_DEV_REVISION(_pcidev) ((_pcidev)->revision)
#define PCI_SUB_VENDOR_ID(_pcidev) ((_pcidev)->subvendor_id)
#define PCI_SUB_DEVICE_ID(_pcidev) ((_pcidev)->subdevice_id)
/* pci-rework functions take a 'pci_device' parameter instead of a tag */
#define PCI_DEV_TAG(_pcidev) (_pcidev)
/* PCI_DEV macros, typically used in printf's, add domain ? XXX */
#define PCI_DEV_BUS(_pcidev) ((_pcidev)->bus)
#define PCI_DEV_DEV(_pcidev) ((_pcidev)->dev)
#define PCI_DEV_FUNC(_pcidev) ((_pcidev)->func)
/* pci-rework functions take a 'pci_device' parameter instead of a tag */
#define PCI_CFG_TAG(_pcidev) (_pcidev)
/* PCI_CFG macros, typically used in DRI init, contain the domain */
#define PCI_CFG_BUS(_pcidev) (((_pcidev)->domain << 8) | \
(_pcidev)->bus)
#define PCI_CFG_DEV(_pcidev) ((_pcidev)->dev)
#define PCI_CFG_FUNC(_pcidev) ((_pcidev)->func)
#define PCI_REGION_BASE(_pcidev, _b, _type) ((_pcidev)->regions[(_b)].base_addr)
#define PCI_REGION_SIZE(_pcidev, _b) ((_pcidev)->regions[(_b)].size)
#define PCI_READ_BYTE(_pcidev, _value_ptr, _offset) \
pci_device_cfg_read_u8((_pcidev), (_value_ptr), (_offset))
#define PCI_READ_LONG(_pcidev, _value_ptr, _offset) \
pci_device_cfg_read_u32((_pcidev), (_value_ptr), (_offset))
#define PCI_WRITE_LONG(_pcidev, _value, _offset) \
pci_device_cfg_write_u32((_pcidev), (_value), (_offset))
#endif /* XSERVER_LIBPCIACCESS */
#ifndef _XF86_PCIINFO_H
#define PCI_VENDOR_CIRRUS 0x1013
/* Cirrus Logic */
#define PCI_CHIP_GD7548 0x0038
#define PCI_CHIP_GD7555 0x0040
#define PCI_CHIP_GD7556 0x004C
#define PCI_CHIP_GD5430 0x00A0
#define PCI_CHIP_GD5434_4 0x00A4
#define PCI_CHIP_GD5434_8 0x00A8
#define PCI_CHIP_GD5436 0x00AC
#define PCI_CHIP_GD5446 0x00B8
#define PCI_CHIP_GD5480 0x00BC
#define PCI_CHIP_GD5462 0x00D0
#define PCI_CHIP_GD5464 0x00D4
#define PCI_CHIP_GD5464BD 0x00D5
#define PCI_CHIP_GD5465 0x00D6
#define PCI_CHIP_6729 0x1100
#define PCI_CHIP_6832 0x1110
#define PCI_CHIP_GD7542 0x1200
#define PCI_CHIP_GD7543 0x1202
#define PCI_CHIP_GD7541 0x1204
#endif
#endif /* CIRPCIRENAME_H */

View File

@@ -0,0 +1,288 @@
/*
Copyright (c) 1999,2000 The XFree86 Project Inc.
based on code written by Mark Vojkovich <markv@valinux.com>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86Pci.h"
#include "shadowfb.h"
#include "servermd.h"
#include "cir.h"
#include "alp.h"
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
_X_EXPORT void
cirRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
CirPtr pCir = CIRPTR(pScrn);
unsigned char *src, *dst;
int Bpp = pScrn->bitsPerPixel >> 3;
int FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
while(num--) {
int x1 = MAX(pbox->x1, 0);
int y1 = MAX(pbox->y1, 0);
int x2 = MIN(pbox->x2, pScrn->virtualX);
int y2 = MIN(pbox->y2, pScrn->virtualY);
int width = (x2 - x1) * Bpp;
int height = y2 - y1;
if (width <= 0 || height <= 0)
continue;
src = pCir->ShadowPtr + (y1 * pCir->ShadowPitch) + (x1 * Bpp);
dst = pCir->FbBase + (y1 * FBPitch) + (x1 * Bpp);
while(height--) {
memcpy(dst, src, width);
dst += FBPitch;
src += pCir->ShadowPitch;
}
pbox++;
}
}
_X_EXPORT void
cirPointerMoved(ScrnInfoPtr pScrn, int x, int y)
{
CirPtr pCir = CIRPTR(pScrn);
int newX, newY;
if(pCir->rotate == 1) {
newX = pScrn->pScreen->height - y - 1;
newY = x;
} else {
newX = y;
newY = pScrn->pScreen->width - x - 1;
}
(*pCir->PointerMoved)(pScrn, newX, newY);
}
_X_EXPORT void
cirRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
CirPtr pCir = CIRPTR(pScrn);
int dstPitch = pScrn->displayWidth;
int srcPitch = -pCir->rotate * pCir->ShadowPitch;
while(num--) {
int x1 = MAX(pbox->x1, 0);
int y1 = MAX(pbox->y1, 0);
int x2 = MIN(pbox->x2, pScrn->virtualX);
int y2 = MIN(pbox->y2, pScrn->virtualY);
int width, height;
CARD8 *dstPtr, *srcPtr;
width = x2 - x1;
y1 = y1 & ~3;
y2 = (y2 + 3) & ~3;
height = (y2 - y1) / 4; /* in dwords */
if (width <= 0 || height <= 0)
continue;
if(pCir->rotate == 1) {
dstPtr = pCir->FbBase +
(x1 * dstPitch) + pScrn->virtualX - y2;
srcPtr = pCir->ShadowPtr + ((1 - y2) * srcPitch) + x1;
} else {
dstPtr = pCir->FbBase +
((pScrn->virtualY - x2) * dstPitch) + y1;
srcPtr = pCir->ShadowPtr + (y1 * srcPitch) + x2 - 1;
}
while(width--) {
CARD8 *src = srcPtr;
CARD32 *dst = (CARD32*)dstPtr;
int count = height;
while(count--) {
*(dst++) = src[0] | (src[srcPitch] << 8) |
(src[srcPitch * 2] << 16) |
(src[srcPitch * 3] << 24);
src += srcPitch * 4;
}
srcPtr += pCir->rotate;
dstPtr += dstPitch;
}
pbox++;
}
}
_X_EXPORT void
cirRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
CirPtr pCir = CIRPTR(pScrn);
int dstPitch = pScrn->displayWidth;
int srcPitch = -pCir->rotate * pCir->ShadowPitch >> 1;
while(num--) {
int x1 = MAX(pbox->x1, 0);
int y1 = MAX(pbox->y1, 0);
int x2 = MIN(pbox->x2, pScrn->virtualX);
int y2 = MIN(pbox->y2, pScrn->virtualY);
int width, height;
CARD16 *dstPtr, *srcPtr;
width = x2 - x1;
y1 = y1 & ~1;
y2 = (y2 + 1) & ~1;
height = (y2 - y1) / 2; /* in dwords */
if (width <= 0 || height <= 0)
continue;
if(pCir->rotate == 1) {
dstPtr = (CARD16*)pCir->FbBase +
(x1 * dstPitch) + pScrn->virtualX - y2;
srcPtr = (CARD16*)pCir->ShadowPtr +
((1 - y2) * srcPitch) + x1;
} else {
dstPtr = (CARD16*)pCir->FbBase +
((pScrn->virtualY - x2) * dstPitch) + y1;
srcPtr = (CARD16*)pCir->ShadowPtr +
(y1 * srcPitch) + x2 - 1;
}
while(width--) {
CARD16 *src = srcPtr;
CARD32 *dst = (CARD32*)dstPtr;
int count = height;
while(count--) {
*(dst++) = src[0] | (src[srcPitch] << 16);
src += srcPitch * 2;
}
srcPtr += pCir->rotate;
dstPtr += dstPitch;
}
pbox++;
}
}
/* this one could be faster */
_X_EXPORT void
cirRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
CirPtr pCir = CIRPTR(pScrn);
int dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
int srcPitch = -pCir->rotate * pCir->ShadowPitch;
while(num--) {
int x1 = MAX(pbox->x1, 0);
int y1 = MAX(pbox->y1, 0);
int x2 = MIN(pbox->x2, pScrn->virtualX);
int y2 = MIN(pbox->y2, pScrn->virtualY);
int width, height;
CARD8 *dstPtr, *srcPtr;
width = x2 - x1;
y1 = y1 & ~3;
y2 = (y2 + 3) & ~3;
height = (y2 - y1) / 4; /* blocks of 3 dwords */
if (width <= 0 || height <= 0)
continue;
if(pCir->rotate == 1) {
dstPtr = pCir->FbBase +
(x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
srcPtr = pCir->ShadowPtr + ((1 - y2) * srcPitch) + (x1 * 3);
} else {
dstPtr = pCir->FbBase +
((pScrn->virtualY - x2) * dstPitch) + (y1 * 3);
srcPtr = pCir->ShadowPtr + (y1 * srcPitch) + (x2 * 3) - 3;
}
while(width--) {
CARD8 *src = srcPtr;
CARD32 *dst = (CARD32*)dstPtr;
int count = height;
while(count--) {
dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
(src[srcPitch] << 24);
dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
(src[srcPitch * 2] << 16) |
(src[(srcPitch * 2) + 1] << 24);
dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
(src[(srcPitch * 3) + 1] << 16) |
(src[(srcPitch * 3) + 2] << 24);
dst += 3;
src += srcPitch * 4;
}
srcPtr += pCir->rotate * 3;
dstPtr += dstPitch;
}
pbox++;
}
}
_X_EXPORT void
cirRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
CirPtr pCir = CIRPTR(pScrn);
int dstPitch = pScrn->displayWidth;
int srcPitch = -pCir->rotate * pCir->ShadowPitch >> 2;
while(num--) {
int x1 = MAX(pbox->x1, 0);
int y1 = MAX(pbox->y1, 0);
int x2 = MIN(pbox->x2, pScrn->virtualX);
int y2 = MIN(pbox->y2, pScrn->virtualY);
int width = x2 - x1;
int height = y2 - y1;
CARD32 *dstPtr, *srcPtr;
if (width <= 0 || height <= 0)
continue;
if(pCir->rotate == 1) {
dstPtr = (CARD32*)pCir->FbBase +
(x1 * dstPitch) + pScrn->virtualX - y2;
srcPtr = (CARD32*)pCir->ShadowPtr +
((1 - y2) * srcPitch) + x1;
} else {
dstPtr = (CARD32*)pCir->FbBase +
((pScrn->virtualY - x2) * dstPitch) + y1;
srcPtr = (CARD32*)pCir->ShadowPtr +
(y1 * srcPitch) + x2 - 1;
}
while(width--) {
CARD32 *src = srcPtr;
CARD32 *dst = dstPtr;
int count = height;
while(count--) {
*(dst++) = *src;
src += srcPitch;
}
srcPtr += pCir->rotate;
dstPtr += dstPitch;
}
pbox++;
}
}

View File

@@ -0,0 +1,105 @@
/*
* Common strutures and function for CL-GD546x -- The Laguna family
*
* lg.h
*
* (c) 1998 Corin Anderson.
* corina@the4cs.com
* Tukwila, WA
*
* Inspired by cir.h
*/
#ifndef LG_H
#define LG_H
#define LG_DEBUG
extern ScrnInfoPtr LgProbe(int entity);
extern const OptionInfoRec * LgAvailableOptions(int chipid);
# ifdef _LG_PRIVATE_
/* Saved registers that are not part of the core VGA */
/* CRTC >= 0x19; Sequencer >= 0x05; Graphics >= 0x09; Attribute >= 0x15 */
/* CR regs */
enum {
/* CR regs */
CR1A,
CR1B,
CR1D,
CR1E,
/* SR regs */
SR07,
SR0E,
SR1E,
/* Must be last! */
LG_LAST_REG
};
#undef FORMAT
typedef struct {
unsigned char ExtVga[LG_LAST_REG];
/* Laguna regs */
CARD8 TILE, BCLK;
CARD16 FORMAT, DTTC, TileCtrl, CONTROL;
CARD16 RIFCtrl, RACCtrl;
CARD32 VSC;
} LgRegRec, *LgRegPtr;
typedef struct {
int tilesPerLine; /* Number of tiles per line */
int pitch; /* Display pitch, in bytes */
int width; /* Tile width. 0 = 128 byte 1 = 256 byte */
} LgLineDataRec, *LgLineDataPtr;
/* lg_driver.c */
extern LgLineDataRec LgLineData[];
/* lg_hwcurs.c */
extern Bool LgHWCursorInit(ScreenPtr pScreen);
extern void LgHideCursor(ScrnInfoPtr pScrn);
extern void LgShowCursor(ScrnInfoPtr pScrn);
/* lg_i2c.c */
extern Bool LgI2CInit(ScrnInfoPtr pScrn);
#define memrb(off) MMIO_IN8(pCir->IOBase,off)
#define memrw(off) MMIO_IN16(pCir->IOBase,off)
#define memrl(off) MMIO_IN32(pCir->IOBase,off)
#define memwb(off,val) MMIO_OUT8(pCir->IOBase,off,val)
#define memww(off,val) MMIO_OUT16(pCir->IOBase,off,val)
#define memwl(off,val) MMIO_OUT32(pCir->IOBase,off,val)
/* Card-specific driver information */
#define LGPTR(p) ((LgPtr)((p)->chip.lg))
typedef struct lgRec {
CARD32 HWCursorAddr;
int HWCursorImageX;
int HWCursorImageY;
int HWCursorTileWidth;
int HWCursorTileHeight;
int lineDataIndex;
int memInterleave;
LgRegRec SavedReg;
LgRegRec ModeReg;
CARD32 oldBitmask;
Bool blitTransparent;
int blitYDir;
} LgRec, *LgPtr;
# endif /* _LG_PRIVATE_ */
#endif /* LG_H */

View File

@@ -0,0 +1,179 @@
#ifndef __LG_BLIT_H
#define __LG_BLIT_H
/*
* bitBLT acceleration for CL-GD546x -- The Laguna family
*
* lg_xaa.h
*
* (c) 1996,1998 Corin Anderson.
* corina@the4cs.com
* Tukwila, WA
*
* This header file draws much from the file cir_blitLG.h in version 3.3.3
* of XFree86.
*/
/* This header file defines the necessary structures, constants, and
variables for using the bitBLT engine on a Laguna family graphics
accelerator. */
enum { /* Offsets into MMIO space for bitBLT regs */
STATUS = 0x0400,
OP0_opRDRAM = 0x0520,
OP1_opRDRAM = 0x0540,
OP2_opRDRAM = 0x0560,
OP0_opMRDRAM = 0x0524,
OP1_opMRDRAM = 0x0544,
OP2_opMRDRAM = 0x0564,
OP0_opSRAM = 0x0528,
OP1_opSRAM = 0x0548,
OP2_opSRAM = 0x0568,
OP1_opMSRAM = 0x054A,
OP2_opMSRAM = 0x056A,
DRAWDEF = 0x0584,
BLTDEF = 0x0586,
BLTEXT_EX = 0x0700,
MBLTEXT_EX = 0x0720,
MONOQW = 0x0588,
QFREE = 0x0404,
PATOFF = 0x052A,
HOSTDATA = 0x0800,
OP_opBGCOLOR = 0x05E4,
OP_opFGCOLOR = 0x05E0,
bltCONTROL = 0x0402,
BITMASK = 0x05E8
};
enum { HOSTDATASIZE = 2048 }; /* The HOSTDATA port is 2048 BYTES */
enum { /* OR these together to form a bitBLT mode */
HOST2SCR = 0x1120, /* CPU/Screen transfer modes */
SCR2HOST = 0x2010,
HOST2PAT = 0x1102,
HOST2SRAM2 = 0x6020, /* CPU to SRAM2 transfer */
SCR2SCR = 0x1110, /* Screen/Screen transfers */
COLORSRC = 0x0000, /* Source is color data */
MONOSRC = 0x0040, /* Source is mono data (color expansion) */
COLORTRANS = 0x0001, /* Transparent screen/screen transfer */
MONOTRANS = 0x0005, /* Transparent screen/screen color expansion */
COLORFILL = 0x0070, /* Solid color fill mode */
SRAM1SCR2SCR = 0x1180, /* Pattern fill, source from SRAM1 */
PAT2SCR = 0x1109, /* Pattern/Screen transfers */
COLORPAT = 0x0000, /* Pattern is color data */
MONOPAT = 0x0004, /* Pattern is mono data (color expansion) */
SRAM2PAT2SCR = 0x1108, /* SRAM2 is pattern source */
PATeqSRC = 0x0800, /* The Pattern and Source operands are the same */
/* Advice from Corey: don't ever try to use
this option! 8) There's a documented bug
with it on the '62, and, well, I have
empirical evidence that either the bug's
still around, even in the '64 and the '65.
It's a performance option, anyway, so not
using it should be okay. */
BLITUP = 0x8000 /* The blit is proceeding from bottom to top */
};
enum { /* Select transparency compare */
TRANSBG = 0x0100,
TRANSFG = 0x0300,
TRANSEQ = 0x0100,
TRANSNE = 0x0300,
TRANSNONE = 0x0000
};
#define LgREADY() ((memrb(STATUS) & 0x07) == 0x00)
#define LgSETROP(rop) memww(DRAWDEF,rop);
#define LgSETTRANSPARENCY(trans) \
memww(DRAWDEF,(trans) | (memrw(DRAWDEF) & 0x00FF));
#define LgSETMODE(mode) memww(BLTDEF,mode);
#define LgSETDSTXY(X, Y) memwl(OP0_opRDRAM, (((Y) << 16) | (X)));
#define LgSETSRCXY(X, Y) memwl(OP1_opRDRAM, (((Y) << 16) | (X)));
#define LgSETPATXY(X, Y) memwl(OP2_opRDRAM, (((Y) << 16) | (X)));
#define LgSETTRANSMASK(X, Y) LgSETPATXY(X, Y)
#define LgSETSRAMDST(offset) memww(OP0_opSRAM, offset);
/* was this a bug? it read OP2_opSRAM */
#define LgSETSRAM1OFFSET(offset) memww(OP1_opSRAM, offset);
#define LgSETSRAM2OFFSET(offset) memww(OP2_opSRAM, offset);
#define LgSETMSRAM1OFFSET(offset) memww(OP1_opMSRAM, offset);
#define LgSETMSRAM2OFFSET(offset) memww(OP2_opMSRAM, offset);
#define LgSETMDSTXY(X, Y) memwl(OP0_opMRDRAM, (((Y) << 16) | (X)));
#define LgSETMSRCXY(X, Y) memwl(OP1_opMRDRAM, (((Y) << 16) | (X)));
#define LgSETMPATXY(X, Y) memwl(OP2_opMRDRAM, (((Y) << 16) | (X)));
#define LgSETMTRANSMASK(X, Y) LgSETMPATXY(X, Y)
#define LgSETPHASE0(phase) memwl( OP0_opRDRAM, phase);
#define LgSETPHASE1(phase) memwl(OP1_opRDRAM, phase);
#define LgSETPHASE2(phase) memwl( OP2_opRDRAM, phase);
#define LgSETMPHASE0(phase) memwl(OP0_opMRDRAM, phase);
#define LgSETMPHASE1(phase) memwl(OP1_opMRDRAM, phase);
#define LgSETEXTENTS(width, height) \
memwl(BLTEXT_EX, (((height) << 16)|(width)));
#if 0
#define LgSETMEXTENTS(width, height) \
memwl(MBLTEXT_EX, (((height) << 16)|(width)));
#else
/* For monochrome (byte) blits, we need to set how many QWORDs of data
encompass the X extent. Write this piece of data into MONOQW. */
#define LgSETMEXTENTS(width, height) \
{ \
memww(MONOQW, ((width + 7) >> 3)); \
memwl(MBLTEXT_EX, (((height) << 16)|(width))); \
}
#define LgSETMEXTENTSNOMONOQW(width, height) \
memwl(MBLTEXT_EX, (((height) << 16)|(width)));
/*
memww(MBLTEXT_EX, height);
memww(MBLTEXT_EX + 2, width);
*/
#endif
#define LgHOSTDATAWRITE(data) memwl(HOSTDATA, data);
#define LgHOSTDATAREAD() (memrl(HOSTDATA))
#define LgSETBACKGROUND(color) memwl(OP_opBGCOLOR, color);
#define LgSETFOREGROUND(color) memwl(OP_opFGCOLOR, color);
#define LgSETPATOFF(xoff, yoff) memww(PATOFF, (((yoff) << 8) | (xoff)));
#define LgSETSWIZZLE() memww(bltCONTROL, memrw(bltCONTROL | 0x0400));
#define LgCLEARSWIZZLE() memww(bltCONTROL, memrw(bltCONTROL & ~0x0400));
#define LgSETBITMASK(m) memwl(BITMASK, m);
#endif /* __LG_BLIT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,384 @@
/*
* Hardware cursor support for CL-GD546x -- The Laugna family
*
* lg_hwcurs.c
*
* (c) 1998 Corin Anderson.
* corina@the4cs.com
* Tukwila, WA
*
* Much of this code is inspired by the HW cursor code from XFree86
* 3.3.3.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86.h"
#include "xf86_OSproc.h"
#include "compiler.h"
#include "xf86Pci.h"
#include "vgaHW.h"
#include "cir.h"
#define _LG_PRIVATE_
#include "lg.h"
#include "lg_blit.h" /* For BitBLT engine macros */
/*
#define LG_CURSOR_DEBUG
*/
#define CURSORWIDTH 64
#define CURSORHEIGHT 64
#define CURSORSIZE (CURSORWIDTH*CURSORHEIGHT/8)
/* Some registers used for the HW cursor. */
enum {
PALETTE_READ_ADDR = 0x00A4,
PALETTE_WRITE_ADDR = 0x00A8,
PALETTE_DATA = 0x00AC,
PALETTE_STATE = 0x00B0,
CURSOR_X_POS = 0x00E0,
CURSOR_Y_POS = 0x00E2,
CURSOR_PRESET = 0x00E4,
CURSOR_CONTROL = 0x00E6,
CURSOR_ADDR = 0x00E8
};
static void
LgFindCursorTile(ScrnInfoPtr pScrn, int *x, int *y, int *width, int *height,
CARD32 *curAddr);
/*
* Set the FG and BG colors of the HW cursor.
*/
static void LgSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
const CirPtr pCir = CIRPTR(pScrn);
#ifdef LG_CURSOR_DEBUG
ErrorF("LgSetCursorColors\n");
#endif
/* Enable access to cursor colors in palette */
memwb(PALETTE_STATE, (memrb(PALETTE_STATE) | (1<<3)));
/* Slam in the color */
memwb(PALETTE_WRITE_ADDR, 0x00);
memwb(PALETTE_DATA, (bg >> 16));
memwb(PALETTE_DATA, (bg >> 8));
memwb(PALETTE_DATA, (bg >> 0));
memwb(PALETTE_WRITE_ADDR, 0x0F);
memwb(PALETTE_DATA, (fg >> 16));
memwb(PALETTE_DATA, (fg >> 8));
memwb(PALETTE_DATA, (fg >> 0));
/* Disable access to cursor colors */
memwb(PALETTE_STATE, (memrb(PALETTE_STATE) & ~(1<<3)));
}
/*
* Set the (x,y) position of the pointer.
*
* Note: (x,y) are /frame/ relative, not /framebuffer/ relative.
* That is, if the virtual desktop has been panned all the way to
* the right, and the pointer is to be in the upper-right hand corner
* of the viewable screen, the pointer coords are (0,0) (even though
* the pointer is on, say (550,0) wrt the frame buffer). This is, of
* course, a /good/ thing -- we don't want to have to deal with where
* the virtual display is, etc, in the cursor code.
*
*/
static void LgSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
const CirPtr pCir = CIRPTR(pScrn);
#if 0
#ifdef LG_CURSOR_DEBUG
ErrorF("LgSetCursorPosition %d %d\n", x, y);
#endif
#endif
if (x < 0 || y < 0) {
CARD16 oldPreset = memrw(CURSOR_PRESET);
CARD16 newPreset = 0x8080 & oldPreset; /* Reserved bits */
if (x < 0) {
newPreset |= ((-x & 0x7F) << 8);
x = 0;
}
if (y < 0) {
newPreset |= ((-y & 0x7F) << 0);
y = 0;
}
memww(CURSOR_PRESET, newPreset);
pCir->CursorIsSkewed = TRUE;
} else if (pCir->CursorIsSkewed) {
/* Reset the hotspot location. */
memww(CURSOR_PRESET, memrw(CURSOR_PRESET & 0x8080));
pCir->CursorIsSkewed = FALSE;
}
/* Commit the new position to the card. */
memww(CURSOR_X_POS, x);
memww(CURSOR_Y_POS, y);
}
/*
* Load the cursor image to the card. The cursor image is given in
* bits. The format is: ???
*/
static void LgLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits)
{
const CirPtr pCir = CIRPTR(pScrn);
const LgPtr pLg = LGPTR(pCir);
volatile CARD32 *pXCursorBits = (CARD32 *)bits;
int l, w;
#ifdef LG_CURSOR_DEBUG
ErrorF("LgLoadCursorImage\n");
#endif
/* All ("all") we have to do is a simple CPU-to-screen copy of the
cursor image to the frame buffer. */
while (!LgREADY()) {}
;
/* Wait until there's ample room in the chip's queue */
while (memrb(QFREE) < 10) {}
;
LgSETMODE(HOST2SCR); /* Host-to-screen blit */
LgSETROP(0x00CC); /* Source copy */
/* First, copy our transparent cursor image to the next 1/2 tile boundary */
/* Destination */
LgSETMDSTXY(pLg->HWCursorImageX+pLg->HWCursorTileWidth, pLg->HWCursorImageY);
/* Set the source pitch. 0 means that, worst case, the source is
aligned only on a byte boundary */
LgSETMPHASE1(0);
LgSETMEXTENTSNOMONOQW(pLg->HWCursorTileWidth, pLg->HWCursorTileHeight);
for (l = 0; l < CURSORHEIGHT; l++) {
/* Plane 0 */
for (w = 0; w < CURSORWIDTH >> 5; w++)
memwl(HOSTDATA, 0x00000000);
/* Plane 1 */
for (w = 0; w < CURSORWIDTH >> 5; w++)
memwl(HOSTDATA, 0x00000000);
}
/* Now, copy the real cursor image */
/* Set the destination */
LgSETMDSTXY(pLg->HWCursorImageX, pLg->HWCursorImageY);
/* Set the source pitch. 0 means that, worst case, the source is
aligned only on a byte boundary */
LgSETMPHASE1(0);
/* Always copy an entire cursor image to the card. */
LgSETMEXTENTSNOMONOQW(pLg->HWCursorTileWidth, pLg->HWCursorTileHeight);
for (l = 0; l < CURSORHEIGHT; l++) {
/* Plane 0 */
for (w = 0; w < CURSORWIDTH >> 5; w++)
memwl(HOSTDATA, *pXCursorBits++);
/* Plane 1 */
for (w = 0; w < CURSORWIDTH >> 5; w++)
memwl(HOSTDATA, *pXCursorBits++);
}
while (!LgREADY())
;
}
/*
* LgFindCursorTile() finds the tile of display memory that will be
* used to load the pointer image into. The tile chosen will be the
* last tile in the last line of the frame buffer.
*/
static void
LgFindCursorTile(ScrnInfoPtr pScrn, int *x, int *y, int *width, int *height,
CARD32 *curAddr)
{
CirPtr pCir = CIRPTR(pScrn);
LgPtr pLg = LGPTR(pCir);
int videoRam = pScrn->videoRam; /* in K */
int tileHeight = LgLineData[pLg->lineDataIndex].width?8:16;
int tileWidth = LgLineData[pLg->lineDataIndex].width?256:128;
int tilesPerLine = LgLineData[pLg->lineDataIndex].tilesPerLine;
int filledOutTileLines, leftoverMem;
int yTile, xTile;
filledOutTileLines = videoRam / (tilesPerLine * 2); /* tiles are 2K */
leftoverMem = videoRam - filledOutTileLines*tilesPerLine*2;
if (leftoverMem > 0) {
yTile = filledOutTileLines;
} else {
/* There is no incomplete row of tiles. Then just use the last
tile in the last line */
yTile = filledOutTileLines - 1;
}
xTile = 0; /* Always use the first tile in the determined tile row */
/* The (x,y) coords of the pointer image. */
if (x)
*x = xTile * tileWidth;
if (y)
*y = yTile * tileHeight;
if (width)
*width = tileWidth;
if (height)
*height = tileHeight / 2;
/* Now, compute the linear address of the cursor image. This process
is unpleasant because the memory is tiled, and we essetially have
to undo the tiling computation. */
if (curAddr) {
unsigned int nIL; /* Interleaving */
nIL = pLg->memInterleave==0x00? 1 : (pLg->memInterleave==0x40 ? 2 : 4);
if (PCI_CHIP_GD5465 == pCir->Chipset) {
/* The Where's The Cursor formula changed for the 5465. It's really
kinda weird now. */
unsigned long page, bank;
unsigned int nX, nY;
nX = xTile * tileWidth;
nY = yTile * tileHeight;
page = (nY / (tileHeight * nIL)) * tilesPerLine + nX / tileWidth;
bank = (nX/tileWidth + nY/tileHeight) % nIL + page/(512*nIL);
page = page & 0x1FF;
*curAddr = bank*1024*1024L + page*2048 + (nY%tileHeight)*tileWidth;
} else {
int tileNumber = (tilesPerLine*nIL) * (yTile/nIL) + yTile % nIL;
*curAddr = tileNumber * 2048;
}
}
}
/*
* Hide/disable the HW cursor.
*/
void LgHideCursor(ScrnInfoPtr pScrn)
{
const CirPtr pCir = CIRPTR(pScrn);
/* To hide the cursor, we kick it off into the corner, and then set the
cursor image to be a transparent bitmap. That way, if X continues
to move the cursor while it is hidden, there is no way that the user
can move the cursor back on screen!
We don't just clear the cursor enable bit because doesn't work in some
cases (like when switching back to text mode).
*/
#ifdef LG_CURSOR_DEBUG
ErrorF("LgHideCursor\n");
#endif
memww(CURSOR_CONTROL, (memrw(CURSOR_CONTROL) & 0xFFFE));
}
void LgShowCursor(ScrnInfoPtr pScrn)
{
const CirPtr pCir = CIRPTR(pScrn);
const LgPtr pLg = LGPTR(pCir);
#ifdef LG_CURSOR_DEBUG
ErrorF("LgShowCursor\n");
#endif
memww(CURSOR_CONTROL,(memrw(CURSOR_CONTROL) | (1<<0)));
memww(CURSOR_ADDR,(pLg->HWCursorAddr & 0x7FFC));
}
/*
* Can the HW cursor be used?
*/
static Bool LgUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
#ifdef LG_CURSOR_DEBUG
ErrorF("LgUseHWCursor\n");
#endif
if(pScrn->bitsPerPixel < 8)
return FALSE;
return TRUE;
}
/*
* Initialize all the fun HW cursor code.
*/
Bool LgHWCursorInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
CirPtr pCir = CIRPTR(pScrn);
xf86CursorInfoPtr infoPtr;
#ifdef LG_CURSOR_DEBUG
ErrorF("LgHWCursorInit\n");
#endif
infoPtr = xf86CreateCursorInfoRec();
if(!infoPtr) return FALSE;
pCir->CursorInfoRec = infoPtr;
LgFindCursorTile(pScrn, &pCir->chip.lg->HWCursorImageX, &pCir->chip.lg->HWCursorImageY,
&pCir->chip.lg->HWCursorTileWidth, &pCir->chip.lg->HWCursorTileHeight,
&pCir->chip.lg->HWCursorAddr);
/* Keep only bits 22:10 of the address. */
pCir->chip.lg->HWCursorAddr = (pCir->chip.lg->HWCursorAddr >> 8) & 0x7FFC;
pCir->CursorIsSkewed = FALSE;
infoPtr->MaxWidth = CURSORWIDTH;
infoPtr->MaxHeight = CURSORHEIGHT;
infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
| HARDWARE_CURSOR_AND_SOURCE_WITH_MASK
| HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64;
infoPtr->SetCursorColors = LgSetCursorColors;
infoPtr->SetCursorPosition = LgSetCursorPosition;
infoPtr->LoadCursorImage = LgLoadCursorImage;
infoPtr->HideCursor = LgHideCursor;
infoPtr->ShowCursor = LgShowCursor;
infoPtr->UseHWCursor = LgUseHWCursor;
#ifdef LG_CURSOR_DEBUG
ErrorF("LgHWCursorInit before xf86InitCursor\n");
#endif
return(xf86InitCursor(pScreen, infoPtr));
}

View File

@@ -0,0 +1,109 @@
/* (c) Itai Nahshon */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86.h"
#include "xf86_OSproc.h"
#include "compiler.h"
#include "xf86Pci.h"
#include "vgaHW.h"
#include "cir.h"
#define _LG_PRIVATE_
#include "lg.h"
static char strI2CBus1[] = "I2C bus 1";
static char strI2CBus2[] = "I2C bus 2";
static void
LgI2CPutBits(I2CBusPtr b, int clock, int data)
{
unsigned int regval, regno;
CirPtr pCir = ((CirPtr) b->DriverPrivate.ptr);
if (b == pCir->I2CPtr1)
regno = 0x280;
else if (b == pCir->I2CPtr2)
regno = 0x282;
else
return;
regval = 0xff7e;
if (clock)
regval |= 0x0080;
if (data)
regval |= 0x0001;
memww(regno, regval);
/*
ErrorF("LgI2CPutBits: %d %d\n", clock, data);
*/
}
static void
LgI2CGetBits(I2CBusPtr b, int *clock, int *data)
{
unsigned int regval, regno;
CirPtr pCir = ((CirPtr) b->DriverPrivate.ptr);
if (b == pCir->I2CPtr1)
regno = 0x280;
else if (b == pCir->I2CPtr2)
regno = 0x282;
else
return;
regval = memrw(regno);
*clock = (regval & 0x8000) != 0;
*data = (regval & 0x0100) != 0;
/*
ErrorF("LgI2CGetBits: %d %d\n", *clock, *data);
*/
}
Bool
LgI2CInit(ScrnInfoPtr pScrn)
{
CirPtr pCir = CIRPTR(pScrn);
I2CBusPtr I2CPtr;
#ifdef LG_DEBUG
ErrorF("LgI2CInit\n");
#endif
I2CPtr = xf86CreateI2CBusRec();
if (!I2CPtr)
return FALSE;
pCir->I2CPtr1 = I2CPtr;
I2CPtr->BusName = strI2CBus1;
I2CPtr->scrnIndex = pScrn->scrnIndex;
I2CPtr->I2CPutBits = LgI2CPutBits;
I2CPtr->I2CGetBits = LgI2CGetBits;
I2CPtr->DriverPrivate.ptr = pCir;
if (!xf86I2CBusInit(I2CPtr))
return FALSE;
I2CPtr = xf86CreateI2CBusRec();
if (!I2CPtr)
return FALSE;
pCir->I2CPtr2 = I2CPtr;
I2CPtr->BusName = strI2CBus2;
I2CPtr->scrnIndex = pScrn->scrnIndex;
I2CPtr->I2CPutBits = LgI2CPutBits;
I2CPtr->I2CGetBits = LgI2CGetBits;
I2CPtr->DriverPrivate.ptr = pCir;
if (!xf86I2CBusInit(I2CPtr))
return FALSE;
return TRUE;
}