Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
6a8bd1ea
Commit
6a8bd1ea
authored
Jan 10, 2003
by
James Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[TRIDENT FBDEV] Driver ported to the new api.
parent
bcf42809
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
617 additions
and
632 deletions
+617
-632
drivers/video/Makefile
drivers/video/Makefile
+2
-2
drivers/video/tridentfb.c
drivers/video/tridentfb.c
+597
-618
include/video/trident.h
include/video/trident.h
+18
-12
No files found.
drivers/video/Makefile
View file @
6a8bd1ea
...
...
@@ -45,7 +45,7 @@ obj-$(CONFIG_FB_OF) += offb.o cfbfillrect.o cfbimgblt.o cfbcopyare
obj-$(CONFIG_FB_IMSTT)
+=
imsttfb.o
obj-$(CONFIG_FB_RETINAZ3)
+=
retz3fb.o
obj-$(CONFIG_FB_CLGEN)
+=
clgenfb.o
obj-$(CONFIG_FB_TRIDENT)
+=
tridentfb.o
obj-$(CONFIG_FB_TRIDENT)
+=
tridentfb.o
cfbfillrect.o cfbimgblt.o cfbcopyarea.o
obj-$(CONFIG_FB_S3TRIO)
+=
S3triofb.o
obj-$(CONFIG_FB_TGA)
+=
tgafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_VESA)
+=
vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
...
...
@@ -71,7 +71,7 @@ obj-$(CONFIG_FB_TX3912) += tx3912fb.o cfbfillrect.o cfbcopyarea.o cfbi
obj-$(CONFIG_FB_MATROX)
+=
matrox/
obj-$(CONFIG_FB_RIVA)
+=
riva/ cfbimgblt.o vgastate.o
obj-$(CONFIG_FB_SIS)
+=
sis/
obj-$(CONFIG_FB_ATY)
+=
aty/ cfbimgblt.o
obj-$(CONFIG_FB_ATY)
+=
aty/ cfbimgblt.o
cfbfillrect.o cfbimgblt.o
obj-$(CONFIG_FB_I810)
+=
i810/ cfbfillrect.o cfbcopyarea.o
\
cfbimgblt.o vgastate.o
...
...
drivers/video/tridentfb.c
View file @
6a8bd1ea
/*
* Frame buffer driver for Trident Blade and Image series
*
* Copyright 2001,2002 - Jani Monoses <jani@
astechnix
.ro>
* Copyright 2001,2002 - Jani Monoses <jani@
iv
.ro>
*
* $Id: tridentfb.c,v 1.3 2002/02/25 20:09:41 marcelo Exp $
*
* CREDITS:(in order of appearance)
* skeletonfb.c by Geert Uytterhoeven and other fb code in drivers/video
* Special thanks ;) to Mattia Crivellini <tia@mclink.it>
* much inspired by the XFree86 4.
1.0
Trident driver sources by Alan Hourihane
* much inspired by the XFree86 4.
x
Trident driver sources by Alan Hourihane
* the FreeVGA project
* Francesco Salvestrini <salvestrini@users.sf.net> XP support,code,suggestions
* NOTES:
* Tested on Compaq Presario 12XL300 with CyberBladei1
* Tested on Toshiba 1800-514 with CyberBladeXPAi1
* No monitors were harmed during the writing of this driver
* TODO:
* timing value tweaking so it looks good on every monitor in every mode
* test text acceleration for the Image series
* test DPMS stuff
* TGUI acceleration
*/
#include <linux/config.h>
...
...
@@ -27,69 +21,41 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb24.h>
#include <video/fbcon-cfb32.h>
#include <linux/delay.h>
#include <video/trident.h>
#include "tridentfb.h"
#define VERSION "0.6.9"
#define VERSION "0.7.8-NEWAPI"
struct
tridentfb_par
{
struct
fb_var_screeninfo
var
;
int
bpp
;
int
hres
;
int
vres
;
int
linelength
;
int
vclk
;
//in MHz
int
vtotal
;
int
vdispend
;
int
vsyncstart
;
int
vsyncend
;
int
vblankstart
;
int
vblankend
;
int
htotal
;
int
hdispend
;
int
hsyncstart
;
int
hsyncend
;
int
hblankstart
;
int
hblankend
;
};
struct
tridentfb_info
{
struct
fb_info_gen
gen
;
unsigned
int
fbmem_virt
;
//framebuffer virtual memory address
unsigned
int
fbmem
;
//framebuffer physical memory address
unsigned
int
memsize
;
//size of fbmem
unsigned
int
io
;
//io space address
unsigned
int
io_virt
;
//iospace virtual memory address
unsigned
int
nativex
;
//flat panel xres
struct
tridentfb_par
currentmode
;
unsigned
int
io_virt
;
//iospace virtual memory address
};
unsigned
char
eng_oper
;
//engine operation...
static
struct
fb_ops
tridentfb_ops
;
static
struct
tridentfb_info
fb_info
;
static
struct
display
disp
;
static
struct
tridentfb_par
default_par
;
/* FIXME:kmalloc these 3 instead */
static
struct
fb_info
fb_info
;
static
int
pseudo_pal
[
16
];
static
struct
{
unsigned
char
red
,
green
,
blue
,
transp
;
}
palette
[
256
];
static
struct
fb_var_screeninfo
default_var
;
static
char
*
tridentfb_name
=
"Trident"
;
static
struct
fb_fix_screeninfo
tridentfb_fix
=
{
.
id
=
"Trident"
,
.
type
=
FB_TYPE_PACKED_PIXELS
,
.
ypanstep
=
1
,
.
visual
=
FB_VISUAL_PSEUDOCOLOR
,
.
accel
=
FB_ACCEL_NONE
,
};
static
int
family
;
static
int
pci_id
;
static
int
chip_id
;
static
int
defaultaccel
;
static
int
displaytype
;
static
int
pseudo_pal
[
16
];
/* defaults which are normally overriden by user values */
...
...
@@ -98,7 +64,6 @@ static char * mode = "640x480";
static
int
bpp
=
8
;
static
int
noaccel
;
static
int
accel
;
static
int
center
;
static
int
stretch
;
...
...
@@ -116,7 +81,6 @@ MODULE_PARM(bpp,"i");
MODULE_PARM
(
center
,
"i"
);
MODULE_PARM
(
stretch
,
"i"
);
MODULE_PARM
(
noaccel
,
"i"
);
MODULE_PARM
(
accel
,
"i"
);
MODULE_PARM
(
memsize
,
"i"
);
MODULE_PARM
(
memdiff
,
"i"
);
MODULE_PARM
(
nativex
,
"i"
);
...
...
@@ -124,6 +88,54 @@ MODULE_PARM(fp,"i");
MODULE_PARM
(
crt
,
"i"
);
static
int
chip3D
;
static
int
chipcyber
;
int
is3Dchip
(
int
id
)
{
return
((
id
==
BLADE3D
)
||
(
id
==
CYBERBLADEE4
)
||
(
id
==
CYBERBLADEi7
)
||
(
id
==
CYBERBLADEi7D
)
||
(
id
==
CYBER9397
)
||
(
id
==
CYBER9397DVD
)
||
(
id
==
CYBER9520
)
||
(
id
==
CYBER9525DVD
)
||
(
id
==
IMAGE975
)
||
(
id
==
IMAGE985
)
||
(
id
==
CYBERBLADEi1
)
||
(
id
==
CYBERBLADEi1D
)
||
(
id
==
CYBERBLADEAi1
)
||
(
id
==
CYBERBLADEAi1D
)
||
(
id
==
CYBERBLADEXPm8
)
||
(
id
==
CYBERBLADEXPm16
)
||
(
id
==
CYBERBLADEXPAi1
));
}
int
iscyber
(
int
id
)
{
switch
(
id
)
{
case
CYBER9388
:
case
CYBER9382
:
case
CYBER9385
:
case
CYBER9397
:
case
CYBER9397DVD
:
case
CYBER9520
:
case
CYBER9525DVD
:
case
CYBERBLADEE4
:
case
CYBERBLADEi7D
:
case
CYBERBLADEi1
:
case
CYBERBLADEi1D
:
case
CYBERBLADEAi1
:
case
CYBERBLADEAi1D
:
case
CYBERBLADEXPAi1
:
return
1
;
case
CYBER9320
:
case
TGUI9660
:
case
IMAGE975
:
case
IMAGE985
:
case
BLADE3D
:
case
CYBERBLADEi7
:
/* VIA MPV4 integrated version */
default:
/* case CYBERBLDAEXPm8: Strange */
/* case CYBERBLDAEXPm16: Strange */
return
0
;
}
}
#define CRT 0x3D0 //CRTC registers offset for color display
...
...
@@ -132,8 +144,8 @@ MODULE_PARM(crt,"i");
#endif
#if TRIDENT_MMIO
#define t_outb(val,reg) writeb(val,
fb_info.
io_virt + reg)
#define t_inb(reg) readb(
fb_info.
io_virt + reg)
#define t_outb(val,reg) writeb(val,
((struct tridentfb_par *)(fb_info.par))->
io_virt + reg)
#define t_inb(reg) readb(
((struct tridentfb_par*)(fb_info.par))->
io_virt + reg)
#else
#define t_outb(val,reg) outb(val,reg)
#define t_inb(reg) inb(reg)
...
...
@@ -143,16 +155,17 @@ MODULE_PARM(crt,"i");
static
struct
accel_switch
{
void
(
*
init_accel
)(
int
,
int
);
void
(
*
wait_engine
)(
void
);
void
(
*
fill_rect
)(
int
,
int
,
int
,
int
,
int
);
void
(
*
copy_rect
)(
int
,
int
,
int
,
int
,
int
,
int
);
void
(
*
fill_rect
)(
__u32
,
__u32
,
__u32
,
__u32
,
__u32
,
__u32
);
void
(
*
copy_rect
)(
__u32
,
__u32
,
__u32
,
__u32
,
__u32
,
__u32
);
}
*
acc
;
#define writemmr(r,v) writel(v, fb_info.io_virt + r)
#define readmmr(r) readl(fb_info.io_virt + r)
#define writemmr(r,v) writel(v, ((struct tridentfb_par *)fb_info.par)->io_virt + r)
#define readmmr(r) readl(((struct tridentfb_par *)fb_info.par)->io_virt + r)
/*
* Blade specific acceleration.Not XP's though those are
* unaccelerated.
* Blade specific acceleration.
*/
#define point(x,y) ((y)<<16|(x))
...
...
@@ -165,7 +178,6 @@ static struct accel_switch {
#define DR1 0x2108
#define DR2 0x210C
#define REPL(x) x = x | x<<16
#define ROP_S 0xCC
static
void
blade_init_accel
(
int
pitch
,
int
bpp
)
...
...
@@ -196,26 +208,26 @@ static void blade_wait_engine(void)
while
(
readmmr
(
STA
)
&
0xFA800000
);
}
static
void
blade_fill_rect
(
int
x
,
int
y
,
int
w
,
int
h
,
int
c
)
static
void
blade_fill_rect
(
__u32
x
,
__u32
y
,
__u32
w
,
__u32
h
,
__u32
c
,
__u32
rop
)
{
writemmr
(
CLR
,
c
);
writemmr
(
ROP
,
ROP_S
);
writemmr
(
ROP
,
rop
?
0x66
:
ROP_S
);
writemmr
(
CMD
,
0x20000000
|
1
<<
19
|
1
<<
4
|
2
<<
2
);
writemmr
(
DR1
,
point
(
x
,
y
));
writemmr
(
DR2
,
point
(
x
+
w
-
1
,
y
+
h
-
1
));
}
static
void
blade_copy_rect
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
w
,
int
h
)
static
void
blade_copy_rect
(
__u32
x1
,
__u32
y1
,
__u32
x2
,
__u32
y2
,
__u32
w
,
__u32
h
)
{
int
s1
,
s2
,
d1
,
d2
;
__u32
s1
,
s2
,
d1
,
d2
;
int
direction
=
2
;
s1
=
point
(
x1
,
y1
);
s2
=
point
(
x1
+
w
-
1
,
y1
+
h
-
1
);
d1
=
point
(
x2
,
y2
);
d2
=
point
(
x2
+
w
-
1
,
y2
+
h
-
1
);
if
((
y1
>
y2
)
||
((
y1
==
y2
)
&&
(
x1
>
x2
)))
if
((
y1
>
y2
)
||
((
y1
==
y2
)
&&
(
x1
>
x2
)))
direction
=
0
;
...
...
@@ -235,6 +247,130 @@ static struct accel_switch accel_blade = {
blade_copy_rect
,
};
/*
* BladeXP specific acceleration functions
*/
#define ROP_P 0xF0
#define masked_point(x,y) ((y & 0xffff)<<16|(x & 0xffff))
static
void
xp_init_accel
(
int
pitch
,
int
bpp
)
{
int
tmp
=
0
,
v1
;
unsigned
char
x
=
0
;
switch
(
bpp
)
{
case
8
:
x
=
0
;
break
;
case
16
:
x
=
1
;
break
;
case
24
:
x
=
3
;
break
;
case
32
:
x
=
2
;
break
;
}
switch
(
pitch
<<
(
bpp
>>
3
))
{
case
8192
:
case
512
:
x
|=
0x00
;
break
;
case
1024
:
x
|=
0x04
;
break
;
case
2048
:
x
|=
0x08
;
break
;
case
4096
:
x
|=
0x0C
;
break
;
}
t_outb
(
x
,
0x2125
);
eng_oper
=
x
|
0x40
;
switch
(
bpp
)
{
case
8
:
tmp
=
18
;
break
;
case
15
:
case
16
:
tmp
=
19
;
break
;
case
24
:
case
32
:
tmp
=
20
;
break
;
}
v1
=
pitch
<<
tmp
;
writemmr
(
0x2154
,
v1
);
writemmr
(
0x2150
,
v1
);
t_outb
(
3
,
0x2126
);
}
static
void
xp_wait_engine
(
void
)
{
int
busy
;
int
count
,
timeout
;
count
=
0
;
timeout
=
0
;
for
(;;)
{
busy
=
t_inb
(
STA
)
&
0x80
;
if
(
busy
!=
0x80
)
return
;
count
++
;
if
(
count
==
10000000
)
{
/* Timeout */
count
=
9990000
;
timeout
++
;
if
(
timeout
==
8
)
{
/* Reset engine */
t_outb
(
0x00
,
0x2120
);
return
;
}
}
}
}
static
void
xp_fill_rect
(
__u32
x
,
__u32
y
,
__u32
w
,
__u32
h
,
__u32
c
,
__u32
rop
)
{
writemmr
(
0x2127
,
ROP_P
);
writemmr
(
0x2158
,
c
);
writemmr
(
0x2128
,
0x4000
);
writemmr
(
0x2140
,
masked_point
(
h
,
w
));
writemmr
(
0x2138
,
masked_point
(
y
,
x
));
t_outb
(
0x01
,
0x2124
);
t_outb
(
eng_oper
,
0x2125
);
}
static
void
xp_copy_rect
(
__u32
x1
,
__u32
y1
,
__u32
x2
,
__u32
y2
,
__u32
w
,
__u32
h
)
{
int
direction
;
__u32
x1_tmp
,
x2_tmp
,
y1_tmp
,
y2_tmp
;
direction
=
0x0004
;
if
((
x1
<
x2
)
&&
(
y1
==
y2
))
{
direction
|=
0x0200
;
x1_tmp
=
x1
+
w
-
1
;
x2_tmp
=
x2
+
w
-
1
;
}
else
{
x1_tmp
=
x1
;
x2_tmp
=
x2
;
}
if
(
y1
<
y2
)
{
direction
|=
0x0100
;
y1_tmp
=
y1
+
h
-
1
;
y2_tmp
=
y2
+
h
-
1
;
}
else
{
y1_tmp
=
y1
;
y2_tmp
=
y2
;
}
writemmr
(
0x2128
,
direction
);
t_outb
(
ROP_S
,
0x2127
);
writemmr
(
0x213C
,
masked_point
(
y1_tmp
,
x1_tmp
));
writemmr
(
0x2138
,
masked_point
(
y2_tmp
,
x2_tmp
));
writemmr
(
0x2140
,
masked_point
(
h
,
w
));
t_outb
(
0x01
,
0x2124
);
}
static
struct
accel_switch
accel_xp
=
{
xp_init_accel
,
xp_wait_engine
,
xp_fill_rect
,
xp_copy_rect
,
};
/*
* Image specific acceleration functions
*/
...
...
@@ -255,7 +391,7 @@ static void image_init_accel(int pitch,int bpp)
writemmr
(
0x2148
,
0x00000000
);
writemmr
(
0x2150
,
0x00000000
);
writemmr
(
0x2154
,
0x00000000
);
writemmr
(
0x2120
,
0x60000000
|
(
pitch
<<
16
)
|
pitch
);
writemmr
(
0x2120
,
0x60000000
|
(
pitch
<<
16
)
|
pitch
);
writemmr
(
0x216C
,
0x00000000
);
writemmr
(
0x2170
,
0x00000000
);
writemmr
(
0x217C
,
0x00000000
);
...
...
@@ -268,7 +404,7 @@ static void image_wait_engine(void)
while
(
readmmr
(
0x2164
)
&
0xF0000000
);
}
static
void
image_fill_rect
(
int
x
,
int
y
,
int
w
,
int
h
,
int
c
)
static
void
image_fill_rect
(
__u32
x
,
__u32
y
,
__u32
w
,
__u32
h
,
__u32
c
,
__u32
rop
)
{
writemmr
(
0x2120
,
0x80000000
);
writemmr
(
0x2120
,
0x90000000
|
ROP_S
);
...
...
@@ -281,9 +417,9 @@ static void image_fill_rect(int x,int y,int w,int h,int c)
writemmr
(
0x2124
,
0x80000000
|
3
<<
22
|
1
<<
10
|
1
<<
9
);
}
static
void
image_copy_rect
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
w
,
int
h
)
static
void
image_copy_rect
(
__u32
x1
,
__u32
y1
,
__u32
x2
,
__u32
y2
,
__u32
w
,
__u32
h
)
{
int
s1
,
s2
,
d1
,
d2
;
__u32
s1
,
s2
,
d1
,
d2
;
int
direction
=
2
;
s1
=
point
(
x1
,
y1
);
s2
=
point
(
x1
+
w
-
1
,
y1
+
h
-
1
);
...
...
@@ -315,108 +451,45 @@ static struct accel_switch accel_image = {
* Accel functions called by the upper layers
*/
static
void
trident_bmove
(
struct
display
*
p
,
int
sy
,
int
sx
,
int
dy
,
int
dx
,
int
height
,
int
width
)
static
void
tridentfb_fillrect
(
struct
fb_info
*
info
,
struct
fb_fillrect
*
fr
)
{
sx
*=
fontwidth
(
p
);
dx
*=
fontwidth
(
p
);
width
*=
fontwidth
(
p
);
sy
*=
fontheight
(
p
);
dy
*=
fontheight
(
p
);
height
*=
fontheight
(
p
);
acc
->
copy_rect
(
sx
,
sy
,
dx
,
dy
,
width
,
height
);
int
bpp
=
info
->
var
.
bits_per_pixel
;
int
dx
,
dy
,
w
,
h
,
col
;
switch
(
bpp
)
{
case
8
:
col
=
fr
->
color
;
break
;
case
16
:
col
=
((
u16
*
)(
info
->
pseudo_palette
))[
fr
->
color
];
break
;
case
32
:
col
=
((
u32
*
)(
info
->
pseudo_palette
))[
fr
->
color
];
break
;
}
acc
->
fill_rect
(
fr
->
dx
,
fr
->
dy
,
fr
->
width
,
fr
->
height
,
col
,
fr
->
rop
);
acc
->
wait_engine
();
}
static
void
trident_clear_helper
(
int
c
,
struct
display
*
p
,
int
sy
,
int
sx
,
int
height
,
int
width
)
static
void
tridentfb_copyarea
(
struct
fb_info
*
info
,
struct
fb_copyarea
*
ca
)
{
sx
*=
fontwidth
(
p
);
sy
*=
fontheight
(
p
);
width
*=
fontwidth
(
p
);
height
*=
fontheight
(
p
);
acc
->
fill_rect
(
sx
,
sy
,
width
,
height
,
c
);
acc
->
copy_rect
(
ca
->
sx
,
ca
->
sy
,
ca
->
dx
,
ca
->
dy
,
ca
->
width
,
ca
->
height
);
acc
->
wait_engine
();
}
#ifdef FBCON_HAS_CFB8
static
void
trident_8bpp_clear
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
sy
,
int
sx
,
int
height
,
int
width
)
{
int
c
;
c
=
attr_bgcol_ec
(
p
,
conp
)
&
0xFF
;
c
|=
c
<<
8
;
c
|=
c
<<
16
;
trident_clear_helper
(
c
,
p
,
sy
,
sx
,
height
,
width
);
}
static
struct
display_switch
trident_8bpp
=
{
.
setup
=
fbcon_cfb8_setup
,
.
bmove
=
trident_bmove
,
.
clear
=
trident_8bpp_clear
,
.
putc
=
fbcon_cfb8_putc
,
.
putcs
=
fbcon_cfb8_putcs
,
.
revc
=
fbcon_cfb8_revc
,
.
clear_margins
=
fbcon_cfb8_clear_margins
,
.
fontwidthmask
=
FONTWIDTH
(
4
)
|
FONTWIDTH
(
8
)
|
FONTWIDTH
(
12
)
|
FONTWIDTH
(
16
)
};
#endif
#ifdef FBCON_HAS_CFB16
static
void
trident_16bpp_clear
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
sy
,
int
sx
,
int
height
,
int
width
)
{
int
c
;
c
=
((
u16
*
)
p
->
dispsw_data
)[
attr_bgcol_ec
(
p
,
conp
)];
c
=
c
|
c
<<
16
;
trident_clear_helper
(
c
,
p
,
sy
,
sx
,
height
,
width
);
}
static
struct
display_switch
trident_16bpp
=
{
.
setup
=
fbcon_cfb16_setup
,
.
bmove
=
trident_bmove
,
.
clear
=
trident_16bpp_clear
,
.
putc
=
fbcon_cfb16_putc
,
.
putcs
=
fbcon_cfb16_putcs
,
.
revc
=
fbcon_cfb16_revc
,
.
clear_margins
=
fbcon_cfb16_clear_margins
,
.
fontwidthmask
=
FONTWIDTH
(
4
)
|
FONTWIDTH
(
8
)
|
FONTWIDTH
(
12
)
|
FONTWIDTH
(
16
)
};
#endif
#ifdef FBCON_HAS_CFB32
static
void
trident_32bpp_clear
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
sy
,
int
sx
,
int
height
,
int
width
)
{
int
c
;
c
=
((
u32
*
)
p
->
dispsw_data
)[
attr_bgcol_ec
(
p
,
conp
)];
trident_clear_helper
(
c
,
p
,
sy
,
sx
,
height
,
width
);
}
static
struct
display_switch
trident_32bpp
=
{
.
setup
=
fbcon_cfb32_setup
,
.
bmove
=
trident_bmove
,
.
clear
=
trident_32bpp_clear
,
.
putc
=
fbcon_cfb32_putc
,
.
putcs
=
fbcon_cfb32_putcs
,
.
revc
=
fbcon_cfb32_revc
,
.
clear_margins
=
fbcon_cfb32_clear_margins
,
.
fontwidthmask
=
FONTWIDTH
(
4
)
|
FONTWIDTH
(
8
)
|
FONTWIDTH
(
12
)
|
FONTWIDTH
(
16
)
};
#endif
/*
* Hardware access functions
*/
static
inline
unsigned
char
read3X4
(
int
reg
)
{
writeb
(
reg
,
fb_info
.
io_virt
+
CRT
+
4
);
return
readb
(
fb_info
.
io_virt
+
CRT
+
5
);
struct
tridentfb_par
*
par
=
(
struct
tridentfb_par
*
)
fb_info
.
par
;
writeb
(
reg
,
par
->
io_virt
+
CRT
+
4
);
return
readb
(
par
->
io_virt
+
CRT
+
5
);
}
static
inline
void
write3X4
(
int
reg
,
unsigned
char
val
)
{
writeb
(
reg
,
fb_info
.
io_virt
+
CRT
+
4
);
writeb
(
val
,
fb_info
.
io_virt
+
CRT
+
5
);
struct
tridentfb_par
*
par
=
(
struct
tridentfb_par
*
)
fb_info
.
par
;
writeb
(
reg
,
par
->
io_virt
+
CRT
+
4
);
writeb
(
val
,
par
->
io_virt
+
CRT
+
5
);
}
static
inline
unsigned
char
read3C4
(
int
reg
)
...
...
@@ -439,14 +512,14 @@ static inline unsigned char read3CE(int reg)
static
inline
void
writeAttr
(
int
reg
,
unsigned
char
val
)
{
readb
(
fb_info
.
io_virt
+
CRT
+
0x0A
);
//flip-flop to index
readb
(
((
struct
tridentfb_par
*
)
fb_info
.
par
)
->
io_virt
+
CRT
+
0x0A
);
//flip-flop to index
t_outb
(
reg
,
0x3C0
);
t_outb
(
val
,
0x3C0
);
}
static
inline
unsigned
char
readAttr
(
int
reg
)
{
readb
(
fb_info
.
io_virt
+
CRT
+
0x0A
);
//flip-flop to index
readb
(
((
struct
tridentfb_par
*
)
fb_info
.
par
)
->
io_virt
+
CRT
+
0x0A
);
//flip-flop to index
t_outb
(
reg
,
0x3C0
);
return
t_inb
(
0x3C1
);
}
...
...
@@ -457,11 +530,22 @@ static inline void write3CE(int reg, unsigned char val)
t_outb
(
val
,
0x3CF
);
}
#define unprotect_all() write3C4(Protection, 0x92);unprotect()
#define unprotect() write3C4(NewMode1,0xC2)
#define bios_reg(reg) write3CE(BiosReg, reg)
#define enable_mmio() outb(PCIReg, 0x3D4); \
outb(inb(0x3D5) | 0x01, 0x3D5)
static
inline
void
enable_mmio
(
void
)
{
/* Goto New Mode */
outb
(
0x0B
,
0x3C4
);
inb
(
0x3C5
);
/* Unprotect registers */
outb
(
NewMode1
,
0x3C4
);
outb
(
0x80
,
0x3C5
);
/* Enable MMIO */
outb
(
PCIReg
,
0x3D4
);
outb
(
inb
(
0x3D5
)
|
0x01
,
0x3D5
);
}
#define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F)
/* Return flat panel's maximum x resolution */
...
...
@@ -474,15 +558,13 @@ static int __init get_nativex(void)
tmp
=
(
read3CE
(
VertStretch
)
>>
4
)
&
3
;
/* detection broken on XPAi ??? misdetects 1024 for 800 */
if
(
pci_id
==
CYBERBLADEXPAi1
&&
tmp
==
3
)
tmp
=
2
;
switch
(
tmp
)
{
case
0
:
x
=
1280
;
y
=
1024
;
break
;
case
1
:
x
=
640
;
y
=
480
;
break
;
case
2
:
x
=
1024
;
y
=
768
;
break
;
default:
x
=
800
;
y
=
600
;
break
;
case
0
:
x
=
1280
;
y
=
1024
;
break
;
case
2
:
x
=
1024
;
y
=
768
;
break
;
case
3
:
x
=
800
;
y
=
600
;
break
;
case
4
:
x
=
1400
;
y
=
1050
;
break
;
case
1
:
default:
x
=
640
;
y
=
480
;
break
;
}
output
(
"%dx%d flat panel found
\n
"
,
x
,
y
);
...
...
@@ -499,6 +581,10 @@ static void set_lwidth(int width)
/* For resolutions smaller than FP resolution stretch */
static
void
screen_stretch
(
void
)
{
if
(
chip_id
!=
CYBERBLADEXPAi1
)
write3CE
(
BiosReg
,
0
);
else
write3CE
(
BiosReg
,
8
);
write3CE
(
VertStretch
,(
read3CE
(
VertStretch
)
&
0x7C
)
|
1
);
write3CE
(
HorStretch
,(
read3CE
(
HorStretch
)
&
0x7C
)
|
1
);
}
...
...
@@ -506,7 +592,6 @@ static void screen_stretch(void)
/* For resolutions smaller than FP resolution center */
static
void
screen_center
(
void
)
{
bios_reg
(
0
);
// no stretch
write3CE
(
VertStretch
,(
read3CE
(
VertStretch
)
&
0x7C
)
|
0x80
);
write3CE
(
HorStretch
,(
read3CE
(
HorStretch
)
&
0x7C
)
|
0x80
);
}
...
...
@@ -515,13 +600,13 @@ static void screen_center(void)
static
void
set_screen_start
(
int
base
)
{
write3X4
(
StartAddrLow
,
base
&
0xFF
);
write3X4
(
StartAddrHigh
,
(
base
&
0xFF00
)
>>
8
);
write3X4
(
CRTCModuleTest
,
(
read3X4
(
CRTCModuleTest
)
&
0xDF
)
|
((
base
&
0x10000
)
>>
11
));
write3X4
(
CRTHiOrd
,
(
read3X4
(
CRTHiOrd
)
&
0xF8
)
|
(
base
&
0xE0000
)
>>
17
);
write3X4
(
StartAddrHigh
,
(
base
&
0xFF00
)
>>
8
);
write3X4
(
CRTCModuleTest
,
(
read3X4
(
CRTCModuleTest
)
&
0xDF
)
|
((
base
&
0x10000
)
>>
11
));
write3X4
(
CRTHiOrd
,
(
read3X4
(
CRTHiOrd
)
&
0xF8
)
|
(
(
base
&
0xE0000
)
>>
17
)
);
}
/* Use 20.12 fixed-point for NTSC value and frequency calculation */
#define calc_freq(n,m,k) ( (
unsigned long)0xE517 * (n+8) / (m+2)*(1<<k)
)
#define calc_freq(n,m,k) ( (
(unsigned long)0xE517 * (n+8) / ((m+2)*(1<<k))) >> 12
)
/* Set dotclock frequency */
static
void
set_vclk
(
int
freq
)
...
...
@@ -542,8 +627,13 @@ static void set_vclk(int freq)
hi
=
(
k
<<
6
)
|
m
;
}
}
write3C4
(
ClockHigh
,
hi
);
write3C4
(
ClockLow
,
lo
);
if
(
chip3D
)
{
write3C4
(
ClockHigh
,
hi
);
write3C4
(
ClockLow
,
lo
);
}
else
{
outb
(
lo
,
0x43C8
);
outb
(
hi
,
0x43C9
);
}
debug
(
"VCLK = %X %X
\n
"
,
hi
,
lo
);
}
...
...
@@ -551,7 +641,9 @@ static void set_vclk(int freq)
static
void
set_number_of_lines
(
int
lines
)
{
int
tmp
=
read3CE
(
CyberEnhance
)
&
0x8F
;
if
(
lines
>
768
)
if
(
lines
>
1024
)
tmp
|=
0x50
;
else
if
(
lines
>
768
)
tmp
|=
0x30
;
else
if
(
lines
>
600
)
tmp
|=
0x20
;
...
...
@@ -568,7 +660,7 @@ static unsigned int __init get_displaytype(void)
{
if
(
fp
)
return
DISPLAY_FP
;
if
(
crt
)
if
(
crt
||
!
chipcyber
)
return
DISPLAY_CRT
;
return
(
read3CE
(
FPConfig
)
&
0x10
)
?
DISPLAY_FP
:
DISPLAY_CRT
;
}
...
...
@@ -576,26 +668,42 @@ static unsigned int __init get_displaytype(void)
/* Try detecting the video memory size */
static
unsigned
int
__init
get_memsize
(
void
)
{
unsigned
char
tmp
;
unsigned
char
tmp
,
tmp2
;
unsigned
int
k
;
/* If memory size provided by user */
if
(
memsize
)
k
=
memsize
*
Kb
;
else
switch
(
pci_id
)
{
case
CYBER9525DVD
:
k
=
2560
*
Kb
;
break
;
case
CYBERBLADEXPAi1
:
k
=
16
*
Mb
;
break
;
case
CYBERBLADEXPm16
:
k
=
16
*
Mb
;
break
;
case
CYBERBLADEXPm8
:
k
=
8
*
Mb
;
break
;
switch
(
chip_id
)
{
case
CYBER9525DVD
:
k
=
2560
*
Kb
;
break
;
default:
tmp
=
read3X4
(
SPR
)
&
0x0F
;
switch
(
tmp
)
{
case
3
:
k
=
1
*
Mb
;
break
;
case
7
:
k
=
2
*
Mb
;
break
;
case
15
:
k
=
4
*
Mb
;
break
;
case
4
:
k
=
8
*
Mb
;
break
;
default:
k
=
1
*
Mb
;
case
0x01
:
k
=
512
;
break
;
case
0x02
:
k
=
6
*
Mb
;
break
;
/* XP */
case
0x03
:
k
=
1
*
Mb
;
break
;
case
0x04
:
k
=
8
*
Mb
;
break
;
case
0x06
:
k
=
10
*
Mb
;
break
;
/* XP */
case
0x07
:
k
=
2
*
Mb
;
break
;
case
0x08
:
k
=
12
*
Mb
;
break
;
/* XP */
case
0x0A
:
k
=
14
*
Mb
;
break
;
/* XP */
case
0x0C
:
k
=
16
*
Mb
;
break
;
/* XP */
case
0x0E
:
/* XP */
tmp2
=
read3C4
(
0xC1
);
switch
(
tmp2
)
{
case
0x00
:
k
=
20
*
Mb
;
break
;
case
0x01
:
k
=
24
*
Mb
;
break
;
case
0x10
:
k
=
28
*
Mb
;
break
;
case
0x11
:
k
=
32
*
Mb
;
break
;
default:
k
=
1
*
Mb
;
break
;
}
break
;
case
0x0F
:
k
=
4
*
Mb
;
break
;
default:
k
=
1
*
Mb
;
}
}
...
...
@@ -604,209 +712,112 @@ static unsigned int __init get_memsize(void)
return
k
;
}
/* Fill in fix */
static
int
trident_encode_fix
(
struct
fb_fix_screeninfo
*
fix
,
const
void
*
par
,
struct
fb_info_gen
*
info
)
/* See if we can handle the video mode described in var */
static
int
tridentfb_check_var
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
{
struct
tridentfb_info
*
i
=
(
struct
tridentfb_info
*
)
info
;
struct
tridentfb_par
*
p
=
(
struct
tridentfb_par
*
)
par
;
int
bpp
=
var
->
bits_per_pixel
;
debug
(
"enter
\n
"
);
memset
(
fix
,
0
,
sizeof
(
struct
fb_fix_screeninfo
));
strcpy
(
fix
->
id
,
tridentfb_name
);
fix
->
smem_start
=
i
->
fbmem
;
fix
->
smem_len
=
i
->
memsize
;
fix
->
type
=
FB_TYPE_PACKED_PIXELS
;
fix
->
type_aux
=
0
;
fix
->
visual
=
p
->
bpp
==
8
?
FB_VISUAL_PSEUDOCOLOR
:
FB_VISUAL_TRUECOLOR
;
fix
->
xpanstep
=
fix
->
ywrapstep
=
0
;
fix
->
ypanstep
=
1
;
fix
->
line_length
=
p
->
linelength
;
fix
->
mmio_start
=
0
;
fix
->
mmio_len
=
0
;
fix
->
accel
=
FB_ACCEL_NONE
;
debug
(
"exit
\n
"
);
return
0
;
}
/* Fill in par from var */
static
int
trident_decode_var
(
const
struct
fb_var_screeninfo
*
var
,
void
*
par
,
struct
fb_info_gen
*
info
)
{
struct
tridentfb_par
*
p
=
(
struct
tridentfb_par
*
)
par
;
struct
tridentfb_info
*
i
=
(
struct
tridentfb_info
*
)
info
;
int
vres
,
vfront
,
vback
,
vsync
;
debug
(
"enter
\n
"
);
p
->
var
=
*
var
;
p
->
bpp
=
var
->
bits_per_pixel
;
if
(
p
->
bpp
==
24
)
p
->
bpp
=
32
;
p
->
linelength
=
var
->
xres_virtual
*
p
->
bpp
/
8
;
/* check color depth */
if
(
bpp
==
24
)
bpp
=
var
->
bits_per_pixel
=
32
;
/* check whether resolution fits on panel and in memory*/
if
(
var
->
xres
>
nativex
)
return
-
EINVAL
;
if
(
var
->
xres
*
var
->
yres_virtual
*
bpp
/
8
>
info
->
fix
.
smem_len
)
return
-
EINVAL
;
switch
(
p
->
bpp
)
{
switch
(
bpp
)
{
case
8
:
p
->
var
.
red
.
offset
=
0
;
p
->
var
.
green
.
offset
=
0
;
p
->
var
.
blue
.
offset
=
0
;
p
->
var
.
red
.
length
=
6
;
p
->
var
.
green
.
length
=
6
;
p
->
var
.
blue
.
length
=
6
;
var
->
red
.
offset
=
0
;
var
->
green
.
offset
=
0
;
var
->
blue
.
offset
=
0
;
var
->
red
.
length
=
6
;
var
->
green
.
length
=
6
;
var
->
blue
.
length
=
6
;
break
;
case
16
:
p
->
var
.
red
.
offset
=
11
;
p
->
var
.
green
.
offset
=
5
;
p
->
var
.
blue
.
offset
=
0
;
p
->
var
.
red
.
length
=
5
;
p
->
var
.
green
.
length
=
6
;
p
->
var
.
blue
.
length
=
5
;
var
->
red
.
offset
=
11
;
var
->
green
.
offset
=
5
;
var
->
blue
.
offset
=
0
;
var
->
red
.
length
=
5
;
var
->
green
.
length
=
6
;
var
->
blue
.
length
=
5
;
break
;
case
32
:
p
->
var
.
red
.
offset
=
16
;
p
->
var
.
green
.
offset
=
8
;
p
->
var
.
blue
.
offset
=
0
;
p
->
var
.
red
.
length
=
8
;
p
->
var
.
green
.
length
=
8
;
p
->
var
.
blue
.
length
=
8
;
var
->
red
.
offset
=
16
;
var
->
green
.
offset
=
8
;
var
->
blue
.
offset
=
0
;
var
->
red
.
length
=
8
;
var
->
green
.
length
=
8
;
var
->
blue
.
length
=
8
;
break
;
default:
return
-
EINVAL
;
}
/* convert from picoseconds to MHz */
p
->
vclk
=
1000000
/
var
->
pixclock
;
if
(
p
->
bpp
==
32
)
p
->
vclk
*=
2
;
p
->
hres
=
var
->
xres
;
vres
=
p
->
vres
=
var
->
yres
;
/* See if requested resolution is larger than flat panel */
if
(
p
->
hres
>
i
->
nativex
&&
flatpanel
)
{
return
-
EINVAL
;
return
-
EINVAL
;
}
/* See if requested resolution fits in available memory */
if
(
p
->
hres
*
p
->
vres
*
p
->
bpp
/
8
>
i
->
memsize
)
{
return
-
EINVAL
;
}
vfront
=
var
->
upper_margin
;
vback
=
var
->
lower_margin
;
vsync
=
var
->
vsync_len
;
/* Compute horizontal and vertical VGA CRTC timing values */
if
(
var
->
vmode
&
FB_VMODE_INTERLACED
)
{
vres
/=
2
;
vfront
/=
2
;
vback
/=
2
;
vsync
/=
2
;
}
if
(
var
->
vmode
&
FB_VMODE_DOUBLE
)
{
vres
*=
2
;
vfront
*=
2
;
vback
*=
2
;
vsync
*=
2
;
}
p
->
htotal
=
(
p
->
hres
+
var
->
left_margin
+
var
->
right_margin
+
var
->
hsync_len
)
/
8
-
10
;
p
->
hdispend
=
p
->
hres
/
8
-
1
;
p
->
hsyncstart
=
(
p
->
hres
+
var
->
right_margin
)
/
8
;
p
->
hsyncend
=
var
->
hsync_len
/
8
;
p
->
hblankstart
=
p
->
hdispend
+
1
;
p
->
hblankend
=
p
->
htotal
+
5
;
p
->
vtotal
=
vres
+
vfront
+
vback
+
vsync
-
2
;
p
->
vdispend
=
vres
-
1
;
p
->
vsyncstart
=
vres
+
vback
;
p
->
vsyncend
=
vsync
;
p
->
vblankstart
=
vres
;
p
->
vblankend
=
p
->
vtotal
+
2
;
debug
(
"exit
\n
"
);
return
0
;
}
/* Fill in var from info */
static
int
trident_encode_var
(
struct
fb_var_screeninfo
*
var
,
const
void
*
par
,
struct
fb_info_gen
*
info
)
{
struct
tridentfb_par
*
p
=
(
struct
tridentfb_par
*
)
par
;
debug
(
"enter
\n
"
);
*
var
=
p
->
var
;
var
->
bits_per_pixel
=
p
->
bpp
;
debug
(
"exit
\n
"
);
return
0
;
}
/* Fill in par from hardware */
static
void
trident_get_par
(
void
*
par
,
struct
fb_info_gen
*
info
)
{
struct
tridentfb_par
*
p
=
(
struct
tridentfb_par
*
)
par
;
struct
tridentfb_info
*
i
=
(
struct
tridentfb_info
*
)
info
;
debug
(
"enter
\n
"
);
*
p
=
i
->
currentmode
;
debug
(
"exit
\n
"
);
}
/* Pan the display */
static
int
trident
_pan_display
(
const
struct
fb_var_screeninfo
*
var
,
struct
fb_info
_gen
*
info
)
static
int
trident
fb_pan_display
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
{
unsigned
int
offset
;
struct
tridentfb_info
*
i
=
(
struct
tridentfb_info
*
)
info
;
debug
(
"enter
\n
"
);
offset
=
(
var
->
xoffset
+
(
var
->
yoffset
*
var
->
xres
))
*
var
->
bits_per_pixel
/
32
;
i
->
currentmode
.
var
.
xoffset
=
var
->
xoffset
;
i
->
currentmode
.
var
.
yoffset
=
var
->
yoffset
;
i
nfo
->
var
.
xoffset
=
var
->
xoffset
;
i
nfo
->
var
.
yoffset
=
var
->
yoffset
;
set_screen_start
(
offset
);
debug
(
"exit
\n
"
);
return
0
;
}
/* Set the hardware from par */
static
void
trident_set_par
(
const
void
*
par
,
struct
fb_info_gen
*
info
)
#define shadowmode_on() write3CE(CyberControl,read3CE(CyberControl) | 0x81)
#define shadowmode_off() write3CE(CyberControl,read3CE(CyberControl) & 0x7E)
/* Set the hardware to the requested video mode */
static
int
tridentfb_set_par
(
struct
fb_info
*
info
)
{
struct
tridentfb_par
*
p
=
(
struct
tridentfb_par
*
)
par
;
struct
tridentfb_info
*
i
=
(
struct
tridentfb_info
*
)
info
;
struct
tridentfb_par
*
par
=
(
struct
tridentfb_par
*
)(
info
->
par
);
u32
htotal
,
hdispend
,
hsyncstart
,
hsyncend
,
hblankstart
,
hblankend
,
vtotal
,
vdispend
,
vsyncstart
,
vsyncend
,
vblankstart
,
vblankend
;
struct
fb_var_screeninfo
*
var
=
&
info
->
var
;
int
bpp
=
var
->
bits_per_pixel
;
unsigned
char
tmp
;
debug
(
"enter
\n
"
);
htotal
=
(
var
->
xres
+
var
->
left_margin
+
var
->
right_margin
+
var
->
hsync_len
)
/
8
-
10
;
hdispend
=
var
->
xres
/
8
-
1
;
hsyncstart
=
(
var
->
xres
+
var
->
right_margin
)
/
8
;
hsyncend
=
var
->
hsync_len
/
8
;
hblankstart
=
hdispend
+
1
;
hblankend
=
htotal
+
5
;
vtotal
=
var
->
yres
+
var
->
upper_margin
+
var
->
lower_margin
+
var
->
vsync_len
-
2
;
vdispend
=
var
->
yres
-
1
;
vsyncstart
=
var
->
yres
+
var
->
lower_margin
;
vsyncend
=
var
->
vsync_len
;
vblankstart
=
var
->
yres
;
vblankend
=
vtotal
+
2
;
i
->
currentmode
=
*
p
;
unprotect_all
();
crtc_unlock
();
enable_mmio
();
crtc_unlock
();
write3CE
(
CyberControl
,
8
);
if
(
flatpanel
&&
p
->
hres
<
i
->
nativex
)
{
if
(
flatpanel
&&
var
->
xres
<
nativex
)
{
/*
* on flat panels with native size larger
* than requested resolution decide whether
* we stretch or center
*/
t_outb
(
0xEB
,
0x3C2
);
write3CE
(
CyberControl
,
0x81
);
if
(
center
)
//|| (p->bpp==32 && pci_id == CYBERBLADEi1D))
shadowmode_on
();
if
(
center
)
screen_center
();
else
if
(
stretch
)
screen_stretch
();
...
...
@@ -817,76 +828,87 @@ static void trident_set_par(const void *par, struct fb_info_gen *info)
}
/* vertical timing values */
write3X4
(
CRTVTotal
,
p
->
vtotal
&
0xFF
);
write3X4
(
CRTVDispEnd
,
p
->
vdispend
&
0xFF
);
write3X4
(
CRTVSyncStart
,
p
->
vsyncstart
&
0xFF
);
write3X4
(
CRTVSyncEnd
,
(
p
->
vsyncend
&
0x0F
));
write3X4
(
CRTVBlankStart
,
p
->
vblankstart
&
0xFF
);
write3X4
(
CRTVTotal
,
vtotal
&
0xFF
);
write3X4
(
CRTVDispEnd
,
vdispend
&
0xFF
);
write3X4
(
CRTVSyncStart
,
vsyncstart
&
0xFF
);
write3X4
(
CRTVSyncEnd
,
(
vsyncend
&
0x0F
));
write3X4
(
CRTVBlankStart
,
vblankstart
&
0xFF
);
write3X4
(
CRTVBlankEnd
,
0
/*p->vblankend & 0xFF*/
);
/* horizontal timing values */
write3X4
(
CRTHTotal
,
p
->
htotal
&
0xFF
);
write3X4
(
CRTHDispEnd
,
p
->
hdispend
&
0xFF
);
write3X4
(
CRTHSyncStart
,
p
->
hsyncstart
&
0xFF
);
write3X4
(
CRTHSyncEnd
,
(
p
->
hsyncend
&
0x1F
)
|
((
p
->
hblankend
&
0x20
)
<<
2
));
write3X4
(
CRTHBlankStart
,
p
->
hblankstart
&
0xFF
);
write3X4
(
CRTHTotal
,
htotal
&
0xFF
);
write3X4
(
CRTHDispEnd
,
hdispend
&
0xFF
);
write3X4
(
CRTHSyncStart
,
hsyncstart
&
0xFF
);
write3X4
(
CRTHSyncEnd
,
(
hsyncend
&
0x1F
)
|
((
hblankend
&
0x20
)
<<
2
));
write3X4
(
CRTHBlankStart
,
hblankstart
&
0xFF
);
write3X4
(
CRTHBlankEnd
,
0
/*(p->hblankend & 0x1F)*/
);
/* higher bits of vertical timing values */
tmp
=
0x10
;
if
(
p
->
vtotal
&
0x100
)
tmp
|=
0x01
;
if
(
p
->
vdispend
&
0x100
)
tmp
|=
0x02
;
if
(
p
->
vsyncstart
&
0x100
)
tmp
|=
0x04
;
if
(
p
->
vblankstart
&
0x100
)
tmp
|=
0x08
;
if
(
p
->
vtotal
&
0x200
)
tmp
|=
0x20
;
if
(
p
->
vdispend
&
0x200
)
tmp
|=
0x40
;
if
(
p
->
vsyncstart
&
0x200
)
tmp
|=
0x80
;
if
(
vtotal
&
0x100
)
tmp
|=
0x01
;
if
(
vdispend
&
0x100
)
tmp
|=
0x02
;
if
(
vsyncstart
&
0x100
)
tmp
|=
0x04
;
if
(
vblankstart
&
0x100
)
tmp
|=
0x08
;
if
(
vtotal
&
0x200
)
tmp
|=
0x20
;
if
(
vdispend
&
0x200
)
tmp
|=
0x40
;
if
(
vsyncstart
&
0x200
)
tmp
|=
0x80
;
write3X4
(
CRTOverflow
,
tmp
);
tmp
=
read3X4
(
CRTHiOrd
)
|
0x08
;
//line compare bit 10
if
(
p
->
vtotal
&
0x400
)
tmp
|=
0x80
;
if
(
p
->
vblankstart
&
0x400
)
tmp
|=
0x40
;
if
(
p
->
vsyncstart
&
0x400
)
tmp
|=
0x20
;
if
(
p
->
vdispend
&
0x400
)
tmp
|=
0x10
;
if
(
vtotal
&
0x400
)
tmp
|=
0x80
;
if
(
vblankstart
&
0x400
)
tmp
|=
0x40
;
if
(
vsyncstart
&
0x400
)
tmp
|=
0x20
;
if
(
vdispend
&
0x400
)
tmp
|=
0x10
;
write3X4
(
CRTHiOrd
,
tmp
);
write3X4
(
HorizOverflow
,
0
);
tmp
=
0
;
if
(
htotal
&
0x800
)
tmp
|=
0x800
>>
11
;
if
(
hblankstart
&
0x800
)
tmp
|=
0x800
>>
7
;
write3X4
(
HorizOverflow
,
tmp
);
tmp
=
0x40
;
if
(
p
->
vblankstart
&
0x200
)
tmp
|=
0x20
;
if
(
p
->
var
.
vmode
&
FB_VMODE_DOUBLE
)
tmp
|=
0x80
;
//double scan for 200 line modes
if
(
vblankstart
&
0x200
)
tmp
|=
0x20
;
//FIXME if (info
->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80; //double scan for 200 line modes
write3X4
(
CRTMaxScanLine
,
tmp
);
write3X4
(
CRTLineCompare
,
0xFF
);
write3X4
(
CRTPRowScan
,
0
);
write3X4
(
CRTModeControl
,
0xC3
);
write3X4
(
LinearAddReg
,
0x20
);
//enable linear addressing
tmp
=
(
p
->
var
.
vmode
&
FB_VMODE_INTERLACED
)
?
0x84
:
0x80
;
tmp
=
(
info
->
var
.
vmode
&
FB_VMODE_INTERLACED
)
?
0x84
:
0x80
;
write3X4
(
CRTCModuleTest
,
tmp
);
//enable access extended memory
write3X4
(
GraphEngReg
,
0x80
);
//enable GE for text acceleration
if
(
p
->
var
.
accel_flags
&
FB_ACCELF_TEXT
)
acc
->
init_accel
(
p
->
hres
,
p
->
bpp
);
write3X4
(
GraphEngReg
,
0x80
);
//enable GE for text acceleration
switch
(
p
->
bpp
)
{
case
8
:
tmp
=
0
;
break
;
case
16
:
tmp
=
5
;
break
;
case
24
:
/* tmp=0x29;break; */
/* seems like 24bpp is same as 32bpp when using vesafb */
case
32
:
tmp
=
9
;
break
;
// if (info->var.accel_flags & FB_ACCELF_TEXT)
//FIXME acc->init_accel(info->var.xres,bpp);
switch
(
bpp
)
{
case
8
:
tmp
=
0x00
;
break
;
case
16
:
tmp
=
0x05
;
break
;
case
24
:
tmp
=
0x29
;
break
;
case
32
:
tmp
=
0x09
;
}
write3X4
(
PixelBusReg
,
tmp
);
write3X4
(
InterfaceSel
,
0x5B
);
//32bit internal data path
write3X4
(
DRAMControl
,
0x30
);
//both IO,linear enable
write3X4
(
Performance
,
0xBF
);
tmp
=
0x10
;
if
(
chipcyber
)
tmp
|=
0x20
;
write3X4
(
DRAMControl
,
tmp
);
//both IO,linear enable
write3X4
(
InterfaceSel
,
read3X4
(
InterfaceSel
)
|
0x40
);
write3X4
(
Performance
,
0x20
);
write3X4
(
PCIReg
,
0x07
);
//MMIO & PCI read and write burst enable
set_vclk
(
p
->
vclk
);
/* convert from picoseconds to MHz */
par
->
vclk
=
1000000
/
info
->
var
.
pixclock
;
if
(
bpp
==
32
)
par
->
vclk
*=
2
;
set_vclk
(
par
->
vclk
);
write3C4
(
0
,
3
);
write3C4
(
1
,
1
);
//set char clock 8 dots wide
...
...
@@ -894,12 +916,17 @@ static void trident_set_par(const void *par, struct fb_info_gen *info)
write3C4
(
3
,
0
);
write3C4
(
4
,
0x0E
);
//memory mode enable bitmaps ??
write3CE
(
MiscExtFunc
,(
p
->
bpp
==
32
)
?
0x1A
:
0x12
);
//divide clock by 2 if 32bpp
write3CE
(
MiscExtFunc
,(
bpp
==
32
)
?
0x1A
:
0x12
);
//divide clock by 2 if 32bpp
//chain4 mode display and CPU path
write3CE
(
0x5
,
0x40
);
//no CGA compat,allow 256 col
write3CE
(
0x6
,
0x05
);
//graphics mode
write3CE
(
0x7
,
0x0F
);
//planes?
if
(
chip_id
==
CYBERBLADEXPAi1
)
{
/* This fixes snow-effect in 32 bpp */
write3X4
(
CRTHSyncStart
,
0x84
);
}
writeAttr
(
0x10
,
0x41
);
//graphics mode and support 256 color modes
writeAttr
(
0x12
,
0x0F
);
//planes
writeAttr
(
0x13
,
0
);
//horizontal pel panning
...
...
@@ -907,10 +934,10 @@ static void trident_set_par(const void *par, struct fb_info_gen *info)
//colors
for
(
tmp
=
0
;
tmp
<
0x10
;
tmp
++
)
writeAttr
(
tmp
,
tmp
);
readb
(
fb_info
.
io_virt
+
CRT
+
0x0A
);
//flip-flop to index
readb
(
par
->
io_virt
+
CRT
+
0x0A
);
//flip-flop to index
t_outb
(
0x20
,
0x3C0
);
//enable attr
switch
(
p
->
bpp
)
{
switch
(
bpp
)
{
case
8
:
tmp
=
0
;
break
;
//256 colors
case
15
:
tmp
=
0x10
;
break
;
case
16
:
tmp
=
0x30
;
break
;
//hicolor
...
...
@@ -927,31 +954,11 @@ static void trident_set_par(const void *par, struct fb_info_gen *info)
t_inb
(
0x3C8
);
if
(
flatpanel
)
set_number_of_lines
(
p
->
vres
);
set_lwidth
(
p
->
hres
*
p
->
bpp
/
(
4
*
16
));
trident_pan_display
(
&
p
->
var
,
info
);
debug
(
"exit
\n
"
);
}
/* Get value of one color register */
static
int
trident_getcolreg
(
unsigned
regno
,
unsigned
*
red
,
unsigned
*
green
,
unsigned
*
blue
,
unsigned
*
transp
,
struct
fb_info
*
info
)
{
struct
tridentfb_info
*
i
=
(
struct
tridentfb_info
*
)
info
;
int
m
=
i
->
currentmode
.
bpp
==
8
?
256
:
16
;
debug
(
"enter %d
\n
"
,
regno
);
if
(
regno
>=
m
)
return
1
;
*
red
=
palette
[
regno
].
red
;
*
green
=
palette
[
regno
].
green
;
*
blue
=
palette
[
regno
].
blue
;
*
transp
=
palette
[
regno
].
transp
;
set_number_of_lines
(
info
->
var
.
yres
);
set_lwidth
(
info
->
var
.
xres
*
bpp
/
(
4
*
16
));
info
->
fix
.
visual
=
(
bpp
==
8
)
?
FB_VISUAL_PSEUDOCOLOR
:
FB_VISUAL_TRUECOLOR
;
info
->
fix
.
line_length
=
info
->
var
.
xres
*
(
bpp
>>
3
);
info
->
cmap
.
len
=
(
bpp
==
8
)
?
256
:
16
;
debug
(
"exit
\n
"
);
return
0
;
}
...
...
@@ -961,19 +968,11 @@ static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned
blue
,
unsigned
transp
,
struct
fb_info
*
info
)
{
struct
tridentfb_info
*
i
=
(
struct
tridentfb_info
*
)
info
;
int
bpp
=
i
->
currentmode
.
bpp
;
int
m
=
bpp
==
8
?
256
:
16
;
debug
(
"enter %d
\n
"
,
regno
);
int
bpp
=
info
->
var
.
bits_per_pixel
;
if
(
regno
>=
m
)
if
(
regno
>=
info
->
cmap
.
len
)
return
1
;
palette
[
regno
].
red
=
red
;
palette
[
regno
].
green
=
green
;
palette
[
regno
].
blue
=
blue
;
palette
[
regno
].
transp
=
transp
;
if
(
bpp
==
8
)
{
t_outb
(
0xFF
,
0x3C6
);
...
...
@@ -995,12 +994,12 @@ static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green,
((
green
&
0xFF00
))
|
((
blue
&
0xFF00
)
>>
8
);
debug
(
"exit
\n
"
);
//
debug("exit\n");
return
0
;
}
/* Try blanking the screen.For flat panels it does nothing */
static
int
trident
_blank
(
int
blank_mode
,
struct
fb_info_gen
*
info
)
static
int
trident
fb_blank
(
int
blank_mode
,
struct
fb_info
*
info
)
{
unsigned
char
PMCont
,
DPMSCont
;
...
...
@@ -1035,218 +1034,194 @@ static int trident_blank(int blank_mode, struct fb_info_gen *info)
}
write3CE
(
PowerStatus
,
DPMSCont
);
t_outb
(
4
,
0x83C8
);
t_outb
(
PMCont
,
0x83C6
);
t_outb
(
4
,
0x83C8
);
t_outb
(
PMCont
,
0x83C6
);
debug
(
"exit
\n
"
);
return
0
;
}
/* Set display switch used by console */
static
void
trident_set_disp
(
const
void
*
par
,
struct
display
*
disp
,
struct
fb_info_gen
*
info
)
static
int
__devinit
trident_pci_probe
(
struct
pci_dev
*
dev
,
const
struct
pci_device_id
*
id
)
{
struct
tridentfb_info
*
i
=
(
struct
tridentfb_info
*
)
info
;
struct
fb_info
*
ii
=
(
struct
fb_info
*
)
info
;
struct
tridentfb_par
*
p
=
(
struct
tridentfb_par
*
)
par
;
int
isaccel
=
p
->
var
.
accel_flags
&
FB_ACCELF_TEXT
;
int
err
;
unsigned
char
revision
;
err
=
pci_enable_device
(
dev
);
if
(
err
)
return
err
;
chip_id
=
id
->
device
;
/* If PCI id is 0x9660 then further detect chip type */
if
(
chip_id
==
TGUI9660
)
{
outb
(
RevisionID
,
0x3C4
);
revision
=
inb
(
0x3C5
);
switch
(
revision
)
{
case
0x22
:
case
0x23
:
chip_id
=
CYBER9397
;
break
;
case
0x2A
:
chip_id
=
CYBER9397DVD
;
break
;
case
0x30
:
case
0x33
:
case
0x34
:
case
0x35
:
case
0x38
:
case
0x3A
:
case
0xB3
:
chip_id
=
CYBER9385
;
break
;
case
0x40
...
0x43
:
chip_id
=
CYBER9382
;
break
;
case
0x4A
:
chip_id
=
CYBER9388
;
break
;
default:
break
;
}
}
info
->
info
.
screen_base
=
(
char
*
)
i
->
fbmem_virt
;
debug
(
"enter
\n
"
);
#ifdef FBCON_HAS_CFB8
if
(
p
->
bpp
==
8
)
{
if
(
isaccel
)
disp
->
dispsw
=
&
trident_8bpp
;
else
disp
->
dispsw
=
&
fbcon_cfb8
;
}
else
#endif
#ifdef FBCON_HAS_CFB16
if
(
p
->
bpp
==
16
)
{
if
(
isaccel
)
disp
->
dispsw
=
&
trident_16bpp
;
else
disp
->
dispsw
=
&
fbcon_cfb16
;
disp
->
dispsw_data
=
ii
->
pseudo_palette
;
/* console palette */
}
else
#endif
#ifdef FBCON_HAS_CFB32
if
(
p
->
bpp
==
32
)
{
if
(
isaccel
)
disp
->
dispsw
=
&
trident_32bpp
;
else
disp
->
dispsw
=
&
fbcon_cfb32
;
disp
->
dispsw_data
=
ii
->
pseudo_palette
;
/* console palette */
}
else
#endif
disp
->
dispsw
=
&
fbcon_dummy
;
debug
(
"exit
\n
"
);
}
chip3D
=
is3Dchip
(
chip_id
);
chipcyber
=
iscyber
(
chip_id
);
static
struct
fbgen_hwswitch
trident_hwswitch
=
{
NULL
,
/* detect not needed */
trident_encode_fix
,
trident_decode_var
,
trident_encode_var
,
trident_get_par
,
trident_set_par
,
trident_getcolreg
,
trident_pan_display
,
trident_blank
,
trident_set_disp
};
if
(
is_xp
(
chip_id
))
{
acc
=
&
accel_xp
;
}
else
if
(
is_blade
(
chip_id
))
{
acc
=
&
accel_blade
;
}
else
{
acc
=
&
accel_image
;
}
/* List of boards that we are trying to support */
static
struct
almost_supported_board
{
int
pci_id
;
int
family
;
struct
accel_switch
*
acc
;
char
*
board_name
;
int
accel
;
}
asb
[]
__initdata
=
{
{
BLADE3D
,
BLADE
,
&
accel_blade
,
"Blade3D"
,
ACCEL
},
{
CYBERBLADEi7
,
BLADE
,
&
accel_blade
,
"CyberBladei7"
,
ACCEL
},
{
CYBERBLADEi7D
,
BLADE
,
&
accel_blade
,
"CyberBladei7D"
,
ACCEL
},
{
CYBERBLADEi1
,
BLADE
,
&
accel_blade
,
"CyberBladei1"
,
ACCEL
},
{
CYBERBLADEi1D
,
BLADE
,
&
accel_blade
,
"CyberBladei1D"
,
ACCEL
},
{
CYBERBLADEAi1
,
BLADE
,
&
accel_blade
,
"CyberBladeAi1"
,
ACCEL
},
{
CYBERBLADEAi1D
,
BLADE
,
&
accel_blade
,
"CyberBladeAi1D"
,
ACCEL
},
{
CYBERBLADEE4
,
BLADE
,
&
accel_blade
,
"CyberBladeE4"
,
ACCEL
},
{
IMAGE975
,
IMAGE
,
&
accel_image
,
"IMAGE975"
,
NOACCEL
},
{
IMAGE985
,
IMAGE
,
&
accel_image
,
"IMAGE985"
,
NOACCEL
},
{
CYBER9320
,
IMAGE
,
&
accel_image
,
"Cyber9320"
,
NOACCEL
},
{
CYBER9388
,
IMAGE
,
&
accel_image
,
"Cyber9388"
,
NOACCEL
},
{
CYBER9520
,
IMAGE
,
&
accel_image
,
"Cyber9520"
,
NOACCEL
},
{
CYBER9525DVD
,
IMAGE
,
&
accel_image
,
"Cyber9525DVD"
,
NOACCEL
},
{
CYBER9397
,
IMAGE
,
&
accel_image
,
"Cyber9397"
,
NOACCEL
},
{
CYBER9397DVD
,
IMAGE
,
&
accel_image
,
"Cyber9397DVD"
,
NOACCEL
},
{
CYBERBLADEXPAi1
,
XP
,
&
accel_blade
,
"CyberBladeXPAi1"
,
NOACCEL
},
{
CYBERBLADEXPm8
,
XP
,
&
accel_blade
,
"CyberBladeXPm8"
,
NOACCEL
},
{
CYBERBLADEXPm16
,
XP
,
&
accel_blade
,
"CyberBladeXPm16"
,
NOACCEL
},
};
/* acceleration is on by default for 3D chips */
defaultaccel
=
chip3D
&&
!
noaccel
;
static
__init
int
trident_find_board
(
void
)
{
int
i
;
struct
pci_dev
*
board
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
asb
);
i
++
)
{
if
((
board
=
pci_find_device
(
PCI_VENDOR_ID_TRIDENT
,
asb
[
i
].
pci_id
,
NULL
)))
{
family
=
asb
[
i
].
family
;
acc
=
asb
[
i
].
acc
;
pci_id
=
asb
[
i
].
pci_id
;
defaultaccel
=
asb
[
i
].
accel
;
fb_info
.
io
=
pci_resource_start
(
board
,
1
);
fb_info
.
fbmem
=
pci_resource_start
(
board
,
0
);
output
(
"%s board found
\n
"
,
asb
[
i
].
board_name
);
return
1
;
}
}
output
(
"No Trident board found
\n
"
);
return
0
;
}
fb_info
.
par
=
&
default_par
;
int
__init
tridentfb_init
(
void
)
{
/* setup MMIO region */
tridentfb_fix
.
mmio_start
=
pci_resource_start
(
dev
,
1
);
tridentfb_fix
.
mmio_len
=
chip3D
?
0x20000
:
0x10000
;
output
(
"Trident framebuffer %s initializing
\n
"
,
VERSION
);
if
(
!
trident_find_board
())
return
-
1
;
if
(
!
request_mem_region
(
fb_info
.
io
,
TRIDENT_IOSIZE
,
"tridentfb"
))
{
if
(
!
request_mem_region
(
tridentfb_fix
.
mmio_start
,
tridentfb_fix
.
mmio_len
,
"tridentfb"
))
{
debug
(
"request_region failed!
\n
"
);
return
-
1
;
}
;
}
fb_info
.
io_virt
=
(
unsigned
int
)
ioremap_nocache
(
fb_info
.
io
,
TRIDENT_IOSIZE
);
default_par
.
io_virt
=
(
unsigned
int
)
ioremap_nocache
(
tridentfb_fix
.
mmio_start
,
tridentfb_fix
.
mmio_len
);
if
(
!
fb_info
.
io_virt
)
{
release_region
(
fb_info
.
io
,
TRIDENT_IOSIZE
);
if
(
!
default_par
.
io_virt
)
{
release_region
(
tridentfb_fix
.
mmio_start
,
tridentfb_fix
.
mmio_len
);
debug
(
"ioremap failed
\n
"
);
return
-
1
;
}
fb_info
.
memsize
=
get_memsize
();
if
(
!
request_mem_region
(
fb_info
.
fbmem
,
fb_info
.
memsize
,
"tridentfb"
))
{
enable_mmio
();
/* setup framebuffer memory */
tridentfb_fix
.
smem_start
=
pci_resource_start
(
dev
,
0
);
tridentfb_fix
.
smem_len
=
get_memsize
();
if
(
!
request_mem_region
(
tridentfb_fix
.
smem_start
,
tridentfb_fix
.
smem_len
,
"tridentfb"
))
{
debug
(
"request_mem_region failed!
\n
"
);
return
-
1
;
}
fb_info
.
fbmem_virt
=
(
unsigned
int
)
ioremap_nocache
(
fb_info
.
fbmem
,
fb_info
.
memsize
);
fb_info
.
screen_base
=
ioremap_nocache
(
tridentfb_fix
.
smem_start
,
tridentfb_fix
.
smem_len
);
if
(
!
fb_info
.
fbmem_virt
)
{
release_mem_region
(
fb_info
.
fbmem
,
fb_info
.
memsize
);
if
(
!
fb_info
.
screen_base
)
{
release_mem_region
(
tridentfb_fix
.
smem_start
,
tridentfb_fix
.
smem_len
);
debug
(
"ioremap failed
\n
"
);
return
-
1
;
}
debug
(
"Trident board found : mem = %X,io = %X, mem_v = %X, io_v = %X
\n
"
,
fb_info
.
fbmem
,
fb_info
.
io
,
fb_info
.
fbmem_virt
,
fb_info
.
io_virt
);
fb_info
.
gen
.
parsize
=
sizeof
(
struct
tridentfb_par
);
fb_info
.
gen
.
fbhw
=
&
trident_hwswitch
;
strcpy
(
fb_info
.
gen
.
info
.
modename
,
tridentfb_name
);
output
(
"%s board found
\n
"
,
dev
->
dev
.
name
);
#if 0
output("Trident board found : mem = %X,io = %X, mem_v = %X, io_v = %X\n",
tridentfb_fix.smem_start, tridentfb_fix.mmio_start, fb_info.screen_base, default_par.io_virt);
#endif
displaytype
=
get_displaytype
();
if
(
flatpanel
)
fb_info
.
nativex
=
get_nativex
();
fb_info
.
gen
.
info
.
changevar
=
NULL
;
fb_info
.
gen
.
info
.
node
=
NODEV
;
fb_info
.
gen
.
info
.
fbops
=
&
tridentfb_ops
;
fb_info
.
gen
.
info
.
disp
=
&
disp
;
fb_info
.
gen
.
info
.
switch_con
=
&
fbgen_switch
;
fb_info
.
gen
.
info
.
updatevar
=
&
fbgen_update_var
;
fb_info
.
gen
.
info
.
flags
=
FBINFO_FLAG_DEFAULT
;
fb_info
.
gen
.
info
.
fontname
[
0
]
=
'\0'
;
fb_info
.
gen
.
info
.
pseudo_palette
=
pseudo_pal
;
/* This should give a reasonable default video mode */
fb_find_mode
(
&
default_var
,
&
fb_info
.
gen
.
info
,
mode
,
NULL
,
0
,
NULL
,
bpp
);
/*
* Unless user explicitly requires accel/noaccel use
* per chip defaults.Accel has priority over noaccel.
*/
if
(
accel
)
defaultaccel
=
ACCEL
;
else
if
(
noaccel
)
defaultaccel
=
NOACCEL
;
if
(
defaultaccel
==
ACCEL
)
nativex
=
get_nativex
();
fb_info
.
fix
=
tridentfb_fix
;
fb_info
.
node
=
NODEV
;
fb_info
.
fbops
=
&
tridentfb_ops
;
fb_info
.
flags
=
FBINFO_FLAG_DEFAULT
;
fb_info
.
pseudo_palette
=
pseudo_pal
;
if
(
!
fb_find_mode
(
&
default_var
,
&
fb_info
,
mode
,
NULL
,
0
,
NULL
,
bpp
))
return
-
EINVAL
;
fb_alloc_cmap
(
&
fb_info
.
cmap
,
256
,
0
);
if
(
defaultaccel
&&
acc
)
default_var
.
accel_flags
|=
FB_ACCELF_TEXT
;
else
default_var
.
accel_flags
&=
~
FB_ACCELF_TEXT
;
trident_decode_var
(
&
default_var
,
&
fb_info
.
currentmode
,
&
fb_info
.
gen
);
fbgen_get_var
(
&
disp
.
var
,
-
1
,
&
fb_info
.
gen
.
info
);
default_var
.
activate
|=
FB_ACTIVATE_NOW
;
fbgen_set_disp
(
-
1
,
&
fb_info
.
gen
);
if
(
register_framebuffer
(
&
fb_info
.
gen
.
info
)
<
0
)
{
printk
(
"Could not register Trident framebuffer
\n
"
);
fb_info
.
var
=
default_var
;
if
(
register_framebuffer
(
&
fb_info
)
<
0
)
{
output
(
"Could not register Trident framebuffer
\n
"
);
return
-
EINVAL
;
}
output
(
"fb%d: %s frame buffer device %dx%d-%dbpp
\n
"
,
minor
(
fb_info
.
gen
.
info
.
node
),
fb_info
.
gen
.
info
.
modename
,
default_var
.
xres
,
minor
(
fb_info
.
node
),
fb_info
.
fix
.
id
,
default_var
.
xres
,
default_var
.
yres
,
default_var
.
bits_per_pixel
);
return
0
;
}
static
void
__devexit
trident_pci_remove
(
struct
pci_dev
*
dev
)
{
struct
tridentfb_par
*
par
=
(
struct
tridentfb_par
*
)
fb_info
.
par
;
unregister_framebuffer
(
&
fb_info
);
iounmap
((
void
*
)
par
->
io_virt
);
iounmap
((
void
*
)
fb_info
.
screen_base
);
release_mem_region
(
tridentfb_fix
.
smem_start
,
tridentfb_fix
.
smem_len
);
release_region
(
tridentfb_fix
.
mmio_start
,
tridentfb_fix
.
mmio_len
);
}
/* List of boards that we are trying to support */
static
struct
pci_device_id
trident_devices
[]
__devinitdata
=
{
{
PCI_VENDOR_ID_TRIDENT
,
BLADE3D
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBERBLADEi7
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBERBLADEi7D
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBERBLADEi1
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBERBLADEi1D
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBERBLADEAi1
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBERBLADEAi1D
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBERBLADEE4
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
TGUI9660
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
IMAGE975
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
IMAGE985
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBER9320
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBER9388
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBER9520
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBER9525DVD
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBER9397
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBER9397DVD
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBERBLADEXPAi1
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBERBLADEXPm8
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_TRIDENT
,
CYBERBLADEXPm16
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
0
,}
};
MODULE_DEVICE_TABLE
(
pci
,
trident_devices
);
static
struct
pci_driver
tridentfb_pci_driver
=
{
name:
"tridentfb"
,
id_table:
trident_devices
,
probe:
trident_pci_probe
,
remove:
__devexit_p
(
trident_pci_remove
)
};
int
__init
tridentfb_init
(
void
)
{
output
(
"Trident framebuffer %s initializing
\n
"
,
VERSION
);
return
pci_module_init
(
&
tridentfb_pci_driver
);
}
void
__exit
tridentfb_exit
(
void
)
{
unregister_framebuffer
(
&
fb_info
.
gen
.
info
);
iounmap
((
void
*
)
fb_info
.
io_virt
);
iounmap
((
void
*
)
fb_info
.
fbmem_virt
);
pci_unregister_driver
(
&
tridentfb_pci_driver
);
}
/*
* Parse user specified options (`video=trident:')
* example:
...
...
@@ -1257,12 +1232,10 @@ int tridentfb_setup(char *options)
char
*
opt
;
if
(
!
options
||
!*
options
)
return
0
;
while
((
opt
=
strsep
(
&
options
,
","
))
!=
NULL
)
{
while
((
opt
=
strsep
(
&
options
,
","
))
!=
NULL
)
{
if
(
!*
opt
)
continue
;
if
(
!
strncmp
(
opt
,
"noaccel"
,
7
))
noaccel
=
1
;
else
if
(
!
strncmp
(
opt
,
"accel"
,
5
))
accel
=
1
;
else
if
(
!
strncmp
(
opt
,
"fp"
,
2
))
displaytype
=
DISPLAY_FP
;
else
if
(
!
strncmp
(
opt
,
"crt"
,
3
))
...
...
@@ -1286,13 +1259,18 @@ int tridentfb_setup(char *options)
}
static
struct
fb_ops
tridentfb_ops
=
{
.
fb_get_fix
=
fbgen_get_fix
,
.
fb_get_var
=
fbgen_get_var
,
.
fb_set_var
=
fbgen_set_var
,
.
fb_get_cmap
=
fbgen_get_cmap
,
.
fb_set_cmap
=
fbgen_set_cmap
,
.
fb_setcolreg
=
tridentfb_setcolreg
,
.
fb_pan_display
=
fbgen_pan_display
,
.
owner
=
THIS_MODULE
,
.
fb_setcolreg
=
tridentfb_setcolreg
,
.
fb_pan_display
=
tridentfb_pan_display
,
.
fb_blank
=
tridentfb_blank
,
.
fb_check_var
=
tridentfb_check_var
,
.
fb_set_par
=
tridentfb_set_par
,
// .fb_fillrect = tridentfb_fillrect,
// .fb_copyarea= tridentfb_copyarea,
.
fb_fillrect
=
cfb_fillrect
,
.
fb_copyarea
=
cfb_copyarea
,
.
fb_imageblit
=
cfb_imageblit
,
.
fb_cursor
=
soft_cursor
,
};
#ifdef MODULE
...
...
@@ -1300,6 +1278,7 @@ module_init(tridentfb_init);
#endif
module_exit
(
tridentfb_exit
);
MODULE_AUTHOR
(
"Jani Monoses <jani@
astechnix
.ro>"
);
MODULE_AUTHOR
(
"Jani Monoses <jani@
iv
.ro>"
);
MODULE_DESCRIPTION
(
"Framebuffer driver for Trident cards"
);
MODULE_LICENSE
(
"GPL"
);
drivers/video/tridentfb
.h
→
include/video/trident
.h
View file @
6a8bd1ea
...
...
@@ -4,7 +4,7 @@
#endif
#if TRIDENTFB_DEBUG
#define debug(f,a...) printk("%s:" f, __FUNCTION__ , ## a)
#define debug(f,a...) printk("%s:" f, __FUNCTION__ , ## a)
;mdelay(1000);
#else
#define debug(f,a...)
#endif
...
...
@@ -18,10 +18,13 @@
#define CYBER9320 0x9320
#define CYBER9388 0x9388
#define CYBER9382 0x9382
/* the real PCI id for this is 9660 */
#define CYBER9385 0x9385
/* ditto */
#define CYBER9397 0x9397
#define CYBER9397DVD 0x939A
#define CYBER9520 0x9520
#define CYBER9525DVD 0x9525
#define TGUI9660 0x9660
#define IMAGE975 0x9750
#define IMAGE985 0x9850
#define BLADE3D 0x9880
...
...
@@ -41,9 +44,19 @@
#define BLADE 1
#define XP 2
#define is_image() (family == IMAGE)
#define is_blade() (family == BLADE)
#define is_xp() (family == XP)
#define is_image(id)
#define is_xp(id) ((id == CYBERBLADEXPAi1) ||\
(id == CYBERBLADEXPm8) ||\
(id == CYBERBLADEXPm16))
#define is_blade(id) ((id == BLADE3D) ||\
(id == CYBERBLADEE4) ||\
(id == CYBERBLADEi7) ||\
(id == CYBERBLADEi7D) ||\
(id == CYBERBLADEi1) ||\
(id == CYBERBLADEi1D) ||\
(id == CYBERBLADEAi1) ||\
(id == CYBERBLADEAi1D))
/* these defines are for 'lcd' variable */
#define LCD_STRETCH 0
...
...
@@ -55,20 +68,13 @@
#define DISPLAY_FP 1
#define flatpanel (displaytype == DISPLAY_FP)
/* these are for defaultaccel variable */
#define ACCEL 1
#define NOACCEL 0
#define TRIDENT_IOSIZE 0x20000
#define NTSC 14.31818
#define PAL 17.73448
/* General Registers */
#define SPR 0x1F
/* Software Programming Register (videoram) */
/* 3C4 */
#define RevisionID 0x09
#define OldOrNew 0x0B
#define OldOrNew 0x0B
#define ConfPort1 0x0C
#define ConfPort2 0x0C
#define NewMode2 0x0D
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment