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
nexedi
linux
Commits
85fa8aa4
Commit
85fa8aa4
authored
Nov 22, 2002
by
James Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Ported Mach64 and NVIDIA driver to final api. A bunch of improvements and bug fixes.
parent
4a20b66c
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1005 additions
and
1572 deletions
+1005
-1572
drivers/video/Kconfig
drivers/video/Kconfig
+33
-37
drivers/video/aty/atyfb.h
drivers/video/aty/atyfb.h
+1
-17
drivers/video/aty/atyfb_base.c
drivers/video/aty/atyfb_base.c
+46
-56
drivers/video/aty/mach64_cursor.c
drivers/video/aty/mach64_cursor.c
+42
-111
drivers/video/aty128fb.c
drivers/video/aty128fb.c
+184
-240
drivers/video/console/Kconfig
drivers/video/console/Kconfig
+0
-6
drivers/video/console/Makefile
drivers/video/console/Makefile
+1
-2
drivers/video/neofb.c
drivers/video/neofb.c
+2
-1
drivers/video/riva/fbdev.c
drivers/video/riva/fbdev.c
+514
-1021
drivers/video/riva/riva_hw.h
drivers/video/riva/riva_hw.h
+1
-0
drivers/video/riva/rivafb.h
drivers/video/riva/rivafb.h
+1
-45
drivers/video/sgivwfb.c
drivers/video/sgivwfb.c
+21
-19
drivers/video/tdfxfb.c
drivers/video/tdfxfb.c
+158
-16
include/linux/fb.h
include/linux/fb.h
+1
-1
No files found.
drivers/video/Kconfig
View file @
85fa8aa4
...
...
@@ -233,33 +233,6 @@ config FB_ATARI
This is the frame buffer device driver for the builtin graphics
chipset found in Ataris.
config FB_ATY
tristate "ATI Mach64 display support" if PCI
depends on FB
help
This driver supports graphics boards with the ATI Mach64 chips.
Say Y if you have such a graphics board.
The driver is also available as a module ( = code which can be
inserted and removed from the running kernel whenever you want). The
module will be called atyfb.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
config FB_ATY
prompt "ATI Mach64 display support"
depends on FB && (SPARC64 && PCI && FB_PCI || ATARI)
config FB_ATY_GX
bool "Mach64 GX support" if PCI
depends on FB_ATY
default y if ATARI
help
Say Y here to support use of the ATI Mach64 Graphics Expression
board (or other boards based on the Mach64 GX chipset) as a
framebuffer device. The ATI product support page for these boards
is at
<http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
config FB_OF
bool "Open Firmware frame buffer device support"
depends on FB && PPC && ALL_PPC
...
...
@@ -649,16 +622,6 @@ config FB_MATROX_MULTIHEAD
There is no need for enabling 'Matrox multihead support' if you have
only one Matrox card in the box.
config FB_ATY_CT
bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
depends on PCI && FB_ATY
default y if SPARC64 && FB_PCI
help
Say Y here to support use of ATI's 64-bit Rage boards (or other
boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
framebuffer device. The ATI product support page for these boards
is at <http://support.ati.com/products/pc/mach64/>.
config FB_RADEON
tristate "ATI Radeon display support"
depends on FB && PCI
...
...
@@ -682,6 +645,39 @@ config FB_ATY128
module will be called aty128fb.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
config FB_ATY
tristate "ATI Mach64 display support" if PCI || ATARI
depends on FB
help
This driver supports graphics boards with the ATI Mach64 chips.
Say Y if you have such a graphics board.
The driver is also available as a module ( = code which can be
inserted and removed from the running kernel whenever you want). The
module will be called atyfb.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
config FB_ATY_CT
bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
depends on PCI && FB_ATY
default y if SPARC64 && FB_PCI
help
Say Y here to support use of ATI's 64-bit Rage boards (or other
boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
framebuffer device. The ATI product support page for these boards
is at <http://support.ati.com/products/pc/mach64/>.
config FB_ATY_GX
bool "Mach64 GX support" if PCI
depends on FB_ATY
default y if ATARI
help
Say Y here to support use of the ATI Mach64 Graphics Expression
board (or other boards based on the Mach64 GX chipset) as a
framebuffer device. The ATI product support page for these boards
is at
<http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
config FB_SIS
tristate "SIS acceleration"
depends on FB && PCI
...
...
drivers/video/aty/atyfb.h
View file @
85fa8aa4
...
...
@@ -3,8 +3,6 @@
*/
#include <linux/config.h>
#include <video/fbcon.h>
/*
* Elements of the hardware specific atyfb_par structure
*/
...
...
@@ -59,19 +57,9 @@ union aty_pll {
*/
struct
aty_cursor
{
int
enable
;
int
on
;
int
vbl_cnt
;
int
blink_rate
;
u32
offset
;
struct
{
u16
x
,
y
;
}
pos
,
hot
,
size
;
u32
color
[
2
];
u8
bits
[
8
][
64
];
u8
mask
[
8
][
64
];
u8
*
ram
;
struct
timer_list
*
timer
;
};
struct
atyfb_par
{
...
...
@@ -93,8 +81,6 @@ struct atyfb_par {
u8
blitter_may_be_busy
;
#ifdef __sparc__
struct
pci_mmap_map
*
mmap_map
;
int
consolecnt
;
int
vtconsole
;
u8
mmaped
;
int
open
;
#endif
...
...
@@ -251,11 +237,9 @@ extern void aty_calc_pll_ct(const struct fb_info *info,
*/
extern
struct
aty_cursor
*
aty_init_cursor
(
struct
fb_info
*
info
);
extern
void
atyfb_cursor
(
struct
display
*
p
,
int
mode
,
int
x
,
int
y
);
extern
int
atyfb_cursor
(
struct
fb_info
*
info
,
struct
fb_cursor
*
cursor
);
extern
void
aty_set_cursor_color
(
struct
fb_info
*
info
);
extern
void
aty_set_cursor_shape
(
struct
fb_info
*
info
);
extern
int
atyfb_set_font
(
struct
display
*
d
,
int
width
,
int
height
);
/*
* Hardware acceleration
...
...
drivers/video/aty/atyfb_base.c
View file @
85fa8aa4
...
...
@@ -208,10 +208,11 @@ static struct fb_ops atyfb_ops = {
.
fb_fillrect
=
atyfb_fillrect
,
.
fb_copyarea
=
atyfb_copyarea
,
.
fb_imageblit
=
atyfb_imageblit
,
.
fb_cursor
=
cfb_cursor
,
#ifdef __sparc__
.
fb_mmap
=
atyfb_mmap
,
#endif
.
fb_
rasterimg
=
atyfb_rasterimg
,
.
fb_
sync
=
atyfb_sync
,
};
static
char
curblink
__initdata
=
1
;
...
...
@@ -681,13 +682,6 @@ static int aty_crtc_to_var(const struct crtc *crtc,
(
v_sync_pol
?
0
:
FB_SYNC_VERT_HIGH_ACT
)
|
(
c_sync
?
FB_SYNC_COMP_HIGH_ACT
:
0
);
var
->
red
.
msb_right
=
0
;
var
->
green
.
msb_right
=
0
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
msb_right
=
0
;
var
->
transp
.
offset
=
0
;
var
->
transp
.
length
=
0
;
var
->
transp
.
msb_right
=
0
;
switch
(
pix_width
)
{
#if 0
case CRTC_PIX_WIDTH_4BPP:
...
...
@@ -696,7 +690,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var->red.length = 8;
var->green.offset = 0;
var->green.length = 8;
var->blue.offset = 0;
var->blue.length = 8;
var->transp.offset = 0;
var->transp.length = 0;
break;
#endif
case
CRTC_PIX_WIDTH_8BPP
:
...
...
@@ -705,7 +702,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var
->
red
.
length
=
8
;
var
->
green
.
offset
=
0
;
var
->
green
.
length
=
8
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
8
;
var
->
transp
.
offset
=
0
;
var
->
transp
.
length
=
0
;
break
;
case
CRTC_PIX_WIDTH_15BPP
:
/* RGB 555 */
bpp
=
16
;
...
...
@@ -713,7 +713,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var
->
red
.
length
=
5
;
var
->
green
.
offset
=
5
;
var
->
green
.
length
=
5
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
5
;
var
->
transp
.
offset
=
0
;
var
->
transp
.
length
=
0
;
break
;
#if 0
case CRTC_PIX_WIDTH_16BPP: /* RGB 565 */
...
...
@@ -722,7 +725,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var->red.length = 5;
var->green.offset = 5;
var->green.length = 6;
var->blue.offset = 0;
var->blue.length = 5;
var->transp.offset = 0;
var->transp.length = 0;
break;
#endif
case
CRTC_PIX_WIDTH_24BPP
:
/* RGB 888 */
...
...
@@ -731,7 +737,10 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var
->
red
.
length
=
8
;
var
->
green
.
offset
=
8
;
var
->
green
.
length
=
8
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
8
;
var
->
transp
.
offset
=
0
;
var
->
transp
.
length
=
0
;
break
;
case
CRTC_PIX_WIDTH_32BPP
:
/* ARGB 8888 */
bpp
=
32
;
...
...
@@ -739,6 +748,7 @@ static int aty_crtc_to_var(const struct crtc *crtc,
var
->
red
.
length
=
8
;
var
->
green
.
offset
=
8
;
var
->
green
.
length
=
8
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
8
;
var
->
transp
.
offset
=
24
;
var
->
transp
.
length
=
8
;
...
...
@@ -848,7 +858,8 @@ static int atyfb_set_par(struct fb_info *info)
#ifdef CONFIG_BOOTX_TEXT
btext_update_display
(
info
->
fix
.
smem_start
,
(((
par
->
crtc
.
h_tot_disp
>>
16
)
&
0xff
)
+
1
)
*
8
,
(((
par
->
crtc
.
h_tot_disp
>>
16
)
&
0xff
)
+
1
)
*
8
,
((
par
->
crtc
.
v_tot_disp
>>
16
)
&
0x7ff
)
+
1
,
info
->
var
.
bits_per_pixel
,
par
->
crtc
.
vxres
*
info
->
var
.
bits_per_pixel
/
8
);
...
...
@@ -882,13 +893,14 @@ static int atyfb_encode_var(struct fb_var_screeninfo *var,
{
int
err
;
memset
(
var
,
0
,
sizeof
(
struct
fb_var_screeninfo
));
if
((
err
=
aty_crtc_to_var
(
&
par
->
crtc
,
var
)))
return
err
;
var
->
pixclock
=
par
->
pll_ops
->
pll_to_var
(
info
,
&
par
->
pll
);
var
->
height
=
-
1
;
var
->
width
=
-
1
;
var
->
nonstd
=
0
;
return
0
;
}
...
...
@@ -920,9 +932,6 @@ static int atyfb_open(struct fb_info *info, int user)
if
(
user
)
{
par
->
open
++
;
par
->
mmaped
=
0
;
par
->
vtconsole
=
-
1
;
}
else
{
par
->
consolecnt
++
;
}
#endif
return
(
0
);
...
...
@@ -949,9 +958,6 @@ static int atyfb_release(struct fb_info *info, int user)
int
was_mmaped
=
par
->
mmaped
;
par
->
mmaped
=
0
;
if
(
par
->
vtconsole
!=
-
1
)
vt_cons
[
par
->
vtconsole
]
->
vc_mode
=
KD_TEXT
;
par
->
vtconsole
=
-
1
;
if
(
was_mmaped
)
{
struct
fb_var_screeninfo
var
;
...
...
@@ -981,8 +987,6 @@ static int atyfb_release(struct fb_info *info, int user)
gen_set_var
(
&
var
,
-
1
,
info
);
}
}
}
else
{
par
->
consolecnt
--
;
}
#endif
return
(
0
);
...
...
@@ -1204,18 +1208,8 @@ static int atyfb_mmap(struct fb_info *info, struct file *file,
vma
->
vm_flags
|=
VM_IO
;
if
(
!
par
->
mmaped
)
{
int
lastconsole
=
0
;
if
(
info
->
display_fg
)
lastconsole
=
info
->
display_fg
->
vc_num
;
if
(
!
par
->
mmaped
)
par
->
mmaped
=
1
;
if
(
par
->
consolecnt
&&
fb_display
[
lastconsole
].
fb_info
==
info
)
{
par
->
vtconsole
=
lastconsole
;
vt_cons
[
lastconsole
]
->
vc_mode
=
KD_GRAPHICS
;
}
}
return
0
;
}
...
...
@@ -1418,15 +1412,15 @@ static int aty_power_mgmt(int sleep, struct atyfb_par *par)
static
int
aty_sleep_notify
(
struct
pmu_sleep_notifier
*
self
,
int
when
)
{
struct
fb_info
*
info
;
struct
atyfb_par
*
par
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
fb
.
par
;
int
result
;
result
=
PBOOK_SLEEP_OK
;
for
(
info
=
first_display
;
info
!=
NULL
;
info
=
par
->
next
)
{
struct
fb_fix_screeninfo
fix
;
int
nb
;
par
=
(
struct
atyfb_par
*
)
info
->
par
;
nb
=
fb_display
[
fg_console
].
var
.
yres
*
info
->
fix
.
line_length
;
switch
(
when
)
{
...
...
@@ -1445,7 +1439,7 @@ static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
if
(
par
->
blitter_may_be_busy
)
wait_for_idle
(
par
);
/* Stop accel engine (stop bus mastering) */
if
(
info
->
var
.
accel_flags
&
FB_ACCELF_TEXT
)
if
(
par
->
accel_flags
&
FB_ACCELF_TEXT
)
aty_reset_engine
(
par
);
/* Backup fb content */
...
...
@@ -1931,15 +1925,8 @@ static int __init aty_init(struct fb_info *info, const char *name)
#endif
#ifdef CONFIG_FB_ATY_CT
if
(
curblink
&&
M64_HAS
(
INTEGRATED
))
{
if
(
curblink
&&
M64_HAS
(
INTEGRATED
))
par
->
cursor
=
aty_init_cursor
(
info
);
if
(
par
->
cursor
)
{
/*
disp->dispsw.cursor = atyfb_cursor;
disp->dispsw.set_font = atyfb_set_font;
*/
}
}
#endif
/* CONFIG_FB_ATY_CT */
info
->
var
=
var
;
...
...
@@ -1992,17 +1979,23 @@ int __init atyfb_init(void)
continue
;
info
=
kmalloc
(
sizeof
(
struct
fb_info
)
+
sizeof
(
struct
atyfb_par
),
GFP_ATOMIC
);
kmalloc
(
sizeof
(
struct
fb_info
),
GFP_ATOMIC
);
if
(
!
info
)
{
printk
(
"atyfb_init: can't alloc fb_info
\n
"
);
return
-
ENXIO
;
}
memset
(
info
,
0
,
sizeof
(
struct
fb_info
)
+
sizeof
(
struct
atyfb_par
));
memset
(
info
,
0
,
sizeof
(
struct
fb_info
));
default_par
=
(
struct
atyfb_par
*
)
(
info
+
1
);
default_par
=
kmalloc
(
sizeof
(
struct
atyfb_par
),
GFP_ATOMIC
);
if
(
!
default_par
)
{
printk
(
"atyfb_init: can't alloc atyfb_par
\n
"
);
kfree
(
info
);
return
-
ENXIO
;
}
memset
(
default_par
,
0
,
sizeof
(
struct
atyfb_par
));
info
->
fix
=
atyfb_fix
;
info
->
par
=
default_par
;
...
...
@@ -2337,6 +2330,7 @@ int __init atyfb_init(void)
if
(
first_display
==
NULL
)
pmu_register_sleep_notifier
(
&
aty_sleep_notifier
);
/* FIXME info->next = first_display; */
default_par
->
next
=
first_display
;
#endif
}
...
...
@@ -2374,7 +2368,7 @@ int __init atyfb_init(void)
info
->
fix
.
smem_start
=
info
->
screen_base
;
/* Fake! */
default_par
->
ati_regbase
=
(
unsigned
long
)
ioremap
(
phys_guiregbase
[
m64_num
],
0x10000
)
+
0xFC00ul
;
info
->
fix
.
mmio_start
=
default_
par
->
ati_regbase
;
/* Fake! */
info
->
fix
.
mmio_start
=
par
->
ati_regbase
;
/* Fake! */
aty_st_le32
(
CLOCK_CNTL
,
0x12345678
,
default_par
);
clock_r
=
aty_ld_le32
(
CLOCK_CNTL
,
default_par
);
...
...
@@ -2633,16 +2627,12 @@ void cleanup_module(void)
if
(
info
->
screen_base
)
iounmap
((
void
*
)
info
->
screen_base
);
#ifdef __BIG_ENDIAN
if
(
par
->
cursor
&&
par
->
cursor
->
ram
)
iounmap
(
par
->
cursor
->
ram
);
if
(
info
->
cursor
&&
info
->
cursor
->
ram
)
iounmap
(
info
->
cursor
->
ram
);
#endif
#endif
if
(
par
->
cursor
)
{
if
(
par
->
cursor
->
timer
)
kfree
(
par
->
cursor
->
timer
);
kfree
(
par
->
cursor
);
}
if
(
info
->
cursor
)
kfree
(
info
->
cursor
);
#ifdef __sparc__
if
(
par
->
mmap_map
)
kfree
(
par
->
mmap_map
);
...
...
drivers/video/aty/mach64_cursor.c
View file @
85fa8aa4
...
...
@@ -19,11 +19,6 @@
#include <video/mach64.h>
#include "atyfb.h"
#define DEFAULT_CURSOR_BLINK_RATE (20)
#define CURSOR_DRAW_DELAY (2)
/*
* Hardware Cursor support.
*/
...
...
@@ -49,50 +44,48 @@ void aty_set_cursor_color(struct fb_info *info)
const
u8
*
red
=
cursor_color_map
;
const
u8
*
green
=
cursor_color_map
;
const
u8
*
blue
=
cursor_color_map
;
int
i
;
u32
fg_color
,
bg_color
;
if
(
!
c
)
return
;
#ifdef __sparc__
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
info
->
display_fg
->
vc_num
==
par
->
vtconsole
))
if
(
par
->
mmaped
)
return
;
#endif
fg_color
=
(
u32
)
red
[
0
]
<<
24
;
fg_color
|=
(
u32
)
green
[
0
]
<<
16
;
fg_color
|=
(
u32
)
blue
[
0
]
<<
8
;
fg_color
|=
(
u32
)
pixel
[
0
];
for
(
i
=
0
;
i
<
2
;
i
++
)
{
c
->
color
[
i
]
=
(
u32
)
red
[
i
]
<<
24
;
c
->
color
[
i
]
|=
(
u32
)
green
[
i
]
<<
16
;
c
->
color
[
i
]
|=
(
u32
)
blue
[
i
]
<<
8
;
c
->
color
[
i
]
|=
(
u32
)
pixel
[
i
];
}
bg_color
=
(
u32
)
red
[
1
]
<<
24
;
bg_color
|=
(
u32
)
green
[
1
]
<<
16
;
bg_color
|=
(
u32
)
blue
[
1
]
<<
8
;
bg_color
|=
(
u32
)
pixel
[
1
];
wait_for_fifo
(
2
,
par
);
aty_st_le32
(
CUR_CLR0
,
c
->
color
[
0
]
,
par
);
aty_st_le32
(
CUR_CLR1
,
c
->
color
[
1
]
,
par
);
aty_st_le32
(
CUR_CLR0
,
fg_color
,
par
);
aty_st_le32
(
CUR_CLR1
,
bg_color
,
par
);
}
void
aty_set_cursor_shape
(
struct
fb_info
*
info
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
struct
fb_cursor
*
cursor
=
&
info
->
cursor
;
struct
aty_cursor
*
c
=
par
->
cursor
;
u8
*
ram
,
m
,
b
;
int
x
,
y
;
if
(
!
c
)
return
;
#ifdef __sparc__
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
info
->
display_fg
->
vc_num
==
par
->
vtconsole
))
if
(
par
->
mmaped
)
return
;
#endif
ram
=
c
->
ram
;
for
(
y
=
0
;
y
<
c
->
size
.
y
;
y
++
)
{
for
(
x
=
0
;
x
<
c
->
size
.
x
>>
2
;
x
++
)
{
for
(
y
=
0
;
y
<
c
ursor
->
image
.
height
;
y
++
)
{
for
(
x
=
0
;
x
<
c
ursor
->
image
.
width
>>
2
;
x
++
)
{
m
=
c
->
mask
[
x
][
y
];
b
=
c
->
bits
[
x
][
y
];
fb_writeb
(
cursor_mask_lookup
[
m
>>
4
]
|
...
...
@@ -106,12 +99,13 @@ void aty_set_cursor_shape(struct fb_info *info)
fb_writeb
(
0xaa
,
ram
++
);
}
}
fb_memset
(
ram
,
0xaa
,
(
64
-
c
->
size
.
y
)
*
16
);
fb_memset
(
ram
,
0xaa
,
(
64
-
c
ursor
->
image
.
height
)
*
16
);
}
static
void
aty_set_cursor
(
struct
fb_info
*
info
,
int
on
)
static
void
aty_set_cursor
(
struct
fb_info
*
info
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
struct
fb_cursor
*
cursor
=
&
info
->
cursor
;
struct
aty_cursor
*
c
=
par
->
cursor
;
u16
xoff
,
yoff
;
int
x
,
y
;
...
...
@@ -120,14 +114,12 @@ static void aty_set_cursor(struct fb_info *info, int on)
return
;
#ifdef __sparc__
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
info
->
display_fg
->
vc_num
==
par
->
vtconsole
))
if
(
par
->
mmaped
)
return
;
#endif
if
(
on
)
{
x
=
c
->
pos
.
x
-
c
->
hot
.
x
-
info
->
var
.
xoffset
;
if
(
cursor
->
enable
)
{
x
=
c
ursor
->
image
.
dx
-
cursor
->
hot
.
x
-
info
->
var
.
xoffset
;
if
(
x
<
0
)
{
xoff
=
-
x
;
x
=
0
;
...
...
@@ -135,7 +127,7 @@ static void aty_set_cursor(struct fb_info *info, int on)
xoff
=
0
;
}
y
=
c
->
pos
.
y
-
c
->
hot
.
y
-
info
->
var
.
yoffset
;
y
=
c
ursor
->
image
.
dy
-
cursor
->
hot
.
y
-
info
->
var
.
yoffset
;
if
(
y
<
0
)
{
yoff
=
-
y
;
y
=
0
;
...
...
@@ -144,10 +136,10 @@ static void aty_set_cursor(struct fb_info *info, int on)
}
wait_for_fifo
(
4
,
par
);
aty_st_le32
(
CUR_OFFSET
,
(
c
->
offset
>>
3
)
+
(
yoff
<<
1
),
aty_st_le32
(
CUR_OFFSET
,
(
info
->
fix
.
smem_len
>>
3
)
+
(
yoff
<<
1
),
par
);
aty_st_le32
(
CUR_HORZ_VERT_OFF
,
((
u32
)
(
64
-
c
->
size
.
y
+
yoff
)
<<
16
)
|
xoff
,
((
u32
)
(
64
-
c
ursor
->
image
.
height
+
yoff
)
<<
16
)
|
xoff
,
par
);
aty_st_le32
(
CUR_HORZ_VERT_POSN
,
((
u32
)
y
<<
16
)
|
x
,
par
);
aty_st_le32
(
GEN_TEST_CNTL
,
aty_ld_le32
(
GEN_TEST_CNTL
,
par
)
...
...
@@ -162,70 +154,25 @@ static void aty_set_cursor(struct fb_info *info, int on)
wait_for_idle
(
par
);
}
static
void
aty_cursor_timer_handler
(
unsigned
long
dev_add
r
)
int
atyfb_cursor
(
struct
fb_info
*
info
,
struct
fb_cursor
*
curso
r
)
{
struct
fb_info
*
info
=
(
struct
fb_info
*
)
dev_addr
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
if
(
!
par
->
cursor
)
return
;
if
(
!
par
->
cursor
->
enable
)
goto
out
;
if
(
par
->
cursor
->
vbl_cnt
&&
--
par
->
cursor
->
vbl_cnt
==
0
)
{
par
->
cursor
->
on
^=
1
;
aty_set_cursor
(
info
,
par
->
cursor
->
on
);
par
->
cursor
->
vbl_cnt
=
par
->
cursor
->
blink_rate
;
}
out:
par
->
cursor
->
timer
->
expires
=
jiffies
+
(
HZ
/
50
);
add_timer
(
par
->
cursor
->
timer
);
}
void
atyfb_cursor
(
struct
display
*
p
,
int
mode
,
int
x
,
int
y
)
{
struct
fb_info
*
info
=
p
->
fb_info
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
struct
aty_cursor
*
c
=
par
->
cursor
;
if
(
!
c
)
return
;
return
-
1
;
#ifdef __sparc__
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
info
->
display_fg
->
vc_num
==
par
->
vtconsole
))
if
(
par
->
mmaped
)
return
;
#endif
x
*=
fontwidth
(
p
);
y
*=
fontheight
(
p
);
if
(
c
->
pos
.
x
==
x
&&
c
->
pos
.
y
==
y
&&
(
mode
==
CM_ERASE
)
==
!
c
->
enable
)
return
;
aty_set_cursor
(
info
);
cursor
->
image
.
dx
=
info
->
cursor
.
image
.
dx
;
cursor
->
image
.
dy
=
info
->
cursor
.
image
.
dy
;
c
->
enable
=
0
;
if
(
c
->
on
)
aty_set_cursor
(
info
,
0
);
c
->
pos
.
x
=
x
;
c
->
pos
.
y
=
y
;
switch
(
mode
)
{
case
CM_ERASE
:
c
->
on
=
0
;
break
;
case
CM_DRAW
:
case
CM_MOVE
:
if
(
c
->
on
)
aty_set_cursor
(
info
,
1
);
else
c
->
vbl_cnt
=
CURSOR_DRAW_DELAY
;
c
->
enable
=
1
;
break
;
}
aty_set_cursor
(
info
);
return
0
;
}
struct
aty_cursor
*
__init
aty_init_cursor
(
struct
fb_info
*
info
)
...
...
@@ -238,47 +185,31 @@ struct aty_cursor *__init aty_init_cursor(struct fb_info *info)
return
0
;
memset
(
cursor
,
0
,
sizeof
(
*
cursor
));
cursor
->
timer
=
kmalloc
(
sizeof
(
*
cursor
->
timer
),
GFP_KERNEL
);
if
(
!
cursor
->
timer
)
{
kfree
(
cursor
);
return
0
;
}
memset
(
cursor
->
timer
,
0
,
sizeof
(
*
cursor
->
timer
));
cursor
->
blink_rate
=
DEFAULT_CURSOR_BLINK_RATE
;
info
->
fix
.
smem_len
-=
PAGE_SIZE
;
cursor
->
offset
=
info
->
fix
.
smem_len
;
#ifdef __sparc__
addr
=
(
unsigned
long
)
info
->
screen_base
-
0x800000
+
cursor
->
offset
;
addr
=
info
->
screen_base
-
0x800000
+
info
->
fix
.
smem_len
;
cursor
->
ram
=
(
u8
*
)
addr
;
#else
#ifdef __BIG_ENDIAN
addr
=
info
->
fix
.
smem_start
-
0x800000
+
cursor
->
offset
;
addr
=
info
->
fix
.
smem_start
-
0x800000
+
info
->
fix
.
smem_len
;
cursor
->
ram
=
(
u8
*
)
ioremap
(
addr
,
1024
);
#else
addr
=
(
unsigned
long
)
info
->
screen_base
+
cursor
->
offset
;
addr
=
(
unsigned
long
)
info
->
screen_base
+
info
->
fix
.
smem_len
;
cursor
->
ram
=
(
u8
*
)
addr
;
#endif
#endif
if
(
!
cursor
->
ram
)
{
kfree
(
cursor
);
return
NULL
;
}
init_timer
(
cursor
->
timer
);
cursor
->
timer
->
expires
=
jiffies
+
(
HZ
/
50
);
cursor
->
timer
->
data
=
(
unsigned
long
)
info
;
cursor
->
timer
->
function
=
aty_cursor_timer_handler
;
add_timer
(
cursor
->
timer
);
return
cursor
;
}
int
atyfb_set_font
(
struct
display
*
d
,
int
width
,
int
height
)
int
atyfb_set_font
(
struct
fb_info
*
info
,
int
width
,
int
height
)
{
struct
fb_info
*
info
=
d
->
fb_info
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
struct
fb_cursor
*
cursor
=
&
info
->
cursor
;
struct
aty_cursor
*
c
=
par
->
cursor
;
int
i
,
j
;
...
...
@@ -288,10 +219,10 @@ int atyfb_set_font(struct display *d, int width, int height)
height
=
16
;
}
c
->
hot
.
x
=
0
;
c
->
hot
.
y
=
0
;
c
->
size
.
x
=
width
;
c
->
size
.
y
=
height
;
c
ursor
->
hot
.
x
=
0
;
c
ursor
->
hot
.
y
=
0
;
c
ursor
->
image
.
width
=
width
;
c
ursor
->
image
.
height
=
height
;
memset
(
c
->
bits
,
0xff
,
sizeof
(
c
->
bits
));
memset
(
c
->
mask
,
0
,
sizeof
(
c
->
mask
));
...
...
drivers/video/aty128fb.c
View file @
85fa8aa4
...
...
@@ -138,13 +138,6 @@ static struct fb_videomode defaultmode __initdata = {
.
vmode
=
FB_VMODE_NONINTERLACED
};
/* struct to hold chip description information */
struct
aty128_chip_info
{
const
char
*
name
;
unsigned
short
device
;
int
chip_gen
;
};
/* Chip generations */
enum
{
rage_128
,
...
...
@@ -152,21 +145,46 @@ enum {
rage_M3
};
/*
* PCI driver prototypes
*/
static
int
aty128_probe
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
);
static
void
aty128_remove
(
struct
pci_dev
*
pdev
);
/* supported Rage128 chipsets */
static
struct
aty128_chip_info
aty128_pci_probe_list
[]
__initdata
=
{
{
"Rage128 RE (PCI)"
,
PCI_DEVICE_ID_ATI_RAGE128_RE
,
rage_128
},
{
"Rage128 RF (AGP)"
,
PCI_DEVICE_ID_ATI_RAGE128_RF
,
rage_128
},
{
"Rage128 RK (PCI)"
,
PCI_DEVICE_ID_ATI_RAGE128_RK
,
rage_128
},
{
"Rage128 RL (AGP)"
,
PCI_DEVICE_ID_ATI_RAGE128_RL
,
rage_128
},
{
"Rage128 Pro PF (AGP)"
,
PCI_DEVICE_ID_ATI_RAGE128_PF
,
rage_128_pro
},
{
"Rage128 Pro PR (PCI)"
,
PCI_DEVICE_ID_ATI_RAGE128_PR
,
rage_128_pro
},
{
"Rage128 Pro TR (AGP)"
,
PCI_DEVICE_ID_ATI_RAGE128_U3
,
rage_128_pro
},
{
"Rage128 Pro TF (AGP)"
,
PCI_DEVICE_ID_ATI_RAGE128_U1
,
rage_128_pro
},
{
"Rage Mobility M3 (PCI)"
,
PCI_DEVICE_ID_ATI_RAGE128_LE
,
rage_M3
},
{
"Rage Mobility M3 (AGP)"
,
PCI_DEVICE_ID_ATI_RAGE128_LF
,
rage_M3
},
{
NULL
,
0
,
rage_128
}
};
static
struct
pci_device_id
aty128_pci_tbl
[]
__devinitdata
=
{
{
PCI_VENDOR_ID_ATI
,
PCI_DEVICE_ID_ATI_RAGE128_RE
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
rage_128
},
{
PCI_VENDOR_ID_ATI
,
PCI_DEVICE_ID_ATI_RAGE128_RF
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
rage_128
},
{
PCI_VENDOR_ID_ATI
,
PCI_DEVICE_ID_ATI_RAGE128_RK
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
rage_128
},
{
PCI_VENDOR_ID_ATI
,
PCI_DEVICE_ID_ATI_RAGE128_RL
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
rage_128
},
{
PCI_VENDOR_ID_ATI
,
PCI_DEVICE_ID_ATI_RAGE128_PF
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
rage_128_pro
},
{
PCI_VENDOR_ID_ATI
,
PCI_DEVICE_ID_ATI_RAGE128_PR
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
rage_128_pro
},
{
PCI_VENDOR_ID_ATI
,
PCI_DEVICE_ID_ATI_RAGE128_U3
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
rage_128_pro
},
{
PCI_VENDOR_ID_ATI
,
PCI_DEVICE_ID_ATI_RAGE128_U1
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
rage_128_pro
},
{
PCI_VENDOR_ID_ATI
,
PCI_DEVICE_ID_ATI_RAGE128_LE
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
rage_M3
},
{
PCI_VENDOR_ID_ATI
,
PCI_DEVICE_ID_ATI_RAGE128_LF
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
rage_M3
},
{
0
,
}
};
MODULE_DEVICE_TABLE
(
pci
,
aty128_pci_tbl
);
static
struct
pci_driver
aty128fb_driver
=
{
name:
"aty128fb"
,
id_table:
aty128_pci_tbl
,
probe:
aty128_probe
,
remove:
__devexit_p
(
aty128_remove
),
};
/* packed BIOS settings */
#ifndef CONFIG_PPC
...
...
@@ -231,11 +249,7 @@ static struct fb_fix_screeninfo aty128fb_fix __initdata = {
.
accel
=
FB_ACCEL_ATI_RAGE128
,
};
static
char
fontname
[
40
]
__initdata
=
{
0
};
static
int
noaccel
__initdata
=
0
;
#ifdef MODULE
static
char
*
font
__initdata
=
NULL
;
static
char
*
mode
__initdata
=
NULL
;
#ifdef CONFIG_MTRR
static
int
nomtrr
__initdata
=
0
;
...
...
@@ -303,9 +317,6 @@ struct aty128fb_par {
u32
vram_size
;
/* onboard video ram */
int
chip_gen
;
const
struct
aty128_meminfo
*
mem
;
/* onboard mem info */
#ifdef CONFIG_PCI
struct
pci_dev
*
pdev
;
#endif
#ifdef CONFIG_MTRR
struct
{
int
vram
;
int
vram_valid
;
}
mtrr
;
#endif
...
...
@@ -321,15 +332,6 @@ struct aty128fb_par {
unsigned
char
blue
[
64
];
};
struct
fb_info_aty128
{
struct
fb_info
fb_info
;
struct
aty128fb_par
par
;
u32
pseudo_palette
[
17
];
struct
fb_info_aty128
*
next
;
};
static
struct
fb_info_aty128
*
board_list
=
NULL
;
#ifdef CONFIG_PMAC_PBOOK
int
aty128_sleep_notify
(
struct
pmu_sleep_notifier
*
self
,
int
when
);
static
struct
pmu_sleep_notifier
aty128_sleep_notifier
=
{
...
...
@@ -342,7 +344,7 @@ static struct pmu_sleep_notifier aty128_sleep_notifier = {
/*
* Interface used by the world
*/
int
aty128fb_init
(
void
);
int
aty128fb_setup
(
char
*
options
);
static
int
aty128fb_check_var
(
struct
fb_var_screeninfo
*
var
,
...
...
@@ -357,12 +359,6 @@ static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
u_long
arg
,
struct
fb_info
*
info
);
static
int
aty128fb_sync
(
struct
fb_info
*
info
);
/*
* Interface to the low level console driver
*/
int
aty128fb_init
(
void
);
/*
* Internal routines
*/
...
...
@@ -371,8 +367,6 @@ static int aty128_encode_var(struct fb_var_screeninfo *var,
const
struct
aty128fb_par
*
par
);
static
int
aty128_decode_var
(
struct
fb_var_screeninfo
*
var
,
struct
aty128fb_par
*
par
);
static
int
aty128_pci_register
(
struct
pci_dev
*
pdev
,
const
struct
aty128_chip_info
*
aci
);
#if !defined(CONFIG_PPC) && !defined(__sparc__)
static
void
__init
aty128_get_pllinfo
(
struct
aty128fb_par
*
par
,
char
*
bios_seg
);
...
...
@@ -1408,33 +1402,21 @@ aty128fb_setup(char *options)
return
0
;
while
((
this_opt
=
strsep
(
&
options
,
","
))
!=
NULL
)
{
if
(
!
strncmp
(
this_opt
,
"font:"
,
5
))
{
char
*
p
;
int
i
;
p
=
this_opt
+
5
;
for
(
i
=
0
;
i
<
sizeof
(
fontname
)
-
1
;
i
++
)
if
(
!*
p
||
*
p
==
' '
||
*
p
==
','
)
break
;
memcpy
(
fontname
,
this_opt
+
5
,
i
);
fontname
[
i
]
=
0
;
}
else
if
(
!
strncmp
(
this_opt
,
"noaccel"
,
7
))
{
noaccel
=
1
;
#ifdef CONFIG_PMAC_PBOOK
}
else
if
(
!
strncmp
(
this_opt
,
"lcd:"
,
4
))
{
if
(
!
strncmp
(
this_opt
,
"lcd:"
,
4
))
{
default_lcd_on
=
simple_strtoul
(
this_opt
+
4
,
NULL
,
0
);
}
else
if
(
!
strncmp
(
this_opt
,
"crt:"
,
4
))
{
default_crt_on
=
simple_strtoul
(
this_opt
+
4
,
NULL
,
0
);
#endif
}
#endif
#ifdef CONFIG_MTRR
else
if
(
!
strncmp
(
this_opt
,
"nomtrr"
,
6
))
{
if
(
!
strncmp
(
this_opt
,
"nomtrr"
,
6
))
{
mtrr
=
0
;
}
#endif
#ifdef CONFIG_ALL_PPC
/* vmode and cmode depreciated */
else
if
(
!
strncmp
(
this_opt
,
"vmode:"
,
6
))
{
if
(
!
strncmp
(
this_opt
,
"vmode:"
,
6
))
{
unsigned
int
vmode
=
simple_strtoul
(
this_opt
+
6
,
NULL
,
0
);
if
(
vmode
>
0
&&
vmode
<=
VMODE_MAX
)
default_vmode
=
vmode
;
...
...
@@ -1468,14 +1450,14 @@ aty128fb_setup(char *options)
*/
static
int
__init
aty128_init
(
struct
fb_info
*
info
,
const
char
*
name
)
aty128_init
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
)
{
struct
fb_info
*
info
=
pci_get_drvdata
(
pdev
);
struct
aty128fb_par
*
par
=
info
->
par
;
struct
fb_var_screeninfo
var
;
u32
dac
;
char
video_card
[
25
]
;
u8
chip_rev
;
const
struct
aty128_chip_info
*
aci
=
&
aty128_pci_probe_list
[
0
];
const
char
*
video_card
;
u32
dac
;
if
(
!
par
->
vram_size
)
/* may have already been probed */
par
->
vram_size
=
aty_ld_le32
(
CONFIG_MEMSIZE
)
&
0x03FFFFFF
;
...
...
@@ -1483,11 +1465,40 @@ aty128_init(struct fb_info *info, const char *name)
/* Get the chip revision */
chip_rev
=
(
aty_ld_le32
(
CONFIG_CNTL
)
>>
16
)
&
0x1F
;
/* put a name with the face */
while
(
aci
->
name
&&
par
->
pdev
->
device
!=
aci
->
device
)
aci
++
;
video_card
=
aci
->
name
?
aci
->
name
:
"Rage128"
;
par
->
chip_gen
=
aci
->
chip_gen
;
switch
(
pdev
->
device
)
{
case
PCI_DEVICE_ID_ATI_RAGE128_RE
:
strcpy
(
video_card
,
"Rage128 RE (PCI)"
);
break
;
case
PCI_DEVICE_ID_ATI_RAGE128_RF
:
strcpy
(
video_card
,
"Rage128 RF (AGP)"
);
break
;
case
PCI_DEVICE_ID_ATI_RAGE128_RK
:
strcpy
(
video_card
,
"Rage128 RK (PCI)"
);
break
;
case
PCI_DEVICE_ID_ATI_RAGE128_RL
:
strcpy
(
video_card
,
"Rage128 RL (AGP)"
);
break
;
case
PCI_DEVICE_ID_ATI_RAGE128_PF
:
strcpy
(
video_card
,
"Rage128 Pro PF (AGP)"
);
break
;
case
PCI_DEVICE_ID_ATI_RAGE128_PR
:
strcpy
(
video_card
,
"Rage128 Pro PR (PCI)"
);
break
;
case
PCI_DEVICE_ID_ATI_RAGE128_U3
:
strcpy
(
video_card
,
"Rage128 Pro TR (AGP)"
);
break
;
case
PCI_DEVICE_ID_ATI_RAGE128_U1
:
strcpy
(
video_card
,
"Rage128 Pro TF (AGP)"
);
break
;
case
PCI_DEVICE_ID_ATI_RAGE128_LE
:
strcpy
(
video_card
,
"Rage Mobility M3 (PCI)"
);
break
;
case
PCI_DEVICE_ID_ATI_RAGE128_LF
:
strcpy
(
video_card
,
"Rage Mobility M3 (AGP)"
);
break
;
default:
return
-
ENODEV
;
}
printk
(
KERN_INFO
"aty128fb: %s [chip rev 0x%x] "
,
video_card
,
chip_rev
);
...
...
@@ -1496,6 +1507,8 @@ aty128_init(struct fb_info *info, const char *name)
else
printk
(
"%dk %s
\n
"
,
par
->
vram_size
/
1024
,
par
->
mem
->
name
);
par
->
chip_gen
=
ent
->
driver_data
;
/* fill in info */
info
->
node
=
NODEV
;
info
->
fbops
=
&
aty128fb_ops
;
...
...
@@ -1553,10 +1566,8 @@ aty128_init(struct fb_info *info, const char *name)
var
=
default_var
;
}
if
(
noaccel
)
var
.
accel_flags
&=
~
FB_ACCELF_TEXT
;
else
var
.
accel_flags
|=
FB_ACCELF_TEXT
;
// var.accel_flags |= FB_ACCELF_TEXT;/* FIXME Will add accel later */
if
(
aty128fb_check_var
(
&
var
,
info
))
{
printk
(
KERN_ERR
"aty128fb: Cannot set default mode.
\n
"
);
...
...
@@ -1590,54 +1601,25 @@ aty128_init(struct fb_info *info, const char *name)
register_backlight_controller
(
&
aty128_backlight_controller
,
par
,
"ati"
);
#endif
/* CONFIG_PMAC_BACKLIGHT */
#ifdef CONFIG_PMAC_PBOOK
if
(
!
par
->
pdev
)
printk
(
KERN_WARNING
"aty128fb: Not a PCI card, can't enable power management
\n
"
);
else
{
par
->
pm_reg
=
pci_find_capability
(
par
->
pdev
,
PCI_CAP_ID_PM
);
par
->
pm_reg
=
pci_find_capability
(
pdev
,
PCI_CAP_ID_PM
);
pmu_register_sleep_notifier
(
&
aty128_sleep_notifier
);
}
#endif
printk
(
KERN_INFO
"fb%d: %s frame buffer device on %s
\n
"
,
minor
(
info
->
node
),
info
->
fix
.
id
,
name
);
minor
(
info
->
node
),
info
->
fix
.
id
,
video_card
);
return
1
;
/* success! */
}
int
__init
aty128fb_init
(
void
)
{
#ifdef CONFIG_PCI
struct
pci_dev
*
pdev
=
NULL
;
const
struct
aty128_chip_info
*
aci
=
&
aty128_pci_probe_list
[
0
];
while
(
aci
->
name
!=
NULL
)
{
pdev
=
pci_find_device
(
PCI_VENDOR_ID_ATI
,
aci
->
device
,
pdev
);
while
(
pdev
!=
NULL
)
{
if
(
aty128_pci_register
(
pdev
,
aci
)
==
0
)
return
0
;
pdev
=
pci_find_device
(
PCI_VENDOR_ID_ATI
,
aci
->
device
,
pdev
);
}
aci
++
;
}
#endif
return
0
;
}
#ifdef CONFIG_PCI
/* register a card ++ajoshi */
static
int
__init
aty128_pci_register
(
struct
pci_dev
*
pdev
,
const
struct
aty128_chip_info
*
aci
)
aty128_probe
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
)
{
struct
fb_info_aty128
*
lump
=
NULL
;
struct
fb_info
*
info
;
struct
aty128fb_par
*
par
;
unsigned
long
fb_addr
,
reg_addr
;
int
err
;
struct
aty128fb_par
*
par
;
struct
fb_info
*
info
;
int
err
,
size
;
#if !defined(CONFIG_PPC) && !defined(__sparc__)
char
*
bios_seg
=
NULL
;
#endif
...
...
@@ -1665,19 +1647,21 @@ aty128_pci_register(struct pci_dev *pdev,
}
/* We have the resources. Now virtualize them */
if
(
!
(
lump
=
kmalloc
(
sizeof
(
struct
fb_info_aty128
),
GFP_ATOMIC
)))
{
size
=
sizeof
(
struct
fb_info
)
+
sizeof
(
struct
aty128fb_par
)
+
sizeof
(
u32
)
*
16
;
if
(
!
(
info
=
kmalloc
(
size
,
GFP_ATOMIC
)))
{
printk
(
KERN_ERR
"aty128fb: can't alloc fb_info_aty128
\n
"
);
goto
err_unmap_out
;
}
memset
(
lump
,
0
,
sizeof
(
struct
fb_info_aty128
));
info
=
&
lump
->
fb_info
;
par
=
&
lump
->
par
;
memset
(
info
,
0
,
size
);
par
=
(
struct
aty128fb_par
*
)(
info
+
1
);
info
->
pseudo_palette
=
(
void
*
)
(
par
+
1
);
memset
(
info
,
0
,
sizeof
(
struct
fb_info
));
info
->
par
=
par
;
info
->
fix
=
aty128fb_fix
;
info
->
pseudo_palette
=
lump
->
pseudo_palette
;
par
->
pdev
=
pdev
;
/* Virtualize mmio region */
info
->
fix
.
mmio_start
=
reg_addr
;
...
...
@@ -1718,13 +1702,11 @@ aty128_pci_register(struct pci_dev *pdev,
}
#endif
aty128_timings
(
par
);
pci_set_drvdata
(
pdev
,
info
);
if
(
!
aty128_init
(
info
,
"PCI"
))
if
(
!
aty128_init
(
pdev
,
ent
))
goto
err_out
;
lump
->
next
=
board_list
;
board_list
=
lump
;
#ifdef CONFIG_MTRR
if
(
mtrr
)
{
par
->
mtrr
.
vram
=
mtrr_add
(
info
->
fix
.
smem_start
,
...
...
@@ -1740,7 +1722,7 @@ aty128_pci_register(struct pci_dev *pdev,
iounmap
(
info
->
screen_base
);
iounmap
(
par
->
regbase
);
err_free_info:
kfree
(
lump
);
kfree
(
info
);
err_unmap_out:
release_mem_region
(
pci_resource_start
(
pdev
,
2
),
pci_resource_len
(
pdev
,
2
));
...
...
@@ -1752,8 +1734,33 @@ aty128_pci_register(struct pci_dev *pdev,
pci_resource_len
(
pdev
,
1
));
return
-
ENODEV
;
}
#endif
/* CONFIG_PCI */
static
void
__devexit
aty128_remove
(
struct
pci_dev
*
pdev
)
{
struct
fb_info
*
info
=
pci_get_drvdata
(
pdev
);
struct
aty128fb_par
*
par
=
info
->
par
;
if
(
!
info
)
return
;
unregister_framebuffer
(
info
);
#ifdef CONFIG_MTRR
if
(
par
->
mtrr
.
vram_valid
)
mtrr_del
(
par
->
mtrr
.
vram
,
info
->
fix
.
smem_start
,
par
->
vram_size
);
#endif
/* CONFIG_MTRR */
iounmap
(
par
->
regbase
);
iounmap
(
info
->
screen_base
);
release_mem_region
(
pci_resource_start
(
pdev
,
0
),
pci_resource_len
(
pdev
,
0
));
release_mem_region
(
pci_resource_start
(
pdev
,
1
),
pci_resource_len
(
pdev
,
1
));
release_mem_region
(
pci_resource_start
(
pdev
,
2
),
pci_resource_len
(
pdev
,
2
));
kfree
(
info
);
}
#endif
/* CONFIG_PCI */
/* PPC and Sparc cannot read video ROM */
#if !defined(CONFIG_PPC) && !defined(__sparc__)
...
...
@@ -2238,8 +2245,6 @@ aty128_set_suspend(struct aty128fb_par *par, int suspend)
}
}
extern
struct
display_switch
fbcon_dummy
;
/*
* Save the contents of the frame buffer when we go to sleep,
* and restore it when we wake up again.
...
...
@@ -2247,15 +2252,9 @@ extern struct display_switch fbcon_dummy;
int
aty128_sleep_notify
(
struct
pmu_sleep_notifier
*
self
,
int
when
)
{
struct
fb_info_aty128
*
board
;
int
result
;
result
=
PBOOK_SLEEP_OK
;
for
(
board
=
board_list
;
board
!=
NULL
;
board
=
board
->
next
)
{
struct
fb_info
*
info
=
&
board
->
fb_info
;
int
result
=
PBOOK_SLEEP_OK
,
nb
;
struct
fb_info
*
info
=
info
;
/* FIXME!!! How do find which framebuffer */
struct
aty128fb_par
*
par
=
info
->
par
;
int
nb
;
nb
=
info
->
var
.
yres
*
info
->
fix
.
line_length
;
...
...
@@ -2272,9 +2271,6 @@ aty128_sleep_notify(struct pmu_sleep_notifier *self, int when)
}
break
;
case
PBOOK_SLEEP_NOW
:
if
(
info
->
currcon
>=
0
)
fb_display
[
info
->
currcon
].
dispsw
=
&
fbcon_dummy
;
wait_for_idle
(
par
);
aty128_reset_engine
(
par
);
wait_for_idle
(
par
);
...
...
@@ -2305,23 +2301,26 @@ aty128_sleep_notify(struct pmu_sleep_notifier *self, int when)
vfree
(
par
->
save_framebuffer
);
par
->
save_framebuffer
=
0
;
}
gen_set_disp
(
-
1
,
info
);
aty128fb_blank
(
0
,
info
);
break
;
}
}
return
result
;
}
#endif
/* CONFIG_PMAC_PBOOK */
#ifdef MODULE
int
__init
aty128fb_init
(
void
)
{
return
pci_module_init
(
&
aty128fb_driver
);
}
static
void
__exit
aty128fb_exit
(
void
)
{
pci_unregister_driver
(
&
aty128fb_driver
);
}
MODULE_AUTHOR
(
"(c)1999-2000 Brad Douglas <brad@neruo.com>"
);
MODULE_DESCRIPTION
(
"FBDev driver for ATI Rage128 / Pro cards"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_PARM
(
noaccel
,
"i"
);
MODULE_PARM_DESC
(
noaccel
,
"Disable hardware acceleration (0 or 1=disabled) (default=0)"
);
MODULE_PARM
(
font
,
"s"
);
MODULE_PARM_DESC
(
font
,
"Specify one of the compiled-in fonts (default=none)"
);
MODULE_PARM
(
mode
,
"s"
);
MODULE_PARM_DESC
(
mode
,
"Specify resolution as
\"
<xres>x<yres>[-<bpp>][@<refresh>]
\"
"
);
#ifdef CONFIG_MTRR
...
...
@@ -2329,58 +2328,3 @@ MODULE_PARM(nomtrr, "i");
MODULE_PARM_DESC
(
nomtrr
,
"Disable MTRR support (0 or 1=disabled) (default=0)"
);
#endif
int
__init
init_module
(
void
)
{
if
(
noaccel
)
{
noaccel
=
1
;
printk
(
KERN_INFO
"aty128fb: Parameter NOACCEL set
\n
"
);
}
if
(
font
)
{
strncpy
(
fontname
,
font
,
sizeof
(
fontname
)
-
1
);
printk
(
KERN_INFO
"aty128fb: Parameter FONT set to %s
\n
"
,
font
);
}
if
(
mode
)
{
mode_option
=
mode
;
printk
(
KERN_INFO
"aty128fb: Parameter MODE set to %s
\n
"
,
mode
);
}
#ifdef CONFIG_MTRR
if
(
nomtrr
)
{
mtrr
=
0
;
printk
(
KERN_INFO
"aty128fb: Parameter NOMTRR set
\n
"
);
}
#endif
aty128fb_init
();
return
0
;
}
void
__exit
cleanup_module
(
void
)
{
struct
fb_info_aty128
*
info
=
board_list
;
while
(
board_list
)
{
info
=
board_list
;
board_list
=
board_list
->
next
;
unregister_framebuffer
(
&
info
->
fb_info
);
#ifdef CONFIG_MTRR
if
(
info
->
mtrr
.
vram_valid
)
mtrr_del
(
info
->
mtrr
.
vram
,
info
->
fix
.
smem_start
,
info
->
vram_size
);
#endif
/* CONFIG_MTRR */
iounmap
(
info
->
par
.
regbase
);
iounmap
(
info
->
fb_info
.
screen_base
);
release_mem_region
(
pci_resource_start
(
info
->
par
.
pdev
,
0
),
pci_resource_len
(
info
->
par
.
pdev
,
0
));
release_mem_region
(
pci_resource_start
(
info
->
par
.
pdev
,
1
),
pci_resource_len
(
info
->
par
.
pdev
,
1
));
release_mem_region
(
pci_resource_start
(
info
->
par
.
pdev
,
2
),
pci_resource_len
(
info
->
par
.
pdev
,
2
));
kfree
(
info
);
}
}
#endif
/* MODULE */
drivers/video/console/Kconfig
View file @
85fa8aa4
...
...
@@ -118,12 +118,6 @@ config FBCON_ADVANCED
If unsure, say N.
config FBCON_ACCEL
tristate "Hardware acceleration support" if FBCON_ADVANCED
depends on FRAMEBUFFER_CONSOLE
default m if !FBCON_ADVANCED && FB_NEOMAGIC!=y && !FB_VESA && !FB_FM2 && FB_HIT!=y && !FB_HP300 && !FB_Q40 && !FB_ANAKIN && !FB_G364 && FB_VIRTUAL!=y && !FB_CLPS711X && !FB_PMAG_BA && !FB_PMAGB_B && FB_3DFX!=y && !FB_TX3912 && !FB_MAXINE && !FB_APOLLO && FB_ATY!=y && FB_ATY128!=y && !FB_MAC && FB_RIVA!=y && FB_HGA!=y && !FB_OF && FB_SGIVW!=y && FB_VGA16!=y && (FB_NEOMAGIC=m || FB_HIT=m || FB_VIRTUAL=m || FB_3DFX=m || FB_RIVA=m || FB_SGIVW=m || FB_HGA=m || FB_ATY128=m)
default y if !FBCON_ADVANCED && (FB_NEOMAGIC=y || FB_VESA || FB_FM2 || FB_HIT=y || FB_HP300 || FB_Q40 || FB_ANAKIN || FB_G364 || FB_VIRTUAL=y || FB_CLPS711X || FB_PMAG_BA || FB_PMAGB_B || FB_3DFX=y || FB_TX3912 || FB_MAXINE || FB_APOLLO || FB_ATY=y || FB_ATY128=y || FB_MAC || FB_RIVA=y || FB_OF || FB_SGIVW=y || FB_HGA=y || FB_VGA16)
config FBCON_AFB
tristate "Amiga bitplanes support" if FBCON_ADVANCED
depends on FRAMEBUFFER_CONSOLE
...
...
drivers/video/console/Makefile
View file @
85fa8aa4
...
...
@@ -27,7 +27,7 @@ obj-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
obj-$(CONFIG_FONT_ACORN_8x8)
+=
font_acorn_8x8.o
obj-$(CONFIG_FONT_MINI_4x6)
+=
font_mini_4x6.o
obj-$(CONFIG_FRAMEBUFFER_CONSOLE)
+=
fbcon.o fonts.o
obj-$(CONFIG_FRAMEBUFFER_CONSOLE)
+=
fbcon.o fonts.o
fbcon-accel.o
# Generic Low Level Drivers
...
...
@@ -37,7 +37,6 @@ obj-$(CONFIG_FBCON_IPLAN2P2) += fbcon-iplan2p2.o
obj-$(CONFIG_FBCON_IPLAN2P4)
+=
fbcon-iplan2p4.o
obj-$(CONFIG_FBCON_IPLAN2P8)
+=
fbcon-iplan2p8.o
obj-$(CONFIG_FBCON_STI)
+=
fbcon-sti.o
obj-$(CONFIG_FBCON_ACCEL)
+=
fbcon-accel.o
# Files generated that shall be removed upon make clean
clean-files
:=
promcon_tbl.c
...
...
drivers/video/neofb.c
View file @
85fa8aa4
...
...
@@ -464,13 +464,14 @@ static void vgaHWRestore(const struct fb_info *info,
/*
* Hardware Acceleration for Neo2200+
*/
static
inline
void
neo2200_sync
(
struct
fb_info
*
info
)
static
inline
int
neo2200_sync
(
struct
fb_info
*
info
)
{
struct
neofb_par
*
par
=
(
struct
neofb_par
*
)
info
->
par
;
int
waitcycles
;
while
(
par
->
neo2200
->
bltStat
&
1
)
waitcycles
++
;
return
0
;
}
static
inline
void
neo2200_wait_fifo
(
struct
fb_info
*
info
,
...
...
drivers/video/riva/fbdev.c
View file @
85fa8aa4
...
...
@@ -25,7 +25,6 @@
* Known bugs and issues:
* restoring text mode fails
* doublescan modes are broken
* option 'noaccel' has no effect
*/
#include <linux/config.h>
...
...
@@ -34,11 +33,9 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/selection.h>
#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/console.h>
...
...
@@ -55,7 +52,7 @@
/* version number of this driver */
#define RIVAFB_VERSION "0.9.
2a
"
#define RIVAFB_VERSION "0.9.
3
"
...
...
@@ -109,10 +106,7 @@
static
int
rivafb_blank
(
int
blank
,
struct
fb_info
*
info
);
extern
void
riva_setup_accel
(
struct
rivafb_info
*
rinfo
);
extern
inline
void
wait_for_idle
(
struct
rivafb_info
*
rinfo
);
extern
inline
void
wait_for_idle
(
struct
riva_par
*
par
);
/* ------------------------------------------------------------------------- *
*
...
...
@@ -136,6 +130,11 @@ enum riva_chips {
CH_GEFORCE2_GTS
,
CH_GEFORCE2_ULTRA
,
CH_QUADRO2_PRO
,
CH_GEFORCE2_GO
,
CH_GEFORCE3
,
CH_GEFORCE3_1
,
CH_GEFORCE3_2
,
CH_QUADRO_DDC
};
/* directly indexed by riva_chips enum, above */
...
...
@@ -158,6 +157,11 @@ static struct riva_chip_info {
{
"GeForce2-GTS"
,
NV_ARCH_10
},
{
"GeForce2-ULTRA"
,
NV_ARCH_10
},
{
"Quadro2-PRO"
,
NV_ARCH_10
},
{
"GeForce2-Go"
,
NV_ARCH_10
},
{
"GeForce3"
,
NV_ARCH_20
},
{
"GeForce3 Ti 200"
,
NV_ARCH_20
},
{
"GeForce3 Ti 500"
,
NV_ARCH_20
},
{
"Quadro DDC"
,
NV_ARCH_20
}
};
static
struct
pci_device_id
rivafb_pci_tbl
[]
__devinitdata
=
{
...
...
@@ -195,6 +199,16 @@ static struct pci_device_id rivafb_pci_tbl[] __devinitdata = {
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
CH_GEFORCE2_ULTRA
},
{
PCI_VENDOR_ID_NVIDIA
,
PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
CH_QUADRO2_PRO
},
{
PCI_VENDOR_ID_NVIDIA
,
PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
CH_GEFORCE2_GO
},
{
PCI_VENDOR_ID_NVIDIA
,
PCI_DEVICE_ID_NVIDIA_GEFORCE3
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
CH_GEFORCE3
},
{
PCI_VENDOR_ID_NVIDIA
,
PCI_DEVICE_ID_NVIDIA_GEFORCE3_1
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
CH_GEFORCE3_1
},
{
PCI_VENDOR_ID_NVIDIA
,
PCI_DEVICE_ID_NVIDIA_GEFORCE3_2
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
CH_GEFORCE3_2
},
{
PCI_VENDOR_ID_NVIDIA
,
PCI_DEVICE_ID_NVIDIA_QUADRO_DDC
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
CH_QUADRO_DDC
},
{
0
,
}
/* terminate list */
};
MODULE_DEVICE_TABLE
(
pci
,
rivafb_pci_tbl
);
...
...
@@ -207,24 +221,9 @@ MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
*
* ------------------------------------------------------------------------- */
#ifdef FBCON_HAS_CFB8
extern
struct
display_switch
fbcon_riva8
;
#endif
#ifdef FBCON_HAS_CFB16
extern
struct
display_switch
fbcon_riva16
;
#endif
#ifdef FBCON_HAS_CFB32
extern
struct
display_switch
fbcon_riva32
;
#endif
#if 0
/* describes the state of a Riva board */
struct rivafb_par {
struct riva_regs state; /* state of hw board */
__u32 visual; /* FB_VISUAL_xxx */
unsigned depth; /* bpp of current mode */
};
#endif
struct
riva_cursor
{
int
enable
;
...
...
@@ -239,19 +238,15 @@ struct riva_cursor {
struct
timer_list
*
timer
;
};
/* ------------------------------------------------------------------------- *
*
* global variables
*
* ------------------------------------------------------------------------- */
struct
rivafb_info
*
riva_boards
=
NULL
;
/* command line data, set in rivafb_setup() */
static
char
fontname
[
40
]
__initdata
=
{
0
};
static
char
noaccel
__initdata
=
0
;
static
u32
pseudo_palette
[
17
]
;
static
char
nomove
=
0
;
static
char
nohwcursor
__initdata
=
0
;
static
char
noblink
=
0
;
...
...
@@ -265,33 +260,40 @@ static char *mode_option __initdata = NULL;
static
char
*
font
=
NULL
;
#endif
static
struct
fb_fix_screeninfo
rivafb_fix
=
{
id:
"nVidia"
,
type:
FB_TYPE_PACKED_PIXELS
,
xpanstep:
1
,
ypanstep:
1
,
};
static
struct
fb_var_screeninfo
rivafb_default_var
=
{
.
xres
=
640
,
.
yres
=
480
,
.
xres_virtual
=
640
,
.
yres_virtual
=
480
,
.
xoffset
=
0
,
.
yoffset
=
0
,
.
bits_per_pixel
=
8
,
.
grayscale
=
0
,
.
red
=
{
0
,
6
,
0
},
.
green
=
{
0
,
6
,
0
},
.
blue
=
{
0
,
6
,
0
},
.
transp
=
{
0
,
0
,
0
},
.
nonstd
=
0
,
.
activate
=
0
,
.
height
=
-
1
,
.
width
=
-
1
,
.
accel_flags
=
0
,
.
pixclock
=
39721
,
.
left_margin
=
40
,
.
right_margin
=
24
,
.
upper_margin
=
32
,
.
lower_margin
=
11
,
.
hsync_len
=
96
,
.
vsync_len
=
2
,
.
sync
=
0
,
.
vmode
=
FB_VMODE_NONINTERLACED
xres:
640
,
yres:
480
,
xres_virtual:
640
,
yres_virtual:
480
,
xoffset:
0
,
yoffset:
0
,
bits_per_pixel:
8
,
grayscale:
0
,
red:
{
0
,
6
,
0
},
green:
{
0
,
6
,
0
},
blue:
{
0
,
6
,
0
},
transp:
{
0
,
0
,
0
},
nonstd:
0
,
activate:
0
,
height:
-
1
,
width:
-
1
,
accel_flags:
FB_ACCELF_TEXT
,
pixclock:
39721
,
left_margin:
40
,
right_margin:
24
,
upper_margin:
32
,
lower_margin:
11
,
hsync_len:
96
,
vsync_len:
2
,
sync:
0
,
vmode:
FB_VMODE_NONINTERLACED
};
/* from GGI */
...
...
@@ -323,70 +325,70 @@ static const struct riva_regs reg_template = {
*
* ------------------------------------------------------------------------- */
static
inline
void
CRTCout
(
struct
riva
fb_info
*
rinfo
,
unsigned
char
index
,
static
inline
void
CRTCout
(
struct
riva
_par
*
par
,
unsigned
char
index
,
unsigned
char
val
)
{
VGA_WR08
(
rinfo
->
riva
.
PCIO
,
0x3d4
,
index
);
VGA_WR08
(
rinfo
->
riva
.
PCIO
,
0x3d5
,
val
);
VGA_WR08
(
par
->
riva
.
PCIO
,
0x3d4
,
index
);
VGA_WR08
(
par
->
riva
.
PCIO
,
0x3d5
,
val
);
}
static
inline
unsigned
char
CRTCin
(
struct
riva
fb_info
*
rinfo
,
static
inline
unsigned
char
CRTCin
(
struct
riva
_par
*
par
,
unsigned
char
index
)
{
VGA_WR08
(
rinfo
->
riva
.
PCIO
,
0x3d4
,
index
);
return
(
VGA_RD08
(
rinfo
->
riva
.
PCIO
,
0x3d5
));
VGA_WR08
(
par
->
riva
.
PCIO
,
0x3d4
,
index
);
return
(
VGA_RD08
(
par
->
riva
.
PCIO
,
0x3d5
));
}
static
inline
void
GRAout
(
struct
riva
fb_info
*
rinfo
,
unsigned
char
index
,
static
inline
void
GRAout
(
struct
riva
_par
*
par
,
unsigned
char
index
,
unsigned
char
val
)
{
VGA_WR08
(
rinfo
->
riva
.
PVIO
,
0x3ce
,
index
);
VGA_WR08
(
rinfo
->
riva
.
PVIO
,
0x3cf
,
val
);
VGA_WR08
(
par
->
riva
.
PVIO
,
0x3ce
,
index
);
VGA_WR08
(
par
->
riva
.
PVIO
,
0x3cf
,
val
);
}
static
inline
unsigned
char
GRAin
(
struct
riva
fb_info
*
rinfo
,
static
inline
unsigned
char
GRAin
(
struct
riva
_par
*
par
,
unsigned
char
index
)
{
VGA_WR08
(
rinfo
->
riva
.
PVIO
,
0x3ce
,
index
);
return
(
VGA_RD08
(
rinfo
->
riva
.
PVIO
,
0x3cf
));
VGA_WR08
(
par
->
riva
.
PVIO
,
0x3ce
,
index
);
return
(
VGA_RD08
(
par
->
riva
.
PVIO
,
0x3cf
));
}
static
inline
void
SEQout
(
struct
riva
fb_info
*
rinfo
,
unsigned
char
index
,
static
inline
void
SEQout
(
struct
riva
_par
*
par
,
unsigned
char
index
,
unsigned
char
val
)
{
VGA_WR08
(
rinfo
->
riva
.
PVIO
,
0x3c4
,
index
);
VGA_WR08
(
rinfo
->
riva
.
PVIO
,
0x3c5
,
val
);
VGA_WR08
(
par
->
riva
.
PVIO
,
0x3c4
,
index
);
VGA_WR08
(
par
->
riva
.
PVIO
,
0x3c5
,
val
);
}
static
inline
unsigned
char
SEQin
(
struct
riva
fb_info
*
rinfo
,
static
inline
unsigned
char
SEQin
(
struct
riva
_par
*
par
,
unsigned
char
index
)
{
VGA_WR08
(
rinfo
->
riva
.
PVIO
,
0x3c4
,
index
);
return
(
VGA_RD08
(
rinfo
->
riva
.
PVIO
,
0x3c5
));
VGA_WR08
(
par
->
riva
.
PVIO
,
0x3c4
,
index
);
return
(
VGA_RD08
(
par
->
riva
.
PVIO
,
0x3c5
));
}
static
inline
void
ATTRout
(
struct
riva
fb_info
*
rinfo
,
unsigned
char
index
,
static
inline
void
ATTRout
(
struct
riva
_par
*
par
,
unsigned
char
index
,
unsigned
char
val
)
{
VGA_WR08
(
rinfo
->
riva
.
PCIO
,
0x3c0
,
index
);
VGA_WR08
(
rinfo
->
riva
.
PCIO
,
0x3c0
,
val
);
VGA_WR08
(
par
->
riva
.
PCIO
,
0x3c0
,
index
);
VGA_WR08
(
par
->
riva
.
PCIO
,
0x3c0
,
val
);
}
static
inline
unsigned
char
ATTRin
(
struct
riva
fb_info
*
rinfo
,
static
inline
unsigned
char
ATTRin
(
struct
riva
_par
*
par
,
unsigned
char
index
)
{
VGA_WR08
(
rinfo
->
riva
.
PCIO
,
0x3c0
,
index
);
return
(
VGA_RD08
(
rinfo
->
riva
.
PCIO
,
0x3c1
));
VGA_WR08
(
par
->
riva
.
PCIO
,
0x3c0
,
index
);
return
(
VGA_RD08
(
par
->
riva
.
PCIO
,
0x3c1
));
}
static
inline
void
MISCout
(
struct
riva
fb_info
*
rinfo
,
unsigned
char
val
)
static
inline
void
MISCout
(
struct
riva
_par
*
par
,
unsigned
char
val
)
{
VGA_WR08
(
rinfo
->
riva
.
PVIO
,
0x3c2
,
val
);
VGA_WR08
(
par
->
riva
.
PVIO
,
0x3c2
,
val
);
}
static
inline
unsigned
char
MISCin
(
struct
riva
fb_info
*
rinfo
)
static
inline
unsigned
char
MISCin
(
struct
riva
_par
*
par
)
{
return
(
VGA_RD08
(
rinfo
->
riva
.
PVIO
,
0x3cc
));
return
(
VGA_RD08
(
par
->
riva
.
PVIO
,
0x3cc
));
}
...
...
@@ -399,39 +401,39 @@ static inline unsigned char MISCin(struct rivafb_info *rinfo)
/**
* riva_cursor_timer_handler - blink timer
* @dev_addr: pointer to riva
fb_info
object containing info for current riva board
* @dev_addr: pointer to riva
_par
object containing info for current riva board
*
* DESCRIPTION:
* Cursor blink timer.
*/
static
void
riva_cursor_timer_handler
(
unsigned
long
dev_addr
)
{
struct
riva
fb_info
*
rinfo
=
(
struct
rivafb_info
*
)
dev_addr
;
struct
riva
_par
*
par
=
(
struct
riva_par
*
)
dev_addr
;
if
(
!
rinfo
->
cursor
)
return
;
if
(
!
par
->
cursor
)
return
;
if
(
!
rinfo
->
cursor
->
enable
)
goto
out
;
if
(
!
par
->
cursor
->
enable
)
goto
out
;
if
(
rinfo
->
cursor
->
last_move_delay
<
1000
)
rinfo
->
cursor
->
last_move_delay
++
;
if
(
par
->
cursor
->
last_move_delay
<
1000
)
par
->
cursor
->
last_move_delay
++
;
if
(
rinfo
->
cursor
->
vbl_cnt
&&
--
rinfo
->
cursor
->
vbl_cnt
==
0
)
{
rinfo
->
cursor
->
on
^=
1
;
if
(
rinfo
->
cursor
->
on
)
*
(
rinfo
->
riva
.
CURSORPOS
)
=
(
rinfo
->
cursor
->
pos
.
x
&
0xFFFF
)
|
(
rinfo
->
cursor
->
pos
.
y
<<
16
);
rinfo
->
riva
.
ShowHideCursor
(
&
rinfo
->
riva
,
rinfo
->
cursor
->
on
);
if
(
par
->
cursor
->
vbl_cnt
&&
--
par
->
cursor
->
vbl_cnt
==
0
)
{
par
->
cursor
->
on
^=
1
;
if
(
par
->
cursor
->
on
)
*
(
par
->
riva
.
CURSORPOS
)
=
(
par
->
cursor
->
pos
.
x
&
0xFFFF
)
|
(
par
->
cursor
->
pos
.
y
<<
16
);
par
->
riva
.
ShowHideCursor
(
&
par
->
riva
,
par
->
cursor
->
on
);
if
(
!
noblink
)
rinfo
->
cursor
->
vbl_cnt
=
rinfo
->
cursor
->
blink_rate
;
par
->
cursor
->
vbl_cnt
=
par
->
cursor
->
blink_rate
;
}
out:
rinfo
->
cursor
->
timer
->
expires
=
jiffies
+
(
HZ
/
100
);
add_timer
(
rinfo
->
cursor
->
timer
);
par
->
cursor
->
timer
->
expires
=
jiffies
+
(
HZ
/
100
);
add_timer
(
par
->
cursor
->
timer
);
}
/**
* rivafb_init_cursor - allocates cursor structure and starts blink timer
* @
rinfo: pointer to rivafb_info
object containing info for current riva board
* @
par: pointer to riva_par
object containing info for current riva board
*
* DESCRIPTION:
* Allocates cursor structure and starts blink timer.
...
...
@@ -442,7 +444,7 @@ static void riva_cursor_timer_handler(unsigned long dev_addr)
* CALLED FROM:
* rivafb_init_one()
*/
static
struct
riva_cursor
*
__init
rivafb_init_cursor
(
struct
riva
fb_info
*
rinfo
)
static
struct
riva_cursor
*
__init
rivafb_init_cursor
(
struct
riva
_par
*
par
)
{
struct
riva_cursor
*
cursor
;
...
...
@@ -461,7 +463,7 @@ static struct riva_cursor * __init rivafb_init_cursor(struct rivafb_info *rinfo)
init_timer
(
cursor
->
timer
);
cursor
->
timer
->
expires
=
jiffies
+
(
HZ
/
100
);
cursor
->
timer
->
data
=
(
unsigned
long
)
rinfo
;
cursor
->
timer
->
data
=
(
unsigned
long
)
par
;
cursor
->
timer
->
function
=
riva_cursor_timer_handler
;
add_timer
(
cursor
->
timer
);
...
...
@@ -470,7 +472,7 @@ static struct riva_cursor * __init rivafb_init_cursor(struct rivafb_info *rinfo)
/**
* rivafb_exit_cursor - stops blink timer and releases cursor structure
* @
rinfo: pointer to rivafb_info
object containing info for current riva board
* @
par: pointer to riva_par
object containing info for current riva board
*
* DESCRIPTION:
* Stops blink timer and releases cursor structure.
...
...
@@ -479,9 +481,9 @@ static struct riva_cursor * __init rivafb_init_cursor(struct rivafb_info *rinfo)
* rivafb_init_one()
* rivafb_remove_one()
*/
static
void
rivafb_exit_cursor
(
struct
riva
fb_info
*
rinfo
)
static
void
rivafb_exit_cursor
(
struct
riva
_par
*
par
)
{
struct
riva_cursor
*
cursor
=
rinfo
->
cursor
;
struct
riva_cursor
*
cursor
=
par
->
cursor
;
if
(
cursor
)
{
if
(
cursor
->
timer
)
{
...
...
@@ -489,13 +491,13 @@ static void rivafb_exit_cursor(struct rivafb_info *rinfo)
kfree
(
cursor
->
timer
);
}
kfree
(
cursor
);
rinfo
->
cursor
=
0
;
par
->
cursor
=
0
;
}
}
/**
* rivafb_download_cursor - writes cursor shape into card registers
* @
rinfo: pointer to riva
fb_info object containing info for current riva board
* @
info: pointer to
fb_info object containing info for current riva board
*
* DESCRIPTION:
* Writes cursor shape into card registers.
...
...
@@ -503,24 +505,25 @@ static void rivafb_exit_cursor(struct rivafb_info *rinfo)
* CALLED FROM:
* riva_load_video_mode()
*/
static
void
rivafb_download_cursor
(
struct
rivafb_info
*
r
info
)
static
void
rivafb_download_cursor
(
struct
fb_info
*
info
)
{
struct
riva_par
*
par
=
(
struct
riva_par
*
)
info
->
par
;
int
i
,
save
;
int
*
image
;
if
(
!
rinfo
->
cursor
)
return
;
if
(
!
par
->
cursor
)
return
;
image
=
(
int
*
)
rinfo
->
cursor
->
image
;
save
=
rinfo
->
riva
.
ShowHideCursor
(
&
rinfo
->
riva
,
0
);
image
=
(
int
*
)
par
->
cursor
->
image
;
save
=
par
->
riva
.
ShowHideCursor
(
&
par
->
riva
,
0
);
for
(
i
=
0
;
i
<
(
MAX_CURS
*
MAX_CURS
*
2
)
/
sizeof
(
int
);
i
++
)
writel
(
image
[
i
],
rinfo
->
riva
.
CURSOR
+
i
);
writel
(
image
[
i
],
par
->
riva
.
CURSOR
+
i
);
rinfo
->
riva
.
ShowHideCursor
(
&
rinfo
->
riva
,
save
);
par
->
riva
.
ShowHideCursor
(
&
par
->
riva
,
save
);
}
/**
* rivafb_create_cursor - sets rectangular cursor
* @
rinfo: pointer to riva
fb_info object containing info for current riva board
* @
info: pointer to
fb_info object containing info for current riva board
* @width: cursor width in pixels
* @height: cursor height in pixels
*
...
...
@@ -531,9 +534,10 @@ static void rivafb_download_cursor(struct rivafb_info *rinfo)
* rivafb_set_font()
* rivafb_set_var()
*/
static
void
rivafb_create_cursor
(
struct
rivafb_info
*
r
info
,
int
width
,
int
height
)
static
void
rivafb_create_cursor
(
struct
fb_info
*
info
,
int
width
,
int
height
)
{
struct
riva_cursor
*
c
=
rinfo
->
cursor
;
struct
riva_par
*
par
=
(
struct
riva_par
*
)
info
->
par
;
struct
riva_cursor
*
c
=
par
->
cursor
;
int
i
,
j
,
idx
;
if
(
c
)
{
...
...
@@ -575,9 +579,7 @@ static void rivafb_create_cursor(struct rivafb_info *rinfo, int width, int heigh
*/
static
int
rivafb_set_font
(
struct
display
*
p
,
int
width
,
int
height
)
{
struct
rivafb_info
*
fb
=
(
struct
rivafb_info
*
)(
p
->
fb_info
);
rivafb_create_cursor
(
fb
,
width
,
height
);
rivafb_create_cursor
(
p
->
fb_info
,
width
,
height
);
return
1
;
}
...
...
@@ -593,8 +595,9 @@ static int rivafb_set_font(struct display *p, int width, int height)
*/
static
void
rivafb_cursor
(
struct
display
*
p
,
int
mode
,
int
x
,
int
y
)
{
struct
rivafb_info
*
rinfo
=
(
struct
rivafb_info
*
)(
p
->
fb_info
);
struct
riva_cursor
*
c
=
rinfo
->
cursor
;
struct
fb_info
*
info
=
p
->
fb_info
;
struct
riva_par
*
par
=
(
struct
riva_par
*
)
info
->
par
;
struct
riva_cursor
*
c
=
par
->
cursor
;
if
(
!
c
)
return
;
...
...
@@ -605,7 +608,7 @@ static void rivafb_cursor(struct display *p, int mode, int x, int y)
return
;
c
->
enable
=
0
;
if
(
c
->
on
)
rinfo
->
riva
.
ShowHideCursor
(
&
rinfo
->
riva
,
0
);
if
(
c
->
on
)
par
->
riva
.
ShowHideCursor
(
&
par
->
riva
,
0
);
c
->
pos
.
x
=
x
;
c
->
pos
.
y
=
y
;
...
...
@@ -619,8 +622,8 @@ static void rivafb_cursor(struct display *p, int mode, int x, int y)
if
(
c
->
last_move_delay
<=
1
)
{
/* rapid cursor movement */
c
->
vbl_cnt
=
CURSOR_SHOW_DELAY
;
}
else
{
*
(
rinfo
->
riva
.
CURSORPOS
)
=
(
x
&
0xFFFF
)
|
(
y
<<
16
);
rinfo
->
riva
.
ShowHideCursor
(
&
rinfo
->
riva
,
1
);
*
(
par
->
riva
.
CURSORPOS
)
=
(
x
&
0xFFFF
)
|
(
y
<<
16
);
par
->
riva
.
ShowHideCursor
(
&
par
->
riva
,
1
);
if
(
!
noblink
)
c
->
vbl_cnt
=
CURSOR_HIDE_DELAY
;
c
->
on
=
1
;
}
...
...
@@ -630,88 +633,12 @@ static void rivafb_cursor(struct display *p, int mode, int x, int y)
}
}
/* ------------------------------------------------------------------------- *
*
* general utility functions
*
* ------------------------------------------------------------------------- */
/**
* riva_set_dispsw - sets dispsw
* @rinfo: pointer to internal driver struct for a given Riva card
* @disp: pointer to display object
*
* DESCRIPTION:
* Sets up console low level operations depending on the current? color depth
* of the display.
*
* CALLED FROM:
* rivafb_set_var()
* rivafb_switch()
* riva_init_disp()
*/
static
void
riva_set_dispsw
(
struct
rivafb_info
*
rinfo
,
struct
display
*
disp
)
{
int
accel
=
disp
->
var
.
accel_flags
&
FB_ACCELF_TEXT
;
DPRINTK
(
"ENTER
\n
"
);
assert
(
rinfo
!=
NULL
);
disp
->
dispsw_data
=
NULL
;
disp
->
type
=
FB_TYPE_PACKED_PIXELS
;
disp
->
type_aux
=
0
;
disp
->
ypanstep
=
1
;
disp
->
ywrapstep
=
0
;
disp
->
can_soft_blank
=
1
;
disp
->
inverse
=
0
;
switch
(
disp
->
var
.
bits_per_pixel
)
{
#ifdef FBCON_HAS_CFB8
case
8
:
rinfo
->
dispsw
=
accel
?
fbcon_riva8
:
fbcon_cfb8
;
disp
->
dispsw
=
&
rinfo
->
dispsw
;
disp
->
line_length
=
disp
->
var
.
xres_virtual
;
disp
->
visual
=
FB_VISUAL_PSEUDOCOLOR
;
break
;
#endif
#ifdef FBCON_HAS_CFB16
case
16
:
rinfo
->
dispsw
=
accel
?
fbcon_riva16
:
fbcon_cfb16
;
disp
->
dispsw_data
=
&
rinfo
->
con_cmap
.
cfb16
;
disp
->
dispsw
=
&
rinfo
->
dispsw
;
disp
->
line_length
=
disp
->
var
.
xres_virtual
*
2
;
disp
->
visual
=
FB_VISUAL_DIRECTCOLOR
;
break
;
#endif
#ifdef FBCON_HAS_CFB32
case
32
:
rinfo
->
dispsw
=
accel
?
fbcon_riva32
:
fbcon_cfb32
;
disp
->
dispsw_data
=
rinfo
->
con_cmap
.
cfb32
;
disp
->
dispsw
=
&
rinfo
->
dispsw
;
disp
->
line_length
=
disp
->
var
.
xres_virtual
*
4
;
disp
->
visual
=
FB_VISUAL_DIRECTCOLOR
;
break
;
#endif
default:
DPRINTK
(
"Setting fbcon_dummy renderer
\n
"
);
rinfo
->
dispsw
=
fbcon_dummy
;
disp
->
dispsw
=
&
rinfo
->
dispsw
;
}
/* FIXME: verify that the above code sets dsp->* fields correctly */
if
(
rinfo
->
cursor
)
{
rinfo
->
dispsw
.
cursor
=
rivafb_cursor
;
rinfo
->
dispsw
.
set_font
=
rivafb_set_font
;
}
DPRINTK
(
"EXIT
\n
"
);
}
/**
* riva_wclut - set CLUT entry
* @chip: pointer to RIVA_HW_INST object
...
...
@@ -738,7 +665,7 @@ static void riva_wclut(RIVA_HW_INST *chip,
/**
* riva_save_state - saves current chip state
* @
rinfo: pointer to rivafb_info
object containing info for current riva board
* @
par: pointer to riva_par
object containing info for current riva board
* @regs: pointer to riva_regs object
*
* DESCRIPTION:
...
...
@@ -748,36 +675,36 @@ static void riva_wclut(RIVA_HW_INST *chip,
* rivafb_init_one()
*/
/* from GGI */
static
void
riva_save_state
(
struct
riva
fb_info
*
rinfo
,
struct
riva_regs
*
regs
)
static
void
riva_save_state
(
struct
riva
_par
*
par
,
struct
riva_regs
*
regs
)
{
int
i
;
rinfo
->
riva
.
LockUnlock
(
&
rinfo
->
riva
,
0
);
par
->
riva
.
LockUnlock
(
&
par
->
riva
,
0
);
rinfo
->
riva
.
UnloadStateExt
(
&
rinfo
->
riva
,
&
regs
->
ext
);
par
->
riva
.
UnloadStateExt
(
&
par
->
riva
,
&
regs
->
ext
);
regs
->
misc_output
=
MISCin
(
rinfo
);
regs
->
misc_output
=
MISCin
(
par
);
for
(
i
=
0
;
i
<
NUM_CRT_REGS
;
i
++
)
{
regs
->
crtc
[
i
]
=
CRTCin
(
rinfo
,
i
);
regs
->
crtc
[
i
]
=
CRTCin
(
par
,
i
);
}
for
(
i
=
0
;
i
<
NUM_ATC_REGS
;
i
++
)
{
regs
->
attr
[
i
]
=
ATTRin
(
rinfo
,
i
);
regs
->
attr
[
i
]
=
ATTRin
(
par
,
i
);
}
for
(
i
=
0
;
i
<
NUM_GRC_REGS
;
i
++
)
{
regs
->
gra
[
i
]
=
GRAin
(
rinfo
,
i
);
regs
->
gra
[
i
]
=
GRAin
(
par
,
i
);
}
for
(
i
=
0
;
i
<
NUM_SEQ_REGS
;
i
++
)
{
regs
->
seq
[
i
]
=
SEQin
(
rinfo
,
i
);
regs
->
seq
[
i
]
=
SEQin
(
par
,
i
);
}
}
/**
* riva_load_state - loads current chip state
* @
rinfo: pointer to rivafb_info
object containing info for current riva board
* @
par: pointer to riva_par
object containing info for current riva board
* @regs: pointer to riva_regs object
*
* DESCRIPTION:
...
...
@@ -789,18 +716,18 @@ static void riva_save_state(struct rivafb_info *rinfo, struct riva_regs *regs)
* rivafb_remove_one()
*/
/* from GGI */
static
void
riva_load_state
(
struct
riva
fb_info
*
rinfo
,
struct
riva_regs
*
regs
)
static
void
riva_load_state
(
struct
riva
_par
*
par
,
struct
riva_regs
*
regs
)
{
int
i
;
RIVA_HW_STATE
*
state
=
&
regs
->
ext
;
int
i
;
CRTCout
(
rinfo
,
0x11
,
0x00
);
CRTCout
(
par
,
0x11
,
0x00
);
rinfo
->
riva
.
LockUnlock
(
&
rinfo
->
riva
,
0
);
par
->
riva
.
LockUnlock
(
&
par
->
riva
,
0
);
rinfo
->
riva
.
LoadStateExt
(
&
rinfo
->
riva
,
state
);
par
->
riva
.
LoadStateExt
(
&
par
->
riva
,
state
);
MISCout
(
rinfo
,
regs
->
misc_output
);
MISCout
(
par
,
regs
->
misc_output
);
for
(
i
=
0
;
i
<
NUM_CRT_REGS
;
i
++
)
{
switch
(
i
)
{
...
...
@@ -808,26 +735,26 @@ static void riva_load_state(struct rivafb_info *rinfo, struct riva_regs *regs)
case
0x20
...
0x40
:
break
;
default:
CRTCout
(
rinfo
,
i
,
regs
->
crtc
[
i
]);
CRTCout
(
par
,
i
,
regs
->
crtc
[
i
]);
}
}
for
(
i
=
0
;
i
<
NUM_ATC_REGS
;
i
++
)
{
ATTRout
(
rinfo
,
i
,
regs
->
attr
[
i
]);
ATTRout
(
par
,
i
,
regs
->
attr
[
i
]);
}
for
(
i
=
0
;
i
<
NUM_GRC_REGS
;
i
++
)
{
GRAout
(
rinfo
,
i
,
regs
->
gra
[
i
]);
GRAout
(
par
,
i
,
regs
->
gra
[
i
]);
}
for
(
i
=
0
;
i
<
NUM_SEQ_REGS
;
i
++
)
{
SEQout
(
rinfo
,
i
,
regs
->
seq
[
i
]);
SEQout
(
par
,
i
,
regs
->
seq
[
i
]);
}
}
/**
* riva_load_video_mode - calculate timings
* @
rinfo: pointer to riva
fb_info object containing info for current riva board
* @
info: pointer to
fb_info object containing info for current riva board
* @video_mode: video mode to set
*
* DESCRIPTION:
...
...
@@ -836,36 +763,36 @@ static void riva_load_state(struct rivafb_info *rinfo, struct riva_regs *regs)
* CALLED FROM:
* rivafb_set_var()
*/
static
void
riva_load_video_mode
(
struct
rivafb_info
*
rinfo
,
struct
fb_var_screeninfo
*
video_mode
)
static
void
riva_load_video_mode
(
struct
fb_info
*
info
)
{
struct
riva_regs
newmode
;
int
bpp
,
width
,
hDisplaySize
,
hDisplay
,
hStart
,
hEnd
,
hTotal
,
height
,
vDisplay
,
vStart
,
vEnd
,
vTotal
,
dotClock
;
struct
riva_par
*
par
=
(
struct
riva_par
*
)
info
->
par
;
struct
riva_regs
newmode
;
/* time to calculate */
rivafb_blank
(
1
,
(
struct
fb_info
*
)
r
info
);
rivafb_blank
(
1
,
info
);
bpp
=
video_mode
->
bits_per_pixel
;
if
(
bpp
==
16
&&
video_mode
->
green
.
length
==
5
)
bpp
=
info
->
var
.
bits_per_pixel
;
if
(
bpp
==
16
&&
info
->
var
.
green
.
length
==
5
)
bpp
=
15
;
width
=
video_mode
->
xres_virtual
;
hDisplaySize
=
video_mode
->
xres
;
width
=
info
->
var
.
xres_virtual
;
hDisplaySize
=
info
->
var
.
xres
;
hDisplay
=
(
hDisplaySize
/
8
)
-
1
;
hStart
=
(
hDisplaySize
+
video_mode
->
right_margin
)
/
8
+
2
;
hEnd
=
(
hDisplaySize
+
video_mode
->
right_margin
+
video_mode
->
hsync_len
)
/
8
-
1
;
hTotal
=
(
hDisplaySize
+
video_mode
->
right_margin
+
video_mode
->
hsync_len
+
video_mode
->
left_margin
)
/
8
-
1
;
height
=
video_mode
->
yres_virtual
;
vDisplay
=
video_mode
->
yres
-
1
;
vStart
=
video_mode
->
yres
+
video_mode
->
lower_margin
-
1
;
vEnd
=
video_mode
->
yres
+
video_mode
->
lower_margin
+
video_mode
->
vsync_len
-
1
;
vTotal
=
video_mode
->
yres
+
video_mode
->
lower_margin
+
video_mode
->
vsync_len
+
video_mode
->
upper_margin
+
2
;
dotClock
=
1000000000
/
video_mode
->
pixclock
;
hStart
=
(
hDisplaySize
+
info
->
var
.
right_margin
)
/
8
+
2
;
hEnd
=
(
hDisplaySize
+
info
->
var
.
right_margin
+
info
->
var
.
hsync_len
)
/
8
-
1
;
hTotal
=
(
hDisplaySize
+
info
->
var
.
right_margin
+
info
->
var
.
hsync_len
+
info
->
var
.
left_margin
)
/
8
-
1
;
height
=
info
->
var
.
yres_virtual
;
vDisplay
=
info
->
var
.
yres
-
1
;
vStart
=
info
->
var
.
yres
+
info
->
var
.
lower_margin
-
1
;
vEnd
=
info
->
var
.
yres
+
info
->
var
.
lower_margin
+
info
->
var
.
vsync_len
-
1
;
vTotal
=
info
->
var
.
yres
+
info
->
var
.
lower_margin
+
info
->
var
.
vsync_len
+
info
->
var
.
upper_margin
+
2
;
dotClock
=
1000000000
/
info
->
var
.
pixclock
;
memcpy
(
&
newmode
,
&
reg_template
,
sizeof
(
struct
riva_regs
));
...
...
@@ -899,83 +826,22 @@ static void riva_load_video_mode(struct rivafb_info *rinfo,
newmode
.
ext
.
width
=
width
;
newmode
.
ext
.
height
=
height
;
rinfo
->
riva
.
CalcStateExt
(
&
rinfo
->
riva
,
&
newmode
.
ext
,
bpp
,
width
,
par
->
riva
.
CalcStateExt
(
&
par
->
riva
,
&
newmode
.
ext
,
bpp
,
width
,
hDisplaySize
,
hDisplay
,
hStart
,
hEnd
,
hTotal
,
height
,
vDisplay
,
vStart
,
vEnd
,
vTotal
,
dotClock
);
rinfo
->
current_state
=
newmode
;
riva_load_state
(
rinfo
,
&
rinfo
->
current_state
);
par
->
current_state
=
newmode
;
riva_load_state
(
par
,
&
par
->
current_state
);
rinfo
->
riva
.
LockUnlock
(
&
rinfo
->
riva
,
0
);
/* important for HW cursor */
rivafb_download_cursor
(
rinfo
);
}
/**
* riva_board_list_add - maintains board list
* @board_list: root node of list of boards
* @new_node: new node to be added
*
* DESCRIPTION:
* Adds @new_node to the list referenced by @board_list.
*
* RETURNS:
* New root node
*
* CALLED FROM:
* rivafb_init_one()
*/
static
struct
rivafb_info
*
riva_board_list_add
(
struct
rivafb_info
*
board_list
,
struct
rivafb_info
*
new_node
)
{
struct
rivafb_info
*
i_p
=
board_list
;
new_node
->
next
=
NULL
;
if
(
board_list
==
NULL
)
return
new_node
;
while
(
i_p
->
next
!=
NULL
)
i_p
=
i_p
->
next
;
i_p
->
next
=
new_node
;
return
board_list
;
}
/**
* riva_board_list_del - maintains board list
* @board_list: root node of list of boards
* @del_node: node to be removed
*
* DESCRIPTION:
* Removes @del_node from the list referenced by @board_list.
*
* RETURNS:
* New root node
*
* CALLED FROM:
* rivafb_remove_one()
*/
static
struct
rivafb_info
*
riva_board_list_del
(
struct
rivafb_info
*
board_list
,
struct
rivafb_info
*
del_node
)
{
struct
rivafb_info
*
i_p
=
board_list
;
if
(
board_list
==
del_node
)
return
del_node
->
next
;
while
(
i_p
->
next
!=
del_node
)
i_p
=
i_p
->
next
;
i_p
->
next
=
del_node
->
next
;
return
board_list
;
par
->
riva
.
LockUnlock
(
&
par
->
riva
,
0
);
/* important for HW cursor */
rivafb_download_cursor
(
info
);
}
/**
* rivafb_do_maximize -
* @
rinfo: pointer to riva
fb_info object containing info for current riva board
* @
info: pointer to
fb_info object containing info for current riva board
* @var:
* @v:
* @nom:
* @den:
*
...
...
@@ -989,9 +855,8 @@ static struct rivafb_info *riva_board_list_del(struct rivafb_info *board_list,
* CALLED FROM:
* rivafb_set_var()
*/
static
int
rivafb_do_maximize
(
struct
rivafb_info
*
r
info
,
static
int
rivafb_do_maximize
(
struct
fb_info
*
info
,
struct
fb_var_screeninfo
*
var
,
struct
fb_var_screeninfo
*
v
,
int
nom
,
int
den
)
{
static
struct
{
...
...
@@ -1007,12 +872,12 @@ static int rivafb_do_maximize(struct rivafb_info *rinfo,
int
i
;
/* use highest possible virtual resolution */
if
(
v
->
xres_virtual
==
-
1
&&
v
->
yres_virtual
==
-
1
)
{
if
(
v
ar
->
xres_virtual
==
-
1
&&
var
->
yres_virtual
==
-
1
)
{
printk
(
KERN_WARNING
PFX
"using maximum available virtual resolution
\n
"
);
for
(
i
=
0
;
modes
[
i
].
xres
!=
-
1
;
i
++
)
{
if
(
modes
[
i
].
xres
*
nom
/
den
*
modes
[
i
].
yres
<
rinfo
->
ram_amount
/
2
)
info
->
fix
.
smem_len
/
2
)
break
;
}
if
(
modes
[
i
].
xres
==
-
1
)
{
...
...
@@ -1021,26 +886,26 @@ static int rivafb_do_maximize(struct rivafb_info *rinfo,
DPRINTK
(
"EXIT - EINVAL error
\n
"
);
return
-
EINVAL
;
}
v
->
xres_virtual
=
modes
[
i
].
xres
;
v
->
yres_virtual
=
modes
[
i
].
yres
;
v
ar
->
xres_virtual
=
modes
[
i
].
xres
;
v
ar
->
yres_virtual
=
modes
[
i
].
yres
;
printk
(
KERN_INFO
PFX
"virtual resolution set to maximum of %dx%d
\n
"
,
v
->
xres_virtual
,
v
->
yres_virtual
);
}
else
if
(
v
->
xres_virtual
==
-
1
)
{
v
->
xres_virtual
=
(
rinfo
->
ram_amount
*
den
/
(
nom
*
v
->
yres_virtual
*
2
))
&
~
15
;
v
ar
->
xres_virtual
,
var
->
yres_virtual
);
}
else
if
(
v
ar
->
xres_virtual
==
-
1
)
{
v
ar
->
xres_virtual
=
(
info
->
fix
.
smem_len
*
den
/
(
nom
*
v
ar
->
yres_virtual
*
2
))
&
~
15
;
printk
(
KERN_WARNING
PFX
"setting virtual X resolution to %d
\n
"
,
v
->
xres_virtual
);
}
else
if
(
v
->
yres_virtual
==
-
1
)
{
v
->
xres_virtual
=
(
v
->
xres_virtual
+
15
)
&
~
15
;
v
->
yres_virtual
=
rinfo
->
ram_amount
*
den
/
(
nom
*
v
->
xres_virtual
*
2
);
"setting virtual X resolution to %d
\n
"
,
v
ar
->
xres_virtual
);
}
else
if
(
v
ar
->
yres_virtual
==
-
1
)
{
v
ar
->
xres_virtual
=
(
var
->
xres_virtual
+
15
)
&
~
15
;
v
ar
->
yres_virtual
=
info
->
fix
.
smem_len
*
den
/
(
nom
*
v
ar
->
xres_virtual
*
2
);
printk
(
KERN_WARNING
PFX
"setting virtual Y resolution to %d
\n
"
,
v
->
yres_virtual
);
"setting virtual Y resolution to %d
\n
"
,
v
ar
->
yres_virtual
);
}
else
{
v
->
xres_virtual
=
(
v
->
xres_virtual
+
15
)
&
~
15
;
if
(
v
->
xres_virtual
*
nom
/
den
*
v
->
yres_virtual
>
rinfo
->
ram_amount
)
{
v
ar
->
xres_virtual
=
(
var
->
xres_virtual
+
15
)
&
~
15
;
if
(
v
ar
->
xres_virtual
*
nom
/
den
*
var
->
yres_virtual
>
info
->
fix
.
smem_len
)
{
printk
(
KERN_ERR
PFX
"mode %dx%dx%d rejected...resolution too high to fit into video memory!
\n
"
,
var
->
xres
,
var
->
yres
,
var
->
bits_per_pixel
);
...
...
@@ -1049,29 +914,55 @@ static int rivafb_do_maximize(struct rivafb_info *rinfo,
}
}
if
(
v
->
xres_virtual
*
nom
/
den
>=
8192
)
{
if
(
v
ar
->
xres_virtual
*
nom
/
den
>=
8192
)
{
printk
(
KERN_WARNING
PFX
"virtual X resolution (%d) is too high, lowering to %d
\n
"
,
v
->
xres_virtual
,
8192
*
den
/
nom
-
16
);
v
->
xres_virtual
=
8192
*
den
/
nom
-
16
;
v
ar
->
xres_virtual
,
8192
*
den
/
nom
-
16
);
v
ar
->
xres_virtual
=
8192
*
den
/
nom
-
16
;
}
if
(
v
->
xres_virtual
<
v
->
xres
)
{
if
(
v
ar
->
xres_virtual
<
var
->
xres
)
{
printk
(
KERN_ERR
PFX
"virtual X resolution (%d) is smaller than real
\n
"
,
v
->
xres_virtual
);
"virtual X resolution (%d) is smaller than real
\n
"
,
v
ar
->
xres_virtual
);
return
-
EINVAL
;
}
if
(
v
->
yres_virtual
<
v
->
yres
)
{
if
(
v
ar
->
yres_virtual
<
var
->
yres
)
{
printk
(
KERN_ERR
PFX
"virtual Y resolution (%d) is smaller than real
\n
"
,
v
->
yres_virtual
);
"virtual Y resolution (%d) is smaller than real
\n
"
,
v
ar
->
yres_virtual
);
return
-
EINVAL
;
}
return
0
;
}
/* acceleration routines */
inline
void
wait_for_idle
(
struct
riva_par
*
par
)
{
while
(
par
->
riva
.
Busy
(
&
par
->
riva
));
}
/* set copy ROP, no mask */
static
void
riva_setup_ROP
(
struct
riva_par
*
par
)
{
RIVA_FIFO_FREE
(
par
->
riva
,
Patt
,
5
);
par
->
riva
.
Patt
->
Shape
=
0
;
par
->
riva
.
Patt
->
Color0
=
0xffffffff
;
par
->
riva
.
Patt
->
Color1
=
0xffffffff
;
par
->
riva
.
Patt
->
Monochrome
[
0
]
=
0xffffffff
;
par
->
riva
.
Patt
->
Monochrome
[
1
]
=
0xffffffff
;
RIVA_FIFO_FREE
(
par
->
riva
,
Rop
,
1
);
par
->
riva
.
Rop
->
Rop3
=
0xCC
;
}
void
riva_setup_accel
(
struct
riva_par
*
par
)
{
RIVA_FIFO_FREE
(
par
->
riva
,
Clip
,
2
);
par
->
riva
.
Clip
->
TopLeft
=
0x0
;
par
->
riva
.
Clip
->
WidthHeight
=
0x80008000
;
riva_setup_ROP
(
par
);
wait_for_idle
(
par
);
}
/* ------------------------------------------------------------------------- *
*
...
...
@@ -1102,344 +993,84 @@ static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
assert
(
var
!=
NULL
);
switch
(
var
->
bits_per_pixel
)
{
#ifdef FBCON_HAS_CFB8
case
8
:
rc
=
256
;
/* pseudocolor... 256 entries HW palette */
break
;
#endif
#ifdef FBCON_HAS_CFB16
case
15
:
rc
=
15
;
/* fix for 15 bpp depths on Riva 128 based cards */
break
;
case
16
:
rc
=
16
;
/* directcolor... 16 entries SW palette */
break
;
/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
#endif
#ifdef FBCON_HAS_CFB32
case
32
:
rc
=
16
;
/* directcolor... 16 entries SW palette */
break
;
/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
#endif
default:
/* should not occur */
break
;
}
return
rc
;
}
/**
* riva_getcolreg
* @regno: register index
* @red: red component
* @green: green component
* @blue: blue component
* @transp: transparency
* @info: pointer to rivafb_info object containing info for current riva board
*
* DESCRIPTION:
* Read a single color register and split it into colors/transparent.
* The return values must have a 16 bit magnitude.
*
* RETURNS:
* Return != 0 for invalid regno.
*
* CALLED FROM:
* rivafb_get_cmap()
* rivafb_switch()
* fbcmap.c:fb_get_cmap()
* fbgen.c:fbgen_get_cmap()
* fbgen.c:fbgen_switch()
*/
static
int
riva_getcolreg
(
unsigned
regno
,
unsigned
*
red
,
unsigned
*
green
,
unsigned
*
blue
,
unsigned
*
transp
,
struct
fb_info
*
info
)
{
struct
rivafb_info
*
rivainfo
=
(
struct
rivafb_info
*
)
info
;
if
(
regno
>=
riva_get_cmap_len
(
&
rivainfo
->
currcon_display
->
var
))
return
1
;
*
red
=
rivainfo
->
palette
[
regno
].
red
;
*
green
=
rivainfo
->
palette
[
regno
].
green
;
*
blue
=
rivainfo
->
palette
[
regno
].
blue
;
*
transp
=
0
;
return
0
;
}
/**
* rivafb_setcolreg
* @regno: register index
* @red: red component
* @green: green component
* @blue: blue component
* @transp: transparency
* @info: pointer to rivafb_info object containing info for current riva board
*
* DESCRIPTION:
* Set a single color register. The values supplied have a 16 bit
* magnitude.
*
* RETURNS:
* Return != 0 for invalid regno.
*
* CALLED FROM:
* rivafb_set_cmap()
* fbcmap.c:fb_set_cmap()
* fbgen.c:fbgen_get_cmap()
* fbgen.c:do_install_cmap()
* fbgen.c:fbgen_set_var()
* fbgen.c:fbgen_switch()
* fbgen.c:fbgen_blank()
* fbgen.c:fbgen_blank()
*/
static
int
rivafb_setcolreg
(
unsigned
regno
,
unsigned
red
,
unsigned
green
,
unsigned
blue
,
unsigned
transp
,
struct
fb_info
*
info
)
{
struct
rivafb_info
*
rivainfo
=
(
struct
rivafb_info
*
)
info
;
RIVA_HW_INST
*
chip
=
&
rivainfo
->
riva
;
struct
display
*
p
;
DPRINTK
(
"ENTER
\n
"
);
assert
(
rivainfo
!=
NULL
);
assert
(
rivainfo
->
currcon_display
!=
NULL
);
p
=
rivainfo
->
currcon_display
;
if
(
regno
>=
riva_get_cmap_len
(
&
p
->
var
))
return
-
EINVAL
;
rivainfo
->
palette
[
regno
].
red
=
red
;
rivainfo
->
palette
[
regno
].
green
=
green
;
rivainfo
->
palette
[
regno
].
blue
=
blue
;
if
(
p
->
var
.
grayscale
)
{
/* gray = 0.30*R + 0.59*G + 0.11*B */
red
=
green
=
blue
=
(
red
*
77
+
green
*
151
+
blue
*
28
)
>>
8
;
}
switch
(
p
->
var
.
bits_per_pixel
)
{
#ifdef FBCON_HAS_CFB8
case
8
:
/* "transparent" stuff is completely ignored. */
riva_wclut
(
chip
,
regno
,
red
>>
8
,
green
>>
8
,
blue
>>
8
);
break
;
#endif
/* FBCON_HAS_CFB8 */
#ifdef FBCON_HAS_CFB16
case
16
:
assert
(
regno
<
16
);
if
(
p
->
var
.
green
.
length
==
5
)
{
/* 0rrrrrgg gggbbbbb */
rivainfo
->
con_cmap
.
cfb16
[
regno
]
=
((
red
&
0xf800
)
>>
1
)
|
((
green
&
0xf800
)
>>
6
)
|
((
blue
&
0xf800
)
>>
11
);
}
else
{
/* rrrrrggg gggbbbbb */
rivainfo
->
con_cmap
.
cfb16
[
regno
]
=
((
red
&
0xf800
)
>>
0
)
|
((
green
&
0xf800
)
>>
5
)
|
((
blue
&
0xf800
)
>>
11
);
}
break
;
#endif
/* FBCON_HAS_CFB16 */
#ifdef FBCON_HAS_CFB32
case
32
:
assert
(
regno
<
16
);
rivainfo
->
con_cmap
.
cfb32
[
regno
]
=
((
red
&
0xff00
)
<<
8
)
|
((
green
&
0xff00
))
|
((
blue
&
0xff00
)
>>
8
);
break
;
#endif
/* FBCON_HAS_CFB32 */
default:
/* do nothing */
break
;
}
return
0
;
}
/* ------------------------------------------------------------------------- *
*
* framebuffer operations
*
* ------------------------------------------------------------------------- */
static
int
rivafb_get_fix
(
struct
fb_fix_screeninfo
*
fix
,
int
con
,
struct
fb_info
*
info
)
{
struct
rivafb_info
*
rivainfo
=
(
struct
rivafb_info
*
)
info
;
struct
display
*
p
;
DPRINTK
(
"ENTER
\n
"
);
assert
(
fix
!=
NULL
);
assert
(
info
!=
NULL
);
assert
(
rivainfo
->
drvr_name
&&
rivainfo
->
drvr_name
[
0
]);
assert
(
rivainfo
->
fb_base_phys
>
0
);
assert
(
rivainfo
->
ram_amount
>
0
);
p
=
(
con
<
0
)
?
rivainfo
->
info
.
disp
:
&
fb_display
[
con
];
memset
(
fix
,
0
,
sizeof
(
struct
fb_fix_screeninfo
));
sprintf
(
fix
->
id
,
"nVidia %s"
,
rivainfo
->
drvr_name
);
fix
->
smem_start
=
rivainfo
->
fb_base_phys
;
fix
->
smem_len
=
rivainfo
->
ram_amount
;
fix
->
type
=
p
->
type
;
fix
->
type_aux
=
p
->
type_aux
;
fix
->
visual
=
p
->
visual
;
fix
->
xpanstep
=
1
;
fix
->
ypanstep
=
1
;
fix
->
ywrapstep
=
0
;
/* FIXME: no ywrap for now */
fix
->
line_length
=
p
->
line_length
;
fix
->
mmio_start
=
rivainfo
->
ctrl_base_phys
;
fix
->
mmio_len
=
rivainfo
->
base0_region_size
;
fix
->
smem_start
=
rivainfo
->
fb_base_phys
;
fix
->
smem_len
=
rivainfo
->
base1_region_size
;
switch
(
rivainfo
->
riva
.
Architecture
)
{
case
NV_ARCH_03
:
fix
->
accel
=
FB_ACCEL_NV3
;
break
;
case
NV_ARCH_04
:
/* riva_hw.c now doesn't distinguish between TNT & TNT2 */
fix
->
accel
=
FB_ACCEL_NV4
;
break
;
case
NV_ARCH_10
:
/* FIXME: ID for GeForce */
fix
->
accel
=
FB_ACCEL_NV4
;
break
;
}
DPRINTK
(
"EXIT, returning 0
\n
"
);
return
0
;
}
static
int
rivafb_get_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
static
int
rivafb_check_var
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
{
struct
rivafb_info
*
rivainfo
=
(
struct
rivafb_info
*
)
info
;
DPRINTK
(
"ENTER
\n
"
);
assert
(
info
!=
NULL
);
assert
(
var
!=
NULL
);
*
var
=
(
con
<
0
)
?
rivainfo
->
disp
.
var
:
fb_display
[
con
].
var
;
DPRINTK
(
"EXIT, returning 0
\n
"
);
return
0
;
}
static
int
rivafb_set_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
info
)
{
struct
rivafb_info
*
rivainfo
=
(
struct
rivafb_info
*
)
info
;
struct
display
*
dsp
;
struct
fb_var_screeninfo
v
;
int
nom
,
den
;
/* translating from pixels->bytes */
int
accel
;
unsigned
chgvar
=
0
;
DPRINTK
(
"ENTER
\n
"
);
assert
(
info
!=
NULL
);
assert
(
var
!=
NULL
);
DPRINTK
(
"Requested: %dx%dx%d
\n
"
,
var
->
xres
,
var
->
yres
,
var
->
bits_per_pixel
);
DPRINTK
(
" virtual: %dx%d
\n
"
,
var
->
xres_virtual
,
var
->
yres_virtual
);
DPRINTK
(
" offset: (%d,%d)
\n
"
,
var
->
xoffset
,
var
->
yoffset
);
DPRINTK
(
"grayscale: %d
\n
"
,
var
->
grayscale
);
dsp
=
(
con
<
0
)
?
rivainfo
->
info
.
disp
:
&
fb_display
[
con
];
assert
(
dsp
!=
NULL
);
/* if var has changed, we should call changevar() later */
if
(
con
>=
0
)
{
chgvar
=
((
dsp
->
var
.
xres
!=
var
->
xres
)
||
(
dsp
->
var
.
yres
!=
var
->
yres
)
||
(
dsp
->
var
.
xres_virtual
!=
var
->
xres_virtual
)
||
(
dsp
->
var
.
yres_virtual
!=
var
->
yres_virtual
)
||
(
dsp
->
var
.
accel_flags
!=
var
->
accel_flags
)
||
(
dsp
->
var
.
bits_per_pixel
!=
var
->
bits_per_pixel
)
||
memcmp
(
&
dsp
->
var
.
red
,
&
var
->
red
,
sizeof
(
var
->
red
))
||
memcmp
(
&
dsp
->
var
.
green
,
&
var
->
green
,
sizeof
(
var
->
green
))
||
memcmp
(
&
dsp
->
var
.
blue
,
&
var
->
blue
,
sizeof
(
var
->
blue
)));
}
memcpy
(
&
v
,
var
,
sizeof
(
v
));
accel
=
v
.
accel_flags
&
FB_ACCELF_TEXT
;
switch
(
v
.
bits_per_pixel
)
{
#ifdef FBCON_HAS_CFB8
switch
(
var
->
bits_per_pixel
)
{
case
1
...
8
:
v
.
bits_per_pixel
=
8
;
v
ar
->
bits_per_pixel
=
8
;
nom
=
1
;
den
=
1
;
v
.
red
.
offset
=
0
;
v
.
red
.
length
=
8
;
v
.
green
.
offset
=
0
;
v
.
green
.
length
=
8
;
v
.
blue
.
offset
=
0
;
v
.
blue
.
length
=
8
;
v
ar
->
red
.
offset
=
0
;
v
ar
->
red
.
length
=
8
;
v
ar
->
green
.
offset
=
0
;
v
ar
->
green
.
length
=
8
;
v
ar
->
blue
.
offset
=
0
;
v
ar
->
blue
.
length
=
8
;
break
;
#endif
#ifdef FBCON_HAS_CFB16
case
9
...
15
:
v
.
green
.
length
=
5
;
v
ar
->
green
.
length
=
5
;
/* fall through */
case
16
:
v
.
bits_per_pixel
=
16
;
v
ar
->
bits_per_pixel
=
16
;
nom
=
2
;
den
=
1
;
if
(
v
.
green
.
length
==
5
)
{
if
(
v
ar
->
green
.
length
==
5
)
{
/* 0rrrrrgg gggbbbbb */
v
.
red
.
offset
=
10
;
v
.
green
.
offset
=
5
;
v
.
blue
.
offset
=
0
;
v
.
red
.
length
=
5
;
v
.
green
.
length
=
5
;
v
.
blue
.
length
=
5
;
v
ar
->
red
.
offset
=
10
;
v
ar
->
green
.
offset
=
5
;
v
ar
->
blue
.
offset
=
0
;
v
ar
->
red
.
length
=
5
;
v
ar
->
green
.
length
=
5
;
v
ar
->
blue
.
length
=
5
;
}
else
{
/* rrrrrggg gggbbbbb */
v
.
red
.
offset
=
11
;
v
.
green
.
offset
=
5
;
v
.
blue
.
offset
=
0
;
v
.
red
.
length
=
5
;
v
.
green
.
length
=
6
;
v
.
blue
.
length
=
5
;
v
ar
->
red
.
offset
=
11
;
v
ar
->
green
.
offset
=
5
;
v
ar
->
blue
.
offset
=
0
;
v
ar
->
red
.
length
=
5
;
v
ar
->
green
.
length
=
6
;
v
ar
->
blue
.
length
=
5
;
}
break
;
#endif
#ifdef FBCON_HAS_CFB32
case
17
...
32
:
v
.
bits_per_pixel
=
32
;
v
ar
->
bits_per_pixel
=
32
;
nom
=
4
;
den
=
1
;
v
.
red
.
offset
=
16
;
v
.
green
.
offset
=
8
;
v
.
blue
.
offset
=
0
;
v
.
red
.
length
=
8
;
v
.
green
.
length
=
8
;
v
.
blue
.
length
=
8
;
v
ar
->
red
.
offset
=
16
;
v
ar
->
green
.
offset
=
8
;
v
ar
->
blue
.
offset
=
0
;
v
ar
->
red
.
length
=
8
;
v
ar
->
green
.
length
=
8
;
v
ar
->
blue
.
length
=
8
;
break
;
#endif
default:
printk
(
KERN_ERR
PFX
"mode %dx%dx%d rejected...color depth not supported.
\n
"
,
...
...
@@ -1448,122 +1079,40 @@ static int rivafb_set_var(struct fb_var_screeninfo *var, int con,
return
-
EINVAL
;
}
if
(
rivafb_do_maximize
(
rivainfo
,
var
,
&
v
,
nom
,
den
)
<
0
)
if
(
rivafb_do_maximize
(
info
,
var
,
nom
,
den
)
<
0
)
return
-
EINVAL
;
if
(
v
.
xoffset
<
0
)
v
.
xoffset
=
0
;
if
(
v
.
yoffset
<
0
)
v
.
yoffset
=
0
;
if
(
v
ar
->
xoffset
<
0
)
v
ar
->
xoffset
=
0
;
if
(
v
ar
->
yoffset
<
0
)
v
ar
->
yoffset
=
0
;
/* truncate xoffset and yoffset to maximum if too high */
if
(
v
.
xoffset
>
v
.
xres_virtual
-
v
.
xres
)
v
.
xoffset
=
v
.
xres_virtual
-
v
.
xres
-
1
;
if
(
v
.
yoffset
>
v
.
yres_virtual
-
v
.
yres
)
v
.
yoffset
=
v
.
yres_virtual
-
v
.
yres
-
1
;
v
.
red
.
msb_right
=
v
.
green
.
msb_right
=
v
.
blue
.
msb_right
=
v
.
transp
.
offset
=
v
.
transp
.
length
=
v
.
transp
.
msb_right
=
0
;
switch
(
v
.
activate
&
FB_ACTIVATE_MASK
)
{
case
FB_ACTIVATE_TEST
:
DPRINTK
(
"EXIT - FB_ACTIVATE_TEST
\n
"
);
return
0
;
case
FB_ACTIVATE_NXTOPEN
:
/* ?? */
case
FB_ACTIVATE_NOW
:
break
;
/* continue */
default:
DPRINTK
(
"EXIT - unknown activation type
\n
"
);
return
-
EINVAL
;
/* unknown */
}
memcpy
(
&
dsp
->
var
,
&
v
,
sizeof
(
v
));
if
(
chgvar
)
{
riva_set_dispsw
(
rivainfo
,
dsp
);
if
(
accel
)
{
if
(
nomove
)
dsp
->
scrollmode
=
SCROLL_YNOMOVE
;
else
dsp
->
scrollmode
=
0
;
}
else
dsp
->
scrollmode
=
SCROLL_YREDRAW
;
if
(
info
&&
info
->
changevar
)
info
->
changevar
(
con
);
}
if
(
var
->
xoffset
>
var
->
xres_virtual
-
var
->
xres
)
var
->
xoffset
=
var
->
xres_virtual
-
var
->
xres
-
1
;
rivafb_create_cursor
(
rivainfo
,
fontwidth
(
dsp
),
fontheight
(
dsp
));
riva_load_video_mode
(
rivainfo
,
&
v
);
if
(
accel
)
riva_setup_accel
(
rivainfo
);
if
(
var
->
yoffset
>
var
->
yres_virtual
-
var
->
yres
)
var
->
yoffset
=
var
->
yres_virtual
-
var
->
yres
-
1
;
DPRINTK
(
"EXIT, returning 0
\n
"
);
var
->
red
.
msb_right
=
var
->
green
.
msb_right
=
var
->
blue
.
msb_right
=
var
->
transp
.
offset
=
var
->
transp
.
length
=
var
->
transp
.
msb_right
=
0
;
var
->
accel_flags
|=
FB_ACCELF_TEXT
;
return
0
;
}
static
int
rivafb_get_cmap
(
struct
fb_cmap
*
cmap
,
int
kspc
,
int
con
,
struct
fb_info
*
info
)
static
int
rivafb_set_par
(
struct
fb_info
*
info
)
{
struct
rivafb_info
*
rivainfo
=
(
struct
rivafb_info
*
)
info
;
struct
display
*
dsp
;
DPRINTK
(
"ENTER
\n
"
);
assert
(
rivainfo
!=
NULL
);
assert
(
cmap
!=
NULL
);
struct
riva_par
*
par
=
(
struct
riva_par
*
)
info
->
par
;
dsp
=
(
con
<
0
)
?
rivainfo
->
info
.
disp
:
&
fb_display
[
con
];
if
(
con
==
info
->
currcon
)
{
/* current console? */
int
rc
=
fb_get_cmap
(
cmap
,
kspc
,
riva_getcolreg
,
info
);
DPRINTK
(
"EXIT - returning %d
\n
"
,
rc
);
return
rc
;
}
else
if
(
dsp
->
cmap
.
len
)
/* non default colormap? */
fb_copy_cmap
(
&
dsp
->
cmap
,
cmap
,
kspc
?
0
:
2
);
else
fb_copy_cmap
(
fb_default_cmap
(
riva_get_cmap_len
(
&
dsp
->
var
)),
cmap
,
kspc
?
0
:
2
);
DPRINTK
(
"EXIT, returning 0
\n
"
);
return
0
;
}
static
int
rivafb_set_cmap
(
struct
fb_cmap
*
cmap
,
int
kspc
,
int
con
,
struct
fb_info
*
info
)
{
struct
rivafb_info
*
rivainfo
=
(
struct
rivafb_info
*
)
info
;
struct
display
*
dsp
;
unsigned
int
cmap_len
;
DPRINTK
(
"ENTER
\n
"
);
assert
(
rivainfo
!=
NULL
);
assert
(
cmap
!=
NULL
);
dsp
=
(
con
<
0
)
?
rivainfo
->
info
.
disp
:
&
fb_display
[
con
];
cmap_len
=
riva_get_cmap_len
(
&
dsp
->
var
);
if
(
dsp
->
cmap
.
len
!=
cmap_len
)
{
int
err
=
fb_alloc_cmap
(
&
dsp
->
cmap
,
cmap_len
,
0
);
if
(
err
)
{
DPRINTK
(
"EXIT - returning %d
\n
"
,
err
);
return
err
;
}
}
if
(
con
==
info
->
currcon
)
{
/* current console? */
int
rc
=
fb_set_cmap
(
cmap
,
kspc
,
info
);
DPRINTK
(
"EXIT - returning %d
\n
"
,
rc
);
return
rc
;
}
else
fb_copy_cmap
(
cmap
,
&
dsp
->
cmap
,
kspc
?
0
:
1
);
DPRINTK
(
"EXIT, returning 0
\n
"
);
//rivafb_create_cursor(info, fontwidth(dsp), fontheight(dsp));
riva_load_video_mode
(
info
);
riva_setup_accel
(
par
);
info
->
fix
.
line_length
=
(
info
->
var
.
xres_virtual
*
(
info
->
var
.
bits_per_pixel
>>
3
));
info
->
fix
.
visual
=
(
info
->
var
.
bits_per_pixel
==
8
)
?
FB_VISUAL_PSEUDOCOLOR
:
FB_VISUAL_DIRECTCOLOR
;
return
0
;
}
...
...
@@ -1583,132 +1132,48 @@ static int rivafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
static
int
rivafb_pan_display
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
info
)
{
struct
riva_par
*
par
=
(
struct
riva_par
*
)
info
->
par
;
unsigned
int
base
;
struct
display
*
dsp
;
struct
rivafb_info
*
rivainfo
=
(
struct
rivafb_info
*
)
info
;
DPRINTK
(
"ENTER
\n
"
);
assert
(
rivainfo
!=
NULL
);
if
(
var
->
xoffset
>
(
var
->
xres_virtual
-
var
->
xres
))
return
-
EINVAL
;
if
(
var
->
yoffset
>
(
var
->
yres_virtual
-
var
->
yres
))
return
-
EINVAL
;
dsp
=
(
con
<
0
)
?
rivainfo
->
info
.
disp
:
&
fb_display
[
con
];
if
(
var
->
vmode
&
FB_VMODE_YWRAP
)
{
if
(
var
->
yoffset
<
0
||
var
->
yoffset
>=
dsp
->
var
.
yres_virtual
||
var
->
yoffset
>=
info
->
var
.
yres_virtual
||
var
->
xoffset
)
return
-
EINVAL
;
}
else
{
if
(
var
->
xoffset
+
dsp
->
var
.
xres
>
dsp
->
var
.
xres_virtual
||
var
->
yoffset
+
dsp
->
var
.
yres
>
dsp
->
var
.
yres_virtual
)
if
(
var
->
xoffset
+
info
->
var
.
xres
>
info
->
var
.
xres_virtual
||
var
->
yoffset
+
info
->
var
.
yres
>
info
->
var
.
yres_virtual
)
return
-
EINVAL
;
}
base
=
var
->
yoffset
*
dsp
->
line_length
+
var
->
xoffset
;
base
=
var
->
yoffset
*
info
->
fix
.
line_length
+
var
->
xoffset
;
if
(
con
==
info
->
currcon
)
{
rivainfo
->
riva
.
SetStartAddress
(
&
rivainfo
->
riva
,
base
);
par
->
riva
.
SetStartAddress
(
&
par
->
riva
,
base
);
}
dsp
->
var
.
xoffset
=
var
->
xoffset
;
dsp
->
var
.
yoffset
=
var
->
yoffset
;
info
->
var
.
xoffset
=
var
->
xoffset
;
info
->
var
.
yoffset
=
var
->
yoffset
;
if
(
var
->
vmode
&
FB_VMODE_YWRAP
)
dsp
->
var
.
vmode
|=
FB_VMODE_YWRAP
;
info
->
var
.
vmode
|=
FB_VMODE_YWRAP
;
else
dsp
->
var
.
vmode
&=
~
FB_VMODE_YWRAP
;
info
->
var
.
vmode
&=
~
FB_VMODE_YWRAP
;
DPRINTK
(
"EXIT, returning 0
\n
"
);
return
0
;
}
static
int
rivafb_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
,
int
con
,
struct
fb_info
*
info
)
{
struct
rivafb_info
*
rivainfo
=
(
struct
rivafb_info
*
)
info
;
DPRINTK
(
"ENTER
\n
"
);
assert
(
rivainfo
!=
NULL
);
/* no rivafb-specific ioctls */
DPRINTK
(
"EXIT, returning -EINVAL
\n
"
);
return
-
EINVAL
;
}
static
int
rivafb_rasterimg
(
struct
fb_info
*
info
,
int
start
)
{
struct
rivafb_info
*
rinfo
=
(
struct
rivafb_info
*
)
info
;
wait_for_idle
(
rinfo
);
return
0
;
}
static
int
rivafb_switch
(
int
con
,
struct
fb_info
*
info
)
{
struct
rivafb_info
*
rivainfo
=
(
struct
rivafb_info
*
)
info
;
struct
fb_cmap
*
cmap
;
struct
display
*
dsp
;
DPRINTK
(
"ENTER
\n
"
);
assert
(
rivainfo
!=
NULL
);
dsp
=
(
con
<
0
)
?
rivainfo
->
info
.
disp
:
&
fb_display
[
con
];
if
(
info
->
currcon
>=
0
)
{
/* Do we have to save the colormap? */
cmap
=
&
(
rivainfo
->
currcon_display
->
cmap
);
DPRINTK
(
"switch1: con = %d, cmap.len = %d
\n
"
,
info
->
currcon
,
cmap
->
len
);
if
(
cmap
->
len
)
{
DPRINTK
(
"switch1a: %p %p %p %p
\n
"
,
cmap
->
red
,
cmap
->
green
,
cmap
->
blue
,
cmap
->
transp
);
fb_get_cmap
(
cmap
,
1
,
riva_getcolreg
,
info
);
}
}
info
->
currcon
=
con
;
rivainfo
->
currcon_display
=
dsp
;
rivafb_set_var
(
&
dsp
->
var
,
con
,
info
);
riva_set_dispsw
(
rivainfo
,
dsp
);
DPRINTK
(
"EXIT, returning 0
\n
"
);
return
0
;
}
static
int
rivafb_updatevar
(
int
con
,
struct
fb_info
*
info
)
{
int
rc
;
DPRINTK
(
"ENTER
\n
"
);
rc
=
(
con
<
0
)
?
-
EINVAL
:
rivafb_pan_display
(
&
fb_display
[
con
].
var
,
con
,
info
);
DPRINTK
(
"EXIT, returning %d
\n
"
,
rc
);
return
rc
;
}
static
int
rivafb_blank
(
int
blank
,
struct
fb_info
*
info
)
{
struct
riva_par
*
par
=
(
struct
riva_par
*
)
info
->
par
;
unsigned
char
tmp
,
vesa
;
struct
rivafb_info
*
rinfo
=
(
struct
rivafb_info
*
)
info
;
DPRINTK
(
"ENTER
\n
"
);
assert
(
rinfo
!=
NULL
);
tmp
=
SEQin
(
rinfo
,
0x01
)
&
~
0x20
;
/* screen on/off */
vesa
=
CRTCin
(
rinfo
,
0x1a
)
&
~
0xc0
;
/* sync on/off */
tmp
=
SEQin
(
par
,
0x01
)
&
~
0x20
;
/* screen on/off */
vesa
=
CRTCin
(
par
,
0x1a
)
&
~
0xc0
;
/* sync on/off */
if
(
blank
)
{
tmp
|=
0x20
;
...
...
@@ -1727,14 +1192,86 @@ static int rivafb_blank(int blank, struct fb_info *info)
}
}
SEQout
(
rinfo
,
0x01
,
tmp
);
CRTCout
(
rinfo
,
0x1a
,
vesa
);
SEQout
(
par
,
0x01
,
tmp
);
CRTCout
(
par
,
0x1a
,
vesa
);
DPRINTK
(
"EXIT
\n
"
);
return
0
;
}
/**
* rivafb_setcolreg
* @regno: register index
* @red: red component
* @green: green component
* @blue: blue component
* @transp: transparency
* @info: pointer to rivafb_info object containing info for current riva board
*
* DESCRIPTION:
* Set a single color register. The values supplied have a 16 bit
* magnitude.
*
* RETURNS:
* Return != 0 for invalid regno.
*
* CALLED FROM:
* rivafb_set_cmap()
* fbcmap.c:fb_set_cmap()
* fbgen.c:fbgen_get_cmap()
* fbgen.c:do_install_cmap()
* fbgen.c:fbgen_set_var()
* fbgen.c:fbgen_switch()
* fbgen.c:fbgen_blank()
* fbgen.c:fbgen_blank()
*/
static
int
rivafb_setcolreg
(
unsigned
regno
,
unsigned
red
,
unsigned
green
,
unsigned
blue
,
unsigned
transp
,
struct
fb_info
*
info
)
{
struct
riva_par
*
par
=
(
struct
riva_par
*
)
info
->
par
;
RIVA_HW_INST
*
chip
=
&
par
->
riva
;
if
(
regno
>=
riva_get_cmap_len
(
&
info
->
var
))
return
-
EINVAL
;
if
(
info
->
var
.
grayscale
)
{
/* gray = 0.30*R + 0.59*G + 0.11*B */
red
=
green
=
blue
=
(
red
*
77
+
green
*
151
+
blue
*
28
)
>>
8
;
}
switch
(
info
->
var
.
bits_per_pixel
)
{
case
8
:
/* "transparent" stuff is completely ignored. */
riva_wclut
(
chip
,
regno
,
red
>>
8
,
green
>>
8
,
blue
>>
8
);
break
;
case
16
:
assert
(
regno
<
16
);
if
(
info
->
var
.
green
.
length
==
5
)
{
/* 0rrrrrgg gggbbbbb */
((
u16
*
)(
info
->
pseudo_palette
))[
regno
]
=
((
red
&
0xf800
)
>>
1
)
|
((
green
&
0xf800
)
>>
6
)
|
((
blue
&
0xf800
)
>>
11
);
}
else
{
/* rrrrrggg gggbbbbb */
((
u16
*
)(
info
->
pseudo_palette
))[
regno
]
=
((
red
&
0xf800
)
>>
0
)
|
((
green
&
0xf800
)
>>
5
)
|
((
blue
&
0xf800
)
>>
11
);
}
break
;
case
32
:
assert
(
regno
<
16
);
((
u32
*
)(
info
->
pseudo_palette
))[
regno
]
=
((
red
&
0xff00
)
<<
8
)
|
((
green
&
0xff00
))
|
((
blue
&
0xff00
)
>>
8
);
break
;
default:
/* do nothing */
break
;
}
return
0
;
}
/* ------------------------------------------------------------------------- *
*
...
...
@@ -1744,98 +1281,50 @@ static int rivafb_blank(int blank, struct fb_info *info)
/* kernel interface */
static
struct
fb_ops
riva_fb_ops
=
{
.
owner
=
THIS_MODULE
,
.
fb_get_fix
=
rivafb_get_fix
,
.
fb_get_var
=
rivafb_get_var
,
.
fb_set_var
=
rivafb_set_var
,
.
fb_get_cmap
=
rivafb_get_cmap
,
.
fb_set_cmap
=
rivafb_set_cmap
,
.
fb_setcolreg
=
rivafb_setcolreg
,
.
fb_pan_display
=
rivafb_pan_display
,
.
fb_blank
=
rivafb_blank
,
.
fb_ioctl
=
rivafb_ioctl
,
.
fb_rasterimg
=
rivafb_rasterimg
,
owner:
THIS_MODULE
,
fb_set_var:
gen_set_var
,
fb_get_cmap:
gen_get_cmap
,
fb_set_cmap:
gen_set_cmap
,
fb_check_var:
rivafb_check_var
,
fb_set_par:
rivafb_set_par
,
fb_setcolreg:
rivafb_setcolreg
,
fb_pan_display:
rivafb_pan_display
,
fb_blank:
rivafb_blank
,
fb_fillrect:
cfb_fillrect
,
fb_copyarea:
cfb_copyarea
,
fb_imageblit:
cfb_imageblit
,
};
static
int
__devinit
riva_init_disp_var
(
struct
rivafb_info
*
rinfo
)
{
#ifndef MODULE
if
(
mode_option
)
fb_find_mode
(
&
rinfo
->
disp
.
var
,
&
rinfo
->
info
,
mode_option
,
NULL
,
0
,
NULL
,
8
);
#endif
return
0
;
}
static
int
__devinit
riva_init_disp
(
struct
rivafb_info
*
rinfo
)
{
struct
fb_info
*
info
;
struct
display
*
disp
;
DPRINTK
(
"ENTER
\n
"
);
assert
(
rinfo
!=
NULL
);
info
=
&
rinfo
->
info
;
disp
=
&
rinfo
->
disp
;
disp
->
var
=
rivafb_default_var
;
if
(
noaccel
)
disp
->
var
.
accel_flags
&=
~
FB_ACCELF_TEXT
;
else
disp
->
var
.
accel_flags
|=
FB_ACCELF_TEXT
;
info
->
disp
=
disp
;
/* FIXME: assure that disp->cmap is completely filled out */
rinfo
->
currcon_display
=
disp
;
if
((
riva_init_disp_var
(
rinfo
))
<
0
)
{
DPRINTK
(
"EXIT, returning -1
\n
"
);
return
-
1
;
}
riva_set_dispsw
(
rinfo
,
disp
);
DPRINTK
(
"EXIT, returning 0
\n
"
);
return
0
;
}
static
int
__devinit
riva_set_fbinfo
(
struct
rivafb_info
*
rinfo
)
static
int
__devinit
riva_set_fbinfo
(
struct
fb_info
*
info
)
{
struct
fb_info
*
info
;
assert
(
rinfo
!=
NULL
);
info
=
&
rinfo
->
info
;
unsigned
int
cmap_len
;
strcpy
(
info
->
modename
,
ri
nfo
->
drvr_name
);
strcpy
(
info
->
modename
,
ri
vafb_fix
.
id
);
info
->
node
=
NODEV
;
info
->
flags
=
FBINFO_FLAG_DEFAULT
;
info
->
fbops
=
&
riva_fb_ops
;
info
->
screen_base
=
rinfo
->
fb_base
;
/* FIXME: set monspecs to what??? */
info
->
var
=
rivafb_default_var
;
info
->
fix
=
rivafb_fix
;
/* FIXME: set monspecs to what??? */
info
->
display_fg
=
NULL
;
info
->
currcon
=
-
1
;
info
->
pseudo_palette
=
pseudo_palette
;
strncpy
(
info
->
fontname
,
fontname
,
sizeof
(
info
->
fontname
));
info
->
fontname
[
sizeof
(
info
->
fontname
)
-
1
]
=
0
;
info
->
changevar
=
NULL
;
info
->
switch_con
=
rivafb_switch
;
info
->
updatevar
=
rivafb_updatevar
;
if
(
riva_init_disp
(
rinfo
)
<
0
)
/* must be done last */
return
-
1
;
info
->
switch_con
=
gen_switch
;
info
->
updatevar
=
gen_update_var
;
cmap_len
=
riva_get_cmap_len
(
&
info
->
var
);
fb_alloc_cmap
(
&
info
->
cmap
,
cmap_len
,
0
);
#ifndef MODULE
if
(
mode_option
)
fb_find_mode
(
&
info
->
var
,
info
,
mode_option
,
NULL
,
0
,
NULL
,
8
);
#endif
return
0
;
}
/* ------------------------------------------------------------------------- *
*
* PCI bus
...
...
@@ -1845,194 +1334,200 @@ static int __devinit riva_set_fbinfo(struct rivafb_info *rinfo)
static
int
__devinit
rivafb_init_one
(
struct
pci_dev
*
pd
,
const
struct
pci_device_id
*
ent
)
{
struct
rivafb_info
*
rinfo
;
struct
riva_chip_info
*
rci
=
&
riva_chip_info
[
ent
->
driver_data
];
struct
riva_par
*
default_par
;
struct
fb_info
*
info
;
assert
(
pd
!=
NULL
);
assert
(
rci
!=
NULL
);
rinfo
=
kmalloc
(
sizeof
(
struct
rivafb_info
),
GFP_KERNEL
);
if
(
!
rinfo
)
info
=
kmalloc
(
sizeof
(
struct
fb_info
)
+
sizeof
(
struct
display
),
GFP_KERNEL
);
if
(
!
info
)
goto
err_out
;
memset
(
rinfo
,
0
,
sizeof
(
struct
rivafb_info
));
default_par
=
kmalloc
(
sizeof
(
struct
riva_par
),
GFP_KERNEL
);
if
(
!
default_par
)
goto
err_out_kfree
;
rinfo
->
drvr_name
=
rci
->
name
;
rinfo
->
riva
.
Architecture
=
rci
->
arch_rev
;
memset
(
info
,
0
,
sizeof
(
struct
fb_info
)
+
sizeof
(
struct
display
))
;
memset
(
default_par
,
0
,
sizeof
(
struct
riva_par
))
;
rinfo
->
pd
=
pd
;
rinfo
->
base0_region_size
=
pci_resource_len
(
pd
,
0
);
rinfo
->
base1_region_size
=
pci_resource_len
(
pd
,
1
);
strcat
(
rivafb_fix
.
id
,
rci
->
name
);
default_par
->
riva
.
Architecture
=
rci
->
arch_rev
;
assert
(
rinfo
->
base0_region_size
>=
0x00800000
);
/* from GGI */
assert
(
rinfo
->
base1_region_size
>=
0x01000000
);
/* from GGI */
rivafb_fix
.
mmio_len
=
pci_resource_len
(
pd
,
0
);
rivafb_fix
.
smem_len
=
pci_resource_len
(
pd
,
1
);
ri
nfo
->
ctrl_base_phys
=
pci_resource_start
(
rinfo
->
pd
,
0
);
ri
nfo
->
fb_base_phys
=
pci_resource_start
(
rinfo
->
pd
,
1
);
ri
vafb_fix
.
mmio_start
=
pci_resource_start
(
pd
,
0
);
ri
vafb_fix
.
smem_start
=
pci_resource_start
(
pd
,
1
);
if
(
!
request_mem_region
(
ri
nfo
->
ctrl_base_phys
,
ri
nfo
->
base0_region_size
,
"rivafb"
))
{
if
(
!
request_mem_region
(
ri
vafb_fix
.
mmio_start
,
ri
vafb_fix
.
mmio_len
,
"rivafb"
))
{
printk
(
KERN_ERR
PFX
"cannot reserve MMIO region
\n
"
);
goto
err_out_kfree
;
}
if
(
!
request_mem_region
(
rinfo
->
fb_base_phys
,
rinfo
->
base1_region_size
,
"rivafb"
))
{
printk
(
KERN_ERR
PFX
"cannot reserve FB region
\n
"
);
goto
err_out_free_base0
;
}
rinfo
->
ctrl_base
=
ioremap
(
rinfo
->
ctrl_base_phys
,
rinfo
->
base0_region_size
);
if
(
!
rinfo
->
ctrl_base
)
{
default_par
->
ctrl_base
=
ioremap
(
rivafb_fix
.
mmio_start
,
rivafb_fix
.
mmio_len
);
if
(
!
default_par
->
ctrl_base
)
{
printk
(
KERN_ERR
PFX
"cannot ioremap MMIO base
\n
"
);
goto
err_out_free_base1
;
}
rinfo
->
fb_base
=
ioremap
(
rinfo
->
fb_base_phys
,
rinfo
->
base1_region_size
);
if
(
!
rinfo
->
fb
_base
)
{
info
->
screen_base
=
ioremap
(
rivafb_fix
.
smem_start
,
rivafb_fix
.
smem_len
);
if
(
!
info
->
screen
_base
)
{
printk
(
KERN_ERR
PFX
"cannot ioremap FB base
\n
"
);
goto
err_out_iounmap_ctrl
;
}
#ifdef CONFIG_MTRR
if
(
!
nomtrr
)
{
rinfo
->
mtrr
.
vram
=
mtrr_add
(
rinfo
->
fb_base_phys
,
rinfo
->
base1_region_size
,
MTRR_TYPE_WRCOMB
,
1
);
if
(
rinfo
->
mtrr
.
vram
<
0
)
{
printk
(
KERN_ERR
PFX
"unable to setup MTRR
\n
"
);
}
else
{
rinfo
->
mtrr
.
vram_valid
=
1
;
/* let there be speed */
printk
(
KERN_INFO
PFX
"RIVA MTRR set to ON
\n
"
);
}
}
#endif
/* CONFIG_MTRR */
rinfo
->
riva
.
EnableIRQ
=
0
;
rinfo
->
riva
.
PRAMDAC
=
(
unsigned
*
)(
rinfo
->
ctrl_base
+
0x00680000
);
rinfo
->
riva
.
PFB
=
(
unsigned
*
)(
rinfo
->
ctrl_base
+
0x00100000
);
rinfo
->
riva
.
PFIFO
=
(
unsigned
*
)(
rinfo
->
ctrl_base
+
0x00002000
);
rinfo
->
riva
.
PGRAPH
=
(
unsigned
*
)(
rinfo
->
ctrl_base
+
0x00400000
);
rinfo
->
riva
.
PEXTDEV
=
(
unsigned
*
)(
rinfo
->
ctrl_base
+
0x00101000
);
rinfo
->
riva
.
PTIMER
=
(
unsigned
*
)(
rinfo
->
ctrl_base
+
0x00009000
);
rinfo
->
riva
.
PMC
=
(
unsigned
*
)(
rinfo
->
ctrl_base
+
0x00000000
);
rinfo
->
riva
.
FIFO
=
(
unsigned
*
)(
rinfo
->
ctrl_base
+
0x00800000
);
default_par
->
riva
.
EnableIRQ
=
0
;
default_par
->
riva
.
PRAMDAC
=
(
unsigned
*
)(
default_par
->
ctrl_base
+
0x00680000
);
default_par
->
riva
.
PFB
=
(
unsigned
*
)(
default_par
->
ctrl_base
+
0x00100000
);
default_par
->
riva
.
PFIFO
=
(
unsigned
*
)(
default_par
->
ctrl_base
+
0x00002000
);
default_par
->
riva
.
PGRAPH
=
(
unsigned
*
)(
default_par
->
ctrl_base
+
0x00400000
);
default_par
->
riva
.
PEXTDEV
=
(
unsigned
*
)(
default_par
->
ctrl_base
+
0x00101000
);
default_par
->
riva
.
PTIMER
=
(
unsigned
*
)(
default_par
->
ctrl_base
+
0x00009000
);
default_par
->
riva
.
PMC
=
(
unsigned
*
)(
default_par
->
ctrl_base
+
0x00000000
);
default_par
->
riva
.
FIFO
=
(
unsigned
*
)(
default_par
->
ctrl_base
+
0x00800000
);
rinfo
->
riva
.
PCIO
=
(
U008
*
)(
rinfo
->
ctrl_base
+
0x00601000
);
rinfo
->
riva
.
PDIO
=
(
U008
*
)(
rinfo
->
ctrl_base
+
0x00681000
);
rinfo
->
riva
.
PVIO
=
(
U008
*
)(
rinfo
->
ctrl_base
+
0x000C0000
);
default_par
->
riva
.
PCIO
=
(
U008
*
)(
default_par
->
ctrl_base
+
0x00601000
);
default_par
->
riva
.
PDIO
=
(
U008
*
)(
default_par
->
ctrl_base
+
0x00681000
);
default_par
->
riva
.
PVIO
=
(
U008
*
)(
default_par
->
ctrl_base
+
0x000C0000
);
rinfo
->
riva
.
IO
=
(
MISCin
(
rinfo
)
&
0x01
)
?
0x3D0
:
0x3B0
;
default_par
->
riva
.
IO
=
(
MISCin
(
default_par
)
&
0x01
)
?
0x3D0
:
0x3B0
;
switch
(
rinfo
->
riva
.
Architecture
)
{
switch
(
default_par
->
riva
.
Architecture
)
{
case
NV_ARCH_03
:
rinfo
->
riva
.
PRAMIN
=
(
unsigned
*
)(
rinfo
->
fb_base
+
0x00C00000
);
default_par
->
riva
.
PRAMIN
=
(
unsigned
*
)(
info
->
screen_base
+
0x00C00000
);
rivafb_fix
.
accel
=
FB_ACCEL_NV3
;
break
;
case
NV_ARCH_04
:
case
NV_ARCH_10
:
rinfo
->
riva
.
PCRTC
=
(
unsigned
*
)(
rinfo
->
ctrl_base
+
0x00600000
);
rinfo
->
riva
.
PRAMIN
=
(
unsigned
*
)(
rinfo
->
ctrl_base
+
0x00710000
);
case
NV_ARCH_20
:
default_par
->
riva
.
PCRTC
=
(
unsigned
*
)(
default_par
->
ctrl_base
+
0x00600000
);
default_par
->
riva
.
PRAMIN
=
(
unsigned
*
)(
default_par
->
ctrl_base
+
0x00710000
);
rivafb_fix
.
accel
=
FB_ACCEL_NV4
;
break
;
}
RivaGetConfig
(
&
rinfo
->
riva
);
RivaGetConfig
(
&
default_par
->
riva
);
/* back to normal */
rivafb_fix
.
smem_len
=
default_par
->
riva
.
RamAmountKBytes
*
1024
;
default_par
->
dclk_max
=
default_par
->
riva
.
MaxVClockFreqKHz
*
1000
;
assert
(
rinfo
->
pd
!=
NULL
);
if
(
!
request_mem_region
(
rivafb_fix
.
smem_start
,
rivafb_fix
.
smem_len
,
"rivafb"
))
{
printk
(
KERN_ERR
PFX
"cannot reserve FB region
\n
"
);
goto
err_out_free_base0
;
}
info
->
screen_base
=
ioremap
(
rivafb_fix
.
smem_start
,
rivafb_fix
.
smem_len
);
if
(
!
info
->
screen_base
)
{
printk
(
KERN_ERR
PFX
"cannot ioremap FB base
\n
"
);
goto
err_out_iounmap_ctrl
;
}
#ifdef CONFIG_MTRR
if
(
!
nomtrr
)
{
default_par
->
mtrr
.
vram
=
mtrr_add
(
rivafb_fix
.
smem_start
,
rivafb_fix
.
smem_len
,
MTRR_TYPE_WRCOMB
,
1
);
if
(
default_par
->
mtrr
.
vram
<
0
)
{
printk
(
KERN_ERR
PFX
"unable to setup MTRR
\n
"
);
}
else
{
default_par
->
mtrr
.
vram_valid
=
1
;
/* let there be speed */
printk
(
KERN_INFO
PFX
"RIVA MTRR set to ON
\n
"
);
}
}
#endif
/* CONFIG_MTRR */
/* unlock io */
CRTCout
(
rinfo
,
0x11
,
0xFF
);
/* vgaHWunlock() + riva unlock
(0x7F) */
rinfo
->
riva
.
LockUnlock
(
&
rinfo
->
riva
,
0
);
CRTCout
(
default_par
,
0x11
,
0xFF
);
/* vgaHWunlock() + riva unlock
(0x7F) */
default_par
->
riva
.
LockUnlock
(
&
default_par
->
riva
,
0
);
riva_save_state
(
rinfo
,
&
rinfo
->
initial_state
);
info
->
disp
=
(
struct
display
*
)(
info
+
1
);
info
->
par
=
default_par
;
rinfo
->
ram_amount
=
rinfo
->
riva
.
RamAmountKBytes
*
1024
;
rinfo
->
dclk_max
=
rinfo
->
riva
.
MaxVClockFreqKHz
*
1000
;
riva_save_state
(
default_par
,
&
default_par
->
initial_state
);
if
(
!
nohwcursor
)
rinfo
->
cursor
=
rivafb_init_cursor
(
rinfo
);
if
(
!
nohwcursor
)
default_par
->
cursor
=
rivafb_init_cursor
(
default_par
);
if
(
riva_set_fbinfo
(
r
info
)
<
0
)
{
if
(
riva_set_fbinfo
(
info
)
<
0
)
{
printk
(
KERN_ERR
PFX
"error setting initial video mode
\n
"
);
goto
err_out_cursor
;
}
if
(
register_framebuffer
(
(
struct
fb_info
*
)
r
info
)
<
0
)
{
if
(
register_framebuffer
(
info
)
<
0
)
{
printk
(
KERN_ERR
PFX
"error registering riva framebuffer
\n
"
);
goto
err_out_load_state
;
}
riva_boards
=
riva_board_list_add
(
riva_boards
,
rinfo
);
pci_set_drvdata
(
pd
,
rinfo
);
pci_set_drvdata
(
pd
,
info
);
printk
(
KERN_INFO
PFX
"PCI nVidia NV%
d
framebuffer ver %s (%s, %dMB @ 0x%lX)
\n
"
,
rinfo
->
riva
.
Architecture
,
"PCI nVidia NV%
x
framebuffer ver %s (%s, %dMB @ 0x%lX)
\n
"
,
default_par
->
riva
.
Architecture
,
RIVAFB_VERSION
,
rinfo
->
drvr_name
,
rinfo
->
ram_amount
/
(
1024
*
1024
),
rinfo
->
fb_base_phys
);
info
->
fix
.
id
,
info
->
fix
.
smem_len
/
(
1024
*
1024
),
info
->
fix
.
smem_start
);
return
0
;
err_out_load_state:
riva_load_state
(
rinfo
,
&
rinfo
->
initial_state
);
riva_load_state
(
default_par
,
&
default_par
->
initial_state
);
err_out_cursor:
rivafb_exit_cursor
(
rinfo
);
rivafb_exit_cursor
(
default_par
);
/* err_out_iounmap_fb: */
iounmap
(
rinfo
->
fb
_base
);
iounmap
(
info
->
screen
_base
);
err_out_iounmap_ctrl:
iounmap
(
rinfo
->
ctrl_base
);
iounmap
(
default_par
->
ctrl_base
);
err_out_free_base1:
release_mem_region
(
rinfo
->
fb_base_phys
,
rinfo
->
base1_region_size
);
release_mem_region
(
info
->
fix
.
smem_start
,
info
->
fix
.
smem_len
);
err_out_free_base0:
release_mem_region
(
rinfo
->
ctrl_base_phys
,
rinfo
->
base0_region_size
);
release_mem_region
(
info
->
fix
.
mmio_start
,
info
->
fix
.
mmio_len
);
err_out_kfree:
kfree
(
r
info
);
kfree
(
info
);
err_out:
return
-
ENODEV
;
}
static
void
__devexit
rivafb_remove_one
(
struct
pci_dev
*
pd
)
{
struct
rivafb_info
*
board
=
pci_get_drvdata
(
pd
);
struct
fb_info
*
info
=
pci_get_drvdata
(
pd
);
struct
riva_par
*
par
=
(
struct
riva_par
*
)
info
->
par
;
if
(
!
board
)
if
(
!
info
)
return
;
riva_
boards
=
riva_board_list_del
(
riva_boards
,
board
);
riva_
load_state
(
par
,
&
par
->
initial_state
);
riva_load_state
(
board
,
&
board
->
initial_state
);
unregister_framebuffer
(
info
);
unregister_framebuffer
((
struct
fb_info
*
)
board
);
rivafb_exit_cursor
(
board
);
rivafb_exit_cursor
(
par
);
#ifdef CONFIG_MTRR
if
(
board
->
mtrr
.
vram_valid
)
mtrr_del
(
board
->
mtrr
.
vram
,
board
->
fb_base_phys
,
board
->
base1_region_size
);
if
(
par
->
mtrr
.
vram_valid
)
mtrr_del
(
par
->
mtrr
.
vram
,
info
->
fix
.
smem_start
,
info
->
fix
.
smem_len
);
#endif
/* CONFIG_MTRR */
iounmap
(
board
->
ctrl_base
);
iounmap
(
board
->
fb_base
);
release_mem_region
(
board
->
ctrl_base_phys
,
board
->
base0_region_size
);
release_mem_region
(
board
->
fb_base_phys
,
board
->
base1_region_size
);
kfree
(
board
);
iounmap
(
par
->
ctrl_base
);
iounmap
(
info
->
screen_base
);
release_mem_region
(
info
->
fix
.
mmio_start
,
info
->
fix
.
mmio_len
);
release_mem_region
(
info
->
fix
.
smem_start
,
info
->
fix
.
smem_len
);
kfree
(
info
);
pci_set_drvdata
(
pd
,
NULL
);
}
/* ------------------------------------------------------------------------- *
*
* initialization
...
...
@@ -2063,8 +1558,6 @@ int __init rivafb_setup(char *options)
}
else
if
(
!
strncmp
(
this_opt
,
"noblink"
,
7
))
{
noblink
=
1
;
}
else
if
(
!
strncmp
(
this_opt
,
"noaccel"
,
7
))
{
noaccel
=
1
;
}
else
if
(
!
strncmp
(
this_opt
,
"nomove"
,
6
))
{
nomove
=
1
;
#ifdef CONFIG_MTRR
...
...
@@ -2081,10 +1574,10 @@ int __init rivafb_setup(char *options)
#endif
/* !MODULE */
static
struct
pci_driver
rivafb_driver
=
{
.
name
=
"rivafb"
,
.
id_table
=
rivafb_pci_tbl
,
.
probe
=
rivafb_init_one
,
.
remove
=
__devexit_p
(
rivafb_remove_one
),
name:
"rivafb"
,
id_table:
rivafb_pci_tbl
,
probe:
rivafb_init_one
,
remove:
__devexit_p
(
rivafb_remove_one
),
};
...
...
drivers/video/riva/riva_hw.h
View file @
85fa8aa4
...
...
@@ -74,6 +74,7 @@ typedef unsigned int U032;
#define NV_ARCH_03 0x03
#define NV_ARCH_04 0x04
#define NV_ARCH_10 0x10
#define NV_ARCH_20 0x20
/***************************************************************************\
* *
* FIFO registers. *
...
...
drivers/video/riva/rivafb.h
View file @
85fa8aa4
...
...
@@ -4,10 +4,6 @@
#include <linux/config.h>
#include <linux/fb.h>
#include <video/fbcon.h>
#include <video/fbcon-cfb4.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb32.h>
#include "riva_hw.h"
/* GGI compatibility macros */
...
...
@@ -27,56 +23,16 @@ struct riva_regs {
RIVA_HW_STATE
ext
;
};
typedef
struct
{
unsigned
char
red
,
green
,
blue
,
transp
;
}
riva_cfb8_cmap_t
;
struct
rivafb_info
;
struct
rivafb_info
{
struct
fb_info
info
;
/* kernel framebuffer info */
struct
riva_par
{
RIVA_HW_INST
riva
;
/* interface to riva_hw.c */
const
char
*
drvr_name
;
/* Riva hardware board type */
unsigned
long
ctrl_base_phys
;
/* physical control register base addr */
unsigned
long
fb_base_phys
;
/* physical framebuffer base addr */
caddr_t
ctrl_base
;
/* virtual control register base addr */
caddr_t
fb_base
;
/* virtual framebuffer base addr */
unsigned
ram_amount
;
/* amount of RAM on card, in bytes */
unsigned
dclk_max
;
/* max DCLK */
struct
riva_regs
initial_state
;
/* initial startup video mode */
struct
riva_regs
current_state
;
struct
display
disp
;
int
currcon
;
struct
display
*
currcon_display
;
struct
rivafb_info
*
next
;
struct
pci_dev
*
pd
;
/* pointer to board's pci info */
unsigned
base0_region_size
;
/* size of control register region */
unsigned
base1_region_size
;
/* size of framebuffer region */
struct
riva_cursor
*
cursor
;
struct
display_switch
dispsw
;
riva_cfb8_cmap_t
palette
[
256
];
/* VGA DAC palette cache */
#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
union
{
#ifdef FBCON_HAS_CFB16
u_int16_t
cfb16
[
16
];
#endif
#ifdef FBCON_HAS_CFB32
u_int32_t
cfb32
[
16
];
#endif
}
con_cmap
;
#endif
/* FBCON_HAS_CFB16 | FBCON_HAS_CFB32 */
#ifdef CONFIG_MTRR
struct
{
int
vram
;
int
vram_valid
;
}
mtrr
;
#endif
...
...
drivers/video/sgivwfb.c
View file @
85fa8aa4
...
...
@@ -23,15 +23,16 @@
#include <asm/uaccess.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/mtrr.h>
#define INCLUDE_TIMING_TABLE_DATA
#define DBE_REG_BASE regs
#include <
video/sgivw
.h>
#define DBE_REG_BASE
default_par.
regs
#include <
asm/sgi-vwdbe
.h>
struct
sgivw_par
{
asregs
*
regs
;
struct
asregs
*
regs
;
u32
cmap_fifo
;
u_long
timing_num
;
};
...
...
@@ -44,11 +45,12 @@ struct sgivw_par {
*/
/* set by arch/i386/kernel/setup.c */
u_
long
sgivwfb_mem_phys
;
u_
long
sgivwfb_mem_size
;
extern
unsigned
long
sgivwfb_mem_phys
;
extern
unsigned
long
sgivwfb_mem_size
;
static
struct
fb_info
fb_info
;
static
struct
sgivw_par
default_par
;
static
u32
pseudo_palette
[
17
];
static
struct
fb_info
fb_info
;
static
int
ypan
=
0
;
static
int
ywrap
=
0
;
...
...
@@ -58,7 +60,7 @@ static struct fb_fix_screeninfo sgivwfb_fix __initdata = {
.
visual
=
FB_VISUAL_PSEUDOCOLOR
,
.
mmio_start
=
DBE_REG_PHYS
,
.
mmio_len
=
DBE_REG_SIZE
,
.
accel
_flags
=
FB_ACCEL_NONE
.
accel
=
FB_ACCEL_NONE
};
static
struct
fb_var_screeninfo
sgivwfb_var
__initdata
=
{
...
...
@@ -152,8 +154,8 @@ static unsigned long bytes_per_pixel(int bpp)
static
void
dbe_TurnOffDma
(
void
)
{
int
i
;
unsigned
int
readVal
;
int
i
;
// Check to see if things are already turned off:
// 1) Check to see if dbe is not using the internal dotclock.
...
...
@@ -219,7 +221,7 @@ static void dbe_TurnOffDma(void)
static
int
sgivwfb_check_var
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
{
int
err
,
activate
=
var
->
activate
;
struct
sgivw_par
*
par
=
(
struct
sgivw_par
*
)
info
->
par
;
struct
dbe_timing_info
*
timing
;
u_long
line_length
;
u_long
min_mode
;
...
...
@@ -362,7 +364,7 @@ static int sgivwfb_set_par(struct fb_info *info)
u32
readVal
,
outputVal
;
int
wholeTilesX
,
maxPixelsPerTileX
;
int
frmWrite1
,
frmWrite2
,
frmWrite3b
;
dbe_timing_info_t
*
currentTiming
;
/* Current Video Timing */
struct
dbe_timing_info_t
*
currentTiming
;
/* Current Video Timing */
int
xpmax
,
ypmax
;
// Monitor resolution
int
bytesPerPixel
;
// Bytes per pixel
...
...
@@ -698,11 +700,16 @@ int __init sgivwfb_init(void)
printk
(
KERN_INFO
"sgivwfb: framebuffer at 0x%lx, size %ldk
\n
"
,
sgivwfb_mem_phys
,
sgivwfb_mem_size
/
1024
);
default_par
.
regs
=
(
asregs
*
)
ioremap_nocache
(
DBE_REG_PHYS
,
DBE_REG_SIZE
);
if
(
!
request_mem_region
(
DBE_REG_PHYS
,
DBE_REG_SIZE
,
"sgivwfb"
))
{
printk
(
KERN_ERR
"sgivwfb: couldn't reserve mmio region
\n
"
);
goto
fail_request_mem_region
;
}
default_par
.
regs
=
(
struct
asregs
*
)
ioremap_nocache
(
DBE_REG_PHYS
,
DBE_REG_SIZE
);
if
(
!
default_par
.
regs
)
{
printk
(
KERN_ERR
"sgivwfb: couldn't ioremap registers
\n
"
);
goto
fail_ioremap_regs
;
}
#ifdef CONFIG_MTRR
mtrr_add
((
unsigned
long
)
sgivwfb_mem_phys
,
sgivwfb_mem_size
,
MTRR_TYPE_WRCOMB
,
1
);
...
...
@@ -722,8 +729,7 @@ int __init sgivwfb_init(void)
fb_info
.
flags
=
FBINFO_FLAG_DEFAULT
;
fb_info
.
screen_base
=
ioremap_nocache
((
unsigned
long
)
sgivwfb_mem_phys
,
sgivwfb_mem_size
);
fb_info
.
screen_base
=
ioremap_nocache
((
unsigned
long
)
sgivwfb_mem_phys
,
sgivwfb_mem_size
);
if
(
!
fb_info
.
screen_base
)
{
printk
(
KERN_ERR
"sgivwfb: couldn't ioremap screen_base
\n
"
);
goto
fail_ioremap_fbmem
;
...
...
@@ -732,15 +738,11 @@ int __init sgivwfb_init(void)
fb_alloc_cmap
(
&
fb_info
.
cmap
,
256
,
0
);
if
(
register_framebuffer
(
&
fb_info
)
<
0
)
{
printk
(
KERN_ERR
"sgivwfb: couldn't register framebuffer
\n
"
);
printk
(
KERN_ERR
"sgivwfb: couldn't register framebuffer
\n
"
);
goto
fail_register_framebuffer
;
}
printk
(
KERN_INFO
"fb%d: Virtual frame buffer device, using %ldK of video memory
\n
"
,
minor
(
fb_info
.
node
),
sgivwfb_mem_size
>>
10
);
printk
(
KERN_INFO
"fb%d: SGI BDE frame buffer device, using %ldK of video memory
\n
"
,
minor
(
fb_info
.
node
,
sgivwfb_mem_size
>>
10
);
return
0
;
fail_register_framebuffer:
...
...
drivers/video/tdfxfb.c
View file @
85fa8aa4
...
...
@@ -165,6 +165,7 @@ static int tdfxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *inf
static
void
tdfxfb_fillrect
(
struct
fb_info
*
info
,
struct
fb_fillrect
*
rect
);
static
void
tdfxfb_copyarea
(
struct
fb_info
*
info
,
struct
fb_copyarea
*
area
);
static
void
tdfxfb_imageblit
(
struct
fb_info
*
info
,
struct
fb_image
*
image
);
static
int
tdfxfb_cursor
(
struct
fb_info
*
info
,
struct
fb_cursor
*
cursor
);
static
struct
fb_ops
tdfxfb_ops
=
{
.
owner
=
THIS_MODULE
,
...
...
@@ -176,6 +177,7 @@ static struct fb_ops tdfxfb_ops = {
.
fb_fillrect
=
tdfxfb_fillrect
,
.
fb_copyarea
=
tdfxfb_copyarea
,
.
fb_imageblit
=
tdfxfb_imageblit
,
.
fb_sync
=
banshee_wait_idle
,
.
fb_cursor
=
cfb_cursor
,
};
...
...
@@ -183,7 +185,7 @@ static struct fb_ops tdfxfb_ops = {
* do_xxx: Hardware-specific functions
*/
static
u32
do_calc_pll
(
int
freq
,
int
*
freq_out
);
static
void
do_write_regs
(
struct
tdfx_par
*
par
,
struct
banshee_reg
*
reg
);
static
void
do_write_regs
(
struct
fb_info
*
info
,
struct
banshee_reg
*
reg
);
static
unsigned
long
do_lfb_size
(
struct
tdfx_par
*
par
,
unsigned
short
);
/*
...
...
@@ -316,8 +318,9 @@ static inline void banshee_make_room(struct tdfx_par *par, int size)
while
((
tdfx_inl
(
par
,
STATUS
)
&
0x1f
)
<
size
);
}
static
inline
void
banshee_wait_idle
(
struct
tdfx_par
*
par
)
static
inline
void
banshee_wait_idle
(
struct
fb_info
*
info
)
{
struct
tdfx_par
*
par
=
(
struct
tdfx_par
*
)
info
->
par
;
int
i
=
0
;
banshee_make_room
(
par
,
1
);
...
...
@@ -368,11 +371,12 @@ static u32 do_calc_pll(int freq, int* freq_out)
return
(
n
<<
8
)
|
(
m
<<
2
)
|
k
;
}
static
void
do_write_regs
(
struct
tdfx_par
*
par
,
struct
banshee_reg
*
reg
)
static
void
do_write_regs
(
struct
fb_info
*
info
,
struct
banshee_reg
*
reg
)
{
struct
tdfx_par
*
par
=
(
struct
tdfx_par
*
)
info
->
par
;
int
i
;
banshee_wait_idle
(
par
);
banshee_wait_idle
(
info
);
tdfx_outl
(
par
,
MISCINIT1
,
tdfx_inl
(
par
,
MISCINIT1
)
|
0x01
);
...
...
@@ -429,7 +433,7 @@ static void do_write_regs(struct tdfx_par *par, struct banshee_reg* reg)
tdfx_outl
(
par
,
CLIP1MAX
,
0x0fff0fff
);
tdfx_outl
(
par
,
SRCXY
,
0
);
banshee_wait_idle
(
par
);
banshee_wait_idle
(
info
);
}
static
unsigned
long
do_lfb_size
(
struct
tdfx_par
*
par
,
unsigned
short
dev_id
)
...
...
@@ -885,7 +889,7 @@ static void tdfxfb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
tdfx_outl
(
par
,
COMMAND_2D
,
COMMAND_2D_FILLRECT
|
(
tdfx_rop
<<
24
));
tdfx_outl
(
par
,
DSTSIZE
,
rect
->
width
|
(
rect
->
height
<<
16
));
tdfx_outl
(
par
,
LAUNCH_2D
,
rect
->
dx
|
(
rect
->
dy
<<
16
));
banshee_wait_idle
(
par
);
banshee_wait_idle
(
info
);
}
/*
...
...
@@ -920,7 +924,7 @@ static void tdfxfb_copyarea(struct fb_info *info, struct fb_copyarea *area)
tdfx_outl
(
par
,
DSTSIZE
,
area
->
width
|
(
area
->
height
<<
16
));
tdfx_outl
(
par
,
DSTXY
,
area
->
dx
|
(
area
->
dy
<<
16
));
tdfx_outl
(
par
,
LAUNCH_2D
,
area
->
sx
|
(
area
->
sy
<<
16
));
banshee_wait_idle
(
par
);
banshee_wait_idle
(
info
);
}
static
void
tdfxfb_imageblit
(
struct
fb_info
*
info
,
struct
fb_image
*
pixmap
)
...
...
@@ -939,8 +943,8 @@ static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap)
tdfx_outl
(
par
,
COLORBACK
,
pixmap
->
bg_color
);
srcfmt
=
0x400000
;
}
else
{
banshee_make_room
(
par
,
6
+
((
size
+
3
)
>>
2
));
srcfmt
=
stride
|
((
bpp
+
((
bpp
==
8
)
?
0
:
8
))
<<
13
)
|
0x400000
;
//
banshee_make_room(par, 6 + ((size + 3) >> 2));
//
srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000;
}
tdfx_outl
(
par
,
SRCXY
,
0
);
...
...
@@ -964,7 +968,144 @@ static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap)
case
2
:
tdfx_outl
(
par
,
LAUNCH_2D
,
*
(
u16
*
)
chardata
);
break
;
case
3
:
tdfx_outl
(
par
,
LAUNCH_2D
,
*
(
u16
*
)
chardata
|
((
chardata
[
3
])
<<
24
));
break
;
}
banshee_wait_idle
(
par
);
banshee_wait_idle
(
info
);
}
static
int
tdfxfb_cursor
(
struct
fb_info
*
info
,
struct
fb_cursor
*
cursor
)
{
struct
tdfx_par
*
par
=
(
struct
tdfx_par
*
)
info
->
par
;
unsigned
long
flags
;
/*
* If the cursor is not be changed this means either we want the
* current cursor state (if enable is set) or we want to query what
* we can do with the cursor (if enable is not set)
*/
if
(
!
cursor
->
set
)
return
0
;
/* Too large of a cursor :-( */
if
(
cursor
->
image
.
width
>
64
||
cursor
->
image
.
height
>
64
)
return
-
ENXIO
;
/*
* If we are going to be changing things we should disable
* the cursor first
*/
if
(
info
->
cursor
.
enable
)
{
spin_lock_irqsave
(
&
par
->
DAClock
,
flags
);
info
->
cursor
.
enable
=
0
;
del_timer
(
&
(
par
->
hwcursor
.
timer
));
tdfx_outl
(
par
,
VIDPROCCFG
,
par
->
hwcursor
.
disable
);
spin_unlock_irqrestore
(
&
par
->
DAClock
,
flags
);
}
/* Disable the Cursor */
if
((
cursor
->
set
&&
FB_CUR_SETCUR
)
&&
!
cursor
->
enable
)
return
0
;
/* fix cursor color - XFree86 forgets to restore it properly */
if
(
cursor
->
set
&&
FB_CUR_SETCMAP
)
{
struct
fb_cmap
cmap
=
cursor
->
image
.
cmap
;
unsigned
long
bg_color
,
fg_color
;
cmap
.
len
=
2
;
/* Voodoo 3+ only support 2 color cursors*/
fg_color
=
((
cmap
.
red
[
cmap
.
start
]
<<
16
)
|
(
cmap
.
green
[
cmap
.
start
]
<<
8
)
|
(
cmap
.
blue
[
cmap
.
start
]));
bg_color
=
((
cmap
.
red
[
cmap
.
start
+
1
]
<<
16
)
|
(
cmap
.
green
[
cmap
.
start
+
1
]
<<
8
)
|
(
cmap
.
blue
[
cmap
.
start
+
1
]));
fb_copy_cmap
(
&
cmap
,
&
info
->
cursor
.
image
.
cmap
,
0
);
spin_lock_irqsave
(
&
par
->
DAClock
,
flags
);
banshee_make_room
(
par
,
2
);
tdfx_outl
(
par
,
HWCURC0
,
bg_color
);
tdfx_outl
(
par
,
HWCURC1
,
fg_color
);
spin_unlock_irqrestore
(
&
par
->
DAClock
,
flags
);
}
if
(
cursor
->
set
&&
FB_CUR_SETPOS
)
{
int
x
,
y
;
x
=
cursor
->
image
.
dx
;
y
=
cursor
->
image
.
dy
;
y
-=
info
->
var
.
yoffset
;
info
->
cursor
.
image
.
dx
=
x
;
info
->
cursor
.
image
.
dy
=
y
;
x
+=
63
;
y
+=
63
;
spin_lock_irqsave
(
&
par
->
DAClock
,
flags
);
banshee_make_room
(
par
,
1
);
tdfx_outl
(
par
,
HWCURLOC
,
(
y
<<
16
)
+
x
);
spin_unlock_irqrestore
(
&
par
->
DAClock
,
flags
);
}
/* Not supported so we fake it */
if
(
cursor
->
set
&&
FB_CUR_SETHOT
)
{
info
->
cursor
.
hot
.
x
=
cursor
->
hot
.
x
;
info
->
cursor
.
hot
.
y
=
cursor
->
hot
.
y
;
}
if
(
cursor
->
set
&&
FB_CUR_SETSHAPE
)
{
/*
* Voodoo 3 and above cards use 2 monochrome cursor patterns.
* The reason is so the card can fetch 8 words at a time
* and are stored on chip for use for the next 8 scanlines.
* This reduces the number of times for access to draw the
* cursor for each screen refresh.
* Each pattern is a bitmap of 64 bit wide and 64 bit high
* (total of 8192 bits or 1024 Kbytes). The two patterns are
* stored in such a way that pattern 0 always resides in the
* lower half (least significant 64 bits) of a 128 bit word
* and pattern 1 the upper half. If you examine the data of
* the cursor image the graphics card uses then from the
* begining you see line one of pattern 0, line one of
* pattern 1, line two of pattern 0, line two of pattern 1,
* etc etc. The linear stride for the cursor is always 16 bytes
* (128 bits) which is the maximum cursor width times two for
* the two monochrome patterns.
*/
u8
*
cursorbase
=
(
u8
*
)
info
->
cursor
.
image
.
data
;
char
*
bitmap
=
cursor
->
image
.
data
;
char
*
mask
=
cursor
->
mask
;
int
i
,
j
,
k
,
h
=
0
;
for
(
i
=
0
;
i
<
64
;
i
++
)
{
if
(
i
<
cursor
->
image
.
height
)
{
j
=
(
cursor
->
image
.
width
+
7
)
>>
3
;
k
=
8
-
j
;
for
(;
j
>
0
;
j
--
)
{
/* Pattern 0. Copy the cursor bitmap to it */
fb_writeb
(
*
bitmap
,
cursorbase
+
h
);
bitmap
++
;
/* Pattern 1. Copy the cursor mask to it */
fb_writeb
(
*
mask
,
cursorbase
+
h
+
8
);
mask
++
;
h
++
;
}
for
(;
k
>
0
;
k
--
)
{
fb_writeb
(
0
,
cursorbase
+
h
);
fb_writeb
(
~
0
,
cursorbase
+
h
+
8
);
h
++
;
}
}
else
{
fb_writel
(
0
,
cursorbase
+
h
);
fb_writel
(
0
,
cursorbase
+
h
+
4
);
fb_writel
(
~
0
,
cursorbase
+
h
+
8
);
fb_writel
(
~
0
,
cursorbase
+
h
+
12
);
h
+=
16
;
}
}
}
/* Turn the cursor on */
cursor
->
enable
=
1
;
info
->
cursor
=
*
cursor
;
mod_timer
(
&
par
->
hwcursor
.
timer
,
jiffies
+
HZ
/
2
);
spin_lock_irqsave
(
&
par
->
DAClock
,
flags
);
banshee_make_room
(
par
,
1
);
tdfx_outl
(
par
,
VIDPROCCFG
,
par
->
hwcursor
.
enable
);
spin_unlock_irqrestore
(
&
par
->
DAClock
,
flags
);
return
0
;
}
/**
...
...
@@ -988,14 +1129,15 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
return
err
;
}
info
=
kmalloc
(
sizeof
(
struct
fb_info
)
+
sizeof
(
struct
display
)
+
sizeof
(
u32
)
*
16
,
GFP_KERNEL
);
size
=
sizeof
(
struct
fb_info
)
+
sizeof
(
struct
tdfx_par
)
+
16
*
sizeof
(
u32
);
info
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
info
)
return
-
ENOMEM
;
memset
(
info
,
0
,
size
of
(
info
)
+
sizeof
(
struct
display
)
+
sizeof
(
u32
)
*
16
);
memset
(
info
,
0
,
size
);
default_par
=
kmalloc
(
sizeof
(
struct
tdfx_par
),
GFP_KERNEL
);
default_par
=
(
struct
tdfx_par
*
)
(
info
+
1
);
/* Configure the default fb_fix_screeninfo first */
switch
(
pdev
->
device
)
{
...
...
@@ -1078,7 +1220,7 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
info
->
fbops
=
&
tdfxfb_ops
;
info
->
fix
=
tdfx_fix
;
info
->
par
=
default_par
;
info
->
pseudo_palette
=
(
void
*
)(
info
+
1
);
info
->
pseudo_palette
=
(
void
*
)(
default_par
+
1
);
info
->
flags
=
FBINFO_FLAG_DEFAULT
;
if
(
!
mode_option
)
...
...
include/linux/fb.h
View file @
85fa8aa4
...
...
@@ -368,7 +368,7 @@ struct fb_ops {
/* perform polling on fb device */
int
(
*
fb_poll
)(
struct
fb_info
*
info
,
poll_table
*
wait
);
/* wait for blit idle, optional */
void
(
*
fb_sync
)(
struct
fb_info
*
info
);
int
(
*
fb_sync
)(
struct
fb_info
*
info
);
/* perform fb specific ioctl (optional) */
int
(
*
fb_ioctl
)(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
,
struct
fb_info
*
info
);
...
...
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