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
d335b16a
Commit
d335b16a
authored
Dec 27, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://are.twiddle.net/tga-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
f914915b
6c56ca7b
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
751 additions
and
1018 deletions
+751
-1018
drivers/video/Makefile
drivers/video/Makefile
+1
-1
drivers/video/cfbcopyarea.c
drivers/video/cfbcopyarea.c
+1
-1
drivers/video/cfbimgblt.c
drivers/video/cfbimgblt.c
+49
-45
drivers/video/tgafb.c
drivers/video/tgafb.c
+618
-902
include/linux/fb.h
include/linux/fb.h
+2
-0
include/video/tgafb.h
include/video/tgafb.h
+80
-69
No files found.
drivers/video/Makefile
View file @
d335b16a
...
@@ -48,7 +48,7 @@ obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o
...
@@ -48,7 +48,7 @@ obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o
obj-$(CONFIG_FB_CLGEN)
+=
clgenfb.o
obj-$(CONFIG_FB_CLGEN)
+=
clgenfb.o
obj-$(CONFIG_FB_TRIDENT)
+=
tridentfb.o
obj-$(CONFIG_FB_TRIDENT)
+=
tridentfb.o
obj-$(CONFIG_FB_S3TRIO)
+=
S3triofb.o
obj-$(CONFIG_FB_S3TRIO)
+=
S3triofb.o
obj-$(CONFIG_FB_TGA)
+=
tgafb.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
obj-$(CONFIG_FB_VESA)
+=
vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_VGA16)
+=
vga16fb.o cfbfillrect.o cfbcopyarea.o
\
obj-$(CONFIG_FB_VGA16)
+=
vga16fb.o cfbfillrect.o cfbcopyarea.o
\
cfbimgblt.o vgastate.o
cfbimgblt.o vgastate.o
...
...
drivers/video/cfbcopyarea.c
View file @
d335b16a
...
@@ -38,7 +38,7 @@
...
@@ -38,7 +38,7 @@
#define BYTES_PER_LONG 4
#define BYTES_PER_LONG 4
#else
#else
#define FB_WRITEL fb_writeq
#define FB_WRITEL fb_writeq
#define FB_READL fb_readq
(x)
#define FB_READL fb_readq
#define SHIFT_PER_LONG 6
#define SHIFT_PER_LONG 6
#define BYTES_PER_LONG 8
#define BYTES_PER_LONG 8
#endif
#endif
...
...
drivers/video/cfbimgblt.c
View file @
d335b16a
...
@@ -21,13 +21,13 @@
...
@@ -21,13 +21,13 @@
*
*
* FIXME
* FIXME
* The code for 24 bit is horrible. It copies byte by byte size instead of
* The code for 24 bit is horrible. It copies byte by byte size instead of
*
long
s like the other sizes. Needs to be optimized.
*
word
s like the other sizes. Needs to be optimized.
*
*
* Tony:
* Tony:
* Incorporate mask tables similar to fbcon-cfb*.c in 2.4 API. This speeds
* Incorporate mask tables similar to fbcon-cfb*.c in 2.4 API. This speeds
* up the code significantly.
* up the code significantly.
*
*
* Code for depths not multiples of BITS_PER_
LONG
is still kludgy, which is
* Code for depths not multiples of BITS_PER_
WORD
is still kludgy, which is
* still processed a bit at a time.
* still processed a bit at a time.
*
*
* Also need to add code to deal with cards endians that are different than
* Also need to add code to deal with cards endians that are different than
...
@@ -48,7 +48,11 @@
...
@@ -48,7 +48,11 @@
#define DPRINTK(fmt, args...)
#define DPRINTK(fmt, args...)
#endif
#endif
static
u32
cfb_tab8
[]
=
{
/* The following code can *not* handle a 64-bit long. */
#define WORD u32
#define BITS_PER_WORD 32
static
WORD
const
cfb_tab8
[]
=
{
#if defined(__BIG_ENDIAN)
#if defined(__BIG_ENDIAN)
0x00000000
,
0x000000ff
,
0x0000ff00
,
0x0000ffff
,
0x00000000
,
0x000000ff
,
0x0000ff00
,
0x0000ffff
,
0x00ff0000
,
0x00ff00ff
,
0x00ffff00
,
0x00ffffff
,
0x00ff0000
,
0x00ff00ff
,
0x00ffff00
,
0x00ffffff
,
...
@@ -64,7 +68,7 @@ static u32 cfb_tab8[] = {
...
@@ -64,7 +68,7 @@ static u32 cfb_tab8[] = {
#endif
#endif
};
};
static
u32
cfb_tab16
[]
=
{
static
WORD
const
cfb_tab16
[]
=
{
#if defined(__BIG_ENDIAN)
#if defined(__BIG_ENDIAN)
0x00000000
,
0x0000ffff
,
0xffff0000
,
0xffffffff
0x00000000
,
0x0000ffff
,
0xffff0000
,
0xffffffff
#elif defined(__LITTLE_ENDIAN)
#elif defined(__LITTLE_ENDIAN)
...
@@ -74,11 +78,11 @@ static u32 cfb_tab16[] = {
...
@@ -74,11 +78,11 @@ static u32 cfb_tab16[] = {
#endif
#endif
};
};
static
u32
cfb_tab32
[]
=
{
static
WORD
const
cfb_tab32
[]
=
{
0x00000000
,
0xffffffff
0x00000000
,
0xffffffff
};
};
#if BITS_PER_
LONG
== 32
#if BITS_PER_
WORD
== 32
#define FB_WRITEL fb_writel
#define FB_WRITEL fb_writel
#define FB_READL fb_readl
#define FB_READL fb_readl
#else
#else
...
@@ -87,7 +91,7 @@ static u32 cfb_tab32[] = {
...
@@ -87,7 +91,7 @@ static u32 cfb_tab32[] = {
#endif
#endif
#if defined (__BIG_ENDIAN)
#if defined (__BIG_ENDIAN)
#define LEFT_POS(bpp) (BITS_PER_
LONG
- bpp)
#define LEFT_POS(bpp) (BITS_PER_
WORD
- bpp)
#define NEXT_POS(pos, bpp) ((pos) -= (bpp))
#define NEXT_POS(pos, bpp) ((pos) -= (bpp))
#define SHIFT_HIGH(val, bits) ((val) >> (bits))
#define SHIFT_HIGH(val, bits) ((val) >> (bits))
#define SHIFT_LOW(val, bits) ((val) << (bits))
#define SHIFT_LOW(val, bits) ((val) << (bits))
...
@@ -99,25 +103,25 @@ static u32 cfb_tab32[] = {
...
@@ -99,25 +103,25 @@ static u32 cfb_tab32[] = {
#endif
#endif
static
inline
void
color_imageblit
(
struct
fb_image
*
image
,
struct
fb_info
*
p
,
u8
*
dst1
,
static
inline
void
color_imageblit
(
struct
fb_image
*
image
,
struct
fb_info
*
p
,
u8
*
dst1
,
unsigned
long
start_index
,
unsigned
long
pitch_index
)
WORD
start_index
,
WORD
pitch_index
)
{
{
/* Draw the penguin */
/* Draw the penguin */
int
i
,
n
;
int
i
,
n
;
unsigned
long
bitmask
=
SHIFT_LOW
(
~
0UL
,
BITS_PER_LONG
-
p
->
var
.
bits_per_pixel
);
WORD
bitmask
=
SHIFT_LOW
(
~
0UL
,
BITS_PER_WORD
-
p
->
var
.
bits_per_pixel
);
u
nsigned
long
*
palette
=
(
unsigned
long
*
)
p
->
pseudo_palette
;
u
32
*
palette
=
(
u32
*
)
p
->
pseudo_palette
;
unsigned
long
*
dst
,
*
dst2
,
color
=
0
,
val
,
shift
;
WORD
*
dst
,
*
dst2
,
color
=
0
,
val
,
shift
;
unsigned
long
null_bits
=
BITS_PER_LONG
-
p
->
var
.
bits_per_pixel
;
WORD
null_bits
=
BITS_PER_WORD
-
p
->
var
.
bits_per_pixel
;
u8
*
src
=
image
->
data
;
u8
*
src
=
image
->
data
;
dst2
=
(
unsigned
long
*
)
dst1
;
dst2
=
(
WORD
*
)
dst1
;
for
(
i
=
image
->
height
;
i
--
;
)
{
for
(
i
=
image
->
height
;
i
--
;
)
{
n
=
image
->
width
;
n
=
image
->
width
;
dst
=
(
unsigned
long
*
)
dst1
;
dst
=
(
WORD
*
)
dst1
;
shift
=
0
;
shift
=
0
;
val
=
0
;
val
=
0
;
if
(
start_index
)
{
if
(
start_index
)
{
unsigned
long
start_mask
=
~
(
SHIFT_HIGH
(
~
0UL
,
start_index
));
WORD
start_mask
=
~
(
SHIFT_HIGH
(
~
0UL
,
start_index
));
val
=
FB_READL
(
dst
)
&
start_mask
;
val
=
FB_READL
(
dst
)
&
start_mask
;
shift
=
start_index
;
shift
=
start_index
;
...
@@ -134,14 +138,14 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p, u8
...
@@ -134,14 +138,14 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p, u8
if
(
shift
==
null_bits
)
if
(
shift
==
null_bits
)
val
=
0
;
val
=
0
;
else
else
val
=
SHIFT_LOW
(
color
,
BITS_PER_
LONG
-
shift
);
val
=
SHIFT_LOW
(
color
,
BITS_PER_
WORD
-
shift
);
}
}
shift
+=
p
->
var
.
bits_per_pixel
;
shift
+=
p
->
var
.
bits_per_pixel
;
shift
&=
(
BITS_PER_
LONG
-
1
);
shift
&=
(
BITS_PER_
WORD
-
1
);
src
++
;
src
++
;
}
}
if
(
shift
)
{
if
(
shift
)
{
unsigned
long
end_mask
=
SHIFT_HIGH
(
~
0UL
,
shift
);
WORD
end_mask
=
SHIFT_HIGH
(
~
0UL
,
shift
);
FB_WRITEL
((
FB_READL
(
dst
)
&
end_mask
)
|
val
,
dst
);
FB_WRITEL
((
FB_READL
(
dst
)
&
end_mask
)
|
val
,
dst
);
}
}
...
@@ -149,35 +153,35 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p, u8
...
@@ -149,35 +153,35 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p, u8
if
(
pitch_index
)
{
if
(
pitch_index
)
{
dst2
+=
p
->
fix
.
line_length
;
dst2
+=
p
->
fix
.
line_length
;
dst1
=
(
char
*
)
dst2
;
dst1
=
(
char
*
)
dst2
;
(
unsigned
long
)
dst1
&=
~
(
sizeof
(
unsigned
long
)
-
1
);
(
size_t
)
dst1
&=
~
(
sizeof
(
WORD
)
-
1
);
start_index
+=
pitch_index
;
start_index
+=
pitch_index
;
start_index
&=
BITS_PER_
LONG
-
1
;
start_index
&=
BITS_PER_
WORD
-
1
;
}
}
}
}
}
}
static
inline
void
slow_imageblit
(
struct
fb_image
*
image
,
struct
fb_info
*
p
,
u8
*
dst1
,
static
inline
void
slow_imageblit
(
struct
fb_image
*
image
,
struct
fb_info
*
p
,
u8
*
dst1
,
unsigned
long
fgcolor
,
unsigned
long
bgcolor
,
WORD
fgcolor
,
WORD
bgcolor
,
unsigned
long
start_index
,
unsigned
long
pitch_index
)
WORD
start_index
,
WORD
pitch_index
)
{
{
unsigned
long
i
,
j
,
l
=
8
;
WORD
i
,
j
,
l
=
8
;
unsigned
long
shift
,
color
,
bpp
=
p
->
var
.
bits_per_pixel
;
WORD
shift
,
color
,
bpp
=
p
->
var
.
bits_per_pixel
;
unsigned
long
*
dst
,
*
dst2
,
val
,
pitch
=
p
->
fix
.
line_length
;
WORD
*
dst
,
*
dst2
,
val
,
pitch
=
p
->
fix
.
line_length
;
unsigned
long
null_bits
=
BITS_PER_LONG
-
bpp
;
WORD
null_bits
=
BITS_PER_WORD
-
bpp
;
u8
*
src
=
image
->
data
;
u8
*
src
=
image
->
data
;
dst2
=
(
unsigned
long
*
)
dst1
;
dst2
=
(
WORD
*
)
dst1
;
for
(
i
=
image
->
height
;
i
--
;
)
{
for
(
i
=
image
->
height
;
i
--
;
)
{
shift
=
0
;
shift
=
0
;
val
=
0
;
val
=
0
;
j
=
image
->
width
;
j
=
image
->
width
;
dst
=
(
unsigned
long
*
)
dst1
;
dst
=
(
WORD
*
)
dst1
;
/* write leading bits */
/* write leading bits */
if
(
start_index
)
{
if
(
start_index
)
{
unsigned
long
start_mask
=
~
(
SHIFT_HIGH
(
~
0UL
,
start_index
));
WORD
start_mask
=
~
(
SHIFT_HIGH
(
~
0UL
,
start_index
));
val
=
FB_READL
(
dst
)
&
start_mask
;
val
=
FB_READL
(
dst
)
&
start_mask
;
shift
=
start_index
;
shift
=
start_index
;
...
@@ -196,15 +200,15 @@ static inline void slow_imageblit(struct fb_image *image, struct fb_info *p, u8
...
@@ -196,15 +200,15 @@ static inline void slow_imageblit(struct fb_image *image, struct fb_info *p, u8
if
(
shift
==
null_bits
)
if
(
shift
==
null_bits
)
val
=
0
;
val
=
0
;
else
else
val
=
SHIFT_LOW
(
color
,
BITS_PER_
LONG
-
shift
);
val
=
SHIFT_LOW
(
color
,
BITS_PER_
WORD
-
shift
);
}
}
shift
+=
bpp
;
shift
+=
bpp
;
shift
&=
(
BITS_PER_
LONG
-
1
);
shift
&=
(
BITS_PER_
WORD
-
1
);
if
(
!
l
)
{
l
=
8
;
src
++
;
};
if
(
!
l
)
{
l
=
8
;
src
++
;
};
}
}
/* write trailing bits */
/* write trailing bits */
if
(
shift
)
{
if
(
shift
)
{
unsigned
long
end_mask
=
SHIFT_HIGH
(
~
0UL
,
shift
);
WORD
end_mask
=
SHIFT_HIGH
(
~
0UL
,
shift
);
FB_WRITEL
((
FB_READL
(
dst
)
&
end_mask
)
|
val
,
dst
);
FB_WRITEL
((
FB_READL
(
dst
)
&
end_mask
)
|
val
,
dst
);
}
}
...
@@ -213,24 +217,24 @@ static inline void slow_imageblit(struct fb_image *image, struct fb_info *p, u8
...
@@ -213,24 +217,24 @@ static inline void slow_imageblit(struct fb_image *image, struct fb_info *p, u8
if
(
pitch_index
)
{
if
(
pitch_index
)
{
dst2
+=
pitch
;
dst2
+=
pitch
;
dst1
=
(
char
*
)
dst2
;
dst1
=
(
char
*
)
dst2
;
(
unsigned
long
)
dst1
&=
~
(
sizeof
(
unsigned
long
)
-
1
);
(
size_t
)
dst1
&=
~
(
sizeof
(
WORD
)
-
1
);
start_index
+=
pitch_index
;
start_index
+=
pitch_index
;
start_index
&=
BITS_PER_
LONG
-
1
;
start_index
&=
BITS_PER_
WORD
-
1
;
}
}
}
}
}
}
static
inline
void
fast_imageblit
(
struct
fb_image
*
image
,
struct
fb_info
*
p
,
u8
*
dst1
,
static
inline
void
fast_imageblit
(
struct
fb_image
*
image
,
struct
fb_info
*
p
,
u8
*
dst1
,
unsigned
long
fgcolor
,
unsigned
long
bgcolor
)
WORD
fgcolor
,
WORD
bgcolor
)
{
{
int
i
,
j
,
k
,
l
=
8
,
n
;
int
i
,
j
,
k
,
l
=
8
,
n
;
unsigned
long
bit_mask
,
end_mask
,
eorx
;
WORD
bit_mask
,
end_mask
,
eorx
;
unsigned
long
fgx
=
fgcolor
,
bgx
=
bgcolor
,
pad
,
bpp
=
p
->
var
.
bits_per_pixel
;
WORD
fgx
=
fgcolor
,
bgx
=
bgcolor
,
pad
,
bpp
=
p
->
var
.
bits_per_pixel
;
unsigned
long
tmp
=
(
1
<<
bpp
)
-
1
;
WORD
tmp
=
(
1
<<
bpp
)
-
1
;
unsigned
long
ppw
=
BITS_PER_LONG
/
bpp
,
ppos
;
WORD
ppw
=
BITS_PER_WORD
/
bpp
,
ppos
;
unsigned
long
*
dst
;
WORD
*
dst
;
u32
*
tab
=
NULL
;
u32
*
tab
=
NULL
;
char
*
src
=
image
->
data
;
char
*
src
=
image
->
data
;
...
@@ -263,7 +267,7 @@ static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, u8
...
@@ -263,7 +267,7 @@ static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, u8
k
=
image
->
width
/
ppw
;
k
=
image
->
width
/
ppw
;
for
(
i
=
image
->
height
;
i
--
;
)
{
for
(
i
=
image
->
height
;
i
--
;
)
{
dst
=
(
unsigned
long
*
)
dst1
;
dst
=
(
WORD
*
)
dst1
;
for
(
j
=
k
;
j
--
;
)
{
for
(
j
=
k
;
j
--
;
)
{
l
-=
ppw
;
l
-=
ppw
;
...
@@ -291,8 +295,8 @@ static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, u8
...
@@ -291,8 +295,8 @@ static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, u8
void
cfb_imageblit
(
struct
fb_info
*
p
,
struct
fb_image
*
image
)
void
cfb_imageblit
(
struct
fb_info
*
p
,
struct
fb_image
*
image
)
{
{
int
x2
,
y2
,
vxres
,
vyres
;
int
x2
,
y2
,
vxres
,
vyres
;
unsigned
long
fgcolor
,
bgcolor
,
start_index
,
bitstart
,
pitch_index
=
0
;
WORD
fgcolor
,
bgcolor
,
start_index
,
bitstart
,
pitch_index
=
0
;
unsigned
long
bpl
=
sizeof
(
unsigned
long
),
bpp
=
p
->
var
.
bits_per_pixel
;
WORD
bpl
=
sizeof
(
WORD
),
bpp
=
p
->
var
.
bits_per_pixel
;
u8
*
dst1
;
u8
*
dst1
;
vxres
=
p
->
var
.
xres_virtual
;
vxres
=
p
->
var
.
xres_virtual
;
...
@@ -315,7 +319,7 @@ void cfb_imageblit(struct fb_info *p, struct fb_image *image)
...
@@ -315,7 +319,7 @@ void cfb_imageblit(struct fb_info *p, struct fb_image *image)
image
->
height
=
y2
-
image
->
dy
;
image
->
height
=
y2
-
image
->
dy
;
bitstart
=
(
image
->
dy
*
p
->
fix
.
line_length
*
8
)
+
(
image
->
dx
*
bpp
);
bitstart
=
(
image
->
dy
*
p
->
fix
.
line_length
*
8
)
+
(
image
->
dx
*
bpp
);
start_index
=
bitstart
&
(
BITS_PER_
LONG
-
1
);
start_index
=
bitstart
&
(
BITS_PER_
WORD
-
1
);
pitch_index
=
(
p
->
fix
.
line_length
&
(
bpl
-
1
))
*
8
;
pitch_index
=
(
p
->
fix
.
line_length
&
(
bpl
-
1
))
*
8
;
bitstart
/=
8
;
bitstart
/=
8
;
...
@@ -332,7 +336,7 @@ void cfb_imageblit(struct fb_info *p, struct fb_image *image)
...
@@ -332,7 +336,7 @@ void cfb_imageblit(struct fb_info *p, struct fb_image *image)
bgcolor
=
image
->
bg_color
;
bgcolor
=
image
->
bg_color
;
}
}
if
(
BITS_PER_
LONG
%
bpp
==
0
&&
!
start_index
&&
!
pitch_index
&&
if
(
BITS_PER_
WORD
%
bpp
==
0
&&
!
start_index
&&
!
pitch_index
&&
bpp
>=
8
&&
bpp
<=
32
&&
(
image
->
width
&
7
)
==
0
)
bpp
>=
8
&&
bpp
<=
32
&&
(
image
->
width
&
7
)
==
0
)
fast_imageblit
(
image
,
p
,
dst1
,
fgcolor
,
bgcolor
);
fast_imageblit
(
image
,
p
,
dst1
,
fgcolor
,
bgcolor
);
else
else
...
...
drivers/video/tgafb.c
View file @
d335b16a
/*
/*
* linux/drivers/video/tgafb.c -- DEC 21030 TGA frame buffer device
* linux/drivers/video/tgafb.c -- DEC 21030 TGA frame buffer device
*
*
* Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha
*
* $Id: tgafb.c,v 1.12.2.3 2000/04/04 06:44:56 mato Exp $
*
* This driver is partly based on the original TGA framebuffer device, which
* was partly based on the original TGA console driver, which are
*
* Copyright (C) 1997 Geert Uytterhoeven
* Copyright (C) 1995 Jay Estabrook
* Copyright (C) 1995 Jay Estabrook
* Copyright (C) 1997 Geert Uytterhoeven
* Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha
* Copyright (C) 2002 Richard Henderson
*
*
* This file is subject to the terms and conditions of the GNU General Public
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* License. See the file COPYING in the main directory of this archive for
* more details.
* more details.
*/
*/
/* KNOWN PROBLEMS/TO DO ===================================================== *
*
* - How to set a single color register on 24-plane cards?
*
* - Hardware cursor/other text acceleration methods
*
* - Some redraws can stall kernel for several seconds
* [This should now be solved by the fast memmove() patch in 2.3.6]
*
* KNOWN PROBLEMS/TO DO ==================================================== */
#include <linux/module.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/
pci
.h>
#include <linux/
fb
.h>
#include <linux/selection.h>
#include <linux/selection.h>
#include <linux/
console
.h>
#include <linux/
pci
.h>
#include <asm/io.h>
#include <asm/io.h>
#include <video/tgafb.h>
#include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb32.h>
#include "tgafb.h"
/*
/*
* Local functions.
* Global declarations
*/
*/
static
struct
tgafb_info
fb_info
;
static
int
tgafb_check_var
(
struct
fb_var_screeninfo
*
,
struct
fb_info
*
);
static
struct
tgafb_par
current_par
;
static
int
tgafb_set_par
(
struct
fb_info
*
);
static
int
current_par_valid
=
0
;
static
void
tgafb_set_pll
(
struct
tga_par
*
,
int
);
static
struct
display
disp
;
static
int
tgafb_setcolreg
(
unsigned
,
unsigned
,
unsigned
,
unsigned
,
unsigned
,
struct
fb_info
*
);
static
char
default_fontname
[
40
]
__initdata
=
{
0
};
static
int
tgafb_blank
(
int
,
struct
fb_info
*
);
static
struct
fb_var_screeninfo
default_var
;
static
void
tgafb_init_fix
(
struct
fb_info
*
);
static
int
default_var_valid
=
0
;
static
int
tgafb_pci_register
(
struct
pci_dev
*
,
const
struct
pci_device_id
*
);
#ifdef MODULE
static
struct
{
u_char
red
,
green
,
blue
,
pad
;
}
palette
[
256
];
static
void
tgafb_pci_unregister
(
struct
pci_dev
*
);
#ifdef FBCON_HAS_CFB32
static
u32
fbcon_cfb32_cmap
[
16
];
#endif
#endif
static
const
char
*
mode_option
=
"640x480@60"
;
/*
* Hardware presets
*/
static
unsigned
int
fb_offset_presets
[
4
]
=
{
TGA_8PLANE_FB_OFFSET
,
TGA_24PLANE_FB_OFFSET
,
0xffffffff
,
TGA_24PLUSZ_FB_OFFSET
};
static
unsigned
int
deep_presets
[
4
]
=
{
/*
0x00014000
,
* Frame buffer operations
0x0001440d
,
0xffffffff
,
0x0001441d
};
static
unsigned
int
rasterop_presets
[
4
]
=
{
0x00000003
,
0x00000303
,
0xffffffff
,
0x00000303
};
static
unsigned
int
mode_presets
[
4
]
=
{
0x00002000
,
0x00002300
,
0xffffffff
,
0x00002300
};
static
unsigned
int
base_addr_presets
[
4
]
=
{
0x00000000
,
0x00000001
,
0xffffffff
,
0x00000001
};
/*
* Predefined video modes
* This is a subset of the standard VESA modes, recalculated from XFree86.
*
* XXX Should we store these in terms of the encoded par structs? Even better,
* fbcon should provide a general mechanism for doing something like this.
*/
static
struct
{
const
char
*
name
;
struct
fb_var_screeninfo
var
;
}
tgafb_predefined
[]
__initdata
=
{
{
"640x480-60"
,
{
640
,
480
,
640
,
480
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
39722
,
40
,
24
,
32
,
11
,
96
,
2
,
0
,
FB_VMODE_NONINTERLACED
}},
{
"800x600-56"
,
{
800
,
600
,
800
,
600
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
27777
,
128
,
24
,
22
,
1
,
72
,
2
,
0
,
FB_VMODE_NONINTERLACED
}},
{
"640x480-72"
,
{
640
,
480
,
640
,
480
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
31746
,
144
,
40
,
30
,
8
,
40
,
3
,
0
,
FB_VMODE_NONINTERLACED
}},
{
"800x600-60"
,
{
800
,
600
,
800
,
600
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
25000
,
88
,
40
,
23
,
1
,
128
,
4
,
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
FB_VMODE_NONINTERLACED
}},
{
"800x600-72"
,
{
800
,
600
,
800
,
600
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
20000
,
64
,
56
,
23
,
37
,
120
,
6
,
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
FB_VMODE_NONINTERLACED
}},
{
"1024x768-60"
,
{
1024
,
768
,
1024
,
768
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
15384
,
168
,
8
,
29
,
3
,
144
,
6
,
0
,
FB_VMODE_NONINTERLACED
}},
{
"1152x864-60"
,
{
1152
,
864
,
1152
,
864
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
11123
,
208
,
64
,
16
,
4
,
256
,
8
,
0
,
FB_VMODE_NONINTERLACED
}},
{
"1024x768-70"
,
{
1024
,
768
,
1024
,
768
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
13333
,
144
,
24
,
29
,
3
,
136
,
6
,
0
,
FB_VMODE_NONINTERLACED
}},
{
"1024x768-76"
,
{
1024
,
768
,
1024
,
768
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
11764
,
208
,
8
,
36
,
16
,
120
,
3
,
0
,
FB_VMODE_NONINTERLACED
}},
{
"1152x864-70"
,
{
1152
,
864
,
1152
,
864
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
10869
,
106
,
56
,
20
,
1
,
160
,
10
,
0
,
FB_VMODE_NONINTERLACED
}},
{
"1280x1024-61"
,
{
1280
,
1024
,
1280
,
1024
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
9090
,
200
,
48
,
26
,
1
,
184
,
3
,
0
,
FB_VMODE_NONINTERLACED
}},
{
"1024x768-85"
,
{
1024
,
768
,
1024
,
768
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
10111
,
192
,
32
,
34
,
14
,
160
,
6
,
0
,
FB_VMODE_NONINTERLACED
}},
{
"1280x1024-70"
,
{
1280
,
1024
,
1280
,
1024
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
7905
,
224
,
32
,
28
,
8
,
160
,
8
,
0
,
FB_VMODE_NONINTERLACED
}},
{
"1152x864-84"
,
{
1152
,
864
,
1152
,
864
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
7407
,
184
,
312
,
32
,
0
,
128
,
12
,
0
,
FB_VMODE_NONINTERLACED
}},
{
"1280x1024-76"
,
{
1280
,
1024
,
1280
,
1024
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
7407
,
248
,
32
,
34
,
3
,
104
,
3
,
0
,
FB_VMODE_NONINTERLACED
}},
{
"1280x1024-85"
,
{
1280
,
1024
,
1280
,
1024
,
0
,
0
,
0
,
0
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
6349
,
224
,
64
,
44
,
1
,
160
,
3
,
0
,
FB_VMODE_NONINTERLACED
}},
/* These are modes used by the two fixed-frequency monitors I have at home.
* You may or may not find these useful.
*/
*/
{
"WYSE1"
,
{
/* 1280x1024 @ 72 Hz, 130 Mhz clock */
static
struct
fb_ops
tgafb_ops
=
{
1280
,
1024
,
1280
,
1024
,
0
,
0
,
0
,
0
,
.
owner
=
THIS_MODULE
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
.
fb_check_var
=
tgafb_check_var
,
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
7692
,
192
,
32
,
47
,
0
,
192
,
5
,
.
fb_set_par
=
tgafb_set_par
,
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
.
fb_setcolreg
=
tgafb_setcolreg
,
FB_VMODE_NONINTERLACED
.
fb_blank
=
tgafb_blank
,
}},
.
fb_fillrect
=
cfb_fillrect
,
{
"IBM3"
,
{
/* 1280x1024 @ 70 Hz, 120 Mhz clock */
.
fb_copyarea
=
cfb_copyarea
,
1280
,
1024
,
1280
,
1024
,
0
,
0
,
0
,
0
,
.
fb_imageblit
=
cfb_imageblit
,
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
8
,
0
},
{
0
,
0
,
0
},
.
fb_cursor
=
soft_cursor
,
0
,
0
,
-
1
,
-
1
,
FB_ACCELF_TEXT
,
8333
,
192
,
32
,
47
,
0
,
192
,
5
,
0
,
FB_VMODE_NONINTERLACED
}}
};
};
#define NUM_TOTAL_MODES ARRAY_SIZE(tgafb_predefined)
/*
/*
* PCI registration operations
* Interface used by the world
*/
*/
static
void
tgafb_detect
(
void
);
static
struct
pci_device_id
const
tgafb_pci_table
[]
=
{
static
int
tgafb_encode_fix
(
struct
fb_fix_screeninfo
*
fix
,
const
void
*
fb_par
,
{
PCI_VENDOR_ID_DEC
,
PCI_DEVICE_ID_DEC_TGA
,
PCI_ANY_ID
,
PCI_ANY_ID
,
struct
fb_info_gen
*
info
);
0
,
0
,
0
}
static
int
tgafb_decode_var
(
const
struct
fb_var_screeninfo
*
var
,
void
*
fb_par
,
};
struct
fb_info_gen
*
info
);
static
int
tgafb_encode_var
(
struct
fb_var_screeninfo
*
var
,
const
void
*
fb_par
,
struct
fb_info_gen
*
info
);
static
void
tgafb_get_par
(
void
*
fb_par
,
struct
fb_info_gen
*
info
);
static
void
tgafb_set_par
(
const
void
*
fb_par
,
struct
fb_info_gen
*
info
);
static
int
tgafb_getcolreg
(
u_int
regno
,
u_int
*
red
,
u_int
*
green
,
u_int
*
blue
,
u_int
*
transp
,
struct
fb_info
*
info
);
static
int
tgafb_setcolreg
(
u_int
regno
,
u_int
red
,
u_int
green
,
u_int
blue
,
u_int
transp
,
struct
fb_info
*
info
);
static
int
tgafb_blank
(
int
blank
,
struct
fb_info_gen
*
info
);
static
void
tgafb_set_disp
(
const
void
*
fb_par
,
struct
display
*
disp
,
struct
fb_info_gen
*
info
);
#ifndef MODULE
int
tgafb_setup
(
char
*
);
#endif
static
void
tgafb_set_pll
(
int
f
);
static
struct
pci_driver
tgafb_driver
=
{
#if 1
.
name
=
"tgafb"
,
static
int
tgafb_set_cmap
(
struct
fb_cmap
*
cmap
,
int
kspc
,
int
con
,
.
id_table
=
tgafb_pci_table
,
struct
fb_info
*
info
);
.
probe
=
tgafb_pci_register
,
static
void
tgafb_update_palette
(
void
);
.
remove
=
__devexit_p
(
tgafb_pci_unregister
),
#endif
};
/*
/**
* Chipset specific functions
* tgafb_check_var - Optional function. Validates a var passed in.
* @var: frame buffer variable screen structure
* @info: frame buffer structure that represents a single frame buffer
*/
*/
static
int
tgafb_check_var
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
static
void
tgafb_detect
(
void
)
{
return
;
}
static
int
tgafb_encode_fix
(
struct
fb_fix_screeninfo
*
fix
,
const
void
*
fb_par
,
struct
fb_info_gen
*
info
)
{
{
struct
tgafb_par
*
par
=
(
struct
tgafb_par
*
)
fb_par
;
struct
tga_par
*
par
=
(
struct
tga_par
*
)
info
->
par
;
strcpy
(
fix
->
id
,
fb_info
.
gen
.
info
.
modename
);
fix
->
type
=
FB_TYPE_PACKED_PIXELS
;
if
(
par
->
tga_type
==
TGA_TYPE_8PLANE
)
{
fix
->
type_aux
=
0
;
if
(
var
->
bits_per_pixel
>
8
)
if
(
fb_info
.
tga_type
==
TGA_TYPE_8PLANE
)
{
fix
->
visual
=
FB_VISUAL_PSEUDOCOLOR
;
}
else
{
fix
->
visual
=
FB_VISUAL_TRUECOLOR
;
}
fix
->
line_length
=
par
->
xres
*
(
par
->
bits_per_pixel
>>
3
);
fix
->
smem_start
=
fb_info
.
tga_fb_base
;
fix
->
smem_len
=
fix
->
line_length
*
par
->
yres
;
fix
->
mmio_start
=
fb_info
.
tga_regs_base
;
fix
->
mmio_len
=
0x1000
;
/* Is this sufficient? */
fix
->
xpanstep
=
fix
->
ypanstep
=
fix
->
ywrapstep
=
0
;
fix
->
accel
=
FB_ACCEL_DEC_TGA
;
return
0
;
}
static
int
tgafb_decode_var
(
const
struct
fb_var_screeninfo
*
var
,
void
*
fb_par
,
struct
fb_info_gen
*
info
)
{
struct
tgafb_par
*
par
=
(
struct
tgafb_par
*
)
fb_par
;
/* round up some */
if
(
fb_info
.
tga_type
==
TGA_TYPE_8PLANE
)
{
if
(
var
->
bits_per_pixel
>
8
)
{
return
-
EINVAL
;
return
-
EINVAL
;
}
par
->
bits_per_pixel
=
8
;
}
else
{
}
else
{
if
(
var
->
bits_per_pixel
>
32
)
{
if
(
var
->
bits_per_pixel
>
32
)
return
-
EINVAL
;
return
-
EINVAL
;
}
}
par
->
bits_per_pixel
=
32
;
}
/* check the values for sanity */
if
(
var
->
xres_virtual
!=
var
->
xres
||
var
->
yres_virtual
!=
var
->
yres
)
if
(
var
->
xres_virtual
!=
var
->
xres
||
return
-
EINVAL
;
var
->
yres_virtual
!=
var
->
yres
||
if
(
var
->
nonstd
)
var
->
nonstd
||
(
1000000000
/
var
->
pixclock
)
>
TGA_PLL_MAX_FREQ
||
return
-
EINVAL
;
(
var
->
vmode
&
FB_VMODE_MASK
)
!=
FB_VMODE_NONINTERLACED
if
(
1000000000
/
var
->
pixclock
>
TGA_PLL_MAX_FREQ
)
#if 0 /* fbmon not done. uncomment for 2.5.x -brad */
return
-
EINVAL
;
|| !fbmon_valid_timings(var->pixclock, var->htotal, var->vtotal, info))
if
((
var
->
vmode
&
FB_VMODE_MASK
)
!=
FB_VMODE_NONINTERLACED
)
#else
)
#endif
return
-
EINVAL
;
return
-
EINVAL
;
/* encode video timings */
par
->
htimings
=
((
var
->
xres
/
4
)
&
TGA_HORIZ_ACT_LSB
)
|
(((
var
->
xres
/
4
)
&
0x600
<<
19
)
&
TGA_HORIZ_ACT_MSB
);
par
->
vtimings
=
(
var
->
yres
&
TGA_VERT_ACTIVE
);
par
->
htimings
|=
((
var
->
right_margin
/
4
)
<<
9
)
&
TGA_HORIZ_FP
;
par
->
vtimings
|=
(
var
->
lower_margin
<<
11
)
&
TGA_VERT_FP
;
par
->
htimings
|=
((
var
->
hsync_len
/
4
)
<<
14
)
&
TGA_HORIZ_SYNC
;
par
->
vtimings
|=
(
var
->
vsync_len
<<
16
)
&
TGA_VERT_SYNC
;
par
->
htimings
|=
((
var
->
left_margin
/
4
)
<<
21
)
&
TGA_HORIZ_BP
;
par
->
vtimings
|=
(
var
->
upper_margin
<<
22
)
&
TGA_VERT_BP
;
if
(
var
->
sync
&
FB_SYNC_HOR_HIGH_ACT
)
par
->
htimings
|=
TGA_HORIZ_POLARITY
;
if
(
var
->
sync
&
FB_SYNC_VERT_HIGH_ACT
)
par
->
vtimings
|=
TGA_VERT_POLARITY
;
if
(
var
->
sync
&
FB_SYNC_ON_GREEN
)
{
par
->
sync_on_green
=
1
;
}
else
{
par
->
sync_on_green
=
0
;
}
/* store other useful values in par */
par
->
xres
=
var
->
xres
;
par
->
yres
=
var
->
yres
;
par
->
pll_freq
=
1000000000
/
var
->
pixclock
;
par
->
bits_per_pixel
=
var
->
bits_per_pixel
;
return
0
;
return
0
;
}
}
/**
static
int
tgafb_encode_var
(
struct
fb_var_screeninfo
*
var
,
const
void
*
fb_par
,
* tgafb_set_par - Optional function. Alters the hardware state.
struct
fb_info_gen
*
info
)
* @info: frame buffer structure that represents a single frame buffer
*/
static
int
tgafb_set_par
(
struct
fb_info
*
info
)
{
{
struct
tgafb_par
*
par
=
(
struct
tgafb_par
*
)
fb_par
;
static
unsigned
int
const
deep_presets
[
4
]
=
{
0x00014000
,
/* decode video timings */
0x0001440d
,
var
->
xres
=
((
par
->
htimings
&
TGA_HORIZ_ACT_LSB
)
|
((
par
->
htimings
&
TGA_HORIZ_ACT_MSB
)
>>
19
))
*
4
;
0xffffffff
,
var
->
yres
=
(
par
->
vtimings
&
TGA_VERT_ACTIVE
);
0x0001441d
var
->
right_margin
=
((
par
->
htimings
&
TGA_HORIZ_FP
)
>>
9
)
*
4
;
};
var
->
lower_margin
=
((
par
->
vtimings
&
TGA_VERT_FP
)
>>
11
);
static
unsigned
int
const
rasterop_presets
[
4
]
=
{
var
->
hsync_len
=
((
par
->
htimings
&
TGA_HORIZ_SYNC
)
>>
14
)
*
4
;
0x00000003
,
var
->
vsync_len
=
((
par
->
vtimings
&
TGA_VERT_SYNC
)
>>
16
);
0x00000303
,
var
->
left_margin
=
((
par
->
htimings
&
TGA_HORIZ_BP
)
>>
21
)
*
4
;
0xffffffff
,
var
->
upper_margin
=
((
par
->
vtimings
&
TGA_VERT_BP
)
>>
22
);
0x00000303
};
if
(
par
->
htimings
&
TGA_HORIZ_POLARITY
)
static
unsigned
int
const
mode_presets
[
4
]
=
{
var
->
sync
|=
FB_SYNC_HOR_HIGH_ACT
;
0x00002000
,
if
(
par
->
vtimings
&
TGA_VERT_POLARITY
)
0x00002300
,
var
->
sync
|=
FB_SYNC_VERT_HIGH_ACT
;
0xffffffff
,
if
(
par
->
sync_on_green
==
1
)
0x00002300
var
->
sync
|=
FB_SYNC_ON_GREEN
;
};
static
unsigned
int
const
base_addr_presets
[
4
]
=
{
var
->
xres_virtual
=
var
->
xres
;
0x00000000
,
var
->
yres_virtual
=
var
->
yres
;
0x00000001
,
var
->
xoffset
=
var
->
yoffset
=
0
;
0xffffffff
,
0x00000001
/* depth-related */
};
if
(
fb_info
.
tga_type
==
TGA_TYPE_8PLANE
)
{
var
->
red
.
offset
=
0
;
var
->
green
.
offset
=
0
;
var
->
blue
.
offset
=
0
;
}
else
{
var
->
red
.
offset
=
16
;
var
->
green
.
offset
=
8
;
var
->
blue
.
offset
=
0
;
}
var
->
bits_per_pixel
=
par
->
bits_per_pixel
;
var
->
grayscale
=
0
;
var
->
red
.
length
=
var
->
green
.
length
=
var
->
blue
.
length
=
8
;
var
->
red
.
msb_right
=
var
->
green
.
msb_right
=
var
->
blue
.
msb_right
=
0
;
var
->
transp
.
offset
=
var
->
transp
.
length
=
var
->
transp
.
msb_right
=
0
;
/* others */
var
->
xoffset
=
var
->
yoffset
=
0
;
var
->
pixclock
=
1000000000
/
par
->
pll_freq
;
var
->
nonstd
=
0
;
var
->
activate
=
0
;
var
->
height
=
var
->
width
=
-
1
;
var
->
accel_flags
=
0
;
return
0
;
}
struct
tga_par
*
par
=
(
struct
tga_par
*
)
info
->
par
;
u32
htimings
,
vtimings
,
pll_freq
;
u8
tga_type
;
int
i
,
j
;
static
void
tgafb_get_par
(
void
*
fb_par
,
struct
fb_info_gen
*
info
)
/* Encode video timings. */
{
htimings
=
(((
info
->
var
.
xres
/
4
)
&
TGA_HORIZ_ACT_LSB
)
struct
tgafb_par
*
par
=
(
struct
tgafb_par
*
)
fb_par
;
|
(((
info
->
var
.
xres
/
4
)
&
0x600
<<
19
)
&
TGA_HORIZ_ACT_MSB
));
vtimings
=
(
info
->
var
.
yres
&
TGA_VERT_ACTIVE
);
htimings
|=
((
info
->
var
.
right_margin
/
4
)
<<
9
)
&
TGA_HORIZ_FP
;
vtimings
|=
(
info
->
var
.
lower_margin
<<
11
)
&
TGA_VERT_FP
;
htimings
|=
((
info
->
var
.
hsync_len
/
4
)
<<
14
)
&
TGA_HORIZ_SYNC
;
vtimings
|=
(
info
->
var
.
vsync_len
<<
16
)
&
TGA_VERT_SYNC
;
htimings
|=
((
info
->
var
.
left_margin
/
4
)
<<
21
)
&
TGA_HORIZ_BP
;
vtimings
|=
(
info
->
var
.
upper_margin
<<
22
)
&
TGA_VERT_BP
;
if
(
current_par_valid
)
if
(
info
->
var
.
sync
&
FB_SYNC_HOR_HIGH_ACT
)
*
par
=
current_par
;
htimings
|=
TGA_HORIZ_POLARITY
;
else
{
if
(
info
->
var
.
sync
&
FB_SYNC_VERT_HIGH_ACT
)
if
(
fb_info
.
tga_type
==
TGA_TYPE_8PLANE
)
vtimings
|=
TGA_VERT_POLARITY
;
default_var
.
bits_per_pixel
=
8
;
else
default_var
.
bits_per_pixel
=
32
;
tgafb_decode_var
(
&
default_var
,
par
,
info
);
par
->
htimings
=
htimings
;
}
par
->
vtimings
=
vtimings
;
}
par
->
sync_on_green
=
!!
(
info
->
var
.
sync
&
FB_SYNC_ON_GREEN
);
static
void
tgafb_set_par
(
const
void
*
fb_par
,
struct
fb_info_gen
*
info
)
/* Store other useful values in par. */
{
par
->
xres
=
info
->
var
.
xres
;
int
i
,
j
;
par
->
yres
=
info
->
var
.
yres
;
struct
tgafb_par
*
par
=
(
struct
tgafb_par
*
)
fb_par
;
par
->
pll_freq
=
pll_freq
=
1000000000
/
info
->
var
.
pixclock
;
par
->
bits_per_pixel
=
info
->
var
.
bits_per_pixel
;
#if 0
tga_type
=
par
->
tga_type
;
/* XXX this will break console switching with X11, maybe I need to test KD_GRAPHICS? */
/* if current_par is valid, check to see if we need to change anything */
if (current_par_valid) {
if (!memcmp(par, ¤t_par, sizeof current_par)) {
return;
}
}
#endif
current_par
=
*
par
;
current_par_valid
=
1
;
/* first, disable video
*/
/* First, disable video.
*/
TGA_WRITE_REG
(
TGA_VALID_VIDEO
|
TGA_VALID_BLANK
,
TGA_VALID_REG
);
TGA_WRITE_REG
(
par
,
TGA_VALID_VIDEO
|
TGA_VALID_BLANK
,
TGA_VALID_REG
);
/* write the DEEP register
*/
/* Write the DEEP register.
*/
while
(
TGA_READ_REG
(
TGA_CMD_STAT_REG
)
&
1
)
/* wait for not busy */
while
(
TGA_READ_REG
(
par
,
TGA_CMD_STAT_REG
)
&
1
)
/* wait for not busy */
continue
;
continue
;
mb
();
mb
();
TGA_WRITE_REG
(
deep_presets
[
fb_info
.
tga_type
],
TGA_DEEP_REG
);
TGA_WRITE_REG
(
par
,
deep_presets
[
tga_type
],
TGA_DEEP_REG
);
while
(
TGA_READ_REG
(
TGA_CMD_STAT_REG
)
&
1
)
/* wait for not busy */
while
(
TGA_READ_REG
(
par
,
TGA_CMD_STAT_REG
)
&
1
)
/* wait for not busy */
continue
;
continue
;
mb
();
mb
();
/* write some more registers
*/
/* Write some more registers.
*/
TGA_WRITE_REG
(
rasterop_presets
[
fb_info
.
tga_type
],
TGA_RASTEROP_REG
);
TGA_WRITE_REG
(
par
,
rasterop_presets
[
tga_type
],
TGA_RASTEROP_REG
);
TGA_WRITE_REG
(
mode_presets
[
fb_info
.
tga_type
],
TGA_MODE_REG
);
TGA_WRITE_REG
(
par
,
mode_presets
[
tga_type
],
TGA_MODE_REG
);
TGA_WRITE_REG
(
base_addr_presets
[
fb_info
.
tga_type
],
TGA_BASE_ADDR_REG
);
TGA_WRITE_REG
(
par
,
base_addr_presets
[
tga_type
],
TGA_BASE_ADDR_REG
);
/* calculate & write the PLL
*/
/* Calculate & write the PLL.
*/
tgafb_set_pll
(
par
->
pll_freq
);
tgafb_set_pll
(
par
,
pll_freq
);
/* write some more registers
*/
/* Write some more registers.
*/
TGA_WRITE_REG
(
0xffffffff
,
TGA_PLANEMASK_REG
);
TGA_WRITE_REG
(
par
,
0xffffffff
,
TGA_PLANEMASK_REG
);
TGA_WRITE_REG
(
0xffffffff
,
TGA_PIXELMASK_REG
);
TGA_WRITE_REG
(
par
,
0xffffffff
,
TGA_PIXELMASK_REG
);
TGA_WRITE_REG
(
0x12345678
,
TGA_BLOCK_COLOR0_REG
);
TGA_WRITE_REG
(
par
,
0x12345678
,
TGA_BLOCK_COLOR0_REG
);
TGA_WRITE_REG
(
0x12345678
,
TGA_BLOCK_COLOR1_REG
);
TGA_WRITE_REG
(
par
,
0x12345678
,
TGA_BLOCK_COLOR1_REG
);
/* init video timing regs
*/
/* Init video timing regs.
*/
TGA_WRITE_REG
(
par
->
htimings
,
TGA_HORIZ_REG
);
TGA_WRITE_REG
(
par
,
htimings
,
TGA_HORIZ_REG
);
TGA_WRITE_REG
(
par
->
vtimings
,
TGA_VERT_REG
);
TGA_WRITE_REG
(
par
,
vtimings
,
TGA_VERT_REG
);
/* initalise RAMDAC
*/
/* Initalise RAMDAC.
*/
if
(
fb_info
.
tga_type
==
TGA_TYPE_8PLANE
)
{
if
(
tga_type
==
TGA_TYPE_8PLANE
)
{
/* init BT485 RAMDAC registers */
/* Init BT485 RAMDAC registers. */
BT485_WRITE
(
0xa2
|
(
par
->
sync_on_green
?
0x8
:
0x0
),
BT485_CMD_0
);
BT485_WRITE
(
par
,
0xa2
|
(
par
->
sync_on_green
?
0x8
:
0x0
),
BT485_WRITE
(
0x01
,
BT485_ADDR_PAL_WRITE
);
BT485_CMD_0
);
BT485_WRITE
(
0x14
,
BT485_CMD_3
);
/* cursor 64x64 */
BT485_WRITE
(
par
,
0x01
,
BT485_ADDR_PAL_WRITE
);
BT485_WRITE
(
0x40
,
BT485_CMD_1
);
BT485_WRITE
(
par
,
0x14
,
BT485_CMD_3
);
/* cursor 64x64 */
BT485_WRITE
(
0x20
,
BT485_CMD_2
);
/* cursor off, for now */
BT485_WRITE
(
par
,
0x40
,
BT485_CMD_1
);
BT485_WRITE
(
0xff
,
BT485_PIXEL_MASK
);
BT485_WRITE
(
par
,
0x20
,
BT485_CMD_2
);
/* cursor off, for now */
BT485_WRITE
(
par
,
0xff
,
BT485_PIXEL_MASK
);
/* fill palette registers
*/
/* Fill palette registers.
*/
BT485_WRITE
(
0x00
,
BT485_ADDR_PAL_WRITE
);
BT485_WRITE
(
par
,
0x00
,
BT485_ADDR_PAL_WRITE
);
TGA_WRITE_REG
(
BT485_DATA_PAL
,
TGA_RAMDAC_SETUP_REG
);
TGA_WRITE_REG
(
par
,
BT485_DATA_PAL
,
TGA_RAMDAC_SETUP_REG
);
for
(
i
=
0
;
i
<
16
;
i
++
)
{
for
(
i
=
0
;
i
<
16
;
i
++
)
{
j
=
color_table
[
i
];
j
=
color_table
[
i
];
TGA_WRITE_REG
(
default_red
[
j
]
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
default_red
[
j
]
|
(
BT485_DATA_PAL
<<
8
),
TGA_WRITE_REG
(
default_grn
[
j
]
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
default_blu
[
j
]
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
default_grn
[
j
]
|
(
BT485_DATA_PAL
<<
8
),
palette
[
i
].
red
=
default_red
[
j
]
;
TGA_RAMDAC_REG
)
;
palette
[
i
].
green
=
default_grn
[
j
];
TGA_WRITE_REG
(
par
,
default_blu
[
j
]
|
(
BT485_DATA_PAL
<<
8
),
palette
[
i
].
blue
=
default_blu
[
j
]
;
TGA_RAMDAC_REG
)
;
}
}
for
(
i
=
0
;
i
<
240
*
3
;
i
+=
4
)
{
for
(
i
=
0
;
i
<
240
*
3
;
i
+=
4
)
{
TGA_WRITE_REG
(
0x55
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
0x55
|
(
BT485_DATA_PAL
<<
8
),
TGA_WRITE_REG
(
0x00
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
0x00
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
0x00
|
(
BT485_DATA_PAL
<<
8
),
TGA_WRITE_REG
(
0x00
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
0x00
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
0x00
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
}
}
}
else
{
/* 24-plane or 24plusZ */
}
else
{
/* 24-plane or 24plusZ */
/* init BT463 registers
*/
/* Init BT463 registers.
*/
BT463_WRITE
(
BT463_REG_ACC
,
BT463_CMD_REG_0
,
0x40
);
BT463_WRITE
(
par
,
BT463_REG_ACC
,
BT463_CMD_REG_0
,
0x40
);
BT463_WRITE
(
BT463_REG_ACC
,
BT463_CMD_REG_1
,
0x08
);
BT463_WRITE
(
par
,
BT463_REG_ACC
,
BT463_CMD_REG_1
,
0x08
);
BT463_WRITE
(
BT463_REG_ACC
,
BT463_CMD_REG_2
,
BT463_WRITE
(
par
,
BT463_REG_ACC
,
BT463_CMD_REG_2
,
(
par
->
sync_on_green
?
0x80
:
0x40
));
(
par
->
sync_on_green
?
0x80
:
0x40
));
BT463_WRITE
(
BT463_REG_ACC
,
BT463_READ_MASK_0
,
0xff
);
BT463_WRITE
(
par
,
BT463_REG_ACC
,
BT463_READ_MASK_0
,
0xff
);
BT463_WRITE
(
BT463_REG_ACC
,
BT463_READ_MASK_1
,
0xff
);
BT463_WRITE
(
par
,
BT463_REG_ACC
,
BT463_READ_MASK_1
,
0xff
);
BT463_WRITE
(
BT463_REG_ACC
,
BT463_READ_MASK_2
,
0xff
);
BT463_WRITE
(
par
,
BT463_REG_ACC
,
BT463_READ_MASK_2
,
0xff
);
BT463_WRITE
(
BT463_REG_ACC
,
BT463_READ_MASK_3
,
0x0f
);
BT463_WRITE
(
par
,
BT463_REG_ACC
,
BT463_READ_MASK_3
,
0x0f
);
BT463_WRITE
(
BT463_REG_ACC
,
BT463_BLINK_MASK_0
,
0x00
);
BT463_WRITE
(
par
,
BT463_REG_ACC
,
BT463_BLINK_MASK_0
,
0x00
);
BT463_WRITE
(
BT463_REG_ACC
,
BT463_BLINK_MASK_1
,
0x00
);
BT463_WRITE
(
par
,
BT463_REG_ACC
,
BT463_BLINK_MASK_1
,
0x00
);
BT463_WRITE
(
BT463_REG_ACC
,
BT463_BLINK_MASK_2
,
0x00
);
BT463_WRITE
(
par
,
BT463_REG_ACC
,
BT463_BLINK_MASK_2
,
0x00
);
BT463_WRITE
(
BT463_REG_ACC
,
BT463_BLINK_MASK_3
,
0x00
);
BT463_WRITE
(
par
,
BT463_REG_ACC
,
BT463_BLINK_MASK_3
,
0x00
);
/* fill the palette
*/
/* Fill the palette.
*/
BT463_LOAD_ADDR
(
0x0000
);
BT463_LOAD_ADDR
(
par
,
0x0000
);
TGA_WRITE_REG
((
BT463_PALETTE
<<
2
)
,
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
BT463_PALETTE
<<
2
,
TGA_RAMDAC_REG
);
for
(
i
=
0
;
i
<
16
;
i
++
)
{
for
(
i
=
0
;
i
<
16
;
i
++
)
{
j
=
color_table
[
i
];
j
=
color_table
[
i
];
TGA_WRITE_REG
(
default_red
[
j
]
|
(
BT463_PALETTE
<<
10
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
default_red
[
j
]
|
(
BT463_PALETTE
<<
10
),
TGA_WRITE_REG
(
default_grn
[
j
]
|
(
BT463_PALETTE
<<
10
),
TGA_RAMDAC_REG
);
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
default_blu
[
j
]
|
(
BT463_PALETTE
<<
10
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
default_grn
[
j
]
|
(
BT463_PALETTE
<<
10
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
default_blu
[
j
]
|
(
BT463_PALETTE
<<
10
),
TGA_RAMDAC_REG
);
}
}
for
(
i
=
0
;
i
<
512
*
3
;
i
+=
4
)
{
for
(
i
=
0
;
i
<
512
*
3
;
i
+=
4
)
{
TGA_WRITE_REG
(
0x55
|
(
BT463_PALETTE
<<
10
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
0x55
|
(
BT463_PALETTE
<<
10
),
TGA_WRITE_REG
(
0x00
|
(
BT463_PALETTE
<<
10
),
TGA_RAMDAC_REG
);
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
0x00
|
(
BT463_PALETTE
<<
10
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
0x00
|
(
BT463_PALETTE
<<
10
),
TGA_WRITE_REG
(
0x00
|
(
BT463_PALETTE
<<
10
),
TGA_RAMDAC_REG
);
TGA_RAMDAC_REG
);
}
TGA_WRITE_REG
(
par
,
0x00
|
(
BT463_PALETTE
<<
10
),
TGA_RAMDAC_REG
);
/* fill window type table after start of vertical retrace */
TGA_WRITE_REG
(
par
,
0x00
|
(
BT463_PALETTE
<<
10
),
while
(
!
(
TGA_READ_REG
(
TGA_INTR_STAT_REG
)
&
0x01
))
TGA_RAMDAC_REG
);
}
/* Fill window type table after start of vertical retrace. */
while
(
!
(
TGA_READ_REG
(
par
,
TGA_INTR_STAT_REG
)
&
0x01
))
continue
;
continue
;
TGA_WRITE_REG
(
0x01
,
TGA_INTR_STAT_REG
);
TGA_WRITE_REG
(
par
,
0x01
,
TGA_INTR_STAT_REG
);
mb
();
mb
();
while
(
!
(
TGA_READ_REG
(
TGA_INTR_STAT_REG
)
&
0x01
))
while
(
!
(
TGA_READ_REG
(
par
,
TGA_INTR_STAT_REG
)
&
0x01
))
continue
;
continue
;
TGA_WRITE_REG
(
0x01
,
TGA_INTR_STAT_REG
);
TGA_WRITE_REG
(
par
,
0x01
,
TGA_INTR_STAT_REG
);
BT463_LOAD_ADDR
(
BT463_WINDOW_TYPE_BASE
);
BT463_LOAD_ADDR
(
par
,
BT463_WINDOW_TYPE_BASE
);
TGA_WRITE_REG
((
BT463_REG_ACC
<<
2
)
,
TGA_RAMDAC_SETUP_REG
);
TGA_WRITE_REG
(
par
,
BT463_REG_ACC
<<
2
,
TGA_RAMDAC_SETUP_REG
);
for
(
i
=
0
;
i
<
16
;
i
++
)
{
for
(
i
=
0
;
i
<
16
;
i
++
)
{
TGA_WRITE_REG
(
0x00
|
(
BT463_REG_ACC
<<
10
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
0x00
|
(
BT463_REG_ACC
<<
10
),
TGA_WRITE_REG
(
0x01
|
(
BT463_REG_ACC
<<
10
),
TGA_RAMDAC_REG
);
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
0x80
|
(
BT463_REG_ACC
<<
10
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
0x01
|
(
BT463_REG_ACC
<<
10
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
0x80
|
(
BT463_REG_ACC
<<
10
),
TGA_RAMDAC_REG
);
}
}
}
}
/* finally, enable video scan
/* Finally, enable video scan (and pray for the monitor... :-) */
(and pray for the monitor... :-) */
TGA_WRITE_REG
(
par
,
TGA_VALID_VIDEO
,
TGA_VALID_REG
);
TGA_WRITE_REG
(
TGA_VALID_VIDEO
,
TGA_VALID_REG
);
}
#define DIFFCHECK(x) { if( m <= 0x3f ) { \
return
0
;
int delta = f - (TGA_PLL_BASE_FREQ * (x)) / (r << shift); \
}
if (delta < 0) delta = -delta; \
if (delta < min_diff) min_diff = delta, vm = m, va = a, vr = r; } }
static
void
tgafb_set_pll
(
int
f
)
#define DIFFCHECK(X) \
do { \
if (m <= 0x3f) { \
int delta = f - (TGA_PLL_BASE_FREQ * (X)) / (r << shift); \
if (delta < 0) \
delta = -delta; \
if (delta < min_diff) \
min_diff = delta, vm = m, va = a, vr = r; \
} \
} while (0)
static
void
tgafb_set_pll
(
struct
tga_par
*
par
,
int
f
)
{
{
int
n
,
shift
,
base
,
min_diff
,
target
;
int
n
,
shift
,
base
,
min_diff
,
target
;
int
r
,
a
,
m
,
vm
=
34
,
va
=
1
,
vr
=
30
;
int
r
,
a
,
m
,
vm
=
34
,
va
=
1
,
vr
=
30
;
for
(
r
=
0
;
r
<
12
;
r
++
)
for
(
r
=
0
;
r
<
12
;
r
++
)
TGA_WRITE_REG
(
!
r
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
!
r
,
TGA_CLOCK_REG
);
if
(
f
>
TGA_PLL_MAX_FREQ
)
if
(
f
>
TGA_PLL_MAX_FREQ
)
f
=
TGA_PLL_MAX_FREQ
;
f
=
TGA_PLL_MAX_FREQ
;
...
@@ -624,51 +344,49 @@ static void tgafb_set_pll(int f)
...
@@ -624,51 +344,49 @@ static void tgafb_set_pll(int f)
else
else
shift
=
2
;
shift
=
2
;
TGA_WRITE_REG
(
shift
&
1
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
shift
&
1
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
shift
>>
1
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
shift
>>
1
,
TGA_CLOCK_REG
);
for
(
r
=
0
;
r
<
10
;
r
++
)
{
for
(
r
=
0
;
r
<
10
;
r
++
)
TGA_WRITE_REG
(
0
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
0
,
TGA_CLOCK_REG
);
}
if
(
f
<=
120000
)
{
if
(
f
<=
120000
)
{
TGA_WRITE_REG
(
0
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
0
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
0
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
0
,
TGA_CLOCK_REG
);
}
}
else
if
(
f
<=
200000
)
{
else
if
(
f
<=
200000
)
{
TGA_WRITE_REG
(
1
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
1
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
0
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
0
,
TGA_CLOCK_REG
);
}
}
else
{
else
{
TGA_WRITE_REG
(
0
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
0
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
1
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
1
,
TGA_CLOCK_REG
);
}
}
TGA_WRITE_REG
(
1
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
1
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
0
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
0
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
0
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
0
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
1
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
1
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
0
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
0
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
1
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
1
,
TGA_CLOCK_REG
);
target
=
(
f
<<
shift
)
/
TGA_PLL_BASE_FREQ
;
target
=
(
f
<<
shift
)
/
TGA_PLL_BASE_FREQ
;
min_diff
=
TGA_PLL_MAX_FREQ
;
min_diff
=
TGA_PLL_MAX_FREQ
;
r
=
7
/
target
;
r
=
7
/
target
;
if
(
!
r
)
if
(
!
r
)
r
=
1
;
r
=
1
;
base
=
target
*
r
;
base
=
target
*
r
;
while
(
base
<
449
)
{
while
(
base
<
449
)
{
for
(
n
=
base
<
7
?
7
:
base
;
n
<
base
+
target
&&
n
<
449
;
n
++
)
{
for
(
n
=
base
<
7
?
7
:
base
;
n
<
base
+
target
&&
n
<
449
;
n
++
)
{
m
=
((
n
+
3
)
/
7
)
-
1
;
m
=
((
n
+
3
)
/
7
)
-
1
;
a
=
0
;
a
=
0
;
DIFFCHECK
((
m
+
1
)
*
7
);
DIFFCHECK
((
m
+
1
)
*
7
);
m
++
;
m
++
;
DIFFCHECK
((
m
+
1
)
*
7
);
DIFFCHECK
((
m
+
1
)
*
7
);
m
=
(
n
/
6
)
-
1
;
m
=
(
n
/
6
)
-
1
;
if
(
(
a
=
n
%
6
))
if
(
(
a
=
n
%
6
))
DIFFCHECK
(
n
);
DIFFCHECK
(
n
);
}
}
r
++
;
r
++
;
base
+=
target
;
base
+=
target
;
...
@@ -676,147 +394,103 @@ static void tgafb_set_pll(int f)
...
@@ -676,147 +394,103 @@ static void tgafb_set_pll(int f)
vr
--
;
vr
--
;
for
(
r
=
0
;
r
<
8
;
r
++
)
{
for
(
r
=
0
;
r
<
8
;
r
++
)
TGA_WRITE_REG
((
vm
>>
r
)
&
1
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
(
par
,
(
vm
>>
r
)
&
1
,
TGA_CLOCK_REG
);
}
for
(
r
=
0
;
r
<
8
;
r
++
)
for
(
r
=
0
;
r
<
8
;
r
++
)
{
TGA_WRITE_REG
(
par
,
(
va
>>
r
)
&
1
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
((
va
>>
r
)
&
1
,
TGA_CLOCK_REG
);
for
(
r
=
0
;
r
<
7
;
r
++
)
}
TGA_WRITE_REG
(
par
,
(
vr
>>
r
)
&
1
,
TGA_CLOCK_REG
);
for
(
r
=
0
;
r
<
7
;
r
++
)
{
TGA_WRITE_REG
(
par
,
((
vr
>>
7
)
&
1
)
|
2
,
TGA_CLOCK_REG
);
TGA_WRITE_REG
((
vr
>>
r
)
&
1
,
TGA_CLOCK_REG
);
}
TGA_WRITE_REG
(((
vr
>>
7
)
&
1
)
|
2
,
TGA_CLOCK_REG
);
}
}
static
int
tgafb_getcolreg
(
u_int
regno
,
u_int
*
red
,
u_int
*
green
,
u_int
*
blue
,
/**
u_int
*
transp
,
struct
fb_info
*
info
)
* tgafb_setcolreg - Optional function. Sets a color register.
* @regno: boolean, 0 copy local, 1 get_user() function
* @red: frame buffer colormap structure
* @green: The green value which can be up to 16 bits wide
* @blue: The blue value which can be up to 16 bits wide.
* @transp: If supported the alpha value which can be up to 16 bits wide.
* @info: frame buffer info structure
*/
static
int
tgafb_setcolreg
(
unsigned
regno
,
unsigned
red
,
unsigned
green
,
unsigned
blue
,
unsigned
transp
,
struct
fb_info
*
info
)
{
{
if
(
regno
>
255
)
struct
tga_par
*
par
=
(
struct
tga_par
*
)
info
->
par
;
return
1
;
*
red
=
(
palette
[
regno
].
red
<<
8
)
|
palette
[
regno
].
red
;
*
green
=
(
palette
[
regno
].
green
<<
8
)
|
palette
[
regno
].
green
;
*
blue
=
(
palette
[
regno
].
blue
<<
8
)
|
palette
[
regno
].
blue
;
*
transp
=
0
;
return
0
;
}
static
int
tgafb_setcolreg
(
u_int
regno
,
u_int
red
,
u_int
green
,
u_int
blue
,
u_int
transp
,
struct
fb_info
*
info
)
{
if
(
regno
>
255
)
if
(
regno
>
255
)
return
1
;
return
1
;
red
>>=
8
;
red
>>=
8
;
green
>>=
8
;
green
>>=
8
;
blue
>>=
8
;
blue
>>=
8
;
palette
[
regno
].
red
=
red
;
palette
[
regno
].
green
=
green
;
palette
[
regno
].
blue
=
blue
;
#ifdef FBCON_HAS_CFB32
if
(
regno
<
16
&&
fb_info
.
tga_type
!=
TGA_TYPE_8PLANE
)
fbcon_cfb32_cmap
[
regno
]
=
(
red
<<
16
)
|
(
green
<<
8
)
|
blue
;
#endif
if
(
fb_info
.
tga_type
==
TGA_TYPE_8PLANE
)
{
if
(
par
->
tga_type
==
TGA_TYPE_8PLANE
)
{
BT485_WRITE
(
regno
,
BT485_ADDR_PAL_WRITE
);
BT485_WRITE
(
par
,
regno
,
BT485_ADDR_PAL_WRITE
);
TGA_WRITE_REG
(
BT485_DATA_PAL
,
TGA_RAMDAC_SETUP_REG
);
TGA_WRITE_REG
(
par
,
BT485_DATA_PAL
,
TGA_RAMDAC_SETUP_REG
);
TGA_WRITE_REG
(
red
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
red
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
green
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
green
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
blue
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
blue
|
(
BT485_DATA_PAL
<<
8
),
TGA_RAMDAC_REG
);
}
else
if
(
regno
<
16
)
{
u32
value
=
(
red
<<
16
)
|
(
green
<<
8
)
|
blue
;
((
u32
*
)
info
->
pseudo_palette
)[
regno
]
=
value
;
}
}
/* How to set a single color register on 24-plane cards?? */
return
0
;
return
0
;
}
}
#if 1
/*
* FIXME: since I don't know how to set a single arbitrary color register
* on 24-plane cards, all color palette registers have to be updated
*/
static
int
tgafb_set_cmap
(
struct
fb_cmap
*
cmap
,
int
kspc
,
int
con
,
struct
fb_info
*
info
)
{
int
err
;
if
(
!
fb_display
[
con
].
cmap
.
len
)
{
/* no colormap allocated? */
/**
if
((
err
=
fb_alloc_cmap
(
&
fb_display
[
con
].
cmap
,
256
,
0
)))
* tgafb_blank - Optional function. Blanks the display.
return
err
;
* @blank_mode: the blank mode we want.
}
* @info: frame buffer structure that represents a single frame buffer
if
(
con
==
info
->
currcon
)
{
/* current console? */
*/
err
=
fb_set_cmap
(
cmap
,
kspc
,
info
);
static
int
#if 1
tgafb_blank
(
int
blank
,
struct
fb_info
*
info
)
if
(
fb_info
.
tga_type
!=
TGA_TYPE_8PLANE
)
tgafb_update_palette
();
#endif
return
err
;
}
else
fb_copy_cmap
(
cmap
,
&
fb_display
[
con
].
cmap
,
kspc
?
0
:
1
);
return
0
;
}
static
void
tgafb_update_palette
(
void
)
{
int
i
;
BT463_LOAD_ADDR
(
0x0000
);
TGA_WRITE_REG
((
BT463_PALETTE
<<
2
),
TGA_RAMDAC_REG
);
for
(
i
=
0
;
i
<
256
;
i
++
)
{
TGA_WRITE_REG
(
palette
[
i
].
red
|
(
BT463_PALETTE
<<
10
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
palette
[
i
].
green
|
(
BT463_PALETTE
<<
10
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
palette
[
i
].
blue
|
(
BT463_PALETTE
<<
10
),
TGA_RAMDAC_REG
);
}
}
#endif
static
int
tgafb_blank
(
int
blank
,
struct
fb_info_gen
*
info
)
{
{
static
int
tga_vesa_blanked
=
0
;
struct
tga_par
*
par
=
(
struct
tga_par
*
)
info
->
par
;
u32
vhcr
,
vvcr
,
vvvr
;
u32
vhcr
,
vvcr
,
vvvr
;
unsigned
long
flags
;
unsigned
long
flags
;
local_irq_save
(
flags
);
local_irq_save
(
flags
);
vhcr
=
TGA_READ_REG
(
TGA_HORIZ_REG
);
vhcr
=
TGA_READ_REG
(
par
,
TGA_HORIZ_REG
);
vvcr
=
TGA_READ_REG
(
TGA_VERT_REG
);
vvcr
=
TGA_READ_REG
(
par
,
TGA_VERT_REG
);
vvvr
=
TGA_READ_REG
(
TGA_VALID_REG
)
&
~
(
TGA_VALID_VIDEO
|
TGA_VALID_BLANK
);
vvvr
=
TGA_READ_REG
(
par
,
TGA_VALID_REG
);
vvvr
&=
~
(
TGA_VALID_VIDEO
|
TGA_VALID_BLANK
);
switch
(
blank
)
{
switch
(
blank
)
{
case
0
:
/* Unblanking */
case
0
:
/* Unblanking */
if
(
tga_
vesa_blanked
)
{
if
(
par
->
vesa_blanked
)
{
TGA_WRITE_REG
(
vhcr
&
0xbfffffff
,
TGA_HORIZ_REG
);
TGA_WRITE_REG
(
par
,
vhcr
&
0xbfffffff
,
TGA_HORIZ_REG
);
TGA_WRITE_REG
(
vvcr
&
0xbfffffff
,
TGA_VERT_REG
);
TGA_WRITE_REG
(
par
,
vvcr
&
0xbfffffff
,
TGA_VERT_REG
);
tga_
vesa_blanked
=
0
;
par
->
vesa_blanked
=
0
;
}
}
TGA_WRITE_REG
(
vvvr
|
TGA_VALID_VIDEO
,
TGA_VALID_REG
);
TGA_WRITE_REG
(
par
,
vvvr
|
TGA_VALID_VIDEO
,
TGA_VALID_REG
);
break
;
break
;
case
1
:
/* Normal blanking */
case
1
:
/* Normal blanking */
TGA_WRITE_REG
(
vvvr
|
TGA_VALID_VIDEO
|
TGA_VALID_BLANK
,
TGA_VALID_REG
);
TGA_WRITE_REG
(
par
,
vvvr
|
TGA_VALID_VIDEO
|
TGA_VALID_BLANK
,
TGA_VALID_REG
);
break
;
break
;
case
2
:
/* VESA blank (vsync off) */
case
2
:
/* VESA blank (vsync off) */
TGA_WRITE_REG
(
vvcr
|
0x40000000
,
TGA_VERT_REG
);
TGA_WRITE_REG
(
par
,
vvcr
|
0x40000000
,
TGA_VERT_REG
);
TGA_WRITE_REG
(
vvvr
|
TGA_VALID_BLANK
,
TGA_VALID_REG
);
TGA_WRITE_REG
(
par
,
vvvr
|
TGA_VALID_BLANK
,
TGA_VALID_REG
);
tga_
vesa_blanked
=
1
;
par
->
vesa_blanked
=
1
;
break
;
break
;
case
3
:
/* VESA blank (hsync off) */
case
3
:
/* VESA blank (hsync off) */
TGA_WRITE_REG
(
vhcr
|
0x40000000
,
TGA_HORIZ_REG
);
TGA_WRITE_REG
(
par
,
vhcr
|
0x40000000
,
TGA_HORIZ_REG
);
TGA_WRITE_REG
(
vvvr
|
TGA_VALID_BLANK
,
TGA_VALID_REG
);
TGA_WRITE_REG
(
par
,
vvvr
|
TGA_VALID_BLANK
,
TGA_VALID_REG
);
tga_
vesa_blanked
=
1
;
par
->
vesa_blanked
=
1
;
break
;
break
;
case
4
:
/* Poweroff */
case
4
:
/* Poweroff */
TGA_WRITE_REG
(
vhcr
|
0x40000000
,
TGA_HORIZ_REG
);
TGA_WRITE_REG
(
par
,
vhcr
|
0x40000000
,
TGA_HORIZ_REG
);
TGA_WRITE_REG
(
vvcr
|
0x40000000
,
TGA_VERT_REG
);
TGA_WRITE_REG
(
par
,
vvcr
|
0x40000000
,
TGA_VERT_REG
);
TGA_WRITE_REG
(
vvvr
|
TGA_VALID_BLANK
,
TGA_VALID_REG
);
TGA_WRITE_REG
(
par
,
vvvr
|
TGA_VALID_BLANK
,
TGA_VALID_REG
);
tga_
vesa_blanked
=
1
;
par
->
vesa_blanked
=
1
;
break
;
break
;
}
}
...
@@ -825,185 +499,227 @@ static int tgafb_blank(int blank, struct fb_info_gen *info)
...
@@ -825,185 +499,227 @@ static int tgafb_blank(int blank, struct fb_info_gen *info)
}
}
static
void
tgafb_set_disp
(
const
void
*
fb_par
,
struct
display
*
disp
,
/*
struct
fb_info_gen
*
info
)
* Initialisation
*/
static
void
tgafb_init_fix
(
struct
fb_info
*
info
)
{
{
switch
(
fb_info
.
tga_type
)
{
struct
tga_par
*
par
=
(
struct
tga_par
*
)
info
->
par
;
#ifdef FBCON_HAS_CFB8
u8
tga_type
=
par
->
tga_type
;
const
char
*
tga_type_name
;
switch
(
tga_type
)
{
case
TGA_TYPE_8PLANE
:
case
TGA_TYPE_8PLANE
:
disp
->
dispsw
=
&
fbcon_cfb8
;
tga_type_name
=
"Digital ZLXp-E1"
;
break
;
break
;
#endif
#ifdef FBCON_HAS_CFB32
case
TGA_TYPE_24PLANE
:
case
TGA_TYPE_24PLANE
:
tga_type_name
=
"Digital ZLXp-E2"
;
break
;
case
TGA_TYPE_24PLUSZ
:
case
TGA_TYPE_24PLUSZ
:
disp
->
dispsw
=
&
fbcon_cfb32
;
tga_type_name
=
"Digital ZLXp-E3"
;
disp
->
dispsw_data
=
&
fbcon_cfb32_cmap
;
break
;
break
;
#endif
default:
default:
disp
->
dispsw
=
&
fbcon_dummy
;
tga_type_name
=
"Unknown"
;
break
;
}
}
disp
->
scrollmode
=
SCROLL_YREDRAW
;
strncpy
(
info
->
fix
.
id
,
tga_type_name
,
sizeof
(
info
->
fix
.
id
)
-
1
)
;
}
info
->
fix
.
id
[
sizeof
(
info
->
fix
.
id
)
-
1
]
=
0
;
info
->
fix
.
type
=
FB_TYPE_PACKED_PIXELS
;
info
->
fix
.
type_aux
=
0
;
info
->
fix
.
visual
=
(
tga_type
==
TGA_TYPE_8PLANE
?
FB_VISUAL_PSEUDOCOLOR
:
FB_VISUAL_TRUECOLOR
);
struct
fbgen_hwswitch
tgafb_hwswitch
=
{
info
->
fix
.
line_length
=
par
->
xres
*
(
par
->
bits_per_pixel
>>
3
);
tgafb_detect
,
tgafb_encode_fix
,
tgafb_decode_var
,
tgafb_encode_var
,
tgafb_get_par
,
info
->
fix
.
smem_start
=
(
size_t
)
par
->
tga_fb_base
;
tgafb_set_par
,
tgafb_getcolreg
,
NULL
,
tgafb_blank
,
info
->
fix
.
smem_len
=
info
->
fix
.
line_length
*
par
->
yres
;
tgafb_set_disp
info
->
fix
.
mmio_start
=
(
size_t
)
par
->
tga_regs_base
;
};
info
->
fix
.
mmio_len
=
0x1000
;
/* Is this sufficient? */
/*
* Hardware Independent functions
*/
info
->
fix
.
xpanstep
=
0
;
info
->
fix
.
ypanstep
=
0
;
info
->
fix
.
ywrapstep
=
0
;
/*
info
->
fix
.
accel
=
FB_ACCEL_DEC_TGA
;
* Frame buffer operations
}
*/
static
struct
fb_ops
tgafb_ops
=
{
.
owner
=
THIS_MODULE
,
.
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
=
tgafb_set_cmap
,
.
fb_setcolreg
=
tgafb_setcolreg
,
.
fb_blank
=
fbgen_blank
,
};
#ifndef MODULE
/*
* Setup
*/
int
__init
tgafb_setup
(
char
*
options
)
{
char
*
this_opt
;
int
i
;
if
(
options
&&
*
options
)
{
static
__devinit
int
while
((
this_opt
=
strsep
(
&
options
,
","
))
!=
NULL
)
{
tgafb_pci_register
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
)
if
(
!*
this_opt
)
{
continue
;
}
{
static
unsigned
int
const
fb_offset_presets
[
4
]
=
{
TGA_8PLANE_FB_OFFSET
,
TGA_24PLANE_FB_OFFSET
,
0xffffffff
,
TGA_24PLUSZ_FB_OFFSET
};
struct
all_info
{
struct
fb_info
info
;
struct
tga_par
par
;
u32
pseudo_palette
[
16
];
}
*
all
;
void
*
mem_base
;
unsigned
long
bar0_start
,
bar0_len
;
u8
tga_type
;
int
ret
;
/* Enable device in PCI config. */
if
(
pci_enable_device
(
pdev
))
{
printk
(
KERN_ERR
"tgafb: Cannot enable PCI device
\n
"
);
return
-
ENODEV
;
}
/* Allocate the fb and par structures. */
all
=
kmalloc
(
sizeof
(
*
all
),
GFP_KERNEL
);
if
(
!
all
)
{
printk
(
KERN_ERR
"tgafb: Cannot allocate memory
\n
"
);
return
-
ENOMEM
;
}
memset
(
all
,
0
,
sizeof
(
*
all
));
pci_set_drvdata
(
pdev
,
all
);
/* Request the mem regions. */
bar0_start
=
pci_resource_start
(
pdev
,
0
);
bar0_len
=
pci_resource_len
(
pdev
,
0
);
ret
=
-
ENODEV
;
if
(
!
request_mem_region
(
bar0_start
,
bar0_len
,
"tgafb"
))
{
printk
(
KERN_ERR
"tgafb: cannot reserve FB region
\n
"
);
goto
err0
;
}
/* Map the framebuffer. */
mem_base
=
ioremap
(
bar0_start
,
bar0_len
);
if
(
!
mem_base
)
{
printk
(
KERN_ERR
"tgafb: Cannot map MMIO
\n
"
);
goto
err1
;
}
/* Grab info about the card. */
tga_type
=
(
readl
(
mem_base
)
>>
12
)
&
0x0f
;
all
->
par
.
pdev
=
pdev
;
all
->
par
.
tga_mem_base
=
mem_base
;
all
->
par
.
tga_fb_base
=
mem_base
+
fb_offset_presets
[
tga_type
];
all
->
par
.
tga_regs_base
=
mem_base
+
TGA_REGS_OFFSET
;
all
->
par
.
tga_type
=
tga_type
;
pci_read_config_byte
(
pdev
,
PCI_REVISION_ID
,
&
all
->
par
.
tga_chip_rev
);
/* Setup framebuffer. */
all
->
info
.
node
=
NODEV
;
all
->
info
.
flags
=
FBINFO_FLAG_DEFAULT
;
all
->
info
.
fbops
=
&
tgafb_ops
;
all
->
info
.
screen_base
=
(
char
*
)
all
->
par
.
tga_fb_base
;
all
->
info
.
currcon
=
-
1
;
all
->
info
.
par
=
&
all
->
par
;
all
->
info
.
pseudo_palette
=
all
->
pseudo_palette
;
/* This should give a reasonable default video mode. */
ret
=
fb_find_mode
(
&
all
->
info
.
var
,
&
all
->
info
,
mode_option
,
NULL
,
0
,
NULL
,
tga_type
==
TGA_TYPE_8PLANE
?
8
:
32
);
if
(
ret
==
0
||
ret
==
4
)
{
printk
(
KERN_ERR
"tgafb: Could not find valid video mode
\n
"
);
ret
=
-
EINVAL
;
goto
err1
;
}
if
(
fb_alloc_cmap
(
&
all
->
info
.
cmap
,
256
,
0
))
{
printk
(
KERN_ERR
"tgafb: Could not allocate color map
\n
"
);
ret
=
-
ENOMEM
;
goto
err1
;
}
tgafb_set_par
(
&
all
->
info
);
tgafb_init_fix
(
&
all
->
info
);
if
(
register_framebuffer
(
&
all
->
info
)
<
0
)
{
printk
(
KERN_ERR
"tgafb: Could not register framebuffer
\n
"
);
ret
=
-
EINVAL
;
goto
err1
;
}
printk
(
KERN_INFO
"tgafb: DC21030 [TGA] detected, rev=0x%02x
\n
"
,
all
->
par
.
tga_chip_rev
);
printk
(
KERN_INFO
"tgafb: at PCI bus %d, device %d, function %d
\n
"
,
pdev
->
bus
->
number
,
PCI_SLOT
(
pdev
->
devfn
),
PCI_FUNC
(
pdev
->
devfn
));
printk
(
KERN_INFO
"fb%d: %s frame buffer device at 0x%lx
\n
"
,
minor
(
all
->
info
.
node
),
all
->
info
.
fix
.
id
,
bar0_start
);
if
(
!
strncmp
(
this_opt
,
"font:"
,
5
))
{
return
0
;
strncpy
(
default_fontname
,
this_opt
+
5
,
sizeof
default_fontname
);
}
else
if
(
!
strncmp
(
this_opt
,
"mode:"
,
5
))
{
err1:
for
(
i
=
0
;
i
<
NUM_TOTAL_MODES
;
i
++
)
{
release_mem_region
(
bar0_start
,
bar0_len
);
if
(
!
strcmp
(
this_opt
+
5
,
tgafb_predefined
[
i
].
name
))
err0:
default_var
=
tgafb_predefined
[
i
].
var
;
kfree
(
all
);
default_var_valid
=
1
;
return
ret
;
}
}
}
else
{
int
__init
printk
(
KERN_ERR
"tgafb: unknown parameter %s
\n
"
,
this_opt
);
tgafb_init
(
void
)
}
{
}
return
pci_module_init
(
&
tgafb_driver
);
}
return
0
;
}
}
#endif
#ifdef MODULE
static
void
__exit
tgafb_pci_unregister
(
struct
pci_dev
*
pdev
)
{
struct
fb_info
*
info
=
pci_get_drvdata
(
pdev
);
struct
tga_par
*
par
=
info
->
par
;
/*
if
(
!
info
)
* Initialisation
return
;
*/
unregister_framebuffer
(
info
);
iounmap
(
par
->
tga_mem_base
);
release_mem_region
(
pci_resource_start
(
pdev
,
0
),
pci_resource_len
(
pdev
,
0
));
kfree
(
info
);
}
int
__init
tgafb_init
(
void
)
static
void
__exit
tgafb_exit
(
void
)
{
{
struct
pci_dev
*
pdev
;
pci_unregister_driver
(
&
tgafb_driver
);
}
pdev
=
pci_find_device
(
PCI_VENDOR_ID_DEC
,
PCI_DEVICE_ID_DEC_TGA
,
NULL
);
#endif
/* MODULE */
if
(
!
pdev
)
return
-
ENXIO
;
/* divine board type */
fb_info
.
tga_mem_base
=
(
unsigned
long
)
ioremap
(
pdev
->
resource
[
0
].
start
,
0
);
fb_info
.
tga_type
=
(
readl
(
fb_info
.
tga_mem_base
)
>>
12
)
&
0x0f
;
fb_info
.
tga_regs_base
=
fb_info
.
tga_mem_base
+
TGA_REGS_OFFSET
;
fb_info
.
tga_fb_base
=
(
fb_info
.
tga_mem_base
+
fb_offset_presets
[
fb_info
.
tga_type
]);
pci_read_config_byte
(
pdev
,
PCI_REVISION_ID
,
&
fb_info
.
tga_chip_rev
);
/* setup framebuffer */
fb_info
.
gen
.
info
.
node
=
NODEV
;
fb_info
.
gen
.
info
.
flags
=
FBINFO_FLAG_DEFAULT
;
fb_info
.
gen
.
info
.
fbops
=
&
tgafb_ops
;
fb_info
.
gen
.
info
.
screen_base
=
(
char
*
)
fb_info
.
tga_fb_base
;
fb_info
.
gen
.
info
.
disp
=
&
disp
;
fb_info
.
gen
.
info
.
currcon
=
-
1
;
fb_info
.
gen
.
info
.
changevar
=
NULL
;
fb_info
.
gen
.
info
.
switch_con
=
&
fbgen_switch
;
fb_info
.
gen
.
info
.
updatevar
=
&
fbgen_update_var
;
strcpy
(
fb_info
.
gen
.
info
.
fontname
,
default_fontname
);
fb_info
.
gen
.
parsize
=
sizeof
(
struct
tgafb_par
);
fb_info
.
gen
.
fbhw
=
&
tgafb_hwswitch
;
fb_info
.
gen
.
fbhw
->
detect
();
printk
(
KERN_INFO
"tgafb: DC21030 [TGA] detected, rev=0x%02x
\n
"
,
fb_info
.
tga_chip_rev
);
printk
(
KERN_INFO
"tgafb: at PCI bus %d, device %d, function %d
\n
"
,
pdev
->
bus
->
number
,
PCI_SLOT
(
pdev
->
devfn
),
PCI_FUNC
(
pdev
->
devfn
));
switch
(
fb_info
.
tga_type
)
{
case
TGA_TYPE_8PLANE
:
strcpy
(
fb_info
.
gen
.
info
.
modename
,
"Digital ZLXp-E1"
);
break
;
case
TGA_TYPE_24PLANE
:
#ifndef MODULE
strcpy
(
fb_info
.
gen
.
info
.
modename
,
"Digital ZLXp-E2"
);
int
__init
break
;
tgafb_setup
(
char
*
arg
)
{
char
*
this_opt
;
case
TGA_TYPE_24PLUSZ
:
if
(
arg
&&
*
arg
)
{
strcpy
(
fb_info
.
gen
.
info
.
modename
,
"Digital ZLXp-E3"
);
while
((
this_opt
=
strsep
(
&
arg
,
","
)))
{
break
;
if
(
!*
this_opt
)
continue
;
if
(
!
strncmp
(
this_opt
,
"mode:"
,
5
))
mode_option
=
this_opt
+
5
;
else
printk
(
KERN_ERR
"tgafb: unknown parameter %s
\n
"
,
this_opt
);
}
}
/* This should give a reasonable default video mode */
if
(
!
default_var_valid
)
{
default_var
=
tgafb_predefined
[
0
].
var
;
}
}
fbgen_get_var
(
&
disp
.
var
,
-
1
,
&
fb_info
.
gen
.
info
);
disp
.
var
.
activate
=
FB_ACTIVATE_NOW
;
fbgen_do_set_var
(
&
disp
.
var
,
1
,
&
fb_info
.
gen
);
fbgen_set_disp
(
-
1
,
&
fb_info
.
gen
);
do_install_cmap
(
0
,
&
fb_info
.
gen
);
if
(
register_framebuffer
(
&
fb_info
.
gen
.
info
)
<
0
)
return
-
EINVAL
;
printk
(
KERN_INFO
"fb%d: %s frame buffer device at 0x%lx
\n
"
,
minor
(
fb_info
.
gen
.
info
.
node
),
fb_info
.
gen
.
info
.
modename
,
pdev
->
resource
[
0
].
start
);
return
0
;
}
return
0
;
/*
* Cleanup
*/
void
__exit
tgafb_cleanup
(
void
)
{
unregister_framebuffer
(
&
fb_info
.
gen
.
info
);
}
}
#endif
/* !MODULE */
/*
/*
* Modularisation
* Modularisation
*/
*/
#ifdef MODULE
#ifdef MODULE
MODULE_LICENSE
(
"GPL"
);
module_init
(
tgafb_init
);
module_init
(
tgafb_init
);
module_exit
(
tgafb_exit
);
#endif
#endif
module_exit
(
tgafb_cleanup
);
MODULE_DESCRIPTION
(
"framebuffer driver for TGA chipset"
);
MODULE_LICENSE
(
"GPL"
);
include/linux/fb.h
View file @
d335b16a
...
@@ -424,9 +424,11 @@ struct fb_info {
...
@@ -424,9 +424,11 @@ struct fb_info {
#define fb_readb __raw_readb
#define fb_readb __raw_readb
#define fb_readw __raw_readw
#define fb_readw __raw_readw
#define fb_readl __raw_readl
#define fb_readl __raw_readl
#define fb_readq __raw_readq
#define fb_writeb __raw_writeb
#define fb_writeb __raw_writeb
#define fb_writew __raw_writew
#define fb_writew __raw_writew
#define fb_writel __raw_writel
#define fb_writel __raw_writel
#define fb_writeq __raw_writeq
#define fb_memset memset_io
#define fb_memset memset_io
#else
#else
...
...
drivers
/video/tgafb.h
→
include
/video/tgafb.h
View file @
d335b16a
...
@@ -13,7 +13,7 @@
...
@@ -13,7 +13,7 @@
#ifndef TGAFB_H
#ifndef TGAFB_H
#define TGAFB_H
#define TGAFB_H
/*
/*
* TGA hardware description (minimal)
* TGA hardware description (minimal)
*/
*/
...
@@ -21,7 +21,7 @@
...
@@ -21,7 +21,7 @@
#define TGA_TYPE_24PLANE 1
#define TGA_TYPE_24PLANE 1
#define TGA_TYPE_24PLUSZ 3
#define TGA_TYPE_24PLUSZ 3
/*
/*
* Offsets within Memory Space
* Offsets within Memory Space
*/
*/
...
@@ -52,8 +52,8 @@
...
@@ -52,8 +52,8 @@
#define TGA_CMD_STAT_REG 0x01f8
#define TGA_CMD_STAT_REG 0x01f8
/*
/*
* u
seful defines for managing the registers
* U
seful defines for managing the registers
*/
*/
#define TGA_HORIZ_ODD 0x80000000
#define TGA_HORIZ_ODD 0x80000000
...
@@ -77,16 +77,16 @@
...
@@ -77,16 +77,16 @@
#define TGA_VALID_CURSOR 0x04
#define TGA_VALID_CURSOR 0x04
/*
/*
* u
seful defines for managing the ICS1562 PLL clock
* U
seful defines for managing the ICS1562 PLL clock
*/
*/
#define TGA_PLL_BASE_FREQ 14318
/* .18 */
#define TGA_PLL_BASE_FREQ 14318
/* .18 */
#define TGA_PLL_MAX_FREQ 230000
#define TGA_PLL_MAX_FREQ 230000
/*
/*
* u
seful defines for managing the BT485 on the 8-plane TGA
* U
seful defines for managing the BT485 on the 8-plane TGA
*/
*/
#define BT485_READ_BIT 0x01
#define BT485_READ_BIT 0x01
...
@@ -111,8 +111,8 @@
...
@@ -111,8 +111,8 @@
#define BT485_CUR_HIGH_Y 0x1e
#define BT485_CUR_HIGH_Y 0x1e
/*
/*
* u
seful defines for managing the BT463 on the 24-plane TGAs
* U
seful defines for managing the BT463 on the 24-plane TGAs
*/
*/
#define BT463_ADDR_LO 0x0
#define BT463_ADDR_LO 0x0
...
@@ -139,55 +139,25 @@
...
@@ -139,55 +139,25 @@
#define BT463_WINDOW_TYPE_BASE 0x0300
#define BT463_WINDOW_TYPE_BASE 0x0300
/*
/*
* The framebuffer driver private data.
* Macros for reading/writing TGA and RAMDAC registers
*/
#define TGA_WRITE_REG(v,r) \
{ writel((v), fb_info.tga_regs_base+(r)); mb(); }
#define TGA_READ_REG(r) readl(fb_info.tga_regs_base+(r))
#define BT485_WRITE(v,r) \
TGA_WRITE_REG((r),TGA_RAMDAC_SETUP_REG); \
TGA_WRITE_REG(((v)&0xff)|((r)<<8),TGA_RAMDAC_REG);
#define BT463_LOAD_ADDR(a) \
TGA_WRITE_REG(BT463_ADDR_LO<<2, TGA_RAMDAC_SETUP_REG); \
TGA_WRITE_REG((BT463_ADDR_LO<<10)|((a)&0xff), TGA_RAMDAC_REG); \
TGA_WRITE_REG(BT463_ADDR_HI<<2, TGA_RAMDAC_SETUP_REG); \
TGA_WRITE_REG((BT463_ADDR_HI<<10)|(((a)>>8)&0xff), TGA_RAMDAC_REG);
#define BT463_WRITE(m,a,v) \
BT463_LOAD_ADDR((a)); \
TGA_WRITE_REG(((m)<<2),TGA_RAMDAC_SETUP_REG); \
TGA_WRITE_REG(((m)<<10)|((v)&0xff),TGA_RAMDAC_REG);
/*
* This structure describes the board.
*/
*/
struct
tga
fb_info
{
struct
tga
_par
{
/* Use the generic framebuffer ops
*/
/* PCI device.
*/
struct
fb_info_gen
gen
;
struct
pci_dev
*
pdev
;
/* Device dependent information */
/* Device dependent information. */
void
*
tga_mem_base
;
void
*
tga_fb_base
;
void
*
tga_regs_base
;
u8
tga_type
;
/* TGA_TYPE_XXX */
u8
tga_type
;
/* TGA_TYPE_XXX */
u8
tga_chip_rev
;
/* dc21030 revision */
u8
tga_chip_rev
;
/* dc21030 revision */
u64
tga_mem_base
;
u64
tga_fb_base
;
u64
tga_regs_base
;
struct
fb_var_screeninfo
default_var
;
/* default video mode */
};
/*
/* Remember blank mode. */
* This structure uniquely defines a video mode.
u8
vesa_blanked
;
*/
struct
tgafb_par
{
/* Define the video mode. */
u32
xres
,
yres
;
/* resolution in pixels */
u32
xres
,
yres
;
/* resolution in pixels */
u32
htimings
;
/* horizontal timing register */
u32
htimings
;
/* horizontal timing register */
u32
vtimings
;
/* vertical timing register */
u32
vtimings
;
/* vertical timing register */
...
@@ -196,4 +166,45 @@ struct tgafb_par {
...
@@ -196,4 +166,45 @@ struct tgafb_par {
u32
sync_on_green
;
/* set if sync is on green */
u32
sync_on_green
;
/* set if sync is on green */
};
};
/*
* Macros for reading/writing TGA and RAMDAC registers
*/
static
inline
void
TGA_WRITE_REG
(
struct
tga_par
*
par
,
u32
v
,
u32
r
)
{
writel
(
v
,
par
->
tga_regs_base
+
r
);
}
static
inline
u32
TGA_READ_REG
(
struct
tga_par
*
par
,
u32
r
)
{
return
readl
(
par
->
tga_regs_base
+
r
);
}
static
inline
void
BT485_WRITE
(
struct
tga_par
*
par
,
u8
v
,
u8
r
)
{
TGA_WRITE_REG
(
par
,
r
,
TGA_RAMDAC_SETUP_REG
);
TGA_WRITE_REG
(
par
,
v
|
(
r
<<
8
),
TGA_RAMDAC_REG
);
}
static
inline
void
BT463_LOAD_ADDR
(
struct
tga_par
*
par
,
u16
a
)
{
TGA_WRITE_REG
(
par
,
BT463_ADDR_LO
<<
2
,
TGA_RAMDAC_SETUP_REG
);
TGA_WRITE_REG
(
par
,
(
BT463_ADDR_LO
<<
10
)
|
(
a
&
0xff
),
TGA_RAMDAC_REG
);
TGA_WRITE_REG
(
par
,
BT463_ADDR_HI
<<
2
,
TGA_RAMDAC_SETUP_REG
);
TGA_WRITE_REG
(
par
,
(
BT463_ADDR_HI
<<
10
)
|
(
a
>>
8
),
TGA_RAMDAC_REG
);
}
static
inline
void
BT463_WRITE
(
struct
tga_par
*
par
,
u32
m
,
u16
a
,
u8
v
)
{
BT463_LOAD_ADDR
(
par
,
a
);
TGA_WRITE_REG
(
par
,
m
<<
2
,
TGA_RAMDAC_SETUP_REG
);
TGA_WRITE_REG
(
par
,
m
<<
10
|
v
,
TGA_RAMDAC_REG
);
}
#endif
/* TGAFB_H */
#endif
/* TGAFB_H */
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