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
0458af5e
Commit
0458af5e
authored
May 16, 2002
by
James Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved VESA framebuffer driver over to new fbdev api
parent
4cc4c697
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
517 additions
and
338 deletions
+517
-338
drivers/video/Makefile
drivers/video/Makefile
+2
-1
drivers/video/cfbcopyarea.c
drivers/video/cfbcopyarea.c
+222
-0
drivers/video/cfbfillrect.c
drivers/video/cfbfillrect.c
+209
-0
drivers/video/vesafb.c
drivers/video/vesafb.c
+84
-337
No files found.
drivers/video/Makefile
View file @
0458af5e
...
...
@@ -69,7 +69,7 @@ obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o
obj-$(CONFIG_FB_CLGEN)
+=
clgenfb.o
obj-$(CONFIG_FB_S3TRIO)
+=
S3triofb.o
obj-$(CONFIG_FB_TGA)
+=
tgafb.o
obj-$(CONFIG_FB_VESA)
+=
vesafb.o
obj-$(CONFIG_FB_VESA)
+=
vesafb.o
cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_VGA16)
+=
vga16fb.o fbcon-vga-planes.o
obj-$(CONFIG_FB_VIRGE)
+=
virgefb.o
obj-$(CONFIG_FB_G364)
+=
g364fb.o
...
...
@@ -138,6 +138,7 @@ obj-$(CONFIG_FBCON_MFB) += fbcon-mfb.o
obj-$(CONFIG_FBCON_VGA)
+=
fbcon-vga.o
obj-$(CONFIG_FBCON_HGA)
+=
fbcon-hga.o
obj-$(CONFIG_FBCON_STI)
+=
fbcon-sti.o
obj-$(CONFIG_FBCON_ACCEL)
+=
fbcon-accel.o
include
$(TOPDIR)/Rules.make
...
...
drivers/video/cfbcopyarea.c
0 → 100644
View file @
0458af5e
/*
* Generic function for frame buffer with packed pixels of any depth.
*
* Copyright (C) June 1999 James Simmons
*
* 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.
*
* NOTES:
*
* This is for cfb packed pixels. Iplan and such are incorporated in the
* drivers that need them.
*
* FIXME
* The code for 24 bit is horrible. It copies byte by byte size instead of
* longs like the other sizes. Needs to be optimized.
*
* Also need to add code to deal with cards endians that are different than
* the native cpu endians. I also need to deal with MSB position in the word.
*
*/
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/slab.h>
#include <asm/types.h>
#include <asm/io.h>
#include <video/fbcon.h>
void
cfb_copyarea
(
struct
fb_info
*
p
,
struct
fb_copyarea
*
area
)
{
int
x2
,
y2
,
lineincr
,
shift
,
shift_right
,
shift_left
,
old_dx
,
old_dy
;
int
n
,
j
,
linesize
=
p
->
fix
.
line_length
,
bpl
=
sizeof
(
unsigned
long
);
unsigned
long
start_index
,
end_index
,
start_mask
,
end_mask
,
last
;
unsigned
long
*
dst
=
NULL
,
*
src
=
NULL
;
char
*
src1
,
*
dst1
;
int
tmp
,
height
;
/* clip the destination */
old_dx
=
area
->
dx
;
old_dy
=
area
->
dy
;
/*
* We could use hardware clipping but on many cards you get around
* hardware clipping by writing to framebuffer directly.
*/
x2
=
area
->
dx
+
area
->
width
;
y2
=
area
->
dy
+
area
->
height
;
area
->
dx
=
area
->
dx
>
0
?
area
->
dx
:
0
;
area
->
dy
=
area
->
dy
>
0
?
area
->
dy
:
0
;
x2
=
x2
<
p
->
var
.
xres_virtual
?
x2
:
p
->
var
.
xres_virtual
;
y2
=
y2
<
p
->
var
.
yres_virtual
?
y2
:
p
->
var
.
yres_virtual
;
area
->
width
=
x2
-
area
->
dx
;
area
->
height
=
y2
-
area
->
dy
;
/* update sx1,sy1 */
area
->
sx
+=
(
area
->
dx
-
old_dx
);
area
->
sy
+=
(
area
->
dy
-
old_dy
);
height
=
area
->
height
;
/* the source must be completely inside the virtual screen */
if
(
area
->
sx
<
0
||
area
->
sy
<
0
||
(
area
->
sx
+
area
->
width
)
>
p
->
var
.
xres_virtual
||
(
area
->
sy
+
area
->
height
)
>
p
->
var
.
yres_virtual
)
return
;
if
(
area
->
dy
<
area
->
sy
||
(
area
->
dy
==
area
->
sy
&&
area
->
dx
<
area
->
sx
))
{
/* start at the top */
src1
=
p
->
screen_base
+
area
->
sy
*
linesize
+
((
area
->
sx
*
p
->
var
.
bits_per_pixel
)
>>
3
);
dst1
=
p
->
screen_base
+
area
->
dy
*
linesize
+
((
area
->
dx
*
p
->
var
.
bits_per_pixel
)
>>
3
);
lineincr
=
linesize
;
}
else
{
/* start at the bottom */
src1
=
p
->
screen_base
+
(
area
->
sy
+
area
->
height
-
1
)
*
linesize
+
(((
area
->
sx
+
area
->
width
-
1
)
*
p
->
var
.
bits_per_pixel
)
>>
3
);
dst1
=
p
->
screen_base
+
(
area
->
dy
+
area
->
height
-
1
)
*
linesize
+
(((
area
->
dx
+
area
->
width
-
1
)
*
p
->
var
.
bits_per_pixel
)
>>
3
);
lineincr
=
-
linesize
;
}
if
((
BITS_PER_LONG
%
p
->
var
.
bits_per_pixel
)
==
0
)
{
int
ppw
=
BITS_PER_LONG
/
p
->
var
.
bits_per_pixel
;
int
n
=
((
area
->
width
*
p
->
var
.
bits_per_pixel
)
>>
3
);
start_index
=
((
unsigned
long
)
src1
&
(
bpl
-
1
));
end_index
=
((
unsigned
long
)
(
src1
+
n
)
&
(
bpl
-
1
));
shift
=
((
unsigned
long
)
dst1
&
(
bpl
-
1
))
-
((
unsigned
long
)
src1
&
(
bpl
-
1
));
start_mask
=
end_mask
=
0
;
if
(
start_index
)
{
start_mask
=
-
1
>>
(
start_index
<<
3
);
n
-=
(
bpl
-
start_index
);
}
if
(
end_index
)
{
end_mask
=
-
1
<<
((
bpl
-
end_index
)
<<
3
);
n
-=
end_index
;
}
n
=
n
/
bpl
;
if
(
n
<=
0
)
{
if
(
start_mask
)
{
if
(
end_mask
)
end_mask
&=
start_mask
;
else
end_mask
=
start_mask
;
start_mask
=
0
;
}
n
=
0
;
}
if
(
shift
)
{
if
(
shift
>
0
)
{
/* dest is over to right more */
shift_right
=
shift
*
p
->
var
.
bits_per_pixel
;
shift_left
=
(
ppw
-
shift
)
*
p
->
var
.
bits_per_pixel
;
}
else
{
/* source is to the right more */
shift_right
=
(
ppw
+
shift
)
*
p
->
var
.
bits_per_pixel
;
shift_left
=
-
shift
*
p
->
var
.
bits_per_pixel
;
}
/* general case, positive increment */
if
(
lineincr
>
0
)
{
if
(
shift
<
0
)
n
++
;
do
{
dst
=
(
unsigned
long
*
)
dst1
;
src
=
(
unsigned
long
*
)
src1
;
last
=
(
fb_readl
(
src
)
&
start_mask
);
if
(
shift
>
0
)
fb_writel
(
fb_readl
(
dst
)
|
(
last
>>
shift_right
),
dst
);
for
(
j
=
0
;
j
<
n
;
j
++
)
{
dst
++
;
tmp
=
fb_readl
(
src
);
src
++
;
fb_writel
((
last
<<
shift_left
)
|
(
tmp
>>
shift_right
),
dst
);
last
=
tmp
;
src
++
;
}
fb_writel
(
fb_readl
(
dst
)
|
(
last
<<
shift_left
),
dst
);
src1
+=
lineincr
;
dst1
+=
lineincr
;
}
while
(
--
height
);
}
else
{
/* general case, negative increment */
if
(
shift
>
0
)
n
++
;
do
{
dst
=
(
unsigned
long
*
)
dst1
;
src
=
(
unsigned
long
*
)
src1
;
last
=
(
fb_readl
(
src
)
&
end_mask
);
if
(
shift
<
0
)
fb_writel
(
fb_readl
(
dst
)
|
(
last
>>
shift_right
),
dst
);
for
(
j
=
0
;
j
<
n
;
j
++
)
{
dst
--
;
tmp
=
fb_readl
(
src
);
src
--
;
fb_writel
((
tmp
<<
shift_left
)
|
(
last
>>
shift_right
),
dst
);
last
=
tmp
;
src
--
;
}
fb_writel
(
fb_readl
(
dst
)
|
(
last
>>
shift_right
),
dst
);
src1
+=
lineincr
;
dst1
+=
lineincr
;
}
while
(
--
height
);
}
}
else
{
/* no shift needed */
if
(
lineincr
>
0
)
{
/* positive increment */
do
{
dst
=
(
unsigned
long
*
)
(
dst1
-
start_index
);
src
=
(
unsigned
long
*
)
(
src1
-
start_index
);
if
(
start_mask
)
fb_writel
(
fb_readl
(
src
)
|
start_mask
,
dst
);
for
(
j
=
0
;
j
<
n
;
j
++
)
{
fb_writel
(
fb_readl
(
src
),
dst
);
dst
++
;
src
++
;
}
if
(
end_mask
)
fb_writel
(
fb_readl
(
src
)
|
end_mask
,
dst
);
src1
+=
lineincr
;
dst1
+=
lineincr
;
}
while
(
--
height
);
}
else
{
/* negative increment */
do
{
dst
=
(
unsigned
long
*
)
dst1
;
src
=
(
unsigned
long
*
)
src1
;
if
(
start_mask
)
fb_writel
(
fb_readl
(
src
)
|
start_mask
,
dst
);
for
(
j
=
0
;
j
<
n
;
j
++
)
{
fb_writel
(
fb_readl
(
src
),
dst
);
dst
--
;
src
--
;
}
src1
+=
lineincr
;
dst1
+=
lineincr
;
}
while
(
--
height
);
}
}
}
}
drivers/video/cfbfillrect.c
0 → 100644
View file @
0458af5e
/*
* Generic fillrect for frame buffers with packed pixels of any depth.
*
* Copyright (C) 2000 James Simmons (jsimmons@linux-fbdev.org)
*
* 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.
*
* NOTES:
*
* The code for depths like 24 that don't have integer number of pixels per
* long is broken and needs to be fixed. For now I turned these types of
* mode off.
*
* Also need to add code to deal with cards endians that are different than
* the native cpu endians. I also need to deal with MSB position in the word.
*
*/
#include <linux/string.h>
#include <linux/fb.h>
#include <asm/types.h>
#include <video/fbcon.h>
void
cfb_fillrect
(
struct
fb_info
*
p
,
struct
fb_fillrect
*
rect
)
{
unsigned
long
start_index
,
end_index
,
start_mask
=
0
,
end_mask
=
0
;
unsigned
long
height
,
ppw
,
fg
,
fgcolor
;
int
i
,
n
,
x2
,
y2
,
linesize
=
p
->
fix
.
line_length
;
int
bpl
=
sizeof
(
unsigned
long
);
unsigned
long
*
dst
;
char
*
dst1
;
if
(
!
rect
->
width
||
!
rect
->
height
)
return
;
/* We could use hardware clipping but on many cards you get around
* hardware clipping by writing to framebuffer directly. */
x2
=
rect
->
dx
+
rect
->
width
;
y2
=
rect
->
dy
+
rect
->
height
;
x2
=
x2
<
p
->
var
.
xres_virtual
?
x2
:
p
->
var
.
xres_virtual
;
y2
=
y2
<
p
->
var
.
yres_virtual
?
y2
:
p
->
var
.
yres_virtual
;
rect
->
width
=
x2
-
rect
->
dx
;
height
=
y2
-
rect
->
dy
;
/* Size of the scanline in bytes */
n
=
(
rect
->
width
*
(
p
->
var
.
bits_per_pixel
>>
3
));
ppw
=
BITS_PER_LONG
/
p
->
var
.
bits_per_pixel
;
dst1
=
p
->
screen_base
+
(
rect
->
dy
*
linesize
)
+
(
rect
->
dx
*
(
p
->
var
.
bits_per_pixel
>>
3
));
start_index
=
((
unsigned
long
)
dst1
&
(
bpl
-
1
));
end_index
=
((
unsigned
long
)
(
dst1
+
n
)
&
(
bpl
-
1
));
if
(
p
->
fix
.
visual
==
FB_VISUAL_TRUECOLOR
)
fg
=
fgcolor
=
((
u32
*
)
(
p
->
pseudo_palette
))[
rect
->
color
];
else
fg
=
fgcolor
=
rect
->
color
;
for
(
i
=
0
;
i
<
ppw
-
1
;
i
++
)
{
fg
<<=
p
->
var
.
bits_per_pixel
;
fg
|=
fgcolor
;
}
if
(
start_index
)
{
start_mask
=
fg
<<
(
start_index
<<
3
);
n
-=
(
bpl
-
start_index
);
}
if
(
end_index
)
{
end_mask
=
fg
>>
((
bpl
-
end_index
)
<<
3
);
n
-=
end_index
;
}
n
=
n
/
bpl
;
if
(
n
<=
0
)
{
if
(
start_mask
)
{
if
(
end_mask
)
end_mask
&=
start_mask
;
else
end_mask
=
start_mask
;
start_mask
=
0
;
}
n
=
0
;
}
if
((
BITS_PER_LONG
%
p
->
var
.
bits_per_pixel
)
==
0
)
{
switch
(
rect
->
rop
)
{
case
ROP_COPY
:
do
{
/* Word align to increases performace :-) */
dst
=
(
unsigned
long
*
)
(
dst1
-
start_index
);
if
(
start_mask
)
{
#if BITS_PER_LONG == 32
fb_writel
(
fb_readl
(
dst
)
|
start_mask
,
dst
);
#else
fb_writeq
(
fb_readq
(
dst
)
|
start_mask
,
dst
);
#endif
dst
++
;
}
for
(
i
=
0
;
i
<
n
;
i
++
)
{
#if BITS_PER_LONG == 32
fb_writel
(
fg
,
dst
);
#else
fb_writeq
(
fg
,
dst
);
#endif
dst
++
;
}
if
(
end_mask
)
#if BITS_PER_LONG == 32
fb_writel
(
fb_readl
(
dst
)
|
end_mask
,
dst
);
#else
fb_writeq
(
fb_readq
(
dst
)
|
end_mask
,
dst
);
#endif
dst1
+=
linesize
;
}
while
(
--
height
);
break
;
case
ROP_XOR
:
do
{
dst
=
(
unsigned
long
*
)
(
dst1
-
start_index
);
if
(
start_mask
)
{
#if BITS_PER_LONG == 32
fb_writel
(
fb_readl
(
dst
)
^
start_mask
,
dst
);
#else
fb_writeq
(
fb_readq
(
dst
)
^
start_mask
,
dst
);
#endif
dst
++
;
}
for
(
i
=
0
;
i
<
n
;
i
++
)
{
#if BITS_PER_LONG == 32
fb_writel
(
fb_readl
(
dst
)
^
fg
,
dst
);
#else
fb_writeq
(
fb_readq
(
dst
)
^
fg
,
dst
);
#endif
dst
++
;
}
if
(
end_mask
)
{
#if BITS_PER_LONG == 32
fb_writel
(
fb_readl
(
dst
)
^
end_mask
,
dst
);
#else
fb_writeq
(
fb_readq
(
dst
)
^
end_mask
,
dst
);
#endif
}
dst1
+=
linesize
;
}
while
(
--
height
);
break
;
}
}
else
{
/* Odd modes like 24 or 80 bits per pixel */
start_mask
=
fg
>>
(
start_index
*
p
->
var
.
bits_per_pixel
);
end_mask
=
fg
<<
(
end_index
*
p
->
var
.
bits_per_pixel
);
/* start_mask =& PFILL24(x1,fg);
end_mask_or = end_mask & PFILL24(x1+width-1,fg); */
n
=
(
rect
->
width
-
start_index
-
end_index
)
/
ppw
;
switch
(
rect
->
rop
)
{
case
ROP_COPY
:
do
{
dst
=
(
unsigned
long
*
)
dst1
;
if
(
start_mask
)
*
dst
|=
start_mask
;
if
((
start_index
+
rect
->
width
)
>
ppw
)
dst
++
;
/* XXX: slow */
for
(
i
=
0
;
i
<
n
;
i
++
)
{
*
dst
++
=
fg
;
}
if
(
end_mask
)
*
dst
|=
end_mask
;
dst1
+=
linesize
;
}
while
(
--
height
);
break
;
case
ROP_XOR
:
do
{
dst
=
(
unsigned
long
*
)
dst1
;
if
(
start_mask
)
*
dst
^=
start_mask
;
if
((
start_mask
+
rect
->
width
)
>
ppw
)
dst
++
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
*
dst
++
^=
fg
;
/* PFILL24(fg,x1+i); */
}
if
(
end_mask
)
*
dst
^=
end_mask
;
dst1
+=
linesize
;
}
while
(
--
height
);
break
;
}
}
return
;
}
drivers/video/vesafb.c
View file @
0458af5e
...
...
@@ -26,71 +26,28 @@
#include <asm/mtrr.h>
#include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb24.h>
#include <video/fbcon-cfb32.h>
#include <video/fbcon-mac.h>
#define dac_reg (0x3c8)
#define dac_val (0x3c9)
/* --------------------------------------------------------------------- */
/*
* card parameters
*/
/* card */
unsigned
long
video_base
;
/* physical addr */
int
video_size
;
char
*
video_vbase
;
/* mapped */
/* mode */
static
int
video_bpp
;
static
int
video_width
;
static
int
video_height
;
static
int
video_height_virtual
;
static
int
video_type
=
FB_TYPE_PACKED_PIXELS
;
static
int
video_visual
;
static
int
video_linelength
;
static
int
video_cmap_len
;
/* --------------------------------------------------------------------- */
static
struct
fb_var_screeninfo
vesafb_defined
=
{
0
,
0
,
0
,
0
,
/* W,H, W, H (virtual) load xres,xres_virtual*/
0
,
0
,
/* virtual -> visible no offset */
8
,
/* depth -> load bits_per_pixel */
0
,
/* greyscale ? */
{
0
,
0
,
0
},
/* R */
{
0
,
0
,
0
},
/* G */
{
0
,
0
,
0
},
/* B */
{
0
,
0
,
0
},
/* transparency */
0
,
/* standard pixel format */
FB_ACTIVATE_NOW
,
-
1
,
-
1
,
0
,
0L
,
0L
,
0L
,
0L
,
0L
,
0L
,
0L
,
0
,
/* No sync info */
FB_VMODE_NONINTERLACED
,
{
0
,
0
,
0
,
0
,
0
,
0
}
activate:
FB_ACTIVATE_NOW
,
height:
-
1
,
width:
-
1
,
vmode:
FB_VMODE_NONINTERLACED
,
};
static
struct
fb_fix_screeninfo
vesafb_fix
=
{
id:
"VESA VGA"
,
type:
FB_TYPE_PACKED_PIXELS
,
accel:
FB_ACCEL_NONE
,
};
static
struct
display
disp
;
static
struct
fb_info
fb_info
;
static
struct
{
u_short
blue
,
green
,
red
,
pad
;
}
palette
[
256
];
static
union
{
#ifdef FBCON_HAS_CFB16
u16
cfb16
[
16
];
#endif
#ifdef FBCON_HAS_CFB24
u32
cfb24
[
16
];
#endif
#ifdef FBCON_HAS_CFB32
u32
cfb32
[
16
];
#endif
}
fbcon_cmap
;
static
u32
pseudo_palette
[
17
];
static
int
inverse
=
0
;
static
int
mtrr
=
0
;
...
...
@@ -101,8 +58,6 @@ static unsigned short *pmi_base = 0;
static
void
(
*
pmi_start
)(
void
);
static
void
(
*
pmi_pal
)(
void
);
static
struct
display_switch
vesafb_sw
;
/* --------------------------------------------------------------------- */
static
int
vesafb_pan_display
(
struct
fb_var_screeninfo
*
var
,
int
con
,
...
...
@@ -119,7 +74,7 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var, int con,
if
((
ypan
==
1
)
&&
var
->
yoffset
+
var
->
yres
>
var
->
yres_virtual
)
return
-
EINVAL
;
offset
=
(
var
->
yoffset
*
video_line
length
+
var
->
xoffset
)
/
4
;
offset
=
(
var
->
yoffset
*
info
->
fix
.
line_
length
+
var
->
xoffset
)
/
4
;
__asm__
__volatile__
(
"call *(%%edi)"
...
...
@@ -132,172 +87,6 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var, int con,
return
0
;
}
static
int
vesafb_update_var
(
int
con
,
struct
fb_info
*
info
)
{
if
(
con
==
info
->
currcon
&&
ypan
)
{
struct
fb_var_screeninfo
*
var
=
&
fb_display
[
info
->
currcon
].
var
;
return
vesafb_pan_display
(
var
,
con
,
info
);
}
return
0
;
}
static
int
vesafb_get_fix
(
struct
fb_fix_screeninfo
*
fix
,
int
con
,
struct
fb_info
*
info
)
{
memset
(
fix
,
0
,
sizeof
(
struct
fb_fix_screeninfo
));
strcpy
(
fix
->
id
,
"VESA VGA"
);
fix
->
smem_start
=
video_base
;
fix
->
smem_len
=
video_size
;
fix
->
type
=
video_type
;
fix
->
visual
=
video_visual
;
fix
->
xpanstep
=
0
;
fix
->
ypanstep
=
ypan
?
1
:
0
;
fix
->
ywrapstep
=
(
ypan
>
1
)
?
1
:
0
;
fix
->
line_length
=
video_linelength
;
return
0
;
}
static
int
vesafb_get_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
info
)
{
if
(
con
==-
1
)
memcpy
(
var
,
&
vesafb_defined
,
sizeof
(
struct
fb_var_screeninfo
));
else
*
var
=
fb_display
[
con
].
var
;
return
0
;
}
static
void
vesafb_set_disp
(
int
con
)
{
struct
fb_fix_screeninfo
fix
;
struct
display
*
display
;
struct
display_switch
*
sw
;
if
(
con
>=
0
)
display
=
&
fb_display
[
con
];
else
display
=
&
disp
;
/* used during initialization */
vesafb_get_fix
(
&
fix
,
con
,
0
);
memset
(
display
,
0
,
sizeof
(
struct
display
));
display
->
visual
=
fix
.
visual
;
display
->
type
=
fix
.
type
;
display
->
type_aux
=
fix
.
type_aux
;
display
->
ypanstep
=
fix
.
ypanstep
;
display
->
ywrapstep
=
fix
.
ywrapstep
;
display
->
line_length
=
fix
.
line_length
;
display
->
next_line
=
fix
.
line_length
;
display
->
can_soft_blank
=
0
;
display
->
inverse
=
inverse
;
vesafb_get_var
(
&
display
->
var
,
-
1
,
&
fb_info
);
switch
(
video_bpp
)
{
#ifdef FBCON_HAS_CFB8
case
8
:
sw
=
&
fbcon_cfb8
;
break
;
#endif
#ifdef FBCON_HAS_CFB16
case
15
:
case
16
:
sw
=
&
fbcon_cfb16
;
display
->
dispsw_data
=
fbcon_cmap
.
cfb16
;
break
;
#endif
#ifdef FBCON_HAS_CFB24
case
24
:
sw
=
&
fbcon_cfb24
;
display
->
dispsw_data
=
fbcon_cmap
.
cfb24
;
break
;
#endif
#ifdef FBCON_HAS_CFB32
case
32
:
sw
=
&
fbcon_cfb32
;
display
->
dispsw_data
=
fbcon_cmap
.
cfb32
;
break
;
#endif
default:
#ifdef FBCON_HAS_MAC
sw
=
&
fbcon_mac
;
break
;
#else
sw
=
&
fbcon_dummy
;
return
;
#endif
}
memcpy
(
&
vesafb_sw
,
sw
,
sizeof
(
*
sw
));
display
->
dispsw
=
&
vesafb_sw
;
if
(
!
ypan
)
{
display
->
scrollmode
=
SCROLL_YREDRAW
;
vesafb_sw
.
bmove
=
fbcon_redraw_bmove
;
}
}
static
int
vesafb_set_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
info
)
{
static
int
first
=
1
;
if
(
var
->
xres
!=
vesafb_defined
.
xres
||
var
->
yres
!=
vesafb_defined
.
yres
||
var
->
xres_virtual
!=
vesafb_defined
.
xres_virtual
||
var
->
yres_virtual
>
video_height_virtual
||
var
->
yres_virtual
<
video_height
||
var
->
xoffset
||
var
->
bits_per_pixel
!=
vesafb_defined
.
bits_per_pixel
||
var
->
nonstd
)
{
if
(
first
)
{
printk
(
KERN_ERR
"Vesafb does not support changing the video mode
\n
"
);
first
=
0
;
}
return
-
EINVAL
;
}
if
((
var
->
activate
&
FB_ACTIVATE_MASK
)
==
FB_ACTIVATE_TEST
)
return
0
;
if
(
ypan
)
{
if
(
vesafb_defined
.
yres_virtual
!=
var
->
yres_virtual
)
{
vesafb_defined
.
yres_virtual
=
var
->
yres_virtual
;
if
(
con
!=
-
1
)
{
fb_display
[
con
].
var
=
vesafb_defined
;
info
->
changevar
(
con
);
}
}
if
(
var
->
yoffset
!=
vesafb_defined
.
yoffset
)
return
vesafb_pan_display
(
var
,
con
,
info
);
return
0
;
}
if
(
var
->
yoffset
)
return
-
EINVAL
;
return
0
;
}
static
int
vesa_getcolreg
(
unsigned
regno
,
unsigned
*
red
,
unsigned
*
green
,
unsigned
*
blue
,
unsigned
*
transp
,
struct
fb_info
*
fb_info
)
{
/*
* Read a single color register and split it into colors/transparent.
* Return != 0 for invalid regno.
*/
if
(
regno
>=
video_cmap_len
)
return
1
;
*
red
=
palette
[
regno
].
red
;
*
green
=
palette
[
regno
].
green
;
*
blue
=
palette
[
regno
].
blue
;
*
transp
=
0
;
return
0
;
}
#ifdef FBCON_HAS_CFB8
static
void
vesa_setpalette
(
int
regno
,
unsigned
red
,
unsigned
green
,
unsigned
blue
)
{
struct
{
u_char
blue
,
green
,
red
,
pad
;
}
entry
;
...
...
@@ -325,11 +114,9 @@ static void vesa_setpalette(int regno, unsigned red, unsigned green, unsigned bl
}
}
#endif
static
int
vesafb_setcolreg
(
unsigned
regno
,
unsigned
red
,
unsigned
green
,
unsigned
blue
,
unsigned
transp
,
struct
fb_info
*
fb_
info
)
struct
fb_info
*
info
)
{
/*
* Set a single color register. The values supplied are
...
...
@@ -338,85 +125,62 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
* != 0 for invalid regno.
*/
if
(
regno
>=
video_cmap_
len
)
if
(
regno
>=
info
->
cmap
.
len
)
return
1
;
palette
[
regno
].
red
=
red
;
palette
[
regno
].
green
=
green
;
palette
[
regno
].
blue
=
blue
;
switch
(
video_bpp
)
{
#ifdef FBCON_HAS_CFB8
switch
(
info
->
var
.
bits_per_pixel
)
{
case
8
:
vesa_setpalette
(
regno
,
red
,
green
,
blue
);
break
;
#endif
#ifdef FBCON_HAS_CFB16
case
15
:
case
16
:
if
(
vesafb_defined
.
red
.
offset
==
10
)
{
if
(
info
->
var
.
red
.
offset
==
10
)
{
/* 1:5:5:5 */
fbcon_cmap
.
cfb16
[
regno
]
=
((
red
&
0xf800
)
>>
1
)
|
((
green
&
0xf800
)
>>
6
)
|
((
blue
&
0xf800
)
>>
11
);
((
u32
*
)
(
info
->
pseudo_palette
))[
regno
]
=
((
red
&
0xf800
)
>>
1
)
|
((
green
&
0xf800
)
>>
6
)
|
((
blue
&
0xf800
)
>>
11
);
}
else
{
/* 0:5:6:5 */
fbcon_cmap
.
cfb16
[
regno
]
=
((
red
&
0xf800
)
)
|
((
green
&
0xfc00
)
>>
5
)
|
((
blue
&
0xf800
)
>>
11
);
((
u32
*
)
(
info
->
pseudo_palette
))[
regno
]
=
((
red
&
0xf800
)
)
|
((
green
&
0xfc00
)
>>
5
)
|
((
blue
&
0xf800
)
>>
11
);
}
break
;
#endif
#ifdef FBCON_HAS_CFB24
case
24
:
red
>>=
8
;
green
>>=
8
;
blue
>>=
8
;
fbcon_cmap
.
cfb24
[
regno
]
=
(
red
<<
vesafb_defined
.
red
.
offset
)
|
(
green
<<
vesafb_defined
.
green
.
offset
)
|
(
blue
<<
vesafb_defined
.
blue
.
offset
);
((
u32
*
)(
info
->
pseudo_palette
))
[
regno
]
=
(
red
<<
info
->
var
.
red
.
offset
)
|
(
green
<<
info
->
var
.
green
.
offset
)
|
(
blue
<<
info
->
var
.
blue
.
offset
);
break
;
#endif
#ifdef FBCON_HAS_CFB32
case
32
:
red
>>=
8
;
green
>>=
8
;
blue
>>=
8
;
fbcon_cmap
.
cfb32
[
regno
]
=
(
red
<<
vesafb_defined
.
red
.
offset
)
|
(
green
<<
vesafb_defined
.
green
.
offset
)
|
(
blue
<<
vesafb_defined
.
blue
.
offset
);
((
u32
*
)(
info
->
pseudo_palette
))
[
regno
]
=
(
red
<<
info
->
var
.
red
.
offset
)
|
(
green
<<
info
->
var
.
green
.
offset
)
|
(
blue
<<
info
->
var
.
blue
.
offset
);
break
;
#endif
}
return
0
;
}
static
int
vesafb_get_cmap
(
struct
fb_cmap
*
cmap
,
int
kspc
,
int
con
,
struct
fb_info
*
info
)
{
if
(
con
==
info
->
currcon
)
/* current console? */
return
fb_get_cmap
(
cmap
,
kspc
,
vesa_getcolreg
,
info
);
else
if
(
fb_display
[
con
].
cmap
.
len
)
/* non default colormap? */
fb_copy_cmap
(
&
fb_display
[
con
].
cmap
,
cmap
,
kspc
?
0
:
2
);
else
fb_copy_cmap
(
fb_default_cmap
(
video_cmap_len
),
cmap
,
kspc
?
0
:
2
);
return
0
;
}
static
struct
fb_ops
vesafb_ops
=
{
owner:
THIS_MODULE
,
fb_get_fix:
vesafb
_get_fix
,
fb_get_var:
vesafb
_get_var
,
fb_set_var:
vesafb
_set_var
,
fb_get_cmap:
vesafb
_get_cmap
,
fb_get_fix:
gen
_get_fix
,
fb_get_var:
gen
_get_var
,
fb_set_var:
gen
_set_var
,
fb_get_cmap:
gen
_get_cmap
,
fb_set_cmap:
gen_set_cmap
,
fb_setcolreg:
vesafb_setcolreg
,
fb_pan_display:
vesafb_pan_display
,
fb_fillrect:
cfb_fillrect
,
fb_copyarea:
cfb_copyarea
,
fb_imageblit:
cfb_imageblit
,
};
int
__init
vesafb_setup
(
char
*
options
)
...
...
@@ -451,59 +215,46 @@ int __init vesafb_setup(char *options)
return
0
;
}
static
int
vesafb_switch
(
int
con
,
struct
fb_info
*
info
)
{
/* Do we have to save the colormap? */
if
(
fb_display
[
info
->
currcon
].
cmap
.
len
)
fb_get_cmap
(
&
fb_display
[
info
->
currcon
].
cmap
,
1
,
vesa_getcolreg
,
info
);
info
->
currcon
=
con
;
/* Install new colormap */
do_install_cmap
(
con
,
info
);
vesafb_update_var
(
con
,
info
);
return
1
;
}
int
__init
vesafb_init
(
void
)
{
int
i
,
j
;
int
video_cmap_len
;
int
i
;
if
(
screen_info
.
orig_video_isVGA
!=
VIDEO_TYPE_VLFB
)
return
-
ENXIO
;
v
ideo_base
=
screen_info
.
lfb_base
;
v
ideo_bpp
=
screen_info
.
lfb_depth
;
if
(
15
==
v
ideo_bpp
)
v
ideo_bpp
=
16
;
v
ideo_width
=
screen_info
.
lfb_width
;
v
ideo_height
=
screen_info
.
lfb_height
;
v
ideo_linelength
=
screen_info
.
lfb_linelength
;
v
ideo_size
=
screen_info
.
lfb_size
*
65536
;
v
ideo_visual
=
(
video_bpp
==
8
)
?
v
esafb_fix
.
smem_start
=
screen_info
.
lfb_base
;
v
esafb_defined
.
bits_per_pixel
=
screen_info
.
lfb_depth
;
if
(
15
==
v
esafb_defined
.
bits_per_pixel
)
v
esafb_defined
.
bits_per_pixel
=
16
;
v
esafb_defined
.
xres
=
screen_info
.
lfb_width
;
v
esafb_defined
.
yres
=
screen_info
.
lfb_height
;
v
esafb_fix
.
line_length
=
screen_info
.
lfb_linelength
;
v
esafb_fix
.
smem_len
=
screen_info
.
lfb_size
*
65536
;
v
esafb_fix
.
visual
=
(
vesafb_defined
.
bits_per_pixel
==
8
)
?
FB_VISUAL_PSEUDOCOLOR
:
FB_VISUAL_TRUECOLOR
;
if
(
!
request_mem_region
(
v
ideo_base
,
video_size
,
"vesafb"
))
{
if
(
!
request_mem_region
(
v
esafb_fix
.
smem_start
,
vesafb_fix
.
smem_len
,
"vesafb"
))
{
printk
(
KERN_WARNING
"vesafb: abort, cannot reserve video memory at 0x%lx
\n
"
,
v
ideo_base
);
v
esafb_fix
.
smem_start
);
/* We cannot make this fatal. Sometimes this comes from magic
spaces our resource handlers simply don't know about */
}
video_vbase
=
ioremap
(
video_base
,
video_size
);
if
(
!
video_v
base
)
{
release_mem_region
(
v
ideo_base
,
video_size
);
fb_info
.
screen_base
=
ioremap
(
vesafb_fix
.
smem_start
,
vesafb_fix
.
smem_len
);
if
(
!
fb_info
.
screen_
base
)
{
release_mem_region
(
v
esafb_fix
.
smem_start
,
vesafb_fix
.
smem_len
);
printk
(
KERN_ERR
"vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx
\n
"
,
v
ideo_size
,
video_base
);
v
esafb_fix
.
smem_len
,
vesafb_fix
.
smem_start
);
return
-
EIO
;
}
printk
(
KERN_INFO
"vesafb: framebuffer at 0x%lx, mapped to 0x%p, size %dk
\n
"
,
v
ideo_base
,
video_vbase
,
video_size
/
1024
);
v
esafb_fix
.
smem_start
,
fb_info
.
screen_base
,
vesafb_fix
.
smem_len
/
1024
);
printk
(
KERN_INFO
"vesafb: mode is %dx%dx%d, linelength=%d, pages=%d
\n
"
,
v
ideo_width
,
video_height
,
video_bpp
,
video_line
length
,
screen_info
.
pages
);
v
esafb_defined
.
xres
,
vesafb_defined
.
yres
,
vesafb_defined
.
bits_per_pixel
,
vesafb_fix
.
line_
length
,
screen_info
.
pages
);
if
(
screen_info
.
vesapm_seg
)
{
printk
(
KERN_INFO
"vesafb: protected mode interface info at %04x:%04x
\n
"
,
...
...
@@ -536,32 +287,27 @@ int __init vesafb_init(void)
}
}
vesafb_defined
.
xres
=
video_width
;
vesafb_defined
.
yres
=
video_height
;
vesafb_defined
.
xres_virtual
=
video_width
;
vesafb_defined
.
yres_virtual
=
video_size
/
video_linelength
;
vesafb_defined
.
bits_per_pixel
=
video_bpp
;
if
(
ypan
&&
vesafb_defined
.
yres_virtual
>
video_height
)
{
vesafb_defined
.
xres_virtual
=
vesafb_defined
.
xres
;
vesafb_defined
.
yres_virtual
=
vesafb_fix
.
smem_len
/
vesafb_fix
.
line_length
;
if
(
ypan
&&
vesafb_defined
.
yres_virtual
>
vesafb_defined
.
yres
)
{
printk
(
KERN_INFO
"vesafb: scrolling: %s using protected mode interface, yres_virtual=%d
\n
"
,
(
ypan
>
1
)
?
"ywrap"
:
"ypan"
,
vesafb_defined
.
yres_virtual
);
}
else
{
printk
(
KERN_INFO
"vesafb: scrolling: redraw
\n
"
);
vesafb_defined
.
yres_virtual
=
v
ideo_height
;
vesafb_defined
.
yres_virtual
=
v
esafb_defined
.
yres
;
ypan
=
0
;
}
video_height_virtual
=
vesafb_defined
.
yres_virtual
;
/* some dummy values for timing to make fbset happy */
vesafb_defined
.
pixclock
=
10000000
/
v
ideo_width
*
1000
/
video_height
;
vesafb_defined
.
left_margin
=
(
v
ideo_width
/
8
)
&
0xf8
;
vesafb_defined
.
pixclock
=
10000000
/
v
esafb_defined
.
xres
*
1000
/
vesafb_defined
.
yres
;
vesafb_defined
.
left_margin
=
(
v
esafb_defined
.
xres
/
8
)
&
0xf8
;
vesafb_defined
.
right_margin
=
32
;
vesafb_defined
.
upper_margin
=
16
;
vesafb_defined
.
lower_margin
=
4
;
vesafb_defined
.
hsync_len
=
(
v
ideo_width
/
8
)
&
0xf8
;
vesafb_defined
.
hsync_len
=
(
v
esafb_defined
.
xres
/
8
)
&
0xf8
;
vesafb_defined
.
vsync_len
=
4
;
if
(
v
ideo_bpp
>
8
)
{
if
(
v
esafb_defined
.
bits_per_pixel
>
8
)
{
vesafb_defined
.
red
.
offset
=
screen_info
.
red_pos
;
vesafb_defined
.
red
.
length
=
screen_info
.
red_size
;
vesafb_defined
.
green
.
offset
=
screen_info
.
green_pos
;
...
...
@@ -585,48 +331,49 @@ int __init vesafb_init(void)
vesafb_defined
.
red
.
length
=
6
;
vesafb_defined
.
green
.
length
=
6
;
vesafb_defined
.
blue
.
length
=
6
;
for
(
i
=
0
;
i
<
16
;
i
++
)
{
j
=
color_table
[
i
];
palette
[
i
].
red
=
default_red
[
j
];
palette
[
i
].
green
=
default_grn
[
j
];
palette
[
i
].
blue
=
default_blu
[
j
];
}
video_cmap_len
=
256
;
}
vesafb_fix
.
ypanstep
=
ypan
?
1
:
0
;
vesafb_fix
.
ywrapstep
=
(
ypan
>
1
)
?
1
:
0
;
/* request failure does not faze us, as vgacon probably has this
* region already (FIXME) */
request_region
(
0x3c0
,
32
,
"vesafb"
);
if
(
mtrr
)
{
int
temp_size
=
v
ideo_size
;
int
temp_size
=
v
esafb_fix
.
smem_len
;
/* Find the largest power-of-two */
while
(
temp_size
&
(
temp_size
-
1
))
temp_size
&=
(
temp_size
-
1
);
/* Try and find a power of two to add */
while
(
temp_size
&&
mtrr_add
(
v
ideo_base
,
temp_size
,
MTRR_TYPE_WRCOMB
,
1
)
==-
EINVAL
)
{
while
(
temp_size
&&
mtrr_add
(
v
esafb_fix
.
smem_start
,
temp_size
,
MTRR_TYPE_WRCOMB
,
1
)
==-
EINVAL
)
{
temp_size
>>=
1
;
}
}
strcpy
(
fb_info
.
modename
,
"VESA VGA"
);
strcpy
(
fb_info
.
modename
,
vesafb_fix
.
id
);
fb_info
.
changevar
=
NULL
;
fb_info
.
node
=
NODEV
;
fb_info
.
fbops
=
&
vesafb_ops
;
fb_info
.
screen_base
=
video_vbase
;
fb_info
.
disp
=&
disp
;
fb_info
.
var
=
vesafb_defined
;
fb_info
.
fix
=
vesafb_fix
;
fb_info
.
currcon
=
-
1
;
fb_info
.
switch_con
=&
vesafb_switch
;
fb_info
.
updatevar
=&
vesafb_update_var
;
fb_info
.
flags
=
FBINFO_FLAG_DEFAULT
;
vesafb_set_disp
(
-
1
);
fb_info
.
disp
=
&
disp
;
fb_info
.
switch_con
=
gen_switch
;
fb_info
.
updatevar
=
gen_update_var
;
fb_info
.
pseudo_palette
=
pseudo_palette
;
fb_info
.
flags
=
FBINFO_FLAG_DEFAULT
;
fb_alloc_cmap
(
&
fb_info
.
cmap
,
video_cmap_len
,
0
);
gen_set_disp
(
-
1
,
&
fb_info
);
if
(
register_framebuffer
(
&
fb_info
)
<
0
)
return
-
EINVAL
;
printk
(
KERN_INFO
"fb%d: %s frame buffer device
\n
"
,
GET_FB_IDX
(
fb_info
.
node
),
fb_info
.
modename
);
GET_FB_IDX
(
fb_info
.
node
),
fb_info
.
fix
.
id
);
return
0
;
}
...
...
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