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
4ff60c0f
Commit
4ff60c0f
authored
Dec 04, 2002
by
James Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Supprt for switching hardware from/to vga text mode.
parent
23dda298
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
923 additions
and
183 deletions
+923
-183
drivers/video/Makefile
drivers/video/Makefile
+5
-3
drivers/video/aty128fb.c
drivers/video/aty128fb.c
+13
-6
drivers/video/cfbimgblt.c
drivers/video/cfbimgblt.c
+2
-2
drivers/video/console/fbcon.c
drivers/video/console/fbcon.c
+216
-98
drivers/video/fbmem.c
drivers/video/fbmem.c
+5
-6
drivers/video/radeonfb.c
drivers/video/radeonfb.c
+3
-27
drivers/video/riva/fbdev.c
drivers/video/riva/fbdev.c
+173
-38
drivers/video/riva/rivafb.h
drivers/video/riva/rivafb.h
+2
-1
drivers/video/vga16fb.c
drivers/video/vga16fb.c
+34
-1
drivers/video/vgastate.c
drivers/video/vgastate.c
+438
-0
include/linux/fb.h
include/linux/fb.h
+31
-0
include/linux/vt_kern.h
include/linux/vt_kern.h
+1
-1
include/video/radeon.h
include/video/radeon.h
+0
-0
No files found.
drivers/video/Makefile
View file @
4ff60c0f
...
...
@@ -6,7 +6,7 @@
# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
export-objs
:=
fbmem.o fbcmap.o fbmon.o modedb.o softcursor.o cfbfillrect.o
\
cfbcopyarea.o cfbimgblt.o cyber2000fb.o
cfbcopyarea.o cfbimgblt.o cyber2000fb.o
vgastate.o
# Each configuration option enables a list of files.
...
...
@@ -50,7 +50,8 @@ obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
obj-$(CONFIG_FB_S3TRIO)
+=
S3triofb.o
obj-$(CONFIG_FB_TGA)
+=
tgafb.o
obj-$(CONFIG_FB_VESA)
+=
vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_VGA16)
+=
vga16fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_VGA16)
+=
vga16fb.o cfbfillrect.o cfbcopyarea.o
\
cfbimgblt.o vgastate.o
obj-$(CONFIG_FB_VIRGE)
+=
virgefb.o
obj-$(CONFIG_FB_G364)
+=
g364fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_FM2)
+=
fm2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
...
...
@@ -69,7 +70,8 @@ obj-$(CONFIG_FB_MAXINE) += maxinefb.o cfbfillrect.o cfbcopyarea.o cfbi
obj-$(CONFIG_FB_TX3912)
+=
tx3912fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_MATROX)
+=
matrox/
obj-$(CONFIG_FB_RIVA)
+=
riva/ cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_RIVA)
+=
riva/ cfbfillrect.o cfbcopyarea.o
\
cfbimgblt.o vgastate.o
obj-$(CONFIG_FB_SIS)
+=
sis/
obj-$(CONFIG_FB_ATY)
+=
aty/ cfbimgblt.o
...
...
drivers/video/aty128fb.c
View file @
4ff60c0f
...
...
@@ -1770,9 +1770,12 @@ static char * __init aty128find_ROM(void)
char
*
rom_base
;
char
*
rom
;
int
stage
;
int
i
;
int
i
,
j
;
char
aty_rom_sig
[]
=
"761295520"
;
/* ATI ROM Signature */
char
R128_sig
[]
=
"R128"
;
/* Rage128 ROM identifier */
char
*
R128_sig
[]
=
{
"R128"
,
/* Rage128 ROM identifier */
"128b"
};
for
(
segstart
=
0x000c0000
;
segstart
<
0x000f0000
;
segstart
+=
0x00001000
)
{
stage
=
1
;
...
...
@@ -1803,10 +1806,14 @@ static char * __init aty128find_ROM(void)
/* ATI signature found. Let's see if it's a Rage128 */
for
(
i
=
0
;
(
i
<
512
)
&&
(
stage
!=
4
);
i
++
)
{
if
(
R128_sig
[
0
]
==
*
rom
)
if
(
strncmp
(
R128_sig
,
rom
,
strlen
(
R128_sig
))
==
0
)
stage
=
4
;
for
(
j
=
0
;
j
<
sizeof
(
R128_sig
)
/
sizeof
(
char
*
);
j
++
)
{
if
(
R128_sig
[
j
][
0
]
==
*
rom
)
if
(
strncmp
(
R128_sig
[
j
],
rom
,
strlen
(
R128_sig
[
j
]))
==
0
)
{
stage
=
4
;
break
;
}
}
rom
++
;
}
if
(
stage
!=
4
)
{
...
...
drivers/video/cfbimgblt.c
View file @
4ff60c0f
...
...
@@ -123,11 +123,11 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p, u8
shift
=
start_index
;
}
while
(
n
--
)
{
if
(
p
->
fix
.
visual
==
FB_VISUAL_PSEUDOCOLOR
)
color
=
*
src
&
bitmask
;
if
(
p
->
fix
.
visual
==
FB_VISUAL_TRUECOLOR
||
p
->
fix
.
visual
==
FB_VISUAL_DIRECTCOLOR
)
color
=
palette
[
*
src
]
&
bitmask
;
else
color
=
*
src
&
bitmask
;
val
|=
SHIFT_HIGH
(
color
,
shift
);
if
(
shift
>=
null_bits
)
{
FB_WRITEL
(
val
,
dst
++
);
...
...
drivers/video/console/fbcon.c
View file @
4ff60c0f
...
...
@@ -317,18 +317,16 @@ void set_con2fb_map(int unit, int newidx)
if
(
newidx
!=
con2fb_map
[
unit
])
{
oldfb
=
registered_fb
[
oldidx
];
newfb
=
registered_fb
[
newidx
];
if
(
newfb
->
fbops
->
owner
)
__MOD_INC_USE_COUNT
(
newfb
->
fbops
->
owner
)
;
if
(
!
try_module_get
(
newfb
->
fbops
->
owner
)
)
return
;
if
(
newfb
->
fbops
->
fb_open
&&
newfb
->
fbops
->
fb_open
(
newfb
,
0
))
{
if
(
newfb
->
fbops
->
owner
)
__MOD_DEC_USE_COUNT
(
newfb
->
fbops
->
owner
);
module_put
(
newfb
->
fbops
->
owner
);
return
;
}
if
(
oldfb
->
fbops
->
fb_release
)
oldfb
->
fbops
->
fb_release
(
oldfb
,
0
);
if
(
oldfb
->
fbops
->
owner
)
__MOD_DEC_USE_COUNT
(
oldfb
->
fbops
->
owner
);
module_put
(
oldfb
->
fbops
->
owner
);
vc
=
fb_display
[
unit
].
conp
;
fontdata
=
fb_display
[
unit
].
fontdata
;
userfont
=
fb_display
[
unit
].
userfont
;
...
...
@@ -596,10 +594,10 @@ static const char *fbcon_startup(void)
info
->
currcon
=
-
1
;
owner
=
info
->
fbops
->
owner
;
if
(
owner
)
__MOD_INC_USE_COUNT
(
owner
)
;
if
(
info
->
fbops
->
fb_open
&&
info
->
fbops
->
fb_open
(
info
,
0
)
&&
owner
)
__MOD_DEC_USE_COUNT
(
owner
);
if
(
!
try_module_get
(
owner
)
)
return
NULL
;
if
(
info
->
fbops
->
fb_open
&&
info
->
fbops
->
fb_open
(
info
,
0
))
module_put
(
owner
);
if
(
info
->
fix
.
type
!=
FB_TYPE_TEXT
)
{
if
(
fbcon_softback_size
)
{
...
...
@@ -2549,111 +2547,226 @@ static inline unsigned safe_shift(unsigned d, int n)
return
n
<
0
?
d
>>
-
n
:
d
<<
n
;
}
static
int
__init
fbcon_show_logo
(
void
)
static
void
__init
fbcon_set_logocmap
(
struct
fb_info
*
info
)
{
struct
display
*
p
=
&
fb_display
[
fg_console
];
/* draw to vt in foreground */
int
i
,
j
,
n
;
for
(
i
=
0
;
i
<
LINUX_LOGO_COLORS
;
i
+=
n
)
{
n
=
LINUX_LOGO_COLORS
-
i
;
if
(
n
>
16
)
/* palette_cmap provides space for only 16 colors at once */
n
=
16
;
palette_cmap
.
start
=
32
+
i
;
palette_cmap
.
len
=
n
;
for
(
j
=
0
;
j
<
n
;
++
j
)
{
palette_cmap
.
red
[
j
]
=
(
linux_logo_red
[
i
+
j
]
<<
8
)
|
linux_logo_red
[
i
+
j
];
palette_cmap
.
green
[
j
]
=
(
linux_logo_green
[
i
+
j
]
<<
8
)
|
linux_logo_green
[
i
+
j
];
palette_cmap
.
blue
[
j
]
=
(
linux_logo_blue
[
i
+
j
]
<<
8
)
|
linux_logo_blue
[
i
+
j
];
}
fb_set_cmap
(
&
palette_cmap
,
1
,
info
);
}
}
static
void
__init
fbcon_set_logo_truepalette
(
struct
fb_info
*
info
,
u32
*
palette
)
{
unsigned
char
mask
[
9
]
=
{
0
,
0x80
,
0xc0
,
0xe0
,
0xf0
,
0xf8
,
0xfc
,
0xfe
,
0xff
};
unsigned
char
redmask
,
greenmask
,
bluemask
;
int
redshift
,
greenshift
,
blueshift
;
int
i
;
/*
* We have to create a temporary palette since console palette is only
* 16 colors long.
*/
/* Bug: Doesn't obey msb_right ... (who needs that?) */
redmask
=
mask
[
info
->
var
.
red
.
length
<
8
?
info
->
var
.
red
.
length
:
8
];
greenmask
=
mask
[
info
->
var
.
green
.
length
<
8
?
info
->
var
.
green
.
length
:
8
];
bluemask
=
mask
[
info
->
var
.
blue
.
length
<
8
?
info
->
var
.
blue
.
length
:
8
];
redshift
=
info
->
var
.
red
.
offset
-
(
8
-
info
->
var
.
red
.
length
);
greenshift
=
info
->
var
.
green
.
offset
-
(
8
-
info
->
var
.
green
.
length
);
blueshift
=
info
->
var
.
blue
.
offset
-
(
8
-
info
->
var
.
blue
.
length
);
for
(
i
=
0
;
i
<
LINUX_LOGO_COLORS
;
i
++
)
{
palette
[
i
+
32
]
=
(
safe_shift
((
linux_logo_red
[
i
]
&
redmask
),
redshift
)
|
safe_shift
((
linux_logo_green
[
i
]
&
greenmask
),
greenshift
)
|
safe_shift
((
linux_logo_blue
[
i
]
&
bluemask
),
blueshift
));
}
}
static
void
__init
fbcon_set_logo_directpalette
(
struct
fb_info
*
info
,
u32
*
palette
)
{
int
redshift
,
greenshift
,
blueshift
;
int
i
;
redshift
=
info
->
var
.
red
.
offset
;
greenshift
=
info
->
var
.
green
.
offset
;
blueshift
=
info
->
var
.
blue
.
offset
;
for
(
i
=
32
;
i
<
LINUX_LOGO_COLORS
;
i
++
)
palette
[
i
]
=
i
<<
redshift
|
i
<<
greenshift
|
i
<<
blueshift
;
}
static
void
__init
fbcon_set_logo
(
struct
fb_info
*
info
,
u8
*
logo
,
int
needs_logo
)
{
int
i
,
j
;
switch
(
needs_logo
)
{
case
4
:
for
(
i
=
0
;
i
<
(
LOGO_W
*
LOGO_H
)
/
2
;
i
++
)
{
logo
[
i
*
2
]
=
linux_logo16
[
i
]
>>
4
;
logo
[(
i
*
2
)
+
1
]
=
linux_logo16
[
i
]
&
0xf
;
}
break
;
case
1
:
case
~
1
:
default:
for
(
i
=
0
;
i
<
(
LOGO_W
*
LOGO_H
)
/
8
;
i
++
)
for
(
j
=
0
;
j
<
8
;
j
++
)
logo
[
i
*
2
]
=
(
linux_logo_bw
[
i
]
&
(
7
-
j
))
?
((
needs_logo
==
1
)
?
1
:
0
)
:
((
needs_logo
==
1
)
?
0
:
1
);
break
;
}
}
/*
* Three (3) kinds of logo maps exist. linux_logo (>16 colors), linux_logo_16
* (16 colors) and linux_logo_bw (2 colors). Depending on the visual format and
* color depth of the framebuffer, the DAC, the pseudo_palette, and the logo data
* will be adjusted accordingly.
*
* Case 1 - linux_logo:
* Color exceeds the number of console colors (16), thus we set the hardware DAC
* using fb_set_cmap() appropriately. The "needs_cmapreset" flag will be set.
*
* For visuals that require color info from the pseudo_palette, we also construct
* one for temporary use. The "needs_directpalette" or "needs_truepalette" flags
* will be set.
*
* Case 2 - linux_logo_16:
* The number of colors just matches the console colors, thus there is no need
* to set the DAC or the pseudo_palette. However, the bitmap is packed, ie,
* each byte contains color information for two pixels (upper and lower nibble).
* To be consistent with fb_imageblit() usage, we therefore separate the two
* nibbles into separate bytes. The "needs_logo" flag will be set to 4.
*
* Case 3 - linux_logo_bw:
* This is similar with Case 2. Each byte contains information for 8 pixels.
* We isolate each bit and expand each into a byte. The "needs_logo" flag will
* be set to 1.
*/
static
int
__init
fbcon_show_logo
(
void
)
{
struct
display
*
p
=
&
fb_display
[
fg_console
];
/* draw to vt in foreground */
struct
fb_info
*
info
=
p
->
fb_info
;
struct
vc_data
*
vc
=
info
->
display_fg
;
struct
fb_image
image
;
u32
*
palette
=
NULL
,
*
saved_palette
=
NULL
;
int
depth
=
info
->
var
.
bits_per_pixel
;
unsigned
char
*
fb
=
info
->
screen_base
;
unsigned
char
*
logo
;
int
i
,
j
,
n
,
x
;
int
logo_depth
,
done
=
0
;
unsigned
char
*
fb
=
info
->
screen_base
,
*
logo_new
=
NULL
;
int
done
=
0
,
x
;
int
needs_cmapreset
=
0
;
int
needs_truepalette
=
0
;
int
needs_directpalette
=
0
;
int
needs_logo
=
0
;
/* Return if the frame buffer is not mapped */
if
(
!
fb
)
if
(
!
fb
||
!
info
->
fbops
->
fb_imageblit
)
return
0
;
/*
* Set colors if visual is PSEUDOCOLOR and we have enough colors, or for
* DIRECTCOLOR
* We don't have to set the colors for the 16-color logo, since that logo
* uses the standard VGA text console palette
*/
if
((
info
->
fix
.
visual
==
FB_VISUAL_PSEUDOCOLOR
&&
depth
>=
8
)
||
(
info
->
fix
.
visual
==
FB_VISUAL_DIRECTCOLOR
&&
depth
>=
24
))
for
(
i
=
0
;
i
<
LINUX_LOGO_COLORS
;
i
+=
n
)
{
n
=
LINUX_LOGO_COLORS
-
i
;
if
(
n
>
16
)
/* palette_cmap provides space for only 16 colors at once */
n
=
16
;
palette_cmap
.
start
=
32
+
i
;
palette_cmap
.
len
=
n
;
for
(
j
=
0
;
j
<
n
;
++
j
)
{
palette_cmap
.
red
[
j
]
=
(
linux_logo_red
[
i
+
j
]
<<
8
)
|
linux_logo_red
[
i
+
j
];
palette_cmap
.
green
[
j
]
=
(
linux_logo_green
[
i
+
j
]
<<
8
)
|
linux_logo_green
[
i
+
j
];
palette_cmap
.
blue
[
j
]
=
(
linux_logo_blue
[
i
+
j
]
<<
8
)
|
linux_logo_blue
[
i
+
j
];
}
fb_set_cmap
(
&
palette_cmap
,
1
,
info
);
image
.
depth
=
info
->
var
.
bits_per_pixel
;
/* reasonable default */
if
(
image
.
depth
>=
8
)
image
.
data
=
linux_logo
;
else
if
(
image
.
depth
>=
4
)
image
.
data
=
linux_logo16
;
else
image
.
data
=
linux_logo_bw
;
switch
(
info
->
fix
.
visual
)
{
case
FB_VISUAL_TRUECOLOR
:
needs_truepalette
=
1
;
if
(
image
.
depth
>=
4
&&
image
.
depth
<=
8
)
needs_logo
=
4
;
else
if
(
image
.
depth
<
4
)
needs_logo
=
1
;
break
;
case
FB_VISUAL_DIRECTCOLOR
:
if
(
image
.
depth
>=
24
)
{
needs_directpalette
=
1
;
needs_cmapreset
=
1
;
}
if
(
depth
>=
8
)
{
logo
=
linux_logo
;
logo_depth
=
8
;
}
else
if
(
depth
>=
4
)
{
logo
=
linux_logo16
;
logo_depth
=
4
;
}
else
{
logo
=
linux_logo_bw
;
logo_depth
=
1
;
}
if
(
info
->
fix
.
visual
==
FB_VISUAL_TRUECOLOR
)
{
unsigned
char
mask
[
9
]
=
{
0
,
0x80
,
0xc0
,
0xe0
,
0xf0
,
0xf8
,
0xfc
,
0xfe
,
0xff
};
unsigned
char
redmask
,
greenmask
,
bluemask
;
int
redshift
,
greenshift
,
blueshift
;
/* Bug: Doesn't obey msb_right ... (who needs that?) */
redmask
=
mask
[
info
->
var
.
red
.
length
<
8
?
info
->
var
.
red
.
length
:
8
];
greenmask
=
mask
[
info
->
var
.
green
.
length
<
8
?
info
->
var
.
green
.
length
:
8
];
bluemask
=
mask
[
info
->
var
.
blue
.
length
<
8
?
info
->
var
.
blue
.
length
:
8
];
redshift
=
info
->
var
.
red
.
offset
-
(
8
-
info
->
var
.
red
.
length
);
greenshift
=
info
->
var
.
green
.
offset
-
(
8
-
info
->
var
.
green
.
length
);
blueshift
=
info
->
var
.
blue
.
offset
-
(
8
-
info
->
var
.
blue
.
length
);
/*
* We have to create a temporary palette since console palette is only
* 16 colors long.
*/
/* 16 colors */
else
if
(
image
.
depth
>=
16
)
needs_logo
=
4
;
/* 2 colors */
else
needs_logo
=
1
;
break
;
case
FB_VISUAL_MONO01
:
/* reversed 0 = fg, 1 = bg */
needs_logo
=
~
1
;
break
;
case
FB_VISUAL_MONO10
:
needs_logo
=
1
;
break
;
case
FB_VISUAL_PSEUDOCOLOR
:
default:
if
(
image
.
depth
>=
8
)
needs_cmapreset
=
1
;
/* fall through */
case
FB_VISUAL_STATIC_PSEUDOCOLOR
:
/* 16 colors */
if
(
image
.
depth
>=
4
&&
image
.
depth
<
8
)
needs_logo
=
4
;
/* 2 colors */
else
if
(
image
.
depth
<
4
)
needs_logo
=
1
;
break
;
}
if
(
needs_cmapreset
)
fbcon_set_logocmap
(
info
);
if
(
needs_truepalette
||
needs_directpalette
)
{
palette
=
kmalloc
(
256
*
4
,
GFP_KERNEL
);
if
(
palette
==
NULL
)
return
(
LOGO_H
+
vc
->
vc_font
.
height
-
1
)
/
vc
->
vc_font
.
height
;
for
(
i
=
0
;
i
<
LINUX_LOGO_COLORS
;
i
++
)
{
palette
[
i
+
32
]
=
(
safe_shift
((
linux_logo_red
[
i
]
&
redmask
),
redshift
)
|
safe_shift
((
linux_logo_green
[
i
]
&
greenmask
),
greenshift
)
|
safe_shift
((
linux_logo_blue
[
i
]
&
bluemask
),
blueshift
));
}
return
1
;
if
(
needs_truepalette
)
fbcon_set_logo_truepalette
(
info
,
palette
);
else
fbcon_set_logo_directpalette
(
info
,
palette
);
saved_palette
=
info
->
pseudo_palette
;
info
->
pseudo_palette
=
palette
;
}
if
(
needs_logo
)
{
logo_new
=
kmalloc
(
LOGO_W
*
LOGO_H
,
GFP_KERNEL
);
if
(
logo_new
==
NULL
)
{
if
(
palette
)
kfree
(
palette
);
if
(
saved_palette
)
info
->
pseudo_palette
=
saved_palette
;
return
1
;
}
image
.
data
=
logo_new
;
fbcon_set_logo
(
info
,
logo_new
,
needs_logo
);
}
image
.
width
=
LOGO_W
;
image
.
height
=
LOGO_H
;
image
.
depth
=
depth
;
image
.
data
=
logo
;
image
.
dy
=
0
;
for
(
x
=
0
;
x
<
num_online_cpus
()
*
(
LOGO_W
+
8
)
&&
...
...
@@ -2667,6 +2780,8 @@ static int __init fbcon_show_logo(void)
kfree
(
palette
);
if
(
saved_palette
!=
NULL
)
info
->
pseudo_palette
=
saved_palette
;
if
(
logo_new
!=
NULL
)
kfree
(
logo_new
);
/*
* Modes not yet supported: packed pixels with depth != 8 (does such a
* thing exist in reality?)
...
...
@@ -2701,7 +2816,10 @@ const struct consw fb_con = {
int
__init
fb_console_init
(
void
)
{
if
(
!
num_registered_fb
)
return
-
ENODEV
;
take_over_console
(
&
fb_con
,
first_fb_vc
,
last_fb_vc
,
fbcon_is_default
);
__unsafe
(
THIS_MODULE
);
return
0
;
}
...
...
drivers/video/fbmem.c
View file @
4ff60c0f
...
...
@@ -730,12 +730,12 @@ fb_open(struct inode *inode, struct file *file)
#endif
/* CONFIG_KMOD */
if
(
!
(
info
=
registered_fb
[
fbidx
]))
return
-
ENODEV
;
if
(
info
->
fbops
->
owner
)
__MOD_INC_USE_COUNT
(
info
->
fbops
->
owner
)
;
if
(
!
try_module_get
(
info
->
fbops
->
owner
)
)
return
-
ENODEV
;
if
(
info
->
fbops
->
fb_open
)
{
res
=
info
->
fbops
->
fb_open
(
info
,
1
);
if
(
res
&&
info
->
fbops
->
owner
)
__MOD_DEC_USE_COUNT
(
info
->
fbops
->
owner
);
if
(
res
)
module_put
(
info
->
fbops
->
owner
);
}
return
res
;
}
...
...
@@ -750,8 +750,7 @@ fb_release(struct inode *inode, struct file *file)
info
=
registered_fb
[
fbidx
];
if
(
info
->
fbops
->
fb_release
)
info
->
fbops
->
fb_release
(
info
,
1
);
if
(
info
->
fbops
->
owner
)
__MOD_DEC_USE_COUNT
(
info
->
fbops
->
owner
);
module_put
(
info
->
fbops
->
owner
);
unlock_kernel
();
return
0
;
}
...
...
drivers/video/radeonfb.c
View file @
4ff60c0f
...
...
@@ -42,8 +42,6 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/console.h>
#include <linux/selection.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/pci.h>
...
...
@@ -54,7 +52,7 @@
#if defined(__powerpc__)
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#include
<video/macmodes.h>
#include
"macmodes.h"
#ifdef CONFIG_NVRAM
#include <linux/nvram.h>
...
...
@@ -80,10 +78,8 @@
#endif
#include <video/radeon.h>
#include <linux/radeonfb.h>
#define DEBUG 1
#if DEBUG
...
...
@@ -681,7 +677,6 @@ static __inline__ int _max(int val1, int val2)
* globals
*/
static
char
fontname
[
40
]
__initdata
;
static
char
*
mode_option
__initdata
;
static
char
noaccel
=
1
;
static
char
mirror
=
0
;
...
...
@@ -1295,7 +1290,6 @@ static int __devinit radeon_init_disp (struct radeonfb_info *rinfo)
var
.
activate
=
FB_ACTIVATE_NOW
;
gen_set_var
(
&
var
,
-
1
,
info
);
return
0
;
}
...
...
@@ -1495,7 +1489,7 @@ static int radeonfb_check_var (struct fb_var_screeninfo *var, struct fb_info *in
}
static
int
radeonfb_pan_display
(
struct
fb_var_screeninfo
*
var
,
int
con
,
static
int
radeonfb_pan_display
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
{
struct
radeonfb_info
*
rinfo
=
(
struct
radeonfb_info
*
)
info
;
...
...
@@ -1509,7 +1503,6 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
OUTREG
(
CRTC_OFFSET
,
((
var
->
yoffset
*
var
->
xres_virtual
+
var
->
xoffset
)
*
var
->
bits_per_pixel
/
8
)
&
~
7
);
return
0
;
}
...
...
@@ -2188,11 +2181,8 @@ static void radeon_write_mode (struct radeonfb_info *rinfo,
static
struct
fb_ops
radeonfb_ops
=
{
.
owner
=
THIS_MODULE
,
.
fb_set_var
=
gen_set_var
,
.
fb_check_var
=
radeonfb_check_var
,
.
fb_set_par
=
radeonfb_set_par
,
.
fb_get_cmap
=
gen_get_cmap
,
.
fb_set_cmap
=
gen_set_cmap
,
.
fb_setcolreg
=
radeonfb_setcolreg
,
.
fb_pan_display
=
radeonfb_pan_display
,
.
fb_blank
=
radeonfb_blank
,
...
...
@@ -2228,11 +2218,6 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
info
->
fbops
=
&
radeonfb_ops
;
info
->
display_fg
=
NULL
;
info
->
screen_base
=
(
char
*
)
rinfo
->
fb_base
;
strncpy
(
info
->
fontname
,
fontname
,
sizeof
(
info
->
fontname
));
info
->
fontname
[
sizeof
(
info
->
fontname
)
-
1
]
=
0
;
info
->
changevar
=
NULL
;
info
->
switch_con
=
gen_switch
;
info
->
updatevar
=
gen_update_var
;
/* Fill fix common fields */
strncpy
(
info
->
fix
.
id
,
rinfo
->
name
,
sizeof
(
info
->
fix
.
id
));
...
...
@@ -3138,16 +3123,7 @@ int __init radeonfb_setup (char *options)
while
((
this_opt
=
strsep
(
&
options
,
","
))
!=
NULL
)
{
if
(
!*
this_opt
)
continue
;
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
);
}
else
if
(
!
strncmp
(
this_opt
,
"noaccel"
,
7
))
{
if
(
!
strncmp
(
this_opt
,
"noaccel"
,
7
))
{
noaccel
=
1
;
}
else
if
(
!
strncmp
(
this_opt
,
"mirror"
,
6
))
{
mirror
=
1
;
...
...
drivers/video/riva/fbdev.c
View file @
4ff60c0f
...
...
@@ -42,6 +42,7 @@
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include "rivafb.h"
#include "nvreg.h"
...
...
@@ -246,15 +247,12 @@ struct riva_cursor {
/* command line data, set in rivafb_setup() */
static
u32
pseudo_palette
[
17
];
static
char
nomove
=
0
;
#ifdef CONFIG_MTRR
static
char
nomtrr
__initdata
=
0
;
#endif
#ifndef MODULE
static
char
*
mode_option
__initdata
=
NULL
;
#else
static
char
*
font
=
NULL
;
#endif
static
struct
fb_fix_screeninfo
rivafb_fix
=
{
...
...
@@ -428,7 +426,7 @@ static void rivafb_load_cursor_image(u8 *data, u8 *mask, struct riva_par *par,
m
=
*
((
u32
*
)
mask
)
++
;
for
(
j
=
0
;
j
<
w
/
2
;
j
++
)
{
tmp
=
0
;
#if defined (__BIG_ENDIAN)
#if defined (__BIG_ENDIAN
__
)
if
(
m
&
(
1
<<
31
))
tmp
=
(
b
&
(
1
<<
31
))
?
fg
<<
16
:
bg
<<
16
;
b
<<=
1
;
...
...
@@ -1162,6 +1160,46 @@ static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
* framebuffer operations
*
* ------------------------------------------------------------------------- */
static
int
rivafb_open
(
struct
fb_info
*
info
,
int
user
)
{
struct
riva_par
*
par
=
(
struct
riva_par
*
)
info
->
par
;
int
cnt
=
atomic_read
(
&
par
->
ref_count
);
if
(
!
cnt
)
{
memset
(
&
par
->
state
,
0
,
sizeof
(
struct
fb_vgastate
));
par
->
state
.
flags
=
VGA_SAVE_MODE
|
VGA_SAVE_FONTS
;
/* save the DAC for Riva128 */
if
(
par
->
riva
.
Architecture
==
NV_ARCH_03
)
par
->
state
.
flags
|=
VGA_SAVE_CMAP
;
fb_save_vga
(
&
par
->
state
);
RivaGetConfig
(
&
par
->
riva
);
riva_save_state
(
par
,
&
par
->
initial_state
);
}
atomic_inc
(
&
par
->
ref_count
);
return
0
;
}
static
int
rivafb_release
(
struct
fb_info
*
info
,
int
user
)
{
struct
riva_par
*
par
=
(
struct
riva_par
*
)
info
->
par
;
int
cnt
=
atomic_read
(
&
par
->
ref_count
);
if
(
!
cnt
)
return
-
EINVAL
;
if
(
cnt
==
1
)
{
par
->
riva
.
LockUnlock
(
&
par
->
riva
,
0
);
par
->
riva
.
LoadStateExt
(
&
par
->
riva
,
&
par
->
initial_state
.
ext
);
fb_restore_vga
(
&
par
->
state
);
par
->
riva
.
LockUnlock
(
&
par
->
riva
,
1
);
}
atomic_dec
(
&
par
->
ref_count
);
return
0
;
}
static
int
rivafb_check_var
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
...
...
@@ -1493,6 +1531,8 @@ static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,
/* kernel interface */
static
struct
fb_ops
riva_fb_ops
=
{
.
owner
=
THIS_MODULE
,
.
fb_open
=
rivafb_open
,
.
fb_release
=
rivafb_release
,
.
fb_check_var
=
rivafb_check_var
,
.
fb_set_par
=
rivafb_set_par
,
.
fb_setcolreg
=
rivafb_setcolreg
,
...
...
@@ -1535,6 +1575,106 @@ static int __devinit riva_set_fbinfo(struct fb_info *info)
*
* ------------------------------------------------------------------------- */
static
void
__devinit
rivafb_get_mem_len
(
struct
riva_par
*
par
,
struct
fb_fix_screeninfo
*
fix
)
{
RIVA_HW_INST
*
chip
=
&
par
->
riva
;
switch
(
chip
->
Architecture
)
{
case
NV_ARCH_03
:
if
(
chip
->
PFB
[
0x00000000
/
4
]
&
0x00000020
)
{
if
(((
chip
->
PMC
[
0x00000000
/
4
]
&
0xF0
)
==
0x20
)
&&
((
chip
->
PMC
[
0x00000000
/
4
]
&
0x0F
)
>=
0x02
))
{
/*
* SDRAM 128 ZX.
*/
switch
(
chip
->
PFB
[
0x00000000
/
4
]
&
0x03
)
{
case
2
:
fix
->
smem_len
=
1024
*
1024
*
4
;
break
;
case
1
:
fix
->
smem_len
=
1024
*
1024
*
2
;
break
;
default:
fix
->
smem_len
=
1024
*
1024
*
8
;
break
;
}
}
else
{
fix
->
smem_len
=
1024
*
1024
*
8
;
}
}
else
{
/*
* SGRAM 128.
*/
switch
(
chip
->
PFB
[
0x00000000
/
4
]
&
0x00000003
)
{
case
0
:
fix
->
smem_len
=
1024
*
1024
*
8
;
break
;
case
2
:
fix
->
smem_len
=
1024
*
1024
*
4
;
break
;
default:
fix
->
smem_len
=
1024
*
1024
*
2
;
break
;
}
}
break
;
case
NV_ARCH_04
:
if
(
chip
->
PFB
[
0x00000000
/
4
]
&
0x00000100
)
{
fix
->
smem_len
=
(((
chip
->
PFB
[
0x00000000
/
4
]
>>
12
)
&
0x0F
)
*
1024
*
2
+
1024
*
2
)
*
1024
;
}
else
{
switch
(
chip
->
PFB
[
0x00000000
/
4
]
&
0x00000003
)
{
case
0
:
fix
->
smem_len
=
1024
*
1024
*
32
;
break
;
case
1
:
fix
->
smem_len
=
1024
*
1024
*
4
;
break
;
case
2
:
fix
->
smem_len
=
1024
*
1024
*
8
;
break
;
case
3
:
default:
fix
->
smem_len
=
1024
*
1024
*
16
;
break
;
}
}
break
;
case
NV_ARCH_10
:
case
NV_ARCH_20
:
switch
((
chip
->
PFB
[
0x0000020C
/
4
]
>>
20
)
&
0x000000FF
)
{
case
0x02
:
fix
->
smem_len
=
1024
*
1024
*
2
;
break
;
case
0x04
:
fix
->
smem_len
=
1024
*
1024
*
4
;
break
;
case
0x08
:
fix
->
smem_len
=
1024
*
1024
*
8
;
break
;
case
0x10
:
fix
->
smem_len
=
1024
*
1024
*
16
;
break
;
case
0x20
:
fix
->
smem_len
=
1024
*
1024
*
32
;
break
;
case
0x40
:
fix
->
smem_len
=
1024
*
1024
*
64
;
break
;
case
0x80
:
fix
->
smem_len
=
1024
*
1024
*
128
;
break
;
default:
fix
->
smem_len
=
1024
*
1024
*
16
;
break
;
}
}
}
static
int
__devinit
rivafb_init_one
(
struct
pci_dev
*
pd
,
const
struct
pci_device_id
*
ent
)
{
...
...
@@ -1586,14 +1726,22 @@ static int __devinit rivafb_init_one(struct pci_dev *pd,
}
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
);
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
);
default_par
->
riva
.
PCIO
=
(
U008
*
)(
default_par
->
ctrl_base
+
0x00601000
);
default_par
->
riva
.
PDIO
=
(
U008
*
)(
default_par
->
ctrl_base
+
0x00681000
);
...
...
@@ -1603,22 +1751,26 @@ static int __devinit rivafb_init_one(struct pci_dev *pd,
switch
(
default_par
->
riva
.
Architecture
)
{
case
NV_ARCH_03
:
default_par
->
riva
.
PRAMIN
=
(
unsigned
*
)(
info
->
screen_base
+
0x00C00000
);
default_par
->
riva
.
PRAMIN
=
(
unsigned
*
)(
info
->
screen_base
+
0x00C00000
);
default_par
->
dclk_max
=
256000000
;
rivafb_fix
.
accel
=
FB_ACCEL_NV3
;
break
;
case
NV_ARCH_04
:
case
NV_ARCH_10
:
case
NV_ARCH_20
:
default_par
->
riva
.
PCRTC
=
(
unsigned
*
)(
default_par
->
ctrl_base
+
0x00600000
);
default_par
->
riva
.
PRAMIN
=
(
unsigned
*
)(
default_par
->
ctrl_base
+
0x00710000
);
default_par
->
riva
.
PCRTC
=
(
unsigned
*
)(
default_par
->
ctrl_base
+
0x00600000
);
default_par
->
riva
.
PRAMIN
=
(
unsigned
*
)(
default_par
->
ctrl_base
+
0x00710000
);
default_par
->
dclk_max
=
250000000
;
rivafb_fix
.
accel
=
FB_ACCEL_NV4
;
break
;
}
RivaGetConfig
(
&
default_par
->
riva
);
rivafb_get_mem_len
(
default_par
,
&
rivafb_fix
);
rivafb_fix
.
smem_len
=
default_par
->
riva
.
RamAmountKBytes
*
1024
;
default_par
->
dclk_max
=
default_par
->
riva
.
MaxVClockFreqKHz
*
1000
;
info
->
par
=
default_par
;
if
(
!
request_mem_region
(
rivafb_fix
.
smem_start
,
rivafb_fix
.
smem_len
,
"rivafb"
))
{
...
...
@@ -1648,14 +1800,6 @@ static int __devinit rivafb_init_one(struct pci_dev *pd,
}
#endif
/* CONFIG_MTRR */
/* unlock io */
CRTCout
(
default_par
,
0x11
,
0xFF
);
/* vgaHWunlock() + riva unlock(0x7F) */
default_par
->
riva
.
LockUnlock
(
&
default_par
->
riva
,
0
);
info
->
par
=
default_par
;
riva_save_state
(
default_par
,
&
default_par
->
initial_state
);
if
(
riva_set_fbinfo
(
info
)
<
0
)
{
printk
(
KERN_ERR
PFX
"error setting initial video mode
\n
"
);
goto
err_out_cursor
;
...
...
@@ -1680,7 +1824,6 @@ static int __devinit rivafb_init_one(struct pci_dev *pd,
return
0
;
err_out_load_state:
riva_load_state
(
default_par
,
&
default_par
->
initial_state
);
err_out_cursor:
/* err_out_iounmap_fb: */
iounmap
(
info
->
screen_base
);
...
...
@@ -1704,8 +1847,6 @@ static void __devexit rivafb_remove_one(struct pci_dev *pd)
if
(
!
info
)
return
;
riva_load_state
(
par
,
&
par
->
initial_state
);
unregister_framebuffer
(
info
);
#ifdef CONFIG_MTRR
...
...
@@ -1742,13 +1883,11 @@ int __init rivafb_setup(char *options)
while
((
this_opt
=
strsep
(
&
options
,
","
))
!=
NULL
)
{
if
(
!*
this_opt
)
continue
;
if
(
!
strncmp
(
this_opt
,
"nomove"
,
6
))
{
nomove
=
1
;
#ifdef CONFIG_MTRR
}
else
if
(
!
strncmp
(
this_opt
,
"nomtrr"
,
6
))
{
if
(
!
strncmp
(
this_opt
,
"nomtrr"
,
6
))
{
nomtrr
=
1
;
#endif
}
else
#endif
mode_option
=
this_opt
;
}
return
0
;
...
...
@@ -1773,9 +1912,7 @@ static struct pci_driver rivafb_driver = {
int
__init
rivafb_init
(
void
)
{
int
err
;
#ifdef MODULE
if
(
font
)
strncpy
(
fontname
,
font
,
sizeof
(
fontname
)
-
1
);
#endif
err
=
pci_module_init
(
&
rivafb_driver
);
if
(
err
)
return
err
;
...
...
@@ -1796,8 +1933,6 @@ MODULE_PARM(font, "s");
MODULE_PARM_DESC
(
font
,
"Specifies one of the compiled-in fonts (default=none)"
);
MODULE_PARM
(
noaccel
,
"i"
);
MODULE_PARM_DESC
(
noaccel
,
"Disables hardware acceleration (0 or 1=disabled) (default=0)"
);
MODULE_PARM
(
nomove
,
"i"
);
MODULE_PARM_DESC
(
nomove
,
"Enables YSCROLL_NOMOVE (0 or 1=enabled) (default=0)"
);
#ifdef CONFIG_MTRR
MODULE_PARM
(
nomtrr
,
"i"
);
MODULE_PARM_DESC
(
nomtrr
,
"Disables MTRR support (0 or 1=disabled) (default=0)"
);
...
...
drivers/video/riva/rivafb.h
View file @
4ff60c0f
...
...
@@ -34,7 +34,8 @@ struct riva_par {
struct
riva_regs
initial_state
;
/* initial startup video mode */
struct
riva_regs
current_state
;
struct
fb_vgastate
state
;
atomic_t
ref_count
;
riva_cfb8_cmap_t
cmap
[
256
];
/* VGA DAC palette cache */
u32
riva_palette
[
16
];
u32
cursor_data
[
32
*
32
/
4
];
...
...
drivers/video/vga16fb.c
View file @
4ff60c0f
...
...
@@ -7,7 +7,8 @@
*
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file COPYING in the main directory of this
* archive for more details. */
* archive for more details.
*/
#include <linux/module.h>
#include <linux/kernel.h>
...
...
@@ -69,6 +70,8 @@ static struct vga16fb_par {
unsigned
char
ModeControl
;
/* CRT-Controller:17h */
unsigned
char
ClockingMode
;
/* Seq-Controller:01h */
}
vga_state
;
struct
fb_vgastate
state
;
atomic_t
ref_count
;
int
palette_blanked
,
vesa_blanked
,
mode
,
isVGA
;
u8
misc
,
pel_msk
,
vss
,
clkdiv
;
u8
crtc
[
VGA_CRT_C
];
...
...
@@ -295,6 +298,34 @@ static void vga16fb_clock_chip(struct vga16fb_par *par,
#define FAIL(X) return -EINVAL
static
int
vga16fb_open
(
struct
fb_info
*
info
,
int
user
)
{
struct
vga16fb_par
*
par
=
(
struct
vga16fb_par
*
)
info
->
par
;
int
cnt
=
atomic_read
(
&
par
->
ref_count
);
if
(
!
cnt
)
{
memset
(
&
par
->
state
,
0
,
sizeof
(
struct
fb_vgastate
));
par
->
state
.
flags
=
8
;
fb_save_vga
(
&
par
->
state
);
}
atomic_inc
(
&
par
->
ref_count
);
return
0
;
}
static
int
vga16fb_release
(
struct
fb_info
*
info
,
int
user
)
{
struct
vga16fb_par
*
par
=
(
struct
vga16fb_par
*
)
info
->
par
;
int
cnt
=
atomic_read
(
&
par
->
ref_count
);
if
(
!
cnt
)
return
-
EINVAL
;
if
(
cnt
==
1
)
fb_restore_vga
(
&
par
->
state
);
atomic_dec
(
&
par
->
ref_count
);
return
0
;
}
static
int
vga16fb_check_var
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
{
...
...
@@ -1346,6 +1377,8 @@ void vga16fb_imageblit(struct fb_info *info, struct fb_image *image)
static
struct
fb_ops
vga16fb_ops
=
{
.
owner
=
THIS_MODULE
,
.
fb_open
=
vga16fb_open
,
.
fb_release
=
vga16fb_release
,
.
fb_check_var
=
vga16fb_check_var
,
.
fb_set_par
=
vga16fb_set_par
,
.
fb_setcolreg
=
vga16fb_setcolreg
,
...
...
drivers/video/vgastate.c
0 → 100644
View file @
4ff60c0f
/*
* linux/include/video/vgastate.c -- VGA state save/restore
*
* Copyright 2002 James Simmons
*
* Copyright history from vga16fb.c:
* Copyright 1999 Ben Pfaff and Petr Vandrovec
* Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm
* Based on VESA framebuffer (c) 1998 Gerd Knorr
*
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file COPYING in the main directory of this
* archive for more details.
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/fb.h>
#include "vga.h"
static
inline
unsigned
char
vga_rcrtcs
(
caddr_t
regbase
,
unsigned
short
iobase
,
unsigned
char
reg
)
{
vga_w
(
regbase
,
iobase
+
0x4
,
reg
);
return
vga_r
(
regbase
,
iobase
+
0x5
);
}
static
inline
void
vga_wcrtcs
(
caddr_t
regbase
,
unsigned
short
iobase
,
unsigned
char
reg
,
unsigned
char
val
)
{
vga_w
(
regbase
,
iobase
+
0x4
,
reg
);
vga_w
(
regbase
,
iobase
+
0x5
,
val
);
}
static
void
save_vga_text
(
struct
fb_vgastate
*
state
)
{
int
i
;
u8
misc
,
attr10
,
gr4
,
gr5
,
gr6
,
seq1
,
seq2
,
seq4
;
/* if in graphics mode, no need to save */
attr10
=
vga_rattr
(
state
->
vgabase
,
0x10
);
if
(
attr10
&
1
)
return
;
/* save regs */
misc
=
vga_r
(
state
->
vgabase
,
VGA_MIS_R
);
gr4
=
vga_rgfx
(
state
->
vgabase
,
VGA_GFX_PLANE_READ
);
gr5
=
vga_rgfx
(
state
->
vgabase
,
VGA_GFX_MODE
);
gr6
=
vga_rgfx
(
state
->
vgabase
,
VGA_GFX_MISC
);
seq2
=
vga_rseq
(
state
->
vgabase
,
VGA_SEQ_PLANE_WRITE
);
seq4
=
vga_rseq
(
state
->
vgabase
,
VGA_SEQ_MEMORY_MODE
);
/* force graphics mode */
vga_w
(
state
->
vgabase
,
VGA_MIS_W
,
misc
|
1
);
/* blank screen */
seq1
=
vga_rseq
(
state
->
vgabase
,
VGA_SEQ_CLOCK_MODE
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_RESET
,
0x1
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_CLOCK_MODE
,
seq1
|
1
<<
5
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_RESET
,
0x3
);
/* save font 0 */
if
(
state
->
flags
&
VGA_SAVE_FONT0
)
{
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_PLANE_WRITE
,
0x4
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_MEMORY_MODE
,
0x6
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_PLANE_READ
,
0x2
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MODE
,
0x0
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MISC
,
0x5
);
for
(
i
=
0
;
i
<
8
*
8192
;
i
++
)
state
->
vga_font0
[
i
]
=
vga_r
(
state
->
fbbase
,
i
);
}
/* save font 1 */
if
(
state
->
flags
&
VGA_SAVE_FONT1
)
{
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_PLANE_WRITE
,
0x8
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_MEMORY_MODE
,
0x6
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_PLANE_READ
,
0x3
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MODE
,
0x0
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MISC
,
0x5
);
for
(
i
=
0
;
i
<
8
*
8192
;
i
++
)
state
->
vga_font1
[
i
]
=
vga_r
(
state
->
fbbase
,
i
);
}
/* save font 2 */
if
(
state
->
flags
&
VGA_SAVE_TEXT
)
{
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_PLANE_WRITE
,
0x1
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_MEMORY_MODE
,
0x6
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_PLANE_READ
,
0x0
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MODE
,
0x0
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MISC
,
0x5
);
for
(
i
=
0
;
i
<
2
*
8192
;
i
++
)
state
->
vga_text
[
i
]
=
vga_r
(
state
->
fbbase
,
i
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_PLANE_WRITE
,
0x2
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_MEMORY_MODE
,
0x6
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_PLANE_READ
,
0x1
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MODE
,
0x0
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MISC
,
0x5
);
for
(
i
=
0
;
i
<
2
*
8192
;
i
++
)
state
->
vga_text
[
i
]
=
vga_r
(
state
->
fbbase
+
2
*
8192
,
i
);
}
/* restore regs */
vga_wattr
(
state
->
vgabase
,
0x10
,
attr10
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_PLANE_WRITE
,
seq2
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_MEMORY_MODE
,
seq4
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_PLANE_READ
,
gr4
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MODE
,
gr5
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MISC
,
gr6
);
vga_w
(
state
->
vgabase
,
VGA_MIS_W
,
misc
);
/* unblank screen */
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_RESET
,
0x1
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_CLOCK_MODE
,
seq1
&
~
(
1
<<
5
));
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_RESET
,
0x3
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_CLOCK_MODE
,
seq1
);
}
static
void
restore_vga_text
(
struct
fb_vgastate
*
state
)
{
int
i
;
u8
misc
,
gr1
,
gr3
,
gr4
,
gr5
,
gr6
,
gr8
;
u8
seq1
,
seq2
,
seq4
;
/* save regs */
misc
=
vga_r
(
state
->
vgabase
,
VGA_MIS_R
);
gr1
=
vga_rgfx
(
state
->
vgabase
,
VGA_GFX_SR_ENABLE
);
gr3
=
vga_rgfx
(
state
->
vgabase
,
VGA_GFX_DATA_ROTATE
);
gr4
=
vga_rgfx
(
state
->
vgabase
,
VGA_GFX_PLANE_READ
);
gr5
=
vga_rgfx
(
state
->
vgabase
,
VGA_GFX_MODE
);
gr6
=
vga_rgfx
(
state
->
vgabase
,
VGA_GFX_MISC
);
gr8
=
vga_rgfx
(
state
->
vgabase
,
VGA_GFX_BIT_MASK
);
seq2
=
vga_rseq
(
state
->
vgabase
,
VGA_SEQ_PLANE_WRITE
);
seq4
=
vga_rseq
(
state
->
vgabase
,
VGA_SEQ_MEMORY_MODE
);
/* force graphics mode */
vga_w
(
state
->
vgabase
,
VGA_MIS_W
,
misc
|
1
);
/* blank screen */
seq1
=
vga_rseq
(
state
->
vgabase
,
VGA_SEQ_CLOCK_MODE
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_RESET
,
0x1
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_CLOCK_MODE
,
seq1
|
1
<<
5
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_RESET
,
0x3
);
if
(
state
->
depth
==
4
)
{
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_DATA_ROTATE
,
0x0
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_BIT_MASK
,
0xff
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_SR_ENABLE
,
0x00
);
}
/* restore font 0 */
if
(
state
->
flags
&
VGA_SAVE_FONT0
)
{
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_PLANE_WRITE
,
0x4
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_MEMORY_MODE
,
0x6
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_PLANE_READ
,
0x2
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MODE
,
0x0
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MISC
,
0x5
);
for
(
i
=
0
;
i
<
8
*
8192
;
i
++
)
vga_w
(
state
->
fbbase
,
i
,
state
->
vga_font0
[
i
]);
}
/* restore font 1 */
if
(
state
->
flags
&
VGA_SAVE_FONT1
)
{
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_PLANE_WRITE
,
0x8
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_MEMORY_MODE
,
0x6
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_PLANE_READ
,
0x3
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MODE
,
0x0
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MISC
,
0x5
);
for
(
i
=
0
;
i
<
8
*
8192
;
i
++
)
vga_w
(
state
->
fbbase
,
i
,
state
->
vga_font1
[
i
]);
}
/* restore font 2 */
if
(
state
->
flags
&
VGA_SAVE_TEXT
)
{
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_PLANE_WRITE
,
0x1
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_MEMORY_MODE
,
0x6
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_PLANE_READ
,
0x0
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MODE
,
0x0
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MISC
,
0x5
);
for
(
i
=
0
;
i
<
2
*
8192
;
i
++
)
vga_w
(
state
->
fbbase
,
i
,
state
->
vga_text
[
i
]);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_PLANE_WRITE
,
0x2
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_MEMORY_MODE
,
0x6
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_PLANE_READ
,
0x1
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MODE
,
0x0
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MISC
,
0x5
);
for
(
i
=
0
;
i
<
2
*
8192
;
i
++
)
vga_w
(
state
->
fbbase
+
2
*
8192
,
i
,
state
->
vga_text
[
i
]);
}
/* unblank screen */
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_RESET
,
0x1
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_CLOCK_MODE
,
seq1
&
~
(
1
<<
5
));
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_RESET
,
0x3
);
/* restore regs */
vga_w
(
state
->
vgabase
,
VGA_MIS_W
,
misc
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_SR_ENABLE
,
gr1
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_DATA_ROTATE
,
gr3
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_PLANE_READ
,
gr4
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MODE
,
gr5
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_MISC
,
gr6
);
vga_wgfx
(
state
->
vgabase
,
VGA_GFX_BIT_MASK
,
gr8
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_CLOCK_MODE
,
seq1
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_PLANE_WRITE
,
seq2
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_MEMORY_MODE
,
seq4
);
}
static
void
save_vga_mode
(
struct
fb_vgastate
*
state
)
{
unsigned
short
iobase
;
int
i
;
state
->
misc
=
vga_r
(
state
->
vgabase
,
VGA_MIS_R
);
if
(
state
->
misc
&
1
)
iobase
=
0x3d0
;
else
iobase
=
0x3b0
;
for
(
i
=
0
;
i
<
state
->
num_crtc
;
i
++
)
state
->
crtc
[
i
]
=
vga_rcrtcs
(
state
->
vgabase
,
iobase
,
i
);
vga_r
(
state
->
vgabase
,
iobase
+
0xa
);
vga_w
(
state
->
vgabase
,
VGA_ATT_W
,
0x00
);
for
(
i
=
0
;
i
<
state
->
num_attr
;
i
++
)
{
vga_r
(
state
->
vgabase
,
iobase
+
0xa
);
state
->
attr
[
i
]
=
vga_rattr
(
state
->
vgabase
,
i
);
}
vga_r
(
state
->
vgabase
,
iobase
+
0xa
);
vga_w
(
state
->
vgabase
,
VGA_ATT_W
,
0x20
);
for
(
i
=
0
;
i
<
state
->
num_gfx
;
i
++
)
state
->
gfx
[
i
]
=
vga_rgfx
(
state
->
vgabase
,
i
);
for
(
i
=
0
;
i
<
state
->
num_seq
;
i
++
)
state
->
seq
[
i
]
=
vga_rseq
(
state
->
vgabase
,
i
);
}
static
void
restore_vga_mode
(
struct
fb_vgastate
*
state
)
{
unsigned
short
iobase
;
int
i
;
vga_w
(
state
->
vgabase
,
VGA_MIS_W
,
state
->
misc
);
if
(
state
->
misc
&
1
)
iobase
=
0x3d0
;
else
iobase
=
0x3b0
;
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_RESET
,
0x01
);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_CLOCK_MODE
,
state
->
seq
[
VGA_SEQ_CLOCK_MODE
]
|
0x20
);
for
(
i
=
2
;
i
<
state
->
num_seq
;
i
++
)
vga_wseq
(
state
->
vgabase
,
i
,
state
->
seq
[
i
]);
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_RESET
,
0x03
);
/* unprotect vga regs */
vga_wcrtcs
(
state
->
vgabase
,
iobase
,
17
,
state
->
crtc
[
17
]
&
~
0x80
);
for
(
i
=
0
;
i
<
state
->
num_crtc
;
i
++
)
vga_wcrtcs
(
state
->
vgabase
,
iobase
,
i
,
state
->
crtc
[
i
]);
for
(
i
=
0
;
i
<
state
->
num_gfx
;
i
++
)
vga_wgfx
(
state
->
vgabase
,
i
,
state
->
gfx
[
i
]);
vga_r
(
state
->
vgabase
,
iobase
+
0xa
);
vga_w
(
state
->
vgabase
,
VGA_ATT_W
,
0x00
);
for
(
i
=
0
;
i
<
state
->
num_attr
;
i
++
)
{
vga_r
(
state
->
vgabase
,
iobase
+
0xa
);
vga_wattr
(
state
->
vgabase
,
i
,
state
->
attr
[
i
]);
}
vga_wseq
(
state
->
vgabase
,
VGA_SEQ_CLOCK_MODE
,
state
->
seq
[
VGA_SEQ_CLOCK_MODE
]);
vga_r
(
state
->
vgabase
,
iobase
+
0xa
);
vga_w
(
state
->
vgabase
,
VGA_ATT_W
,
0x20
);
}
static
void
save_vga_cmap
(
struct
fb_vgastate
*
state
)
{
int
i
;
vga_w
(
state
->
vgabase
,
VGA_PEL_MSK
,
0xff
);
/* assumes DAC is readable and writable */
vga_w
(
state
->
vgabase
,
VGA_PEL_IR
,
0x00
);
for
(
i
=
0
;
i
<
768
;
i
++
)
state
->
vga_cmap
[
i
]
=
vga_r
(
state
->
vgabase
,
VGA_PEL_D
);
}
static
void
restore_vga_cmap
(
struct
fb_vgastate
*
state
)
{
int
i
;
vga_w
(
state
->
vgabase
,
VGA_PEL_MSK
,
0xff
);
vga_w
(
state
->
vgabase
,
VGA_PEL_IW
,
0x00
);
for
(
i
=
0
;
i
<
768
;
i
++
)
vga_w
(
state
->
vgabase
,
VGA_PEL_D
,
state
->
vga_cmap
[
i
]);
}
static
void
vga_cleanup
(
struct
fb_vgastate
*
state
)
{
if
(
state
->
vga_font0
)
kfree
(
state
->
vga_font0
);
if
(
state
->
vga_font1
)
kfree
(
state
->
vga_font1
);
if
(
state
->
vga_text
)
kfree
(
state
->
vga_text
);
if
(
state
->
fbbase
)
iounmap
(
state
->
fbbase
);
if
(
state
->
vga_cmap
)
kfree
(
state
->
vga_cmap
);
if
(
state
->
attr
)
kfree
(
state
->
attr
);
if
(
state
->
crtc
)
kfree
(
state
->
crtc
);
if
(
state
->
gfx
)
kfree
(
state
->
gfx
);
if
(
state
->
seq
)
kfree
(
state
->
seq
);
}
int
fb_save_vga
(
struct
fb_vgastate
*
state
)
{
state
->
vga_font0
=
NULL
;
state
->
vga_font1
=
NULL
;
state
->
vga_text
=
NULL
;
state
->
vga_cmap
=
NULL
;
state
->
attr
=
NULL
;
state
->
crtc
=
NULL
;
state
->
gfx
=
NULL
;
state
->
seq
=
NULL
;
if
(
state
->
flags
&
VGA_SAVE_CMAP
)
{
state
->
vga_cmap
=
kmalloc
(
768
,
GFP_KERNEL
);
if
(
!
state
->
vga_cmap
)
{
vga_cleanup
(
state
);
return
1
;
}
save_vga_cmap
(
state
);
}
if
(
state
->
flags
&
VGA_SAVE_MODE
)
{
if
(
state
->
num_attr
<
21
)
state
->
num_attr
=
21
;
if
(
state
->
num_crtc
<
25
)
state
->
num_crtc
=
25
;
if
(
state
->
num_gfx
<
9
)
state
->
num_gfx
=
9
;
if
(
state
->
num_seq
<
5
)
state
->
num_seq
=
5
;
state
->
attr
=
kmalloc
(
state
->
num_attr
,
GFP_KERNEL
);
state
->
crtc
=
kmalloc
(
state
->
num_crtc
,
GFP_KERNEL
);
state
->
gfx
=
kmalloc
(
state
->
num_gfx
,
GFP_KERNEL
);
state
->
seq
=
kmalloc
(
state
->
num_seq
,
GFP_KERNEL
);
if
(
!
state
->
attr
||
!
state
->
crtc
||
!
state
->
gfx
||
!
state
->
seq
)
{
vga_cleanup
(
state
);
return
1
;
}
save_vga_mode
(
state
);
}
if
(
state
->
flags
&
VGA_SAVE_FONT0
)
{
state
->
vga_font0
=
kmalloc
(
8192
*
8
,
GFP_KERNEL
);
if
(
!
state
->
vga_font0
)
{
vga_cleanup
(
state
);
return
1
;
}
}
if
(
state
->
flags
&
VGA_SAVE_FONT1
)
{
state
->
vga_font1
=
kmalloc
(
8192
*
8
,
GFP_KERNEL
);
if
(
!
state
->
vga_font1
)
{
vga_cleanup
(
state
);
return
1
;
}
}
if
(
state
->
flags
&
VGA_SAVE_TEXT
)
{
state
->
vga_text
=
kmalloc
(
8192
*
4
,
GFP_KERNEL
);
if
(
!
state
->
vga_text
)
{
vga_cleanup
(
state
);
return
1
;
}
}
if
(
state
->
flags
&
VGA_SAVE_FONTS
)
{
state
->
fbbase
=
ioremap
(
0xA0000
,
8
*
8192
);
if
(
!
state
->
fbbase
)
{
vga_cleanup
(
state
);
return
1
;
}
save_vga_text
(
state
);
iounmap
(
state
->
fbbase
);
state
->
fbbase
=
NULL
;
}
return
0
;
}
int
fb_restore_vga
(
struct
fb_vgastate
*
state
)
{
if
(
state
->
flags
&
VGA_SAVE_MODE
)
restore_vga_mode
(
state
);
if
(
state
->
flags
&
VGA_SAVE_FONTS
)
{
state
->
fbbase
=
ioremap
(
0xA0000
,
8
*
8192
);
if
(
!
state
->
fbbase
)
{
vga_cleanup
(
state
);
return
1
;
}
restore_vga_text
(
state
);
}
if
(
state
->
flags
&
VGA_SAVE_CMAP
)
restore_vga_cmap
(
state
);
vga_cleanup
(
state
);
return
0
;
}
#ifdef MODULE
int
init_module
(
void
)
{
return
0
;
};
void
cleanup_module
(
void
)
{};
#endif
EXPORT_SYMBOL
(
fb_save_vga
);
EXPORT_SYMBOL
(
fb_restore_vga
);
MODULE_AUTHOR
(
"James Simmons <jsimmons@users.sf.net>"
);
MODULE_DESCRIPTION
(
"VGA State Save/Restore"
);
MODULE_LICENSE
(
"GPL"
);
include/linux/fb.h
View file @
4ff60c0f
...
...
@@ -321,6 +321,37 @@ struct fb_cursor {
struct
fb_image
image
;
/* Cursor image */
};
/* VGA State Save and Restore */
#define VGA_SAVE_FONT0 1
/* save/restore plane 2 fonts */
#define VGA_SAVE_FONT1 2
/* save/restore plane 3 fonts */
#define VGA_SAVE_TEXT 4
/* save/restore plane 0/1 fonts */
#define VGA_SAVE_FONTS 7
/* save/restore all fonts */
#define VGA_SAVE_MODE 8
/* save/restore video mode */
#define VGA_SAVE_CMAP 16
/* save/restore color map/DAC */
struct
fb_vgastate
{
caddr_t
vgabase
;
/* mmio base, if supported */
__u32
flags
;
/* what state/s to save (see VGA_SAVE_*) */
__u32
depth
;
/* current fb depth, not important */
__u32
num_attr
;
/* number of att registers, 0 for default */
__u32
num_crtc
;
/* number of crt registers, 0 for default */
__u32
num_gfx
;
/* number of gfx registers, 0 for default */
__u32
num_seq
;
/* number of seq registers, 0 for default */
caddr_t
fbbase
;
/* -- DO NOT ALTER STARTING HERE -- */
__u8
*
vga_font0
;
__u8
*
vga_font1
;
__u8
*
vga_text
;
__u8
*
vga_cmap
;
__u8
*
attr
;
__u8
*
crtc
;
__u8
*
gfx
;
__u8
*
seq
;
__u8
misc
;
};
extern
int
fb_save_vga
(
struct
fb_vgastate
*
state
);
extern
int
fb_restore_vga
(
struct
fb_vgastate
*
state
);
#ifdef __KERNEL__
#include <linux/fs.h>
...
...
include/linux/vt_kern.h
View file @
4ff60c0f
...
...
@@ -9,8 +9,8 @@
#include <linux/config.h>
#include <linux/vt.h>
#include <linux/kd.h>
#include <linux/console_struct.h>
#include <linux/tty.h>
#include <linux/console_struct.h>
/*
* Presently, a lot of graphics programs do not restore the contents of
...
...
include/
linux
/radeon.h
→
include/
video
/radeon.h
View file @
4ff60c0f
File moved
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