Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
66749d48
Commit
66749d48
authored
May 29, 2002
by
James Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Ported over NeoMagic over to new api.
parent
b64c5b15
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1679 additions
and
2036 deletions
+1679
-2036
drivers/video/Config.in
drivers/video/Config.in
+8
-10
drivers/video/Makefile
drivers/video/Makefile
+1
-1
drivers/video/neofb.c
drivers/video/neofb.c
+1617
-1945
include/video/neo_reg.h
include/video/neo_reg.h
+53
-80
No files found.
drivers/video/Config.in
View file @
66749d48
...
@@ -262,7 +262,7 @@ if [ "$CONFIG_FB" = "y" ]; then
...
@@ -262,7 +262,7 @@ if [ "$CONFIG_FB" = "y" ]; then
if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \
if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \
"$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
"$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
"$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_TGA" = "y" -o \
"$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_TGA" = "y" -o \
"$CONFIG_FB_
NEOMAGIC
" = "y" -o "$CONFIG_FB_PM3" = "y" -o \
"$CONFIG_FB_
TX3912
" = "y" -o "$CONFIG_FB_PM3" = "y" -o \
"$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \
"$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \
"$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
"$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
"$CONFIG_FB_CGFOURTEEN" = "y" -o "$CONFIG_FB_TRIDENT" = "y" -o \
"$CONFIG_FB_CGFOURTEEN" = "y" -o "$CONFIG_FB_TRIDENT" = "y" -o \
...
@@ -275,13 +275,13 @@ if [ "$CONFIG_FB" = "y" ]; then
...
@@ -275,13 +275,13 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
"$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
"$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_SIS" = "y" -o \
"$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_SIS" = "y" -o \
"$CONFIG_FB_PMAG_BA" = "y" -o "$CONFIG_FB_PMAGB_B" = "y" -o \
"$CONFIG_FB_PMAG_BA" = "y" -o "$CONFIG_FB_PMAGB_B" = "y" -o \
"$CONFIG_FB_MAXINE" = "y"
-o "$CONFIG_FB_TX3912" = "y"
]; then
"$CONFIG_FB_MAXINE" = "y" ]; then
define_tristate CONFIG_FBCON_CFB8 y
define_tristate CONFIG_FBCON_CFB8 y
else
else
if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
"$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
"$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
"$CONFIG_FB_OF" = "m" -o "$CONFIG_FB_TGA" = "m" -o \
"$CONFIG_FB_OF" = "m" -o "$CONFIG_FB_TGA" = "m" -o \
"$CONFIG_FB_
NEOMAGIC
" = "m" -o "$CONFIG_FB_PM3" = "m" -o \
"$CONFIG_FB_
SIS
" = "m" -o "$CONFIG_FB_PM3" = "m" -o \
"$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \
"$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \
"$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
"$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
"$CONFIG_FB_CGFOURTEEN" = "m" -o "$CONFIG_FB_TRIDENT" = "m" -o \
"$CONFIG_FB_CGFOURTEEN" = "m" -o "$CONFIG_FB_TRIDENT" = "m" -o \
...
@@ -294,12 +294,12 @@ if [ "$CONFIG_FB" = "y" ]; then
...
@@ -294,12 +294,12 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \
"$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \
"$CONFIG_FB_PMAG_BA" = "m" -o "$CONFIG_FB_PMAGB_B" = "m" -o \
"$CONFIG_FB_PMAG_BA" = "m" -o "$CONFIG_FB_PMAGB_B" = "m" -o \
"$CONFIG_FB_MAXINE" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
"$CONFIG_FB_MAXINE" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
"$CONFIG_FB_SA1100" = "m"
-o "$CONFIG_FB_SIS" = "m"
]; then
"$CONFIG_FB_SA1100" = "m" ]; then
define_tristate CONFIG_FBCON_CFB8 m
define_tristate CONFIG_FBCON_CFB8 m
fi
fi
fi
fi
if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \
if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \
"$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_
NEOMAGIC
" = "y" -o \
"$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_
PVR2
" = "y" -o \
"$CONFIG_FB_TRIDENT" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \
"$CONFIG_FB_TRIDENT" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \
"$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
"$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
"$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
"$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
...
@@ -309,12 +309,11 @@ if [ "$CONFIG_FB" = "y" ]; then
...
@@ -309,12 +309,11 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
"$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
"$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
"$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
"$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_PM3" = "y" -o \
"$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_PM3" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" ]; then
"$CONFIG_FB_PVR2" = "y" ]; then
define_tristate CONFIG_FBCON_CFB16 y
define_tristate CONFIG_FBCON_CFB16 y
else
else
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
"$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_
NEOMAGIC
" = "m" -o \
"$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_
PVR2
" = "m" -o \
"$CONFIG_FB_TRIDENT" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \
"$CONFIG_FB_TRIDENT" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \
"$CONFIG_FB_VOODOO1" = "m" -o "$CONFIG_FB_PM3" = "m" -o \
"$CONFIG_FB_VOODOO1" = "m" -o "$CONFIG_FB_PM3" = "m" -o \
"$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
"$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
...
@@ -324,8 +323,7 @@ if [ "$CONFIG_FB" = "y" ]; then
...
@@ -324,8 +323,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_SGIVW" = "m" -o \
"$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_SGIVW" = "m" -o \
"$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
"$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
"$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
"$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
"$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
"$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_RADEON" = "m" ]; then
"$CONFIG_FB_PVR2" = "m" ]; then
define_tristate CONFIG_FBCON_CFB16 m
define_tristate CONFIG_FBCON_CFB16 m
fi
fi
fi
fi
...
...
drivers/video/Makefile
View file @
66749d48
...
@@ -48,7 +48,7 @@ obj-$(CONFIG_FB_Q40) += q40fb.o cfbfillrect.o cfbcopyarea.o cfbimgb
...
@@ -48,7 +48,7 @@ obj-$(CONFIG_FB_Q40) += q40fb.o cfbfillrect.o cfbcopyarea.o cfbimgb
obj-$(CONFIG_FB_ATARI)
+=
atafb.o
obj-$(CONFIG_FB_ATARI)
+=
atafb.o
obj-$(CONFIG_FB_ATY128)
+=
aty128fb.o
obj-$(CONFIG_FB_ATY128)
+=
aty128fb.o
obj-$(CONFIG_FB_RADEON)
+=
radeonfb.o
obj-$(CONFIG_FB_RADEON)
+=
radeonfb.o
obj-$(CONFIG_FB_NEOMAGIC)
+=
neofb.o
obj-$(CONFIG_FB_NEOMAGIC)
+=
neofb.o
cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_IGA)
+=
igafb.o
obj-$(CONFIG_FB_IGA)
+=
igafb.o
obj-$(CONFIG_FB_CONTROL)
+=
controlfb.o
obj-$(CONFIG_FB_CONTROL)
+=
controlfb.o
obj-$(CONFIG_FB_PLATINUM)
+=
platinumfb.o
obj-$(CONFIG_FB_PLATINUM)
+=
platinumfb.o
...
...
drivers/video/neofb.c
View file @
66749d48
...
@@ -11,6 +11,8 @@
...
@@ -11,6 +11,8 @@
* Public License. See the file COPYING in the main directory of this
* Public License. See the file COPYING in the main directory of this
* archive for more details.
* archive for more details.
*
*
* 0.3.3
* - Porting over to new fbdev api. (jsimmons)
*
*
* 0.3.2
* 0.3.2
* - got rid of all floating point (dok)
* - got rid of all floating point (dok)
...
@@ -66,15 +68,11 @@
...
@@ -66,15 +68,11 @@
#endif
#endif
#include <video/fbcon.h>
#include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/neo_reg.h>
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb24.h>
#include <video/fbcon-cfb32.h>
#
include "neofb.h
"
#
define NEOFB_VERSION "0.3.3
"
struct
neofb_par
default_par
;
#define NEOFB_VERSION "0.3.2"
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
...
@@ -97,7 +95,8 @@ MODULE_PARM_DESC(internal, "Enable output on internal LCD Display.");
...
@@ -97,7 +95,8 @@ MODULE_PARM_DESC(internal, "Enable output on internal LCD Display.");
MODULE_PARM
(
external
,
"i"
);
MODULE_PARM
(
external
,
"i"
);
MODULE_PARM_DESC
(
external
,
"Enable output on external CRT."
);
MODULE_PARM_DESC
(
external
,
"Enable output on external CRT."
);
MODULE_PARM
(
nostretch
,
"i"
);
MODULE_PARM
(
nostretch
,
"i"
);
MODULE_PARM_DESC
(
nostretch
,
"Disable stretching of modes smaller than LCD."
);
MODULE_PARM_DESC
(
nostretch
,
"Disable stretching of modes smaller than LCD."
);
MODULE_PARM
(
nopciburst
,
"i"
);
MODULE_PARM
(
nopciburst
,
"i"
);
MODULE_PARM_DESC
(
nopciburst
,
"Disable PCI burst mode."
);
MODULE_PARM_DESC
(
nopciburst
,
"Disable PCI burst mode."
);
...
@@ -107,46 +106,45 @@ MODULE_PARM_DESC(nopciburst, "Disable PCI burst mode.");
...
@@ -107,46 +106,45 @@ MODULE_PARM_DESC(nopciburst, "Disable PCI burst mode.");
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
static
biosMode
bios8
[]
=
{
static
biosMode
bios8
[]
=
{
{
320
,
240
,
0x40
},
{
320
,
240
,
0x40
},
{
300
,
400
,
0x42
},
{
300
,
400
,
0x42
},
{
640
,
400
,
0x20
},
{
640
,
400
,
0x20
},
{
640
,
480
,
0x21
},
{
640
,
480
,
0x21
},
{
800
,
600
,
0x23
},
{
800
,
600
,
0x23
},
{
1024
,
768
,
0x25
},
{
1024
,
768
,
0x25
},
};
};
static
biosMode
bios16
[]
=
{
static
biosMode
bios16
[]
=
{
{
320
,
200
,
0x2e
},
{
320
,
200
,
0x2e
},
{
320
,
240
,
0x41
},
{
320
,
240
,
0x41
},
{
300
,
400
,
0x43
},
{
300
,
400
,
0x43
},
{
640
,
480
,
0x31
},
{
640
,
480
,
0x31
},
{
800
,
600
,
0x34
},
{
800
,
600
,
0x34
},
{
1024
,
768
,
0x37
},
{
1024
,
768
,
0x37
},
};
};
static
biosMode
bios24
[]
=
{
static
biosMode
bios24
[]
=
{
{
640
,
480
,
0x32
},
{
640
,
480
,
0x32
},
{
800
,
600
,
0x35
},
{
800
,
600
,
0x35
},
{
1024
,
768
,
0x38
}
{
1024
,
768
,
0x38
}
};
};
#ifdef NO_32BIT_SUPPORT_YET
#ifdef NO_32BIT_SUPPORT_YET
/* FIXME: guessed values, wrong */
/* FIXME: guessed values, wrong */
static
biosMode
bios32
[]
=
{
static
biosMode
bios32
[]
=
{
{
640
,
480
,
0x33
},
{
640
,
480
,
0x33
},
{
800
,
600
,
0x36
},
{
800
,
600
,
0x36
},
{
1024
,
768
,
0x39
}
{
1024
,
768
,
0x39
}
};
};
#endif
#endif
static
int
neoFindMode
(
int
xres
,
int
yres
,
int
depth
)
static
int
neoFindMode
(
int
xres
,
int
yres
,
int
depth
)
{
{
int
xres_s
;
int
xres_s
;
int
i
,
size
;
int
i
,
size
;
biosMode
*
mode
;
biosMode
*
mode
;
switch
(
depth
)
switch
(
depth
)
{
{
case
8
:
case
8
:
size
=
sizeof
(
bios8
)
/
sizeof
(
biosMode
);
size
=
sizeof
(
bios8
)
/
sizeof
(
biosMode
);
mode
=
bios8
;
mode
=
bios8
;
...
@@ -169,15 +167,12 @@ static int neoFindMode (int xres, int yres, int depth)
...
@@ -169,15 +167,12 @@ static int neoFindMode (int xres, int yres, int depth)
return
0
;
return
0
;
}
}
for
(
i
=
0
;
i
<
size
;
i
++
)
for
(
i
=
0
;
i
<
size
;
i
++
)
{
{
if
(
xres
<=
mode
[
i
].
x_res
)
{
if
(
xres
<=
mode
[
i
].
x_res
)
{
xres_s
=
mode
[
i
].
x_res
;
xres_s
=
mode
[
i
].
x_res
;
for
(;
i
<
size
;
i
++
)
for
(;
i
<
size
;
i
++
)
{
{
if
(
mode
[
i
].
x_res
!=
xres_s
)
if
(
mode
[
i
].
x_res
!=
xres_s
)
return
mode
[
i
-
1
].
mode
;
return
mode
[
i
-
1
].
mode
;
if
(
yres
<=
mode
[
i
].
y_res
)
if
(
yres
<=
mode
[
i
].
y_res
)
return
mode
[
i
].
mode
;
return
mode
[
i
].
mode
;
}
}
...
@@ -186,20 +181,284 @@ static int neoFindMode (int xres, int yres, int depth)
...
@@ -186,20 +181,284 @@ static int neoFindMode (int xres, int yres, int depth)
return
mode
[
size
-
1
].
mode
;
return
mode
[
size
-
1
].
mode
;
}
}
/*
* neoCalcVCLK --
*
* Determine the closest clock frequency to the one requested.
*/
#define REF_FREQ 0xe517
/* 14.31818 in 20.12 fixed point */
#define MAX_N 127
#define MAX_D 31
#define MAX_F 1
static
void
neoCalcVCLK
(
const
struct
fb_info
*
info
,
struct
neofb_par
*
par
,
long
freq
)
{
int
n
,
d
,
f
;
int
n_best
=
0
,
d_best
=
0
,
f_best
=
0
;
long
f_best_diff
=
(
0x7ffff
<<
12
);
/* 20.12 */
long
f_target
=
(
freq
<<
12
)
/
1000
;
/* 20.12 */
for
(
f
=
0
;
f
<=
MAX_F
;
f
++
)
for
(
n
=
0
;
n
<=
MAX_N
;
n
++
)
for
(
d
=
0
;
d
<=
MAX_D
;
d
++
)
{
long
f_out
;
/* 20.12 */
long
f_diff
;
/* 20.12 */
f_out
=
((((
n
+
1
)
<<
12
)
/
((
d
+
1
)
*
(
1
<<
f
)))
>>
12
)
*
REF_FREQ
;
f_diff
=
abs
(
f_out
-
f_target
);
if
(
f_diff
<
f_best_diff
)
{
f_best_diff
=
f_diff
;
n_best
=
n
;
d_best
=
d
;
f_best
=
f
;
}
}
if
(
info
->
fix
.
accel
==
FB_ACCEL_NEOMAGIC_NM2200
||
info
->
fix
.
accel
==
FB_ACCEL_NEOMAGIC_NM2230
||
info
->
fix
.
accel
==
FB_ACCEL_NEOMAGIC_NM2360
||
info
->
fix
.
accel
==
FB_ACCEL_NEOMAGIC_NM2380
)
{
/* NOT_DONE: We are trying the full range of the 2200 clock.
We should be able to try n up to 2047 */
par
->
VCLK3NumeratorLow
=
n_best
;
par
->
VCLK3NumeratorHigh
=
(
f_best
<<
7
);
}
else
par
->
VCLK3NumeratorLow
=
n_best
|
(
f_best
<<
7
);
par
->
VCLK3Denominator
=
d_best
;
#ifdef NEOFB_DEBUG
printk
(
"neoVCLK: f:%d NumLow=%d NumHi=%d Den=%d Df=%d
\n
"
,
f_target
>>
12
,
par
->
VCLK3NumeratorLow
,
par
->
VCLK3NumeratorHigh
,
par
->
VCLK3Denominator
,
f_best_diff
>>
12
);
#endif
}
/*
* vgaHWInit --
* Handle the initialization, etc. of a screen.
* Return FALSE on failure.
*/
static
int
vgaHWInit
(
const
struct
fb_var_screeninfo
*
var
,
const
struct
fb_info
*
info
,
struct
neofb_par
*
par
,
struct
xtimings
*
timings
)
{
par
->
MiscOutReg
=
0x23
;
if
(
!
(
timings
->
sync
&
FB_SYNC_HOR_HIGH_ACT
))
par
->
MiscOutReg
|=
0x40
;
if
(
!
(
timings
->
sync
&
FB_SYNC_VERT_HIGH_ACT
))
par
->
MiscOutReg
|=
0x80
;
/*
* Time Sequencer
*/
par
->
Sequencer
[
0
]
=
0x00
;
par
->
Sequencer
[
1
]
=
0x01
;
par
->
Sequencer
[
2
]
=
0x0F
;
par
->
Sequencer
[
3
]
=
0x00
;
/* Font select */
par
->
Sequencer
[
4
]
=
0x0E
;
/* Misc */
/*
* CRTC Controller
*/
par
->
CRTC
[
0
]
=
(
timings
->
HTotal
>>
3
)
-
5
;
par
->
CRTC
[
1
]
=
(
timings
->
HDisplay
>>
3
)
-
1
;
par
->
CRTC
[
2
]
=
(
timings
->
HDisplay
>>
3
)
-
1
;
par
->
CRTC
[
3
]
=
(((
timings
->
HTotal
>>
3
)
-
1
)
&
0x1F
)
|
0x80
;
par
->
CRTC
[
4
]
=
(
timings
->
HSyncStart
>>
3
);
par
->
CRTC
[
5
]
=
((((
timings
->
HTotal
>>
3
)
-
1
)
&
0x20
)
<<
2
)
|
(((
timings
->
HSyncEnd
>>
3
))
&
0x1F
);
par
->
CRTC
[
6
]
=
(
timings
->
VTotal
-
2
)
&
0xFF
;
par
->
CRTC
[
7
]
=
(((
timings
->
VTotal
-
2
)
&
0x100
)
>>
8
)
|
(((
timings
->
VDisplay
-
1
)
&
0x100
)
>>
7
)
|
((
timings
->
VSyncStart
&
0x100
)
>>
6
)
|
(((
timings
->
VDisplay
-
1
)
&
0x100
)
>>
5
)
|
0x10
|
(((
timings
->
VTotal
-
2
)
&
0x200
)
>>
4
)
|
(((
timings
->
VDisplay
-
1
)
&
0x200
)
>>
3
)
|
((
timings
->
VSyncStart
&
0x200
)
>>
2
);
par
->
CRTC
[
8
]
=
0x00
;
par
->
CRTC
[
9
]
=
(((
timings
->
VDisplay
-
1
)
&
0x200
)
>>
4
)
|
0x40
;
if
(
timings
->
dblscan
)
par
->
CRTC
[
9
]
|=
0x80
;
par
->
CRTC
[
10
]
=
0x00
;
par
->
CRTC
[
11
]
=
0x00
;
par
->
CRTC
[
12
]
=
0x00
;
par
->
CRTC
[
13
]
=
0x00
;
par
->
CRTC
[
14
]
=
0x00
;
par
->
CRTC
[
15
]
=
0x00
;
par
->
CRTC
[
16
]
=
timings
->
VSyncStart
&
0xFF
;
par
->
CRTC
[
17
]
=
(
timings
->
VSyncEnd
&
0x0F
)
|
0x20
;
par
->
CRTC
[
18
]
=
(
timings
->
VDisplay
-
1
)
&
0xFF
;
par
->
CRTC
[
19
]
=
var
->
xres_virtual
>>
4
;
par
->
CRTC
[
20
]
=
0x00
;
par
->
CRTC
[
21
]
=
(
timings
->
VDisplay
-
1
)
&
0xFF
;
par
->
CRTC
[
22
]
=
(
timings
->
VTotal
-
1
)
&
0xFF
;
par
->
CRTC
[
23
]
=
0xC3
;
par
->
CRTC
[
24
]
=
0xFF
;
/*
* are these unnecessary?
* vgaHWHBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
* vgaHWVBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
*/
/*
* Graphics Display Controller
*/
par
->
Graphics
[
0
]
=
0x00
;
par
->
Graphics
[
1
]
=
0x00
;
par
->
Graphics
[
2
]
=
0x00
;
par
->
Graphics
[
3
]
=
0x00
;
par
->
Graphics
[
4
]
=
0x00
;
par
->
Graphics
[
5
]
=
0x40
;
par
->
Graphics
[
6
]
=
0x05
;
/* only map 64k VGA memory !!!! */
par
->
Graphics
[
7
]
=
0x0F
;
par
->
Graphics
[
8
]
=
0xFF
;
par
->
Attribute
[
0
]
=
0x00
;
/* standard colormap translation */
par
->
Attribute
[
1
]
=
0x01
;
par
->
Attribute
[
2
]
=
0x02
;
par
->
Attribute
[
3
]
=
0x03
;
par
->
Attribute
[
4
]
=
0x04
;
par
->
Attribute
[
5
]
=
0x05
;
par
->
Attribute
[
6
]
=
0x06
;
par
->
Attribute
[
7
]
=
0x07
;
par
->
Attribute
[
8
]
=
0x08
;
par
->
Attribute
[
9
]
=
0x09
;
par
->
Attribute
[
10
]
=
0x0A
;
par
->
Attribute
[
11
]
=
0x0B
;
par
->
Attribute
[
12
]
=
0x0C
;
par
->
Attribute
[
13
]
=
0x0D
;
par
->
Attribute
[
14
]
=
0x0E
;
par
->
Attribute
[
15
]
=
0x0F
;
par
->
Attribute
[
16
]
=
0x41
;
par
->
Attribute
[
17
]
=
0xFF
;
par
->
Attribute
[
18
]
=
0x0F
;
par
->
Attribute
[
19
]
=
0x00
;
par
->
Attribute
[
20
]
=
0x00
;
return
0
;
}
static
void
vgaHWLock
(
void
)
{
/* Protect CRTC[0-7] */
VGAwCR
(
0x11
,
VGArCR
(
0x11
)
|
0x80
);
}
static
void
vgaHWUnlock
(
void
)
{
/* Unprotect CRTC[0-7] */
VGAwCR
(
0x11
,
VGArCR
(
0x11
)
&
~
0x80
);
}
static
void
neoLock
(
void
)
{
VGAwGR
(
0x09
,
0x00
);
vgaHWLock
();
}
static
void
neoUnlock
(
void
)
{
vgaHWUnlock
();
VGAwGR
(
0x09
,
0x26
);
}
/*
* vgaHWSeqReset
* perform a sequencer reset.
*/
void
vgaHWSeqReset
(
int
start
)
{
if
(
start
)
VGAwSEQ
(
0x00
,
0x01
);
/* Synchronous Reset */
else
VGAwSEQ
(
0x00
,
0x03
);
/* End Reset */
}
void
vgaHWProtect
(
int
on
)
{
unsigned
char
tmp
;
if
(
on
)
{
/*
* Turn off screen and disable sequencer.
*/
tmp
=
VGArSEQ
(
0x01
);
vgaHWSeqReset
(
1
);
/* start synchronous reset */
VGAwSEQ
(
0x01
,
tmp
|
0x20
);
/* disable the display */
VGAenablePalette
();
}
else
{
/*
* Reenable sequencer, then turn on screen.
*/
tmp
=
VGArSEQ
(
0x01
);
VGAwSEQ
(
0x01
,
tmp
&
~
0x20
);
/* reenable display */
vgaHWSeqReset
(
0
);
/* clear synchronousreset */
VGAdisablePalette
();
}
}
static
void
vgaHWRestore
(
const
struct
fb_info
*
info
,
const
struct
neofb_par
*
par
)
{
int
i
;
VGAwMISC
(
par
->
MiscOutReg
);
for
(
i
=
1
;
i
<
5
;
i
++
)
VGAwSEQ
(
i
,
par
->
Sequencer
[
i
]);
/* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */
VGAwCR
(
17
,
par
->
CRTC
[
17
]
&
~
0x80
);
for
(
i
=
0
;
i
<
25
;
i
++
)
VGAwCR
(
i
,
par
->
CRTC
[
i
]);
for
(
i
=
0
;
i
<
9
;
i
++
)
VGAwGR
(
i
,
par
->
Graphics
[
i
]);
VGAenablePalette
();
for
(
i
=
0
;
i
<
21
;
i
++
)
VGAwATTR
(
i
,
par
->
Attribute
[
i
]);
VGAdisablePalette
();
}
/* -------------------- Hardware specific routines ------------------------- */
/* -------------------- Hardware specific routines ------------------------- */
/*
/*
* Hardware Acceleration for Neo2200+
* Hardware Acceleration for Neo2200+
*/
*/
static
inline
void
neo2200_wait_idle
(
struct
neofb_info
*
fb
)
static
inline
void
neo2200_wait_idle
(
struct
neofb_par
*
par
)
{
{
int
waitcycles
;
int
waitcycles
;
while
(
fb
->
neo2200
->
bltStat
&
1
)
while
(
par
->
neo2200
->
bltStat
&
1
)
waitcycles
++
;
waitcycles
++
;
}
}
static
inline
void
neo2200_wait_fifo
(
struct
neofb_info
*
fb
,
static
inline
void
neo2200_wait_fifo
(
struct
neofb_par
*
par
,
int
requested_fifo_space
)
int
requested_fifo_space
)
{
{
// ndev->neo.waitfifo_calls++;
// ndev->neo.waitfifo_calls++;
...
@@ -225,19 +484,19 @@ static inline void neo2200_wait_fifo (struct neofb_info *fb,
...
@@ -225,19 +484,19 @@ static inline void neo2200_wait_fifo (struct neofb_info *fb,
neo_fifo_space -= requested_fifo_space;
neo_fifo_space -= requested_fifo_space;
*/
*/
neo2200_wait_idle
(
fb
);
neo2200_wait_idle
(
par
);
}
}
static
inline
void
neo2200_accel_init
(
struct
neofb_info
*
fb
,
static
inline
void
neo2200_accel_init
(
struct
fb_info
*
fb
,
struct
fb_var_screeninfo
*
var
)
struct
fb_var_screeninfo
*
var
)
{
{
Neo2200
*
neo2200
=
fb
->
neo2200
;
struct
neofb_par
*
par
=
(
struct
neofb_par
*
)
fb
->
par
;
Neo2200
*
neo2200
=
par
->
neo2200
;
u32
bltMod
,
pitch
;
u32
bltMod
,
pitch
;
neo2200_wait_idle
(
fb
);
neo2200_wait_idle
(
par
);
switch
(
var
->
bits_per_pixel
)
switch
(
var
->
bits_per_pixel
)
{
{
case
8
:
case
8
:
bltMod
=
NEO_MODE1_DEPTH8
;
bltMod
=
NEO_MODE1_DEPTH8
;
pitch
=
var
->
xres_virtual
;
pitch
=
var
->
xres_virtual
;
...
@@ -248,7 +507,8 @@ static inline void neo2200_accel_init (struct neofb_info *fb,
...
@@ -248,7 +507,8 @@ static inline void neo2200_accel_init (struct neofb_info *fb,
pitch
=
var
->
xres_virtual
*
2
;
pitch
=
var
->
xres_virtual
*
2
;
break
;
break
;
default:
default:
printk
(
KERN_ERR
"neofb: neo2200_accel_init: unexpected bits per pixel!
\n
"
);
printk
(
KERN_ERR
"neofb: neo2200_accel_init: unexpected bits per pixel!
\n
"
);
return
;
return
;
}
}
...
@@ -256,36 +516,26 @@ static inline void neo2200_accel_init (struct neofb_info *fb,
...
@@ -256,36 +516,26 @@ static inline void neo2200_accel_init (struct neofb_info *fb,
neo2200
->
pitch
=
(
pitch
<<
16
)
|
pitch
;
neo2200
->
pitch
=
(
pitch
<<
16
)
|
pitch
;
}
}
static
void
neo2200_accel_setup
(
struct
display
*
p
)
{
struct
neofb_info
*
fb
=
(
struct
neofb_info
*
)
p
->
fb_info
;
struct
fb_var_screeninfo
*
var
=
&
p
->
fb_info
->
var
;
fb
->
dispsw
->
setup
(
p
);
neo2200_accel_init
(
fb
,
var
);
}
static
void
static
void
neo2200_accel_bmove
(
struct
display
*
p
,
int
sy
,
int
sx
,
int
dy
,
int
dx
,
neo2200_accel_bmove
(
struct
display
*
p
,
int
sy
,
int
sx
,
int
dy
,
int
dx
,
int
height
,
int
width
)
int
height
,
int
width
)
{
{
struct
neofb_info
*
fb
=
(
struct
neofb_info
*
)
p
->
fb_info
;
struct
fb_info
*
fb
=
(
struct
fb_info
*
)
p
->
fb_info
;
struct
fb_var_screeninfo
*
var
=
&
p
->
fb_info
->
var
;
struct
fb_var_screeninfo
*
var
=
&
p
->
fb_info
->
var
;
Neo2200
*
neo2200
=
fb
->
neo2200
;
struct
neofb_par
*
par
=
(
struct
neofb_par
*
)
fb
->
par
;
Neo2200
*
neo2200
=
par
->
neo2200
;
u_long
src
,
dst
;
u_long
src
,
dst
;
int
bpp
,
pitch
,
inc_y
;
int
bpp
,
pitch
,
inc_y
;
u_int
fh
,
fw
;
u_int
fh
,
fw
;
/* setting blitting direction does not work, so this case is unaccelerated */
/* setting blitting direction does not work, so this case is unaccelerated */
if
(
sx
!=
dx
)
if
(
sx
!=
dx
)
{
{
neo2200_wait_idle
(
par
);
neo2200_wait_idle
(
fb
);
p
->
dispsw
->
bmove
(
p
,
sy
,
sx
,
dy
,
dx
,
height
,
width
);
fb
->
dispsw
->
bmove
(
p
,
sy
,
sx
,
dy
,
dx
,
height
,
width
);
return
;
return
;
}
}
bpp
=
(
var
->
bits_per_pixel
+
7
)
/
8
;
bpp
=
(
var
->
bits_per_pixel
+
7
)
/
8
;
pitch
=
var
->
xres_virtual
*
bpp
;
pitch
=
var
->
xres_virtual
*
bpp
;
fw
=
fontwidth
(
p
);
fw
=
fontwidth
(
p
);
...
@@ -299,727 +549,97 @@ neo2200_accel_bmove (struct display *p, int sy, int sx, int dy, int dx,
...
@@ -299,727 +549,97 @@ neo2200_accel_bmove (struct display *p, int sy, int sx, int dy, int dx,
if
(
sy
>
dy
)
if
(
sy
>
dy
)
inc_y
=
fh
;
inc_y
=
fh
;
else
else
{
{
inc_y
=
-
fh
;
inc_y
=
-
fh
;
sy
+=
(
height
-
1
)
*
fh
;
sy
+=
(
height
-
1
)
*
fh
;
dy
+=
(
height
-
1
)
*
fh
;
dy
+=
(
height
-
1
)
*
fh
;
}
}
neo2200_wait_fifo
(
fb
,
1
);
neo2200_wait_fifo
(
par
,
1
);
/* set blt control */
/* set blt control */
neo2200
->
bltCntl
=
NEO_BC3_FIFO_EN
|
neo2200
->
bltCntl
=
NEO_BC3_FIFO_EN
|
NEO_BC3_SKIP_MAPPING
|
0x0c0000
;
NEO_BC3_SKIP_MAPPING
|
0x0c0000
;
/* looks silly, but setting the blitting direction did not work */
while
(
height
--
)
{
src
=
sx
+
sy
*
pitch
;
dst
=
dx
+
dy
*
pitch
;
neo2200_wait_fifo
(
fb
,
3
);
neo2200
->
srcStart
=
src
;
neo2200
->
dstStart
=
dst
;
neo2200
->
xyExt
=
(
fh
<<
16
)
|
(
width
&
0xffff
);
sy
+=
inc_y
;
dy
+=
inc_y
;
}
}
static
void
neo2200_accel_clear
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
sy
,
int
sx
,
int
height
,
int
width
)
{
struct
neofb_info
*
fb
=
(
struct
neofb_info
*
)
p
->
fb_info
;
struct
fb_var_screeninfo
*
var
=
&
p
->
fb_info
->
var
;
Neo2200
*
neo2200
=
fb
->
neo2200
;
u_long
dst
;
u_int
fw
,
fh
;
u32
bgx
=
attr_bgcol_ec
(
p
,
conp
);
fw
=
fontwidth
(
p
);
fh
=
fontheight
(
p
);
dst
=
sx
*
fw
+
sy
*
var
->
xres_virtual
*
fh
;
width
=
width
*
fw
;
height
=
height
*
fh
;
neo2200_wait_fifo
(
fb
,
4
);
/* set blt control */
neo2200
->
bltCntl
=
NEO_BC3_FIFO_EN
|
NEO_BC0_SRC_IS_FG
|
NEO_BC3_SKIP_MAPPING
|
0x0c0000
;
switch
(
var
->
bits_per_pixel
)
{
case
8
:
neo2200
->
fgColor
=
bgx
;
break
;
case
16
:
neo2200
->
fgColor
=
((
u16
*
)(
p
->
fb_info
)
->
pseudo_palette
)[
bgx
];
break
;
}
neo2200
->
dstStart
=
dst
*
((
var
->
bits_per_pixel
+
7
)
/
8
);
neo2200
->
xyExt
=
(
height
<<
16
)
|
(
width
&
0xffff
);
}
static
void
neo2200_accel_putc
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
c
,
int
yy
,
int
xx
)
{
struct
neofb_info
*
fb
=
(
struct
neofb_info
*
)
p
->
fb_info
;
neo2200_wait_idle
(
fb
);
fb
->
dispsw
->
putc
(
conp
,
p
,
c
,
yy
,
xx
);
}
static
void
neo2200_accel_putcs
(
struct
vc_data
*
conp
,
struct
display
*
p
,
const
unsigned
short
*
s
,
int
count
,
int
yy
,
int
xx
)
{
struct
neofb_info
*
fb
=
(
struct
neofb_info
*
)
p
->
fb_info
;
neo2200_wait_idle
(
fb
);
fb
->
dispsw
->
putcs
(
conp
,
p
,
s
,
count
,
yy
,
xx
);
}
static
void
neo2200_accel_revc
(
struct
display
*
p
,
int
xx
,
int
yy
)
{
struct
neofb_info
*
fb
=
(
struct
neofb_info
*
)
p
->
fb_info
;
neo2200_wait_idle
(
fb
);
fb
->
dispsw
->
revc
(
p
,
xx
,
yy
);
}
static
void
neo2200_accel_clear_margins
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
bottom_only
)
{
struct
neofb_info
*
fb
=
(
struct
neofb_info
*
)
p
->
fb_info
;
fb
->
dispsw
->
clear_margins
(
conp
,
p
,
bottom_only
);
}
static
struct
display_switch
fbcon_neo2200_accel
=
{
setup:
neo2200_accel_setup
,
bmove:
neo2200_accel_bmove
,
clear:
neo2200_accel_clear
,
putc:
neo2200_accel_putc
,
putcs:
neo2200_accel_putcs
,
revc:
neo2200_accel_revc
,
clear_margins:
neo2200_accel_clear_margins
,
fontwidthmask:
FONTWIDTH
(
8
)
|
FONTWIDTH
(
16
)
};
/* --------------------------------------------------------------------- */
/*
* Set a single color register. Return != 0 for invalid regno.
*/
static
int
neofb_setcolreg
(
u_int
regno
,
u_int
red
,
u_int
green
,
u_int
blue
,
u_int
transp
,
struct
fb_info
*
fb
)
{
struct
neofb_info
*
info
=
(
struct
neofb_info
*
)
fb
;
if
(
regno
>=
NR_PALETTE
)
return
-
EINVAL
;
info
->
palette
[
regno
].
red
=
red
;
info
->
palette
[
regno
].
green
=
green
;
info
->
palette
[
regno
].
blue
=
blue
;
info
->
palette
[
regno
].
transp
=
transp
;
switch
(
fb
->
var
.
bits_per_pixel
)
{
#ifdef FBCON_HAS_CFB8
case
8
:
outb
(
regno
,
0x3c8
);
outb
(
red
>>
10
,
0x3c9
);
outb
(
green
>>
10
,
0x3c9
);
outb
(
blue
>>
10
,
0x3c9
);
break
;
#endif
#ifdef FBCON_HAS_CFB16
case
16
:
if
(
regno
<
16
)
((
u16
*
)
fb
->
pseudo_palette
)[
regno
]
=
((
red
&
0xf800
)
)
|
((
green
&
0xfc00
)
>>
5
)
|
((
blue
&
0xf800
)
>>
11
);
break
;
#endif
#ifdef FBCON_HAS_CFB24
case
24
:
if
(
regno
<
16
)
((
u32
*
)
fb
->
pseudo_palette
)[
regno
]
=
((
red
&
0xff00
)
<<
8
)
|
((
green
&
0xff00
)
)
|
((
blue
&
0xff00
)
>>
8
);
break
;
#endif
#ifdef NO_32BIT_SUPPORT_YET
#ifdef FBCON_HAS_CFB32
case
32
:
if
(
regno
<
16
)
((
u32
*
)
fb
->
pseudo_palette
)[
regno
]
=
((
transp
&
0xff00
)
<<
16
)
|
((
red
&
0xff00
)
<<
8
)
|
((
green
&
0xff00
)
)
|
((
blue
&
0xff00
)
>>
8
);
break
;
#endif
#endif
default:
return
1
;
}
return
0
;
}
static
void
vgaHWLock
(
void
)
{
/* Protect CRTC[0-7] */
VGAwCR
(
0x11
,
VGArCR
(
0x11
)
|
0x80
);
}
static
void
vgaHWUnlock
(
void
)
{
/* Unprotect CRTC[0-7] */
VGAwCR
(
0x11
,
VGArCR
(
0x11
)
&
~
0x80
);
}
static
void
neoLock
(
void
)
{
VGAwGR
(
0x09
,
0x00
);
vgaHWLock
();
}
static
void
neoUnlock
(
void
)
{
vgaHWUnlock
();
VGAwGR
(
0x09
,
0x26
);
}
/*
* vgaHWSeqReset
* perform a sequencer reset.
*/
void
vgaHWSeqReset
(
int
start
)
{
if
(
start
)
VGAwSEQ
(
0x00
,
0x01
);
/* Synchronous Reset */
else
VGAwSEQ
(
0x00
,
0x03
);
/* End Reset */
}
void
vgaHWProtect
(
int
on
)
{
unsigned
char
tmp
;
if
(
on
)
{
/*
* Turn off screen and disable sequencer.
*/
tmp
=
VGArSEQ
(
0x01
);
vgaHWSeqReset
(
1
);
/* start synchronous reset */
VGAwSEQ
(
0x01
,
tmp
|
0x20
);
/* disable the display */
VGAenablePalette
();
}
else
{
/*
* Reenable sequencer, then turn on screen.
*/
tmp
=
VGArSEQ
(
0x01
);
VGAwSEQ
(
0x01
,
tmp
&
~
0x20
);
/* reenable display */
vgaHWSeqReset
(
0
);
/* clear synchronousreset */
VGAdisablePalette
();
}
}
static
void
vgaHWRestore
(
const
struct
neofb_info
*
info
,
const
struct
neofb_par
*
par
)
{
int
i
;
VGAwMISC
(
par
->
MiscOutReg
);
for
(
i
=
1
;
i
<
5
;
i
++
)
VGAwSEQ
(
i
,
par
->
Sequencer
[
i
]);
/* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */
VGAwCR
(
17
,
par
->
CRTC
[
17
]
&
~
0x80
);
for
(
i
=
0
;
i
<
25
;
i
++
)
VGAwCR
(
i
,
par
->
CRTC
[
i
]);
for
(
i
=
0
;
i
<
9
;
i
++
)
VGAwGR
(
i
,
par
->
Graphics
[
i
]);
VGAenablePalette
();
for
(
i
=
0
;
i
<
21
;
i
++
)
VGAwATTR
(
i
,
par
->
Attribute
[
i
]);
VGAdisablePalette
();
}
static
void
neofb_set_par
(
struct
neofb_info
*
info
,
const
struct
neofb_par
*
par
)
{
unsigned
char
temp
;
int
i
;
int
clock_hi
=
0
;
DBG
(
"neofb_set_par"
);
neoUnlock
();
vgaHWProtect
(
1
);
/* Blank the screen */
/* linear colormap for non palettized modes */
switch
(
par
->
depth
)
{
case
8
:
break
;
case
16
:
for
(
i
=
0
;
i
<
64
;
i
++
)
{
outb
(
i
,
0x3c8
);
outb
(
i
<<
1
,
0x3c9
);
outb
(
i
,
0x3c9
);
outb
(
i
<<
1
,
0x3c9
);
}
break
;
case
24
:
#ifdef NO_32BIT_SUPPORT_YET
case
32
:
#endif
for
(
i
=
0
;
i
<
256
;
i
++
)
{
outb
(
i
,
0x3c8
);
outb
(
i
,
0x3c9
);
outb
(
i
,
0x3c9
);
outb
(
i
,
0x3c9
);
}
break
;
}
/* alread unlocked above */
/* BOGUS VGAwGR (0x09, 0x26);*/
/* don't know what this is, but it's 0 from bootup anyway */
VGAwGR
(
0x15
,
0x00
);
/* was set to 0x01 by my bios in text and vesa modes */
VGAwGR
(
0x0A
,
par
->
GeneralLockReg
);
/*
* The color mode needs to be set before calling vgaHWRestore
* to ensure the DAC is initialized properly.
*
* NOTE: Make sure we don't change bits make sure we don't change
* any reserved bits.
*/
temp
=
VGArGR
(
0x90
);
switch
(
info
->
accel
)
{
case
FB_ACCEL_NEOMAGIC_NM2070
:
temp
&=
0xF0
;
/* Save bits 7:4 */
temp
|=
(
par
->
ExtColorModeSelect
&
~
0xF0
);
break
;
case
FB_ACCEL_NEOMAGIC_NM2090
:
case
FB_ACCEL_NEOMAGIC_NM2093
:
case
FB_ACCEL_NEOMAGIC_NM2097
:
case
FB_ACCEL_NEOMAGIC_NM2160
:
case
FB_ACCEL_NEOMAGIC_NM2200
:
case
FB_ACCEL_NEOMAGIC_NM2230
:
case
FB_ACCEL_NEOMAGIC_NM2360
:
case
FB_ACCEL_NEOMAGIC_NM2380
:
temp
&=
0x70
;
/* Save bits 6:4 */
temp
|=
(
par
->
ExtColorModeSelect
&
~
0x70
);
break
;
}
VGAwGR
(
0x90
,
temp
);
/*
* In some rare cases a lockup might occur if we don't delay
* here. (Reported by Miles Lane)
*/
//mdelay(200);
/*
* Disable horizontal and vertical graphics and text expansions so
* that vgaHWRestore works properly.
*/
temp
=
VGArGR
(
0x25
);
temp
&=
0x39
;
VGAwGR
(
0x25
,
temp
);
/*
* Sleep for 200ms to make sure that the two operations above have
* had time to take effect.
*/
mdelay
(
200
);
/*
* This function handles restoring the generic VGA registers. */
vgaHWRestore
(
info
,
par
);
VGAwGR
(
0x0E
,
par
->
ExtCRTDispAddr
);
VGAwGR
(
0x0F
,
par
->
ExtCRTOffset
);
temp
=
VGArGR
(
0x10
);
temp
&=
0x0F
;
/* Save bits 3:0 */
temp
|=
(
par
->
SysIfaceCntl1
&
~
0x0F
);
/* VESA Bios sets bit 1! */
VGAwGR
(
0x10
,
temp
);
VGAwGR
(
0x11
,
par
->
SysIfaceCntl2
);
VGAwGR
(
0x15
,
0
/*par->SingleAddrPage*/
);
VGAwGR
(
0x16
,
0
/*par->DualAddrPage*/
);
temp
=
VGArGR
(
0x20
);
switch
(
info
->
accel
)
{
case
FB_ACCEL_NEOMAGIC_NM2070
:
temp
&=
0xFC
;
/* Save bits 7:2 */
temp
|=
(
par
->
PanelDispCntlReg1
&
~
0xFC
);
break
;
case
FB_ACCEL_NEOMAGIC_NM2090
:
case
FB_ACCEL_NEOMAGIC_NM2093
:
case
FB_ACCEL_NEOMAGIC_NM2097
:
case
FB_ACCEL_NEOMAGIC_NM2160
:
temp
&=
0xDC
;
/* Save bits 7:6,4:2 */
temp
|=
(
par
->
PanelDispCntlReg1
&
~
0xDC
);
break
;
case
FB_ACCEL_NEOMAGIC_NM2200
:
case
FB_ACCEL_NEOMAGIC_NM2230
:
case
FB_ACCEL_NEOMAGIC_NM2360
:
case
FB_ACCEL_NEOMAGIC_NM2380
:
temp
&=
0x98
;
/* Save bits 7,4:3 */
temp
|=
(
par
->
PanelDispCntlReg1
&
~
0x98
);
break
;
}
VGAwGR
(
0x20
,
temp
);
temp
=
VGArGR
(
0x25
);
temp
&=
0x38
;
/* Save bits 5:3 */
temp
|=
(
par
->
PanelDispCntlReg2
&
~
0x38
);
VGAwGR
(
0x25
,
temp
);
if
(
info
->
accel
!=
FB_ACCEL_NEOMAGIC_NM2070
)
{
temp
=
VGArGR
(
0x30
);
temp
&=
0xEF
;
/* Save bits 7:5 and bits 3:0 */
temp
|=
(
par
->
PanelDispCntlReg3
&
~
0xEF
);
VGAwGR
(
0x30
,
temp
);
}
VGAwGR
(
0x28
,
par
->
PanelVertCenterReg1
);
VGAwGR
(
0x29
,
par
->
PanelVertCenterReg2
);
VGAwGR
(
0x2a
,
par
->
PanelVertCenterReg3
);
if
(
info
->
accel
!=
FB_ACCEL_NEOMAGIC_NM2070
)
{
VGAwGR
(
0x32
,
par
->
PanelVertCenterReg4
);
VGAwGR
(
0x33
,
par
->
PanelHorizCenterReg1
);
VGAwGR
(
0x34
,
par
->
PanelHorizCenterReg2
);
VGAwGR
(
0x35
,
par
->
PanelHorizCenterReg3
);
}
if
(
info
->
accel
==
FB_ACCEL_NEOMAGIC_NM2160
)
VGAwGR
(
0x36
,
par
->
PanelHorizCenterReg4
);
if
(
info
->
accel
==
FB_ACCEL_NEOMAGIC_NM2200
||
info
->
accel
==
FB_ACCEL_NEOMAGIC_NM2230
||
info
->
accel
==
FB_ACCEL_NEOMAGIC_NM2360
||
info
->
accel
==
FB_ACCEL_NEOMAGIC_NM2380
)
{
VGAwGR
(
0x36
,
par
->
PanelHorizCenterReg4
);
VGAwGR
(
0x37
,
par
->
PanelVertCenterReg5
);
VGAwGR
(
0x38
,
par
->
PanelHorizCenterReg5
);
clock_hi
=
1
;
}
/* Program VCLK3 if needed. */
if
(
par
->
ProgramVCLK
&&
((
VGArGR
(
0x9B
)
!=
par
->
VCLK3NumeratorLow
)
||
(
VGArGR
(
0x9F
)
!=
par
->
VCLK3Denominator
)
||
(
clock_hi
&&
((
VGArGR
(
0x8F
)
&
~
0x0f
)
!=
(
par
->
VCLK3NumeratorHigh
&
~
0x0F
)))))
{
VGAwGR
(
0x9B
,
par
->
VCLK3NumeratorLow
);
if
(
clock_hi
)
{
temp
=
VGArGR
(
0x8F
);
temp
&=
0x0F
;
/* Save bits 3:0 */
temp
|=
(
par
->
VCLK3NumeratorHigh
&
~
0x0F
);
VGAwGR
(
0x8F
,
temp
);
}
VGAwGR
(
0x9F
,
par
->
VCLK3Denominator
);
}
if
(
par
->
biosMode
)
VGAwCR
(
0x23
,
par
->
biosMode
);
VGAwGR
(
0x93
,
0xc0
);
/* Gives 5x faster framebuffer writes !!! */
/* Program vertical extension register */
if
(
info
->
accel
==
FB_ACCEL_NEOMAGIC_NM2200
||
info
->
accel
==
FB_ACCEL_NEOMAGIC_NM2230
||
info
->
accel
==
FB_ACCEL_NEOMAGIC_NM2360
||
info
->
accel
==
FB_ACCEL_NEOMAGIC_NM2380
)
{
VGAwCR
(
0x70
,
par
->
VerticalExt
);
}
vgaHWProtect
(
0
);
/* Turn on screen */
/* Calling this also locks offset registers required in update_start */
neoLock
();
}
static
void
neofb_update_start
(
struct
neofb_info
*
info
,
struct
fb_var_screeninfo
*
var
)
{
int
oldExtCRTDispAddr
;
int
Base
;
DBG
(
"neofb_update_start"
);
Base
=
(
var
->
yoffset
*
var
->
xres_virtual
+
var
->
xoffset
)
>>
2
;
Base
*=
(
var
->
bits_per_pixel
+
7
)
/
8
;
neoUnlock
();
/*
* These are the generic starting address registers.
*/
VGAwCR
(
0x0C
,
(
Base
&
0x00FF00
)
>>
8
);
VGAwCR
(
0x0D
,
(
Base
&
0x00FF
));
/*
* Make sure we don't clobber some other bits that might already
* have been set. NOTE: NM2200 has a writable bit 3, but it shouldn't
* be needed.
*/
oldExtCRTDispAddr
=
VGArGR
(
0x0E
);
VGAwGR
(
0x0E
,(((
Base
>>
16
)
&
0x0f
)
|
(
oldExtCRTDispAddr
&
0xf0
)));
neoLock
();
}
/*
* neoCalcVCLK --
*
* Determine the closest clock frequency to the one requested.
*/
#define REF_FREQ 0xe517
/* 14.31818 in 20.12 fixed point */
#define MAX_N 127
#define MAX_D 31
#define MAX_F 1
static
void
neoCalcVCLK
(
const
struct
neofb_info
*
info
,
struct
neofb_par
*
par
,
long
freq
)
{
int
n
,
d
,
f
;
int
n_best
=
0
,
d_best
=
0
,
f_best
=
0
;
long
f_best_diff
=
(
0x7ffff
<<
12
);
/* 20.12 */
long
f_target
=
(
freq
<<
12
)
/
1000
;
/* 20.12 */
for
(
f
=
0
;
f
<=
MAX_F
;
f
++
)
for
(
n
=
0
;
n
<=
MAX_N
;
n
++
)
for
(
d
=
0
;
d
<=
MAX_D
;
d
++
)
{
long
f_out
;
/* 20.12 */
long
f_diff
;
/* 20.12 */
f_out
=
((((
n
+
1
)
<<
12
)
/
((
d
+
1
)
*
(
1
<<
f
)))
>>
12
)
*
REF_FREQ
;
f_diff
=
abs
(
f_out
-
f_target
);
if
(
f_diff
<
f_best_diff
)
{
f_best_diff
=
f_diff
;
n_best
=
n
;
d_best
=
d
;
f_best
=
f
;
}
}
if
(
info
->
accel
==
FB_ACCEL_NEOMAGIC_NM2200
||
info
->
accel
==
FB_ACCEL_NEOMAGIC_NM2230
||
info
->
accel
==
FB_ACCEL_NEOMAGIC_NM2360
||
info
->
accel
==
FB_ACCEL_NEOMAGIC_NM2380
)
{
/* NOT_DONE: We are trying the full range of the 2200 clock.
We should be able to try n up to 2047 */
par
->
VCLK3NumeratorLow
=
n_best
;
par
->
VCLK3NumeratorHigh
=
(
f_best
<<
7
);
}
else
par
->
VCLK3NumeratorLow
=
n_best
|
(
f_best
<<
7
);
par
->
VCLK3Denominator
=
d_best
;
#ifdef NEOFB_DEBUG
printk
(
"neoVCLK: f:%d NumLow=%d NumHi=%d Den=%d Df=%d
\n
"
,
f_target
>>
12
,
par
->
VCLK3NumeratorLow
,
par
->
VCLK3NumeratorHigh
,
par
->
VCLK3Denominator
,
f_best_diff
>>
12
);
#endif
}
/*
* vgaHWInit --
* Handle the initialization, etc. of a screen.
* Return FALSE on failure.
*/
static
int
vgaHWInit
(
const
struct
fb_var_screeninfo
*
var
,
const
struct
neofb_info
*
info
,
struct
neofb_par
*
par
,
struct
xtimings
*
timings
)
{
par
->
MiscOutReg
=
0x23
;
if
(
!
(
timings
->
sync
&
FB_SYNC_HOR_HIGH_ACT
))
par
->
MiscOutReg
|=
0x40
;
if
(
!
(
timings
->
sync
&
FB_SYNC_VERT_HIGH_ACT
))
par
->
MiscOutReg
|=
0x80
;
/*
* Time Sequencer
*/
par
->
Sequencer
[
0
]
=
0x00
;
par
->
Sequencer
[
1
]
=
0x01
;
par
->
Sequencer
[
2
]
=
0x0F
;
par
->
Sequencer
[
3
]
=
0x00
;
/* Font select */
par
->
Sequencer
[
4
]
=
0x0E
;
/* Misc */
/*
* CRTC Controller
*/
par
->
CRTC
[
0
]
=
(
timings
->
HTotal
>>
3
)
-
5
;
par
->
CRTC
[
1
]
=
(
timings
->
HDisplay
>>
3
)
-
1
;
par
->
CRTC
[
2
]
=
(
timings
->
HDisplay
>>
3
)
-
1
;
par
->
CRTC
[
3
]
=
(((
timings
->
HTotal
>>
3
)
-
1
)
&
0x1F
)
|
0x80
;
par
->
CRTC
[
4
]
=
(
timings
->
HSyncStart
>>
3
);
par
->
CRTC
[
5
]
=
((((
timings
->
HTotal
>>
3
)
-
1
)
&
0x20
)
<<
2
)
|
(((
timings
->
HSyncEnd
>>
3
))
&
0x1F
);
par
->
CRTC
[
6
]
=
(
timings
->
VTotal
-
2
)
&
0xFF
;
par
->
CRTC
[
7
]
=
(((
timings
->
VTotal
-
2
)
&
0x100
)
>>
8
)
|
(((
timings
->
VDisplay
-
1
)
&
0x100
)
>>
7
)
|
((
timings
->
VSyncStart
&
0x100
)
>>
6
)
|
(((
timings
->
VDisplay
-
1
)
&
0x100
)
>>
5
)
|
0x10
|
(((
timings
->
VTotal
-
2
)
&
0x200
)
>>
4
)
|
(((
timings
->
VDisplay
-
1
)
&
0x200
)
>>
3
)
|
((
timings
->
VSyncStart
&
0x200
)
>>
2
);
par
->
CRTC
[
8
]
=
0x00
;
par
->
CRTC
[
9
]
=
(((
timings
->
VDisplay
-
1
)
&
0x200
)
>>
4
)
|
0x40
;
if
(
timings
->
dblscan
)
/* looks silly, but setting the blitting direction did not work */
par
->
CRTC
[
9
]
|=
0x80
;
while
(
height
--
)
{
src
=
sx
+
sy
*
pitch
;
dst
=
dx
+
dy
*
pitch
;
par
->
CRTC
[
10
]
=
0x00
;
neo2200_wait_fifo
(
par
,
3
);
par
->
CRTC
[
11
]
=
0x00
;
par
->
CRTC
[
12
]
=
0x00
;
par
->
CRTC
[
13
]
=
0x00
;
par
->
CRTC
[
14
]
=
0x00
;
par
->
CRTC
[
15
]
=
0x00
;
par
->
CRTC
[
16
]
=
timings
->
VSyncStart
&
0xFF
;
par
->
CRTC
[
17
]
=
(
timings
->
VSyncEnd
&
0x0F
)
|
0x20
;
par
->
CRTC
[
18
]
=
(
timings
->
VDisplay
-
1
)
&
0xFF
;
par
->
CRTC
[
19
]
=
var
->
xres_virtual
>>
4
;
par
->
CRTC
[
20
]
=
0x00
;
par
->
CRTC
[
21
]
=
(
timings
->
VDisplay
-
1
)
&
0xFF
;
par
->
CRTC
[
22
]
=
(
timings
->
VTotal
-
1
)
&
0xFF
;
par
->
CRTC
[
23
]
=
0xC3
;
par
->
CRTC
[
24
]
=
0xFF
;
/*
neo2200
->
srcStart
=
src
;
* are these unnecessary?
neo2200
->
dstStart
=
dst
;
* vgaHWHBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
neo2200
->
xyExt
=
(
fh
<<
16
)
|
(
width
&
0xffff
);
* vgaHWVBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
*/
/*
sy
+=
inc_y
;
* Graphics Display Controller
dy
+=
inc_y
;
*/
}
par
->
Graphics
[
0
]
=
0x00
;
}
par
->
Graphics
[
1
]
=
0x00
;
par
->
Graphics
[
2
]
=
0x00
;
par
->
Graphics
[
3
]
=
0x00
;
par
->
Graphics
[
4
]
=
0x00
;
par
->
Graphics
[
5
]
=
0x40
;
par
->
Graphics
[
6
]
=
0x05
;
/* only map 64k VGA memory !!!! */
par
->
Graphics
[
7
]
=
0x0F
;
par
->
Graphics
[
8
]
=
0xFF
;
static
void
neo2200_accel_clear
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
sy
,
int
sx
,
int
height
,
int
width
)
{
struct
fb_info
*
fb
=
(
struct
fb_info
*
)
p
->
fb_info
;
struct
fb_var_screeninfo
*
var
=
&
p
->
fb_info
->
var
;
struct
neofb_par
*
par
=
(
struct
neofb_par
*
)
fb
->
par
;
Neo2200
*
neo2200
=
par
->
neo2200
;
u_long
dst
;
u_int
fw
,
fh
;
u32
bgx
=
attr_bgcol_ec
(
p
,
conp
);
par
->
Attribute
[
0
]
=
0x00
;
/* standard colormap translation */
fw
=
fontwidth
(
p
);
par
->
Attribute
[
1
]
=
0x01
;
fh
=
fontheight
(
p
);
par
->
Attribute
[
2
]
=
0x02
;
par
->
Attribute
[
3
]
=
0x03
;
par
->
Attribute
[
4
]
=
0x04
;
par
->
Attribute
[
5
]
=
0x05
;
par
->
Attribute
[
6
]
=
0x06
;
par
->
Attribute
[
7
]
=
0x07
;
par
->
Attribute
[
8
]
=
0x08
;
par
->
Attribute
[
9
]
=
0x09
;
par
->
Attribute
[
10
]
=
0x0A
;
par
->
Attribute
[
11
]
=
0x0B
;
par
->
Attribute
[
12
]
=
0x0C
;
par
->
Attribute
[
13
]
=
0x0D
;
par
->
Attribute
[
14
]
=
0x0E
;
par
->
Attribute
[
15
]
=
0x0F
;
par
->
Attribute
[
16
]
=
0x41
;
par
->
Attribute
[
17
]
=
0xFF
;
par
->
Attribute
[
18
]
=
0x0F
;
par
->
Attribute
[
19
]
=
0x00
;
par
->
Attribute
[
20
]
=
0x00
;
return
0
;
dst
=
sx
*
fw
+
sy
*
var
->
xres_virtual
*
fh
;
width
=
width
*
fw
;
height
=
height
*
fh
;
neo2200_wait_fifo
(
par
,
4
);
/* set blt control */
neo2200
->
bltCntl
=
NEO_BC3_FIFO_EN
|
NEO_BC0_SRC_IS_FG
|
NEO_BC3_SKIP_MAPPING
|
0x0c0000
;
switch
(
var
->
bits_per_pixel
)
{
case
8
:
neo2200
->
fgColor
=
bgx
;
break
;
case
16
:
neo2200
->
fgColor
=
((
u16
*
)
(
p
->
fb_info
)
->
pseudo_palette
)[
bgx
];
break
;
}
neo2200
->
dstStart
=
dst
*
((
var
->
bits_per_pixel
+
7
)
/
8
);
neo2200
->
xyExt
=
(
height
<<
16
)
|
(
width
&
0xffff
);
}
}
static
int
neofb_decode_var
(
struct
fb_var_screeninfo
*
var
,
const
struct
neofb_info
*
info
,
/* --------------------------------------------------------------------- */
struct
neofb_par
*
par
)
static
int
neofb_check_var
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
{
{
struct
neofb_par
*
par
=
(
struct
neofb_par
*
)
info
->
par
;
unsigned
int
pixclock
=
var
->
pixclock
;
struct
xtimings
timings
;
struct
xtimings
timings
;
int
lcd_stretch
;
int
hoffset
,
voffset
;
int
memlen
,
vramlen
;
int
memlen
,
vramlen
;
int
mode_ok
=
0
;
int
mode_ok
=
0
;
unsigned
int
pixclock
=
var
->
pixclock
;
DBG
(
"neofb_decode
_var"
);
DBG
(
"neofb_check
_var"
);
if
(
!
pixclock
)
pixclock
=
10000
;
/* 10ns = 100MHz */
if
(
!
pixclock
)
pixclock
=
10000
;
/* 10ns = 100MHz */
timings
.
pixclock
=
1000000000
/
pixclock
;
timings
.
pixclock
=
1000000000
/
pixclock
;
if
(
timings
.
pixclock
<
1
)
timings
.
pixclock
=
1
;
if
(
timings
.
pixclock
<
1
)
timings
.
pixclock
=
1
;
if
(
timings
.
pixclock
>
par
->
maxClock
)
return
-
EINVAL
;
timings
.
dblscan
=
var
->
vmode
&
FB_VMODE_DOUBLE
;
timings
.
dblscan
=
var
->
vmode
&
FB_VMODE_DOUBLE
;
timings
.
interlaced
=
var
->
vmode
&
FB_VMODE_INTERLACED
;
timings
.
interlaced
=
var
->
vmode
&
FB_VMODE_INTERLACED
;
timings
.
HDisplay
=
var
->
xres
;
timings
.
HDisplay
=
var
->
xres
;
...
@@ -1032,24 +652,18 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
...
@@ -1032,24 +652,18 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
timings
.
VTotal
=
timings
.
VSyncEnd
+
var
->
upper_margin
;
timings
.
VTotal
=
timings
.
VSyncEnd
+
var
->
upper_margin
;
timings
.
sync
=
var
->
sync
;
timings
.
sync
=
var
->
sync
;
if
(
timings
.
pixclock
>
info
->
maxClock
)
return
-
EINVAL
;
/* Is the mode larger than the LCD panel? */
/* Is the mode larger than the LCD panel? */
if
((
var
->
xres
>
info
->
NeoPanelWidth
)
||
if
((
var
->
xres
>
par
->
NeoPanelWidth
)
||
(
var
->
yres
>
info
->
NeoPanelHeight
))
(
var
->
yres
>
par
->
NeoPanelHeight
))
{
{
printk
(
KERN_INFO
printk
(
KERN_INFO
"Mode (%dx%d) larger than the LCD panel (%dx%d)
\n
"
,
"Mode (%dx%d) larger than the LCD panel (%dx%d)
\n
"
,
var
->
xres
,
var
->
xres
,
var
->
yres
,
par
->
NeoPanelWidth
,
var
->
yres
,
par
->
NeoPanelHeight
);
info
->
NeoPanelWidth
,
info
->
NeoPanelHeight
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
/* Is the mode one of the acceptable sizes? */
/* Is the mode one of the acceptable sizes? */
switch
(
var
->
xres
)
switch
(
var
->
xres
)
{
{
case
1280
:
case
1280
:
if
(
var
->
yres
==
1024
)
if
(
var
->
yres
==
1024
)
mode_ok
=
1
;
mode_ok
=
1
;
...
@@ -1068,58 +682,87 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
...
@@ -1068,58 +682,87 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
break
;
break
;
}
}
if
(
!
mode_ok
)
if
(
!
mode_ok
)
{
{
printk
(
KERN_INFO
printk
(
KERN_INFO
"Mode (%dx%d) won't display properly on LCD
\n
"
,
"Mode (%dx%d) won't display properly on LCD
\n
"
,
var
->
xres
,
var
->
yres
);
var
->
xres
,
var
->
yres
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
var
->
red
.
msb_right
=
0
;
var
->
green
.
msb_right
=
0
;
var
->
blue
.
msb_right
=
0
;
switch
(
var
->
bits_per_pixel
)
switch
(
var
->
bits_per_pixel
)
{
{
case
8
:
/* PSEUDOCOLOUR, 256 */
#ifdef FBCON_HAS_CFB8
var
->
transp
.
offset
=
0
;
case
8
:
var
->
transp
.
length
=
0
;
var
->
red
.
offset
=
0
;
var
->
red
.
length
=
8
;
var
->
green
.
offset
=
0
;
var
->
green
.
length
=
8
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
8
;
break
;
break
;
#endif
#ifdef FBCON_HAS_CFB16
case
16
:
/* DIRECTCOLOUR, 64k */
case
16
:
var
->
transp
.
offset
=
0
;
var
->
transp
.
length
=
0
;
var
->
red
.
offset
=
11
;
var
->
red
.
length
=
5
;
var
->
green
.
offset
=
5
;
var
->
green
.
length
=
6
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
5
;
break
;
break
;
#endif
#ifdef FBCON_HAS_CFB24
case
24
:
/* TRUECOLOUR, 16m */
case
24
:
var
->
transp
.
offset
=
0
;
var
->
transp
.
length
=
0
;
var
->
red
.
offset
=
16
;
var
->
red
.
length
=
8
;
var
->
green
.
offset
=
8
;
var
->
green
.
length
=
8
;
var
->
blue
.
offset
=
0
;
break
;
break
;
#endif
#ifdef NO_32BIT_SUPPORT_YET
#ifdef NO_32BIT_SUPPORT_YET
# ifdef FBCON_HAS_CFB32
case
32
:
/* TRUECOLOUR, 16m */
case
32
:
var
->
transp
.
offset
=
24
;
var
->
transp
.
length
=
8
;
var
->
red
.
offset
=
16
;
var
->
red
.
length
=
8
;
var
->
green
.
offset
=
8
;
var
->
green
.
length
=
8
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
8
;
break
;
break
;
# endif
#endif
#endif
default:
default:
printk
(
KERN_WARNING
"neofb: no support for %dbpp
\n
"
,
var
->
bits_per_pixel
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
par
->
depth
=
var
->
bits_per_pixel
;
vramlen
=
info
->
fix
.
smem_len
;
if
(
vramlen
>
4
*
1024
*
1024
)
vramlen
=
info
->
video
.
len
;
vramlen
=
4
*
1024
*
1024
;
if
(
vramlen
>
4
*
1024
*
1024
)
vramlen
=
4
*
1024
*
1024
;
if
(
var
->
yres_virtual
<
var
->
yres
)
if
(
var
->
yres_virtual
<
var
->
yres
)
var
->
yres_virtual
=
var
->
yres
;
var
->
yres_virtual
=
var
->
yres
;
if
(
var
->
xres_virtual
<
var
->
xres
)
if
(
var
->
xres_virtual
<
var
->
xres
)
var
->
xres_virtual
=
var
->
xres
;
var
->
xres_virtual
=
var
->
xres
;
memlen
=
var
->
xres_virtual
*
var
->
bits_per_pixel
*
var
->
yres_virtual
/
8
;
memlen
=
if
(
memlen
>
vramlen
)
var
->
xres_virtual
*
var
->
bits_per_pixel
*
var
->
yres_virtual
/
{
8
;
var
->
yres_virtual
=
vramlen
*
8
/
(
var
->
xres_virtual
*
var
->
bits_per_pixel
);
if
(
memlen
>
vramlen
)
{
memlen
=
var
->
xres_virtual
*
var
->
bits_per_pixel
*
var
->
yres_virtual
/
8
;
var
->
yres_virtual
=
vramlen
*
8
/
(
var
->
xres_virtual
*
var
->
bits_per_pixel
);
memlen
=
var
->
xres_virtual
*
var
->
bits_per_pixel
*
var
->
yres_virtual
/
8
;
}
}
/* we must round yres/xres down, we already rounded y/xres_virtual up
/* we must round yres/xres down, we already rounded y/xres_virtual up
...
@@ -1133,13 +776,49 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
...
@@ -1133,13 +776,49 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
if
(
var
->
yoffset
+
var
->
yres
>
var
->
yres_virtual
)
if
(
var
->
yoffset
+
var
->
yres
>
var
->
yres_virtual
)
var
->
yoffset
=
var
->
yres_virtual
-
var
->
yres
;
var
->
yoffset
=
var
->
yres_virtual
-
var
->
yres
;
if
(
var
->
bits_per_pixel
>=
24
||
!
par
->
neo2200
)
var
->
accel_flags
&=
~
FB_ACCELF_TEXT
;
return
0
;
}
static
int
neofb_set_par
(
struct
fb_info
*
info
)
{
struct
neofb_par
*
par
=
(
struct
neofb_par
*
)
info
->
par
;
struct
xtimings
timings
;
unsigned
char
temp
;
int
i
,
clock_hi
=
0
;
int
lcd_stretch
;
int
hoffset
,
voffset
;
DBG
(
"neofb_set_par"
);
neoUnlock
();
vgaHWProtect
(
1
);
/* Blank the screen */
timings
.
dblscan
=
info
->
var
.
vmode
&
FB_VMODE_DOUBLE
;
timings
.
interlaced
=
info
->
var
.
vmode
&
FB_VMODE_INTERLACED
;
timings
.
HDisplay
=
info
->
var
.
xres
;
timings
.
HSyncStart
=
timings
.
HDisplay
+
info
->
var
.
right_margin
;
timings
.
HSyncEnd
=
timings
.
HSyncStart
+
info
->
var
.
hsync_len
;
timings
.
HTotal
=
timings
.
HSyncEnd
+
info
->
var
.
left_margin
;
timings
.
VDisplay
=
info
->
var
.
yres
;
timings
.
VSyncStart
=
timings
.
VDisplay
+
info
->
var
.
lower_margin
;
timings
.
VSyncEnd
=
timings
.
VSyncStart
+
info
->
var
.
vsync_len
;
timings
.
VTotal
=
timings
.
VSyncEnd
+
info
->
var
.
upper_margin
;
timings
.
sync
=
info
->
var
.
sync
;
timings
.
pixclock
=
PICOS2KHZ
(
info
->
var
.
pixclock
);
if
(
timings
.
pixclock
<
1
)
timings
.
pixclock
=
1
;
/*
/*
* This will allocate the datastructure and initialize all of the
* This will allocate the datastructure and initialize all of the
* generic VGA registers.
* generic VGA registers.
*/
*/
if
(
vgaHWInit
(
var
,
info
,
par
,
&
timings
))
if
(
vgaHWInit
(
&
info
->
var
,
info
,
par
,
&
timings
))
return
-
EINVAL
;
return
-
EINVAL
;
/*
/*
...
@@ -1148,27 +827,26 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
...
@@ -1148,27 +827,26 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
*/
*/
par
->
Attribute
[
16
]
=
0x01
;
par
->
Attribute
[
16
]
=
0x01
;
switch
(
var
->
bits_per_pixel
)
switch
(
info
->
var
.
bits_per_pixel
)
{
{
case
8
:
case
8
:
par
->
CRTC
[
0x13
]
=
var
->
xres_virtual
>>
3
;
par
->
CRTC
[
0x13
]
=
info
->
var
.
xres_virtual
>>
3
;
par
->
ExtCRTOffset
=
var
->
xres_virtual
>>
11
;
par
->
ExtCRTOffset
=
info
->
var
.
xres_virtual
>>
11
;
par
->
ExtColorModeSelect
=
0x11
;
par
->
ExtColorModeSelect
=
0x11
;
break
;
break
;
case
16
:
case
16
:
par
->
CRTC
[
0x13
]
=
var
->
xres_virtual
>>
2
;
par
->
CRTC
[
0x13
]
=
info
->
var
.
xres_virtual
>>
2
;
par
->
ExtCRTOffset
=
var
->
xres_virtual
>>
10
;
par
->
ExtCRTOffset
=
info
->
var
.
xres_virtual
>>
10
;
par
->
ExtColorModeSelect
=
0x13
;
par
->
ExtColorModeSelect
=
0x13
;
break
;
break
;
case
24
:
case
24
:
par
->
CRTC
[
0x13
]
=
(
var
->
xres_virtual
*
3
)
>>
3
;
par
->
CRTC
[
0x13
]
=
(
info
->
var
.
xres_virtual
*
3
)
>>
3
;
par
->
ExtCRTOffset
=
(
var
->
xres_virtual
*
3
)
>>
11
;
par
->
ExtCRTOffset
=
(
info
->
var
.
xres_virtual
*
3
)
>>
11
;
par
->
ExtColorModeSelect
=
0x14
;
par
->
ExtColorModeSelect
=
0x14
;
break
;
break
;
#ifdef NO_32BIT_SUPPORT_YET
#ifdef NO_32BIT_SUPPORT_YET
case
32
:
/* FIXME: guessed values */
case
32
:
/* FIXME: guessed values */
par
->
CRTC
[
0x13
]
=
var
->
xres_virtual
>>
1
;
par
->
CRTC
[
0x13
]
=
info
->
var
.
xres_virtual
>>
1
;
par
->
ExtCRTOffset
=
var
->
xres_virtual
>>
9
;
par
->
ExtCRTOffset
=
info
->
var
.
xres_virtual
>>
9
;
par
->
ExtColorModeSelect
=
0x15
;
par
->
ExtColorModeSelect
=
0x15
;
break
;
break
;
#endif
#endif
...
@@ -1179,13 +857,13 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
...
@@ -1179,13 +857,13 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
par
->
ExtCRTDispAddr
=
0x10
;
par
->
ExtCRTDispAddr
=
0x10
;
/* Vertical Extension */
/* Vertical Extension */
par
->
VerticalExt
=
(((
timings
.
VTotal
-
2
)
&
0x400
)
>>
10
)
par
->
VerticalExt
=
(((
timings
.
VTotal
-
2
)
&
0x400
)
>>
10
)
|
(((
timings
.
VDisplay
-
1
)
&
0x400
)
>>
9
)
|
(((
timings
.
VDisplay
-
1
)
&
0x400
)
>>
9
)
|
(((
timings
.
VSyncStart
)
&
0x400
)
>>
8
)
|
(((
timings
.
VSyncStart
)
&
0x400
)
>>
8
)
|
(((
timings
.
VSyncStart
)
&
0x400
)
>>
7
);
|
(((
timings
.
VSyncStart
)
&
0x400
)
>>
7
);
/* Fast write bursts on unless disabled. */
/* Fast write bursts on unless disabled. */
if
(
info
->
pci_burst
)
if
(
par
->
pci_burst
)
par
->
SysIfaceCntl1
=
0x30
;
par
->
SysIfaceCntl1
=
0x30
;
else
else
par
->
SysIfaceCntl1
=
0x00
;
par
->
SysIfaceCntl1
=
0x00
;
...
@@ -1194,9 +872,9 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
...
@@ -1194,9 +872,9 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
/* Enable any user specified display devices. */
/* Enable any user specified display devices. */
par
->
PanelDispCntlReg1
=
0x00
;
par
->
PanelDispCntlReg1
=
0x00
;
if
(
info
->
internal_display
)
if
(
par
->
internal_display
)
par
->
PanelDispCntlReg1
|=
0x02
;
par
->
PanelDispCntlReg1
|=
0x02
;
if
(
info
->
external_display
)
if
(
par
->
external_display
)
par
->
PanelDispCntlReg1
|=
0x01
;
par
->
PanelDispCntlReg1
|=
0x01
;
/* If the user did not specify any display devices, then... */
/* If the user did not specify any display devices, then... */
...
@@ -1206,8 +884,7 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
...
@@ -1206,8 +884,7 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
}
}
/* If we are using a fixed mode, then tell the chip we are. */
/* If we are using a fixed mode, then tell the chip we are. */
switch
(
var
->
xres
)
switch
(
info
->
var
.
xres
)
{
{
case
1280
:
case
1280
:
par
->
PanelDispCntlReg1
|=
0x60
;
par
->
PanelDispCntlReg1
|=
0x60
;
break
;
break
;
...
@@ -1223,8 +900,7 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
...
@@ -1223,8 +900,7 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
}
}
/* Setup shadow register locking. */
/* Setup shadow register locking. */
switch
(
par
->
PanelDispCntlReg1
&
0x03
)
switch
(
par
->
PanelDispCntlReg1
&
0x03
)
{
{
case
0x01
:
/* External CRT only mode: */
case
0x01
:
/* External CRT only mode: */
par
->
GeneralLockReg
=
0x00
;
par
->
GeneralLockReg
=
0x00
;
/* We need to program the VCLK for external display only mode. */
/* We need to program the VCLK for external display only mode. */
...
@@ -1247,12 +923,9 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
...
@@ -1247,12 +923,9 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
par
->
PanelDispCntlReg2
=
0x00
;
par
->
PanelDispCntlReg2
=
0x00
;
par
->
PanelDispCntlReg3
=
0x00
;
par
->
PanelDispCntlReg3
=
0x00
;
if
(
info
->
lcd_stretch
&&
if
(
par
->
lcd_stretch
&&
(
par
->
PanelDispCntlReg1
==
0x02
)
&&
/* LCD only */
(
par
->
PanelDispCntlReg1
==
0x02
)
&&
/* LCD only */
(
info
->
var
.
xres
!=
par
->
NeoPanelWidth
))
{
(
var
->
xres
!=
info
->
NeoPanelWidth
))
switch
(
info
->
var
.
xres
)
{
{
switch
(
var
->
xres
)
{
case
320
:
/* Needs testing. KEM -- 24 May 98 */
case
320
:
/* Needs testing. KEM -- 24 May 98 */
case
400
:
/* Needs testing. KEM -- 24 May 98 */
case
400
:
/* Needs testing. KEM -- 24 May 98 */
case
640
:
case
640
:
...
@@ -1265,8 +938,7 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
...
@@ -1265,8 +938,7 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
lcd_stretch
=
0
;
lcd_stretch
=
0
;
/* No stretching in these modes. */
/* No stretching in these modes. */
}
}
}
}
else
else
lcd_stretch
=
0
;
lcd_stretch
=
0
;
/*
/*
...
@@ -1285,35 +957,31 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
...
@@ -1285,35 +957,31 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
par
->
PanelHorizCenterReg5
=
0x00
;
par
->
PanelHorizCenterReg5
=
0x00
;
if
(
par
->
PanelDispCntlReg1
&
0x02
)
if
(
par
->
PanelDispCntlReg1
&
0x02
)
{
{
if
(
info
->
var
.
xres
==
par
->
NeoPanelWidth
)
{
if
(
var
->
xres
==
info
->
NeoPanelWidth
)
{
/*
/*
* No centering required when the requested display width
* No centering required when the requested display width
* equals the panel width.
* equals the panel width.
*/
*/
}
}
else
{
else
{
par
->
PanelDispCntlReg2
|=
0x01
;
par
->
PanelDispCntlReg2
|=
0x01
;
par
->
PanelDispCntlReg3
|=
0x10
;
par
->
PanelDispCntlReg3
|=
0x10
;
/* Calculate the horizontal and vertical offsets. */
/* Calculate the horizontal and vertical offsets. */
if
(
!
lcd_stretch
)
if
(
!
lcd_stretch
)
{
{
hoffset
=
hoffset
=
((
info
->
NeoPanelWidth
-
var
->
xres
)
>>
4
)
-
1
;
((
par
->
NeoPanelWidth
-
voffset
=
((
info
->
NeoPanelHeight
-
var
->
yres
)
>>
1
)
-
2
;
info
->
var
.
xres
)
>>
4
)
-
1
;
}
voffset
=
else
((
par
->
NeoPanelHeight
-
{
info
->
var
.
yres
)
>>
1
)
-
2
;
}
else
{
/* Stretched modes cannot be centered. */
/* Stretched modes cannot be centered. */
hoffset
=
0
;
hoffset
=
0
;
voffset
=
0
;
voffset
=
0
;
}
}
switch
(
var
->
xres
)
switch
(
info
->
var
.
xres
)
{
{
case
320
:
/* Needs testing. KEM -- 24 May 98 */
case
320
:
/* Needs testing. KEM -- 24 May 98 */
par
->
PanelHorizCenterReg3
=
hoffset
;
par
->
PanelHorizCenterReg3
=
hoffset
;
par
->
PanelVertCenterReg2
=
voffset
;
par
->
PanelVertCenterReg2
=
voffset
;
...
@@ -1342,210 +1010,267 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
...
@@ -1342,210 +1010,267 @@ static int neofb_decode_var (struct fb_var_screeninfo *var,
}
}
}
}
par
->
biosMode
=
neoFindMode
(
var
->
xres
,
var
->
yres
,
var
->
bits_per_pixel
);
par
->
biosMode
=
neoFindMode
(
info
->
var
.
xres
,
info
->
var
.
yres
,
info
->
var
.
bits_per_pixel
);
/*
* Calculate the VCLK that most closely matches the requested dot
* clock.
*/
neoCalcVCLK
(
info
,
par
,
timings
.
pixclock
);
/* Since we program the clocks ourselves, always use VCLK3. */
par
->
MiscOutReg
|=
0x0C
;
/* linear colormap for non palettized modes */
switch
(
info
->
var
.
bits_per_pixel
)
{
case
8
:
/* PseudoColor, 256 */
info
->
fix
.
visual
=
FB_VISUAL_PSEUDOCOLOR
;
break
;
case
16
:
/* DirectColor, 64k */
info
->
fix
.
visual
=
FB_VISUAL_DIRECTCOLOR
;
for
(
i
=
0
;
i
<
64
;
i
++
)
{
outb
(
i
,
0x3c8
);
outb
(
i
<<
1
,
0x3c9
);
outb
(
i
,
0x3c9
);
outb
(
i
<<
1
,
0x3c9
);
}
break
;
case
24
:
#ifdef NO_32BIT_SUPPORT_YET
case
32
:
#endif
/* TrueColor, 16m */
info
->
fix
.
visual
=
FB_VISUAL_TRUECOLOR
;
for
(
i
=
0
;
i
<
256
;
i
++
)
{
outb
(
i
,
0x3c8
);
outb
(
i
,
0x3c9
);
outb
(
i
,
0x3c9
);
outb
(
i
,
0x3c9
);
}
break
;
}
/* alread unlocked above */
/* BOGUS VGAwGR (0x09, 0x26); */
/* don't know what this is, but it's 0 from bootup anyway */
VGAwGR
(
0x15
,
0x00
);
/* was set to 0x01 by my bios in text and vesa modes */
VGAwGR
(
0x0A
,
par
->
GeneralLockReg
);
/*
* The color mode needs to be set before calling vgaHWRestore
* to ensure the DAC is initialized properly.
*
* NOTE: Make sure we don't change bits make sure we don't change
* any reserved bits.
*/
temp
=
VGArGR
(
0x90
);
switch
(
info
->
fix
.
accel
)
{
case
FB_ACCEL_NEOMAGIC_NM2070
:
temp
&=
0xF0
;
/* Save bits 7:4 */
temp
|=
(
par
->
ExtColorModeSelect
&
~
0xF0
);
break
;
case
FB_ACCEL_NEOMAGIC_NM2090
:
case
FB_ACCEL_NEOMAGIC_NM2093
:
case
FB_ACCEL_NEOMAGIC_NM2097
:
case
FB_ACCEL_NEOMAGIC_NM2160
:
case
FB_ACCEL_NEOMAGIC_NM2200
:
case
FB_ACCEL_NEOMAGIC_NM2230
:
case
FB_ACCEL_NEOMAGIC_NM2360
:
case
FB_ACCEL_NEOMAGIC_NM2380
:
temp
&=
0x70
;
/* Save bits 6:4 */
temp
|=
(
par
->
ExtColorModeSelect
&
~
0x70
);
break
;
}
VGAwGR
(
0x90
,
temp
);
/*
/*
* Calculate the VCLK that most closely matches the requested dot
* In some rare cases a lockup might occur if we don't delay
* clock.
* here. (Reported by Miles Lane)
*/
*/
neoCalcVCLK
(
info
,
par
,
timings
.
pixclock
);
//mdelay(200
);
/* Since we program the clocks ourselves, always use VCLK3. */
/*
par
->
MiscOutReg
|=
0x0C
;
* Disable horizontal and vertical graphics and text expansions so
* that vgaHWRestore works properly.
*/
temp
=
VGArGR
(
0x25
);
temp
&=
0x39
;
VGAwGR
(
0x25
,
temp
);
return
0
;
/*
}
* Sleep for 200ms to make sure that the two operations above have
* had time to take effect.
*/
mdelay
(
200
);
static
int
neofb_set_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
/*
struct
fb_info
*
fb
)
* This function handles restoring the generic VGA registers. */
{
vgaHWRestore
(
info
,
par
);
struct
neofb_info
*
info
=
(
struct
neofb_info
*
)
fb
;
struct
display
*
display
;
struct
neofb_par
par
;
int
err
,
chgvar
=
0
;
DBG
(
"neofb_set_var"
);
err
=
neofb_decode_var
(
var
,
info
,
&
par
);
VGAwGR
(
0x0E
,
par
->
ExtCRTDispAddr
);
if
(
err
)
VGAwGR
(
0x0F
,
par
->
ExtCRTOffset
);
return
err
;
temp
=
VGArGR
(
0x10
);
temp
&=
0x0F
;
/* Save bits 3:0 */
temp
|=
(
par
->
SysIfaceCntl1
&
~
0x0F
);
/* VESA Bios sets bit 1! */
VGAwGR
(
0x10
,
temp
);
if
(
var
->
activate
&
FB_ACTIVATE_TEST
)
VGAwGR
(
0x11
,
par
->
SysIfaceCntl2
);
return
0
;
VGAwGR
(
0x15
,
0
/*par->SingleAddrPage */
);
VGAwGR
(
0x16
,
0
/*par->DualAddrPage */
);
if
(
con
<
0
)
temp
=
VGArGR
(
0x20
);
{
switch
(
info
->
fix
.
accel
)
{
display
=
fb
->
disp
;
case
FB_ACCEL_NEOMAGIC_NM2070
:
chgvar
=
0
;
temp
&=
0xFC
;
/* Save bits 7:2 */
temp
|=
(
par
->
PanelDispCntlReg1
&
~
0xFC
);
break
;
case
FB_ACCEL_NEOMAGIC_NM2090
:
case
FB_ACCEL_NEOMAGIC_NM2093
:
case
FB_ACCEL_NEOMAGIC_NM2097
:
case
FB_ACCEL_NEOMAGIC_NM2160
:
temp
&=
0xDC
;
/* Save bits 7:6,4:2 */
temp
|=
(
par
->
PanelDispCntlReg1
&
~
0xDC
);
break
;
case
FB_ACCEL_NEOMAGIC_NM2200
:
case
FB_ACCEL_NEOMAGIC_NM2230
:
case
FB_ACCEL_NEOMAGIC_NM2360
:
case
FB_ACCEL_NEOMAGIC_NM2380
:
temp
&=
0x98
;
/* Save bits 7,4:3 */
temp
|=
(
par
->
PanelDispCntlReg1
&
~
0x98
);
break
;
}
}
else
VGAwGR
(
0x20
,
temp
);
{
display
=
fb_display
+
con
;
temp
=
VGArGR
(
0x25
);
temp
&=
0x38
;
/* Save bits 5:3 */
if
(
fb
->
var
.
xres
!=
var
->
xres
)
temp
|=
(
par
->
PanelDispCntlReg2
&
~
0x38
);
chgvar
=
1
;
VGAwGR
(
0x25
,
temp
);
if
(
fb
->
var
.
yres
!=
var
->
yres
)
chgvar
=
1
;
if
(
info
->
fix
.
accel
!=
FB_ACCEL_NEOMAGIC_NM2070
)
{
if
(
fb
->
var
.
xres_virtual
!=
var
->
xres_virtual
)
temp
=
VGArGR
(
0x30
);
chgvar
=
1
;
temp
&=
0xEF
;
/* Save bits 7:5 and bits 3:0 */
if
(
fb
->
var
.
yres_virtual
!=
var
->
yres_virtual
)
temp
|=
(
par
->
PanelDispCntlReg3
&
~
0xEF
);
chgvar
=
1
;
VGAwGR
(
0x30
,
temp
);
if
(
fb
->
var
.
bits_per_pixel
!=
var
->
bits_per_pixel
)
chgvar
=
1
;
}
}
if
(
!
info
->
neo2200
)
VGAwGR
(
0x28
,
par
->
PanelVertCenterReg1
);
var
->
accel_flags
&=
~
FB_ACCELF_TEXT
;
VGAwGR
(
0x29
,
par
->
PanelVertCenterReg2
);
VGAwGR
(
0x2a
,
par
->
PanelVertCenterReg3
);
var
->
red
.
msb_right
=
0
;
if
(
info
->
fix
.
accel
!=
FB_ACCEL_NEOMAGIC_NM2070
)
{
var
->
green
.
msb_right
=
0
;
VGAwGR
(
0x32
,
par
->
PanelVertCenterReg4
);
var
->
blue
.
msb_right
=
0
;
VGAwGR
(
0x33
,
par
->
PanelHorizCenterReg1
);
VGAwGR
(
0x34
,
par
->
PanelHorizCenterReg2
);
VGAwGR
(
0x35
,
par
->
PanelHorizCenterReg3
);
}
switch
(
var
->
bits_per_pixel
)
if
(
info
->
fix
.
accel
==
FB_ACCEL_NEOMAGIC_NM2160
)
{
VGAwGR
(
0x36
,
par
->
PanelHorizCenterReg4
);
#ifdef FBCON_HAS_CFB8
case
8
:
/* PSEUDOCOLOUR, 256 */
var
->
transp
.
offset
=
0
;
var
->
transp
.
length
=
0
;
var
->
red
.
offset
=
0
;
var
->
red
.
length
=
8
;
var
->
green
.
offset
=
0
;
var
->
green
.
length
=
8
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
8
;
fb
->
fix
.
visual
=
FB_VISUAL_PSEUDOCOLOR
;
if
(
info
->
fix
.
accel
==
FB_ACCEL_NEOMAGIC_NM2200
||
info
->
dispsw
=
&
fbcon_cfb8
;
info
->
fix
.
accel
==
FB_ACCEL_NEOMAGIC_NM2230
||
display
->
dispsw_data
=
NULL
;
info
->
fix
.
accel
==
FB_ACCEL_NEOMAGIC_NM2360
||
display
->
next_line
=
var
->
xres_virtual
;
info
->
fix
.
accel
==
FB_ACCEL_NEOMAGIC_NM2380
)
{
break
;
VGAwGR
(
0x36
,
par
->
PanelHorizCenterReg4
);
#endif
VGAwGR
(
0x37
,
par
->
PanelVertCenterReg5
);
VGAwGR
(
0x38
,
par
->
PanelHorizCenterReg5
);
#ifdef FBCON_HAS_CFB16
clock_hi
=
1
;
case
16
:
/* DIRECTCOLOUR, 64k */
}
var
->
transp
.
offset
=
0
;
var
->
transp
.
length
=
0
;
var
->
red
.
offset
=
11
;
var
->
red
.
length
=
5
;
var
->
green
.
offset
=
5
;
var
->
green
.
length
=
6
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
5
;
fb
->
fix
.
visual
=
FB_VISUAL_DIRECTCOLOR
;
/* Program VCLK3 if needed. */
info
->
dispsw
=
&
fbcon_cfb16
;
if
(
par
->
ProgramVCLK
&&
((
VGArGR
(
0x9B
)
!=
par
->
VCLK3NumeratorLow
)
display
->
dispsw_data
=
fb
->
pseudo_palette
;
||
(
VGArGR
(
0x9F
)
!=
par
->
VCLK3Denominator
)
display
->
next_line
=
var
->
xres_virtual
*
2
;
||
(
clock_hi
&&
((
VGArGR
(
0x8F
)
&
~
0x0f
)
break
;
!=
(
par
->
#endif
VCLK3NumeratorHigh
&
~
0x0F
)))))
{
VGAwGR
(
0x9B
,
par
->
VCLK3NumeratorLow
);
if
(
clock_hi
)
{
temp
=
VGArGR
(
0x8F
);
temp
&=
0x0F
;
/* Save bits 3:0 */
temp
|=
(
par
->
VCLK3NumeratorHigh
&
~
0x0F
);
VGAwGR
(
0x8F
,
temp
);
}
VGAwGR
(
0x9F
,
par
->
VCLK3Denominator
);
}
#ifdef FBCON_HAS_CFB24
if
(
par
->
biosMode
)
case
24
:
/* TRUECOLOUR, 16m */
VGAwCR
(
0x23
,
par
->
biosMode
);
var
->
transp
.
offset
=
0
;
var
->
transp
.
length
=
0
;
var
->
red
.
offset
=
16
;
var
->
red
.
length
=
8
;
var
->
green
.
offset
=
8
;
var
->
green
.
length
=
8
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
8
;
fb
->
fix
.
visual
=
FB_VISUAL_TRUECOLOR
;
VGAwGR
(
0x93
,
0xc0
);
/* Gives 5x faster framebuffer writes !!! */
info
->
dispsw
=
&
fbcon_cfb24
;
display
->
dispsw_data
=
fb
->
pseudo_palette
;
display
->
next_line
=
var
->
xres_virtual
*
3
;
var
->
accel_flags
&=
~
FB_ACCELF_TEXT
;
/* Program vertical extension register */
break
;
if
(
info
->
fix
.
accel
==
FB_ACCEL_NEOMAGIC_NM2200
||
#endif
info
->
fix
.
accel
==
FB_ACCEL_NEOMAGIC_NM2230
||
info
->
fix
.
accel
==
FB_ACCEL_NEOMAGIC_NM2360
||
info
->
fix
.
accel
==
FB_ACCEL_NEOMAGIC_NM2380
)
{
VGAwCR
(
0x70
,
par
->
VerticalExt
);
}
#ifdef NO_32BIT_SUPPORT_YET
# ifdef FBCON_HAS_CFB32
case
32
:
/* TRUECOLOUR, 16m */
var
->
transp
.
offset
=
24
;
var
->
transp
.
length
=
8
;
var
->
red
.
offset
=
16
;
var
->
red
.
length
=
8
;
var
->
green
.
offset
=
8
;
var
->
green
.
length
=
8
;
var
->
blue
.
offset
=
0
;
var
->
blue
.
length
=
8
;
fb
->
fix
.
visual
=
FB_VISUAL_TRUECOLOR
;
vgaHWProtect
(
0
);
/* Turn on screen */
info
->
dispsw
=
&
fbcon_cfb32
;
display
->
dispsw_data
=
fb
->
pseudo_palette
;
display
->
next_line
=
var
->
xres_virtual
*
4
;
var
->
accel_flags
&=
~
FB_ACCELF_TEXT
;
/* Calling this also locks offset registers required in update_start */
break
;
neoLock
();
# endif
#endif
default:
info
->
fix
.
line_length
=
printk
(
KERN_WARNING
"neofb: no support for %dbpp
\n
"
,
var
->
bits_per_pixel
);
info
->
var
.
xres_virtual
*
(
info
->
var
.
bits_per_pixel
>>
3
);
info
->
dispsw
=
&
fbcon_dummy
;
var
->
accel_flags
&=
~
FB_ACCELF_TEXT
;
break
;
}
if
(
var
->
accel_flags
&
FB_ACCELF_TEXT
)
if
(
info
->
var
.
accel_flags
&
FB_ACCELF_TEXT
)
display
->
dispsw
=
&
fbcon_neo2200_accel
;
neo2200_accel_init
(
info
,
&
info
->
var
);
else
return
0
;
display
->
dispsw
=
info
->
dispsw
;
}
static
void
neofb_update_start
(
struct
fb_info
*
info
,
struct
fb_var_screeninfo
*
var
)
{
int
oldExtCRTDispAddr
;
int
Base
;
fb
->
fix
.
line_length
=
display
->
next_line
;
DBG
(
"neofb_update_start"
)
;
display
->
line_length
=
fb
->
fix
.
line_length
;
Base
=
(
var
->
yoffset
*
var
->
xres_virtual
+
var
->
xoffset
)
>>
2
;
display
->
visual
=
fb
->
fix
.
visual
;
Base
*=
(
var
->
bits_per_pixel
+
7
)
/
8
;
display
->
type
=
fb
->
fix
.
type
;
display
->
type_aux
=
fb
->
fix
.
type_aux
;
display
->
ypanstep
=
fb
->
fix
.
ypanstep
;
display
->
ywrapstep
=
fb
->
fix
.
ywrapstep
;
display
->
can_soft_blank
=
1
;
display
->
inverse
=
0
;
fb
->
var
=
*
var
;
neoUnlock
();
fb
->
var
.
activate
&=
~
FB_ACTIVATE_ALL
;
/*
/*
* Update the old var. The fbcon drivers still use this.
* These are the generic starting address registers.
* Once they are using cfb->fb.var, this can be dropped.
* --rmk
*/
*/
display
->
var
=
fb
->
var
;
VGAwCR
(
0x0C
,
(
Base
&
0x00FF00
)
>>
8
);
VGAwCR
(
0x0D
,
(
Base
&
0x00FF
));
/*
/*
* If we are setting all the virtual consoles, also set the
* Make sure we don't clobber some other bits that might already
* defaults used to create new consoles.
* have been set. NOTE: NM2200 has a writable bit 3, but it shouldn't
* be needed.
*/
*/
if
(
var
->
activate
&
FB_ACTIVATE_ALL
)
oldExtCRTDispAddr
=
VGArGR
(
0x0E
);
fb
->
disp
->
var
=
fb
->
var
;
VGAwGR
(
0x0E
,
(((
Base
>>
16
)
&
0x0f
)
|
(
oldExtCRTDispAddr
&
0xf0
)));
if
(
chgvar
&&
fb
&&
fb
->
changevar
)
fb
->
changevar
(
con
);
if
(
con
==
info
->
fb
.
currcon
)
{
if
(
chgvar
||
con
<
0
)
neofb_set_par
(
info
,
&
par
);
neofb_update_start
(
info
,
var
);
fb_set_cmap
(
&
fb
->
cmap
,
1
,
fb
);
if
(
var
->
accel_flags
&
FB_ACCELF_TEXT
)
neo2200_accel_init
(
info
,
var
);
}
return
0
;
neoLock
()
;
}
}
/*
/*
* Pan or Wrap the Display
* Pan or Wrap the Display
*/
*/
static
int
neofb_pan_display
(
struct
fb_var_screeninfo
*
var
,
int
con
,
static
int
neofb_pan_display
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
fb
)
struct
fb_info
*
fb
)
{
{
struct
neofb_info
*
info
=
(
struct
neofb_info
*
)
fb
;
struct
fb_info
*
info
=
(
struct
fb_info
*
)
fb
;
u_int
y_bottom
;
u_int
y_bottom
;
y_bottom
=
var
->
yoffset
;
y_bottom
=
var
->
yoffset
;
...
@@ -1558,7 +1283,7 @@ static int neofb_pan_display (struct fb_var_screeninfo *var, int con,
...
@@ -1558,7 +1283,7 @@ static int neofb_pan_display (struct fb_var_screeninfo *var, int con,
if
(
y_bottom
>
fb
->
var
.
yres_virtual
)
if
(
y_bottom
>
fb
->
var
.
yres_virtual
)
return
-
EINVAL
;
return
-
EINVAL
;
neofb_update_start
(
info
,
var
);
neofb_update_start
(
info
,
var
);
fb
->
var
.
xoffset
=
var
->
xoffset
;
fb
->
var
.
xoffset
=
var
->
xoffset
;
fb
->
var
.
yoffset
=
var
->
yoffset
;
fb
->
var
.
yoffset
=
var
->
yoffset
;
...
@@ -1571,71 +1296,12 @@ static int neofb_pan_display (struct fb_var_screeninfo *var, int con,
...
@@ -1571,71 +1296,12 @@ static int neofb_pan_display (struct fb_var_screeninfo *var, int con,
return
0
;
return
0
;
}
}
/*
* Update the `var' structure (called by fbcon.c)
*
* This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
* Since it's called by a kernel driver, no range checking is done.
*/
static
int
neofb_updatevar
(
int
con
,
struct
fb_info
*
fb
)
{
struct
neofb_info
*
info
=
(
struct
neofb_info
*
)
fb
;
neofb_update_start
(
info
,
&
fb_display
[
con
].
var
);
return
0
;
}
static
int
neofb_switch
(
int
con
,
struct
fb_info
*
fb
)
{
struct
neofb_info
*
info
=
(
struct
neofb_info
*
)
fb
;
struct
display
*
disp
;
struct
fb_cmap
*
cmap
;
if
(
info
->
fb
.
currcon
>=
0
)
{
disp
=
fb_display
+
info
->
fb
.
currcon
;
/*
* Save the old colormap and video mode.
*/
disp
->
var
=
fb
->
var
;
if
(
disp
->
cmap
.
len
)
fb_copy_cmap
(
&
fb
->
cmap
,
&
disp
->
cmap
,
0
);
}
info
->
fb
.
currcon
=
con
;
disp
=
fb_display
+
con
;
/*
* Install the new colormap and change the video mode. By default,
* fbcon sets all the colormaps and video modes to the default
* values at bootup.
*
* Really, we want to set the colourmap size depending on the
* depth of the new video mode. For now, we leave it at its
* default 256 entry.
*/
if
(
disp
->
cmap
.
len
)
cmap
=
&
disp
->
cmap
;
else
cmap
=
fb_default_cmap
(
1
<<
disp
->
var
.
bits_per_pixel
);
fb_copy_cmap
(
cmap
,
&
fb
->
cmap
,
0
);
disp
->
var
.
activate
=
FB_ACTIVATE_NOW
;
neofb_set_var
(
&
disp
->
var
,
con
,
fb
);
return
0
;
}
/*
/*
* (Un)Blank the display.
* (Un)Blank the display.
*/
*/
static
int
neofb_blank
(
int
blank
,
struct
fb_info
*
fb
)
static
int
neofb_blank
(
int
blank
,
struct
fb_info
*
fb
)
{
{
// struct neofb_info *info = (struct neo
fb_info *)fb;
// struct fb_info *info = (struct
fb_info *)fb;
/*
/*
* Blank the screen if blank_mode != 0, else unblank. If
* Blank the screen if blank_mode != 0, else unblank. If
...
@@ -1653,8 +1319,7 @@ static int neofb_blank (int blank, struct fb_info *fb)
...
@@ -1653,8 +1319,7 @@ static int neofb_blank (int blank, struct fb_info *fb)
* run "setterm -powersave powerdown" to take advantage
* run "setterm -powersave powerdown" to take advantage
*/
*/
switch
(
blank
)
switch
(
blank
)
{
{
case
4
:
/* powerdown - both sync lines down */
case
4
:
/* powerdown - both sync lines down */
break
;
break
;
case
3
:
/* hsync off */
case
3
:
/* hsync off */
...
@@ -1671,14 +1336,19 @@ static int neofb_blank (int blank, struct fb_info *fb)
...
@@ -1671,14 +1336,19 @@ static int neofb_blank (int blank, struct fb_info *fb)
static
struct
fb_ops
neofb_ops
=
{
static
struct
fb_ops
neofb_ops
=
{
owner:
THIS_MODULE
,
owner:
THIS_MODULE
,
fb_set_var:
neofb_set_var
,
fb_check_var:
neofb_check_var
,
fb_set_par:
neofb_set_par
,
fb_set_var:
gen_set_var
,
fb_get_fix:
gen_get_fix
,
fb_get_var:
gen_get_var
,
fb_get_cmap:
gen_get_cmap
,
fb_set_cmap:
gen_set_cmap
,
fb_set_cmap:
gen_set_cmap
,
fb_setcolreg:
neofb_setcolreg
,
fb_setcolreg:
neofb_setcolreg
,
fb_pan_display:
neofb_pan_display
,
fb_pan_display:
neofb_pan_display
,
fb_blank:
neofb_blank
,
fb_blank:
neofb_blank
,
fb_get_fix:
gen_get_fix
,
fb_fillrect:
cfb_fillrect
,
fb_get_var:
gen_get_var
,
fb_copyarea:
cfb_copyarea
,
fb_get_cmap:
gen_get_cmap
,
fb_imageblit:
cfb_imageblit
,
};
};
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
...
@@ -1759,106 +1429,104 @@ static struct fb_var_screeninfo __devinitdata neofb_var1280x1024x8 = {
...
@@ -1759,106 +1429,104 @@ static struct fb_var_screeninfo __devinitdata neofb_var1280x1024x8 = {
static
struct
fb_var_screeninfo
*
neofb_var
=
NULL
;
static
struct
fb_var_screeninfo
*
neofb_var
=
NULL
;
static
int
__devinit
neo_map_mmio
(
struct
fb_info
*
info
,
struct
pci_dev
*
dev
)
static
int
__devinit
neo_map_mmio
(
struct
neofb_info
*
info
)
{
{
struct
neofb_par
*
par
=
(
struct
neofb_par
*
)
info
->
par
;
DBG
(
"neo_map_mmio"
);
DBG
(
"neo_map_mmio"
);
info
->
mmio
.
pbase
=
pci_resource_start
(
info
->
pci
dev
,
1
);
info
->
fix
.
mmio_start
=
pci_resource_start
(
dev
,
1
);
info
->
mmio
.
len
=
MMIO_SIZE
;
info
->
fix
.
mmio_len
=
MMIO_SIZE
;
if
(
!
request_mem_region
(
info
->
mmio
.
pbase
,
MMIO_SIZE
,
"memory mapped I/O"
))
if
(
!
request_mem_region
{
(
info
->
fix
.
mmio_start
,
MMIO_SIZE
,
"memory mapped I/O"
))
{
printk
(
"neofb: memory mapped IO in use
\n
"
);
printk
(
"neofb: memory mapped IO in use
\n
"
);
return
-
EBUSY
;
return
-
EBUSY
;
}
}
info
->
mmio
.
vbase
=
ioremap
(
info
->
mmio
.
pbase
,
MMIO_SIZE
);
par
->
mmio_vbase
=
ioremap
(
info
->
fix
.
mmio_start
,
MMIO_SIZE
);
if
(
!
info
->
mmio
.
vbase
)
if
(
!
par
->
mmio_vbase
)
{
{
printk
(
"neofb: unable to map memory mapped IO
\n
"
);
printk
(
"neofb: unable to map memory mapped IO
\n
"
);
release_mem_region
(
info
->
fix
.
mmio_start
,
info
->
fix
.
mmio_len
);
release_mem_region
(
info
->
mmio
.
pbase
,
info
->
mmio
.
len
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
else
else
printk
(
KERN_INFO
"neofb: mapped io at %p
\n
"
,
printk
(
KERN_INFO
"neofb: mapped io at %p
\n
"
,
info
->
mmio
.
vbase
);
par
->
mmio_vbase
);
info
->
fb
.
fix
.
mmio_start
=
info
->
mmio
.
pbase
;
info
->
fb
.
fix
.
mmio_len
=
info
->
mmio
.
len
;
return
0
;
return
0
;
}
}
static
void
__devinit
neo_unmap_mmio
(
struct
neo
fb_info
*
info
)
static
void
__devinit
neo_unmap_mmio
(
struct
fb_info
*
info
)
{
{
struct
neofb_par
*
par
=
(
struct
neofb_par
*
)
info
->
par
;
DBG
(
"neo_unmap_mmio"
);
DBG
(
"neo_unmap_mmio"
);
if
(
info
->
mmio
.
vbase
)
if
(
par
->
mmio_vbase
)
{
{
iounmap
(
par
->
mmio_vbase
);
iounmap
(
info
->
mmio
.
vbase
);
par
->
mmio_vbase
=
NULL
;
info
->
mmio
.
vbase
=
NULL
;
release_mem_region
(
info
->
mmio
.
pbase
,
info
->
mmio
.
len
);
release_mem_region
(
info
->
fix
.
mmio_start
,
info
->
fix
.
mmio_
len
);
}
}
}
}
static
int
__devinit
neo_map_video
(
struct
neofb_info
*
info
,
int
video_len
)
static
int
__devinit
neo_map_video
(
struct
fb_info
*
info
,
struct
pci_dev
*
dev
,
int
video_len
)
{
{
struct
neofb_par
*
par
=
(
struct
neofb_par
*
)
info
->
par
;
DBG
(
"neo_map_video"
);
DBG
(
"neo_map_video"
);
info
->
video
.
pbase
=
pci_resource_start
(
info
->
pci
dev
,
0
);
info
->
fix
.
smem_start
=
pci_resource_start
(
dev
,
0
);
info
->
video
.
len
=
video_len
;
info
->
fix
.
smem_len
=
video_len
;
if
(
!
request_mem_region
(
info
->
video
.
pbase
,
info
->
video
.
len
,
"frame buffer"
))
if
(
!
request_mem_region
{
(
info
->
fix
.
smem_start
,
info
->
fix
.
smem_len
,
"frame buffer"
))
{
printk
(
"neofb: frame buffer in use
\n
"
);
printk
(
"neofb: frame buffer in use
\n
"
);
return
-
EBUSY
;
return
-
EBUSY
;
}
}
info
->
video
.
vbase
=
ioremap
(
info
->
video
.
pbase
,
info
->
video
.
len
);
info
->
screen_base
=
ioremap
(
info
->
fix
.
smem_start
,
info
->
fix
.
smem_len
);
if
(
!
info
->
video
.
vbase
)
if
(
!
info
->
screen_base
)
{
{
printk
(
"neofb: unable to map screen memory
\n
"
);
printk
(
"neofb: unable to map screen memory
\n
"
);
release_mem_region
(
info
->
fix
.
smem_start
,
info
->
fix
.
smem_len
);
release_mem_region
(
info
->
video
.
pbase
,
info
->
video
.
len
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
else
else
printk
(
KERN_INFO
"neofb: mapped framebuffer at %p
\n
"
,
printk
(
KERN_INFO
"neofb: mapped framebuffer at %p
\n
"
,
info
->
video
.
vbase
);
info
->
screen_base
);
info
->
fb
.
fix
.
smem_start
=
info
->
video
.
pbase
;
info
->
fb
.
fix
.
smem_len
=
info
->
video
.
len
;
info
->
fb
.
screen_base
=
info
->
video
.
vbase
;
#ifdef CONFIG_MTRR
#ifdef CONFIG_MTRR
info
->
video
.
mtrr
=
mtrr_add
(
info
->
video
.
pbase
,
pci_resource_len
(
info
->
pcidev
,
0
),
MTRR_TYPE_WRCOMB
,
1
);
par
->
mtrr
=
mtrr_add
(
info
->
fix
.
smem_start
,
pci_resource_len
(
dev
,
0
),
MTRR_TYPE_WRCOMB
,
1
);
#endif
#endif
/* Clear framebuffer, it's all white in memory after boot */
/* Clear framebuffer, it's all white in memory after boot */
memset
(
info
->
video
.
vbase
,
0
,
info
->
video
.
len
);
memset
(
info
->
screen_base
,
0
,
info
->
fix
.
smem_len
);
return
0
;
return
0
;
}
}
static
void
__devinit
neo_unmap_video
(
struct
neo
fb_info
*
info
)
static
void
__devinit
neo_unmap_video
(
struct
fb_info
*
info
)
{
{
struct
neofb_par
*
par
=
(
struct
neofb_par
*
)
info
->
par
;
DBG
(
"neo_unmap_video"
);
DBG
(
"neo_unmap_video"
);
if
(
info
->
video
.
vbase
)
if
(
info
->
screen_base
)
{
{
#ifdef CONFIG_MTRR
#ifdef CONFIG_MTRR
mtrr_del
(
info
->
video
.
mtrr
,
info
->
video
.
pbase
,
info
->
video
.
len
);
mtrr_del
(
par
->
mtrr
,
info
->
fix
.
smem_start
,
info
->
fix
.
smem_len
);
#endif
#endif
iounmap
(
info
->
video
.
vbase
);
iounmap
(
info
->
screen_base
);
info
->
video
.
vbase
=
NULL
;
info
->
screen_base
=
NULL
;
info
->
fb
.
screen_base
=
NULL
;
release_mem_region
(
info
->
video
.
pbase
,
info
->
video
.
len
);
release_mem_region
(
info
->
fix
.
smem_start
,
info
->
fix
.
smem_
len
);
}
}
}
}
static
int
__devinit
neo_init_hw
(
struct
neo
fb_info
*
info
)
static
int
__devinit
neo_init_hw
(
struct
fb_info
*
info
)
{
{
struct
neofb_par
*
par
=
(
struct
neofb_par
*
)
info
->
par
;
int
videoRam
=
896
;
int
videoRam
=
896
;
int
maxClock
=
65000
;
int
maxClock
=
65000
;
int
CursorMem
=
1024
;
int
CursorMem
=
1024
;
...
@@ -1874,64 +1542,65 @@ static int __devinit neo_init_hw (struct neofb_info *info)
...
@@ -1874,64 +1542,65 @@ static int __devinit neo_init_hw (struct neofb_info *info)
neoUnlock
();
neoUnlock
();
#if 0
#if 0
printk (KERN_DEBUG "--- Neo extended register dump ---\n");
printk(KERN_DEBUG "--- Neo extended register dump ---\n");
for (w=0; w<0x85; w++)
for (w = 0; w < 0x85; w++)
printk (KERN_DEBUG "CR %p: %p\n", (void*)w, (void*)VGArCR (w));
printk(KERN_DEBUG "CR %p: %p\n", (void *) w,
for (w=0; w<0xC7; w++)
(void *) VGArCR(w));
printk (KERN_DEBUG "GR %p: %p\n", (void*)w, (void*)VGArGR (w));
for (w = 0; w < 0xC7; w++)
printk(KERN_DEBUG "GR %p: %p\n", (void *) w,
(void *) VGArGR(w));
#endif
#endif
/* Determine the panel type */
/* Determine the panel type */
VGAwGR
(
0x09
,
0x26
);
VGAwGR
(
0x09
,
0x26
);
type
=
VGArGR
(
0x21
);
type
=
VGArGR
(
0x21
);
display
=
VGArGR
(
0x20
);
display
=
VGArGR
(
0x20
);
/* Determine panel width -- used in NeoValidMode. */
/* Determine panel width -- used in NeoValidMode. */
w
=
VGArGR
(
0x20
);
w
=
VGArGR
(
0x20
);
VGAwGR
(
0x09
,
0x00
);
VGAwGR
(
0x09
,
0x00
);
switch
((
w
&
0x18
)
>>
3
)
switch
((
w
&
0x18
)
>>
3
)
{
{
case
0x00
:
case
0x00
:
info
->
NeoPanelWidth
=
640
;
par
->
NeoPanelWidth
=
640
;
info
->
NeoPanelHeight
=
480
;
par
->
NeoPanelHeight
=
480
;
neofb_var
=
&
neofb_var640x480x8
;
neofb_var
=
&
neofb_var640x480x8
;
break
;
break
;
case
0x01
:
case
0x01
:
info
->
NeoPanelWidth
=
800
;
par
->
NeoPanelWidth
=
800
;
info
->
NeoPanelHeight
=
600
;
par
->
NeoPanelHeight
=
600
;
neofb_var
=
&
neofb_var800x600x8
;
neofb_var
=
&
neofb_var800x600x8
;
break
;
break
;
case
0x02
:
case
0x02
:
info
->
NeoPanelWidth
=
1024
;
par
->
NeoPanelWidth
=
1024
;
info
->
NeoPanelHeight
=
768
;
par
->
NeoPanelHeight
=
768
;
neofb_var
=
&
neofb_var1024x768x8
;
neofb_var
=
&
neofb_var1024x768x8
;
break
;
break
;
case
0x03
:
case
0x03
:
/* 1280x1024 panel support needs to be added */
/* 1280x1024 panel support needs to be added */
#ifdef NOT_DONE
#ifdef NOT_DONE
info
->
NeoPanelWidth
=
1280
;
par
->
NeoPanelWidth
=
1280
;
info
->
NeoPanelHeight
=
1024
;
par
->
NeoPanelHeight
=
1024
;
neofb_var
=
&
neofb_var1280x1024x8
;
neofb_var
=
&
neofb_var1280x1024x8
;
break
;
break
;
#else
#else
printk
(
KERN_ERR
"neofb: Only 640x480, 800x600 and 1024x768 panels are currently supported
\n
"
);
printk
(
KERN_ERR
"neofb: Only 640x480, 800x600 and 1024x768 panels are currently supported
\n
"
);
return
-
1
;
return
-
1
;
#endif
#endif
default:
default:
info
->
NeoPanelWidth
=
640
;
par
->
NeoPanelWidth
=
640
;
info
->
NeoPanelHeight
=
480
;
par
->
NeoPanelHeight
=
480
;
neofb_var
=
&
neofb_var640x480x8
;
neofb_var
=
&
neofb_var640x480x8
;
break
;
break
;
}
}
printk
(
KERN_INFO
"Panel is a %dx%d %s %s display
\n
"
,
printk
(
KERN_INFO
"Panel is a %dx%d %s %s display
\n
"
,
info
->
NeoPanelWidth
,
par
->
NeoPanelWidth
,
info
->
NeoPanelHeight
,
par
->
NeoPanelHeight
,
(
type
&
0x02
)
?
"color"
:
"monochrome"
,
(
type
&
0x02
)
?
"color"
:
"monochrome"
,
(
type
&
0x10
)
?
"TFT"
:
"dual scan"
);
(
type
&
0x10
)
?
"TFT"
:
"dual scan"
);
switch
(
info
->
accel
)
switch
(
info
->
fix
.
accel
)
{
{
case
FB_ACCEL_NEOMAGIC_NM2070
:
case
FB_ACCEL_NEOMAGIC_NM2070
:
videoRam
=
896
;
videoRam
=
896
;
maxClock
=
65000
;
maxClock
=
65000
;
...
@@ -1978,7 +1647,7 @@ static int __devinit neo_init_hw (struct neofb_info *info)
...
@@ -1978,7 +1647,7 @@ static int __devinit neo_init_hw (struct neofb_info *info)
maxWidth
=
1280
;
maxWidth
=
1280
;
maxHeight
=
1024
;
/* ???? */
maxHeight
=
1024
;
/* ???? */
info
->
neo2200
=
(
Neo2200
*
)
info
->
mmio
.
vbase
;
par
->
neo2200
=
(
Neo2200
*
)
par
->
mmio_
vbase
;
break
;
break
;
case
FB_ACCEL_NEOMAGIC_NM2230
:
case
FB_ACCEL_NEOMAGIC_NM2230
:
videoRam
=
3008
;
videoRam
=
3008
;
...
@@ -1989,7 +1658,7 @@ static int __devinit neo_init_hw (struct neofb_info *info)
...
@@ -1989,7 +1658,7 @@ static int __devinit neo_init_hw (struct neofb_info *info)
maxWidth
=
1280
;
maxWidth
=
1280
;
maxHeight
=
1024
;
/* ???? */
maxHeight
=
1024
;
/* ???? */
info
->
neo2200
=
(
Neo2200
*
)
info
->
mmio
.
vbase
;
par
->
neo2200
=
(
Neo2200
*
)
par
->
mmio_
vbase
;
break
;
break
;
case
FB_ACCEL_NEOMAGIC_NM2360
:
case
FB_ACCEL_NEOMAGIC_NM2360
:
videoRam
=
4096
;
videoRam
=
4096
;
...
@@ -2000,7 +1669,7 @@ static int __devinit neo_init_hw (struct neofb_info *info)
...
@@ -2000,7 +1669,7 @@ static int __devinit neo_init_hw (struct neofb_info *info)
maxWidth
=
1280
;
maxWidth
=
1280
;
maxHeight
=
1024
;
/* ???? */
maxHeight
=
1024
;
/* ???? */
info
->
neo2200
=
(
Neo2200
*
)
info
->
mmio
.
vbase
;
par
->
neo2200
=
(
Neo2200
*
)
par
->
mmio_
vbase
;
break
;
break
;
case
FB_ACCEL_NEOMAGIC_NM2380
:
case
FB_ACCEL_NEOMAGIC_NM2380
:
videoRam
=
6144
;
videoRam
=
6144
;
...
@@ -2011,155 +1680,156 @@ static int __devinit neo_init_hw (struct neofb_info *info)
...
@@ -2011,155 +1680,156 @@ static int __devinit neo_init_hw (struct neofb_info *info)
maxWidth
=
1280
;
maxWidth
=
1280
;
maxHeight
=
1024
;
/* ???? */
maxHeight
=
1024
;
/* ???? */
info
->
neo2200
=
(
Neo2200
*
)
info
->
mmio
.
vbase
;
par
->
neo2200
=
(
Neo2200
*
)
par
->
mmio_
vbase
;
break
;
break
;
}
}
info
->
maxClock
=
maxClock
;
par
->
maxClock
=
maxClock
;
return
videoRam
*
1024
;
return
videoRam
*
1024
;
}
}
static
struct
neofb_info
*
__devinit
neo_alloc_fb_info
(
struct
pci_dev
*
dev
,
static
struct
fb_info
*
__devinit
neo_alloc_fb_info
(
struct
pci_dev
*
dev
,
const
struct
pci_device_id
*
id
)
const
struct
pci_device_id
*
id
)
{
{
struct
neofb_info
*
info
;
struct
fb_info
*
info
;
struct
neofb_par
*
par
;
info
=
kmalloc
(
sizeof
(
struct
neo
fb_info
)
+
sizeof
(
struct
display
)
+
info
=
kmalloc
(
sizeof
(
struct
fb_info
)
+
sizeof
(
struct
display
)
+
sizeof
(
u32
)
*
16
,
GFP_KERNEL
);
sizeof
(
u32
)
*
16
,
GFP_KERNEL
);
if
(
!
info
)
if
(
!
info
)
return
NULL
;
return
NULL
;
memset
(
info
,
0
,
sizeof
(
struct
neofb_info
)
+
sizeof
(
struct
display
));
memset
(
info
,
0
,
sizeof
(
struct
fb_info
)
+
sizeof
(
struct
display
));
info
->
fb
.
currcon
=
-
1
;
par
=
&
default_par
;
info
->
pcidev
=
dev
;
memset
(
par
,
0
,
sizeof
(
struct
neofb_par
));
info
->
accel
=
id
->
driver_data
;
info
->
pci_burst
=
!
nopciburst
;
info
->
currcon
=
-
1
;
info
->
lcd_stretch
=
!
nostretch
;
info
->
fix
.
accel
=
id
->
driver_data
;
if
(
!
internal
&&
!
external
)
par
->
pci_burst
=
!
nopciburst
;
{
par
->
lcd_stretch
=
!
nostretch
;
info
->
internal_display
=
1
;
info
->
external_display
=
0
;
if
(
!
internal
&&
!
external
)
{
}
par
->
internal_display
=
1
;
else
par
->
external_display
=
0
;
{
}
else
{
info
->
internal_display
=
internal
;
par
->
internal_display
=
internal
;
info
->
external_display
=
external
;
par
->
external_display
=
external
;
}
}
switch
(
info
->
accel
)
switch
(
info
->
fix
.
accel
)
{
{
case
FB_ACCEL_NEOMAGIC_NM2070
:
case
FB_ACCEL_NEOMAGIC_NM2070
:
sprintf
(
info
->
fb
.
fix
.
id
,
"MagicGraph 128"
);
sprintf
(
info
->
fix
.
id
,
"MagicGraph 128"
);
break
;
break
;
case
FB_ACCEL_NEOMAGIC_NM2090
:
case
FB_ACCEL_NEOMAGIC_NM2090
:
sprintf
(
info
->
fb
.
fix
.
id
,
"MagicGraph 128V"
);
sprintf
(
info
->
fix
.
id
,
"MagicGraph 128V"
);
break
;
break
;
case
FB_ACCEL_NEOMAGIC_NM2093
:
case
FB_ACCEL_NEOMAGIC_NM2093
:
sprintf
(
info
->
fb
.
fix
.
id
,
"MagicGraph 128ZV"
);
sprintf
(
info
->
fix
.
id
,
"MagicGraph 128ZV"
);
break
;
break
;
case
FB_ACCEL_NEOMAGIC_NM2097
:
case
FB_ACCEL_NEOMAGIC_NM2097
:
sprintf
(
info
->
fb
.
fix
.
id
,
"MagicGraph 128ZV+"
);
sprintf
(
info
->
fix
.
id
,
"MagicGraph 128ZV+"
);
break
;
break
;
case
FB_ACCEL_NEOMAGIC_NM2160
:
case
FB_ACCEL_NEOMAGIC_NM2160
:
sprintf
(
info
->
fb
.
fix
.
id
,
"MagicGraph 128XD"
);
sprintf
(
info
->
fix
.
id
,
"MagicGraph 128XD"
);
break
;
break
;
case
FB_ACCEL_NEOMAGIC_NM2200
:
case
FB_ACCEL_NEOMAGIC_NM2200
:
sprintf
(
info
->
fb
.
fix
.
id
,
"MagicGraph 256AV"
);
sprintf
(
info
->
fix
.
id
,
"MagicGraph 256AV"
);
break
;
break
;
case
FB_ACCEL_NEOMAGIC_NM2230
:
case
FB_ACCEL_NEOMAGIC_NM2230
:
sprintf
(
info
->
fb
.
fix
.
id
,
"MagicGraph 256AV+"
);
sprintf
(
info
->
fix
.
id
,
"MagicGraph 256AV+"
);
break
;
break
;
case
FB_ACCEL_NEOMAGIC_NM2360
:
case
FB_ACCEL_NEOMAGIC_NM2360
:
sprintf
(
info
->
fb
.
fix
.
id
,
"MagicGraph 256ZX"
);
sprintf
(
info
->
fix
.
id
,
"MagicGraph 256ZX"
);
break
;
break
;
case
FB_ACCEL_NEOMAGIC_NM2380
:
case
FB_ACCEL_NEOMAGIC_NM2380
:
sprintf
(
info
->
fb
.
fix
.
id
,
"MagicGraph 256XL+"
);
sprintf
(
info
->
fix
.
id
,
"MagicGraph 256XL+"
);
break
;
break
;
}
}
info
->
fb
.
fix
.
type
=
FB_TYPE_PACKED_PIXELS
;
info
->
fix
.
type
=
FB_TYPE_PACKED_PIXELS
;
info
->
fb
.
fix
.
type_aux
=
0
;
info
->
fix
.
type_aux
=
0
;
info
->
fb
.
fix
.
xpanstep
=
0
;
info
->
fix
.
xpanstep
=
0
;
info
->
fb
.
fix
.
ypanstep
=
4
;
info
->
fix
.
ypanstep
=
4
;
info
->
fb
.
fix
.
ywrapstep
=
0
;
info
->
fix
.
ywrapstep
=
0
;
info
->
fb
.
fix
.
accel
=
id
->
driver_data
;
info
->
fix
.
accel
=
id
->
driver_data
;
info
->
fb
.
var
.
nonstd
=
0
;
info
->
var
.
nonstd
=
0
;
info
->
fb
.
var
.
activate
=
FB_ACTIVATE_NOW
;
info
->
var
.
activate
=
FB_ACTIVATE_NOW
;
info
->
fb
.
var
.
height
=
-
1
;
info
->
var
.
height
=
-
1
;
info
->
fb
.
var
.
width
=
-
1
;
info
->
var
.
width
=
-
1
;
info
->
fb
.
var
.
accel_flags
=
0
;
info
->
var
.
accel_flags
=
0
;
strcpy
(
info
->
fb
.
modename
,
info
->
fb
.
fix
.
id
);
strcpy
(
info
->
modename
,
info
->
fix
.
id
);
info
->
fb
.
fbops
=
&
neofb_ops
;
info
->
fbops
=
&
neofb_ops
;
info
->
fb
.
changevar
=
NULL
;
info
->
changevar
=
NULL
;
info
->
fb
.
switch_con
=
neofb_switch
;
info
->
switch_con
=
gen_switch
;
info
->
fb
.
updatevar
=
neofb_updatevar
;
info
->
updatevar
=
gen_update_var
;
info
->
fb
.
flags
=
FBINFO_FLAG_DEFAULT
;
info
->
flags
=
FBINFO_FLAG_DEFAULT
;
info
->
fb
.
disp
=
(
struct
display
*
)(
info
+
1
);
info
->
par
=
par
;
info
->
fb
.
pseudo_palette
=
(
void
*
)(
info
->
fb
.
disp
+
1
);
info
->
disp
=
(
struct
display
*
)
(
info
+
1
);
info
->
pseudo_palette
=
(
void
*
)
(
info
->
disp
+
1
);
fb_alloc_cmap
(
&
info
->
fb
.
cmap
,
NR_PALETTE
,
0
);
fb_alloc_cmap
(
&
info
->
cmap
,
NR_PALETTE
,
0
);
return
info
;
return
info
;
}
}
static
void
__devinit
neo_free_fb_info
(
struct
neo
fb_info
*
info
)
static
void
__devinit
neo_free_fb_info
(
struct
fb_info
*
info
)
{
{
if
(
info
)
if
(
info
)
{
{
/*
/*
* Free the colourmap
* Free the colourmap
*/
*/
fb_alloc_cmap
(
&
info
->
fb
.
cmap
,
0
,
0
);
fb_alloc_cmap
(
&
info
->
cmap
,
0
,
0
);
kfree
(
info
);
kfree
(
info
);
}
}
}
}
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
static
int
__devinit
neofb_probe
(
struct
pci_dev
*
dev
,
const
struct
pci_device_id
*
id
)
static
int
__devinit
neofb_probe
(
struct
pci_dev
*
dev
,
const
struct
pci_device_id
*
id
)
{
{
struct
neo
fb_info
*
info
;
struct
fb_info
*
info
;
u_int
h_sync
,
v_sync
;
u_int
h_sync
,
v_sync
;
int
err
;
int
err
;
int
video_len
;
int
video_len
;
DBG
(
"neofb_probe"
);
DBG
(
"neofb_probe"
);
err
=
pci_enable_device
(
dev
);
err
=
pci_enable_device
(
dev
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
err
=
-
ENOMEM
;
err
=
-
ENOMEM
;
info
=
neo_alloc_fb_info
(
dev
,
id
);
info
=
neo_alloc_fb_info
(
dev
,
id
);
if
(
!
info
)
if
(
!
info
)
goto
failed
;
goto
failed
;
err
=
neo_map_mmio
(
info
);
err
=
neo_map_mmio
(
info
,
dev
);
if
(
err
)
if
(
err
)
goto
failed
;
goto
failed
;
video_len
=
neo_init_hw
(
info
);
video_len
=
neo_init_hw
(
info
);
if
(
video_len
<
0
)
if
(
video_len
<
0
)
{
{
err
=
video_len
;
err
=
video_len
;
goto
failed
;
goto
failed
;
}
}
err
=
neo_map_video
(
info
,
video_len
);
err
=
neo_map_video
(
info
,
dev
,
video_len
);
if
(
err
)
if
(
err
)
goto
failed
;
goto
failed
;
neofb_set_var
(
neofb_var
,
-
1
,
&
info
->
fb
);
gen_set_var
(
neofb_var
,
-
1
,
info
);
/*
/*
* Calculate the hsync and vsync frequencies. Note that
* Calculate the hsync and vsync frequencies. Note that
...
@@ -2167,24 +1837,27 @@ static int __devinit neofb_probe (struct pci_dev* dev, const struct pci_device_i
...
@@ -2167,24 +1837,27 @@ static int __devinit neofb_probe (struct pci_dev* dev, const struct pci_device_i
* the precision and fit the results into 32-bit registers.
* the precision and fit the results into 32-bit registers.
* (1953125000 * 512 = 1e12)
* (1953125000 * 512 = 1e12)
*/
*/
h_sync
=
1953125000
/
info
->
fb
.
var
.
pixclock
;
h_sync
=
1953125000
/
info
->
var
.
pixclock
;
h_sync
=
h_sync
*
512
/
(
info
->
fb
.
var
.
xres
+
info
->
fb
.
var
.
left_margin
+
h_sync
=
info
->
fb
.
var
.
right_margin
+
info
->
fb
.
var
.
hsync_len
);
h_sync
*
512
/
(
info
->
var
.
xres
+
info
->
var
.
left_margin
+
v_sync
=
h_sync
/
(
info
->
fb
.
var
.
yres
+
info
->
fb
.
var
.
upper_margin
+
info
->
var
.
right_margin
+
info
->
fb
.
var
.
lower_margin
+
info
->
fb
.
var
.
vsync_len
);
info
->
var
.
hsync_len
);
v_sync
=
printk
(
KERN_INFO
"neofb v"
NEOFB_VERSION
": %dkB VRAM, using %dx%d, %d.%03dkHz, %dHz
\n
"
,
h_sync
/
(
info
->
var
.
yres
+
info
->
var
.
upper_margin
+
info
->
fb
.
fix
.
smem_len
>>
10
,
info
->
var
.
lower_margin
+
info
->
var
.
vsync_len
);
info
->
fb
.
var
.
xres
,
info
->
fb
.
var
.
yres
,
h_sync
/
1000
,
h_sync
%
1000
,
v_sync
);
printk
(
KERN_INFO
"neofb v"
NEOFB_VERSION
": %dkB VRAM, using %dx%d, %d.%03dkHz, %dHz
\n
"
,
info
->
fix
.
smem_len
>>
10
,
info
->
var
.
xres
,
err
=
register_framebuffer
(
&
info
->
fb
);
info
->
var
.
yres
,
h_sync
/
1000
,
h_sync
%
1000
,
v_sync
);
err
=
register_framebuffer
(
info
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
failed
;
goto
failed
;
printk
(
KERN_INFO
"fb%d: %s frame buffer device
\n
"
,
printk
(
KERN_INFO
"fb%d: %s frame buffer device
\n
"
,
GET_FB_IDX
(
info
->
fb
.
node
),
info
->
fb
.
modename
);
GET_FB_IDX
(
info
->
node
),
info
->
modename
);
/*
/*
* Our driver data
* Our driver data
...
@@ -2193,33 +1866,33 @@ static int __devinit neofb_probe (struct pci_dev* dev, const struct pci_device_i
...
@@ -2193,33 +1866,33 @@ static int __devinit neofb_probe (struct pci_dev* dev, const struct pci_device_i
return
0
;
return
0
;
failed:
failed:
neo_unmap_video
(
info
);
neo_unmap_video
(
info
);
neo_unmap_mmio
(
info
);
neo_unmap_mmio
(
info
);
neo_free_fb_info
(
info
);
neo_free_fb_info
(
info
);
return
err
;
return
err
;
}
}
static
void
__devexit
neofb_remove
(
struct
pci_dev
*
dev
)
static
void
__devexit
neofb_remove
(
struct
pci_dev
*
dev
)
{
{
struct
neofb_info
*
info
=
(
struct
neofb_info
*
)
dev
->
driver_data
;
struct
fb_info
*
info
=
(
struct
fb_info
*
)
dev
->
driver_data
;
DBG
(
"neofb_remove"
);
DBG
(
"neofb_remove"
);
if
(
info
)
if
(
info
)
{
{
/*
/*
* If unregister_framebuffer fails, then
* If unregister_framebuffer fails, then
* we will be leaving hooks that could cause
* we will be leaving hooks that could cause
* oopsen laying around.
* oopsen laying around.
*/
*/
if
(
unregister_framebuffer
(
&
info
->
fb
))
if
(
unregister_framebuffer
(
info
))
printk
(
KERN_WARNING
"neofb: danger danger! Oopsen imminent!
\n
"
);
printk
(
KERN_WARNING
"neofb: danger danger! Oopsen imminent!
\n
"
);
neo_unmap_video
(
info
);
neo_unmap_video
(
info
);
neo_unmap_mmio
(
info
);
neo_unmap_mmio
(
info
);
neo_free_fb_info
(
info
);
neo_free_fb_info
(
info
);
/*
/*
* Ensure that the driver data is no longer
* Ensure that the driver data is no longer
...
@@ -2271,18 +1944,18 @@ static struct pci_driver neofb_driver = {
...
@@ -2271,18 +1944,18 @@ static struct pci_driver neofb_driver = {
/* **************************** init-time only **************************** */
/* **************************** init-time only **************************** */
static
void
__init
neo_init
(
void
)
static
void
__init
neo_init
(
void
)
{
{
DBG
(
"neo_init"
);
DBG
(
"neo_init"
);
pci_register_driver
(
&
neofb_driver
);
pci_register_driver
(
&
neofb_driver
);
}
}
/* **************************** exit-time only **************************** */
/* **************************** exit-time only **************************** */
static
void
__exit
neo_done
(
void
)
static
void
__exit
neo_done
(
void
)
{
{
DBG
(
"neo_done"
);
DBG
(
"neo_done"
);
pci_unregister_driver
(
&
neofb_driver
);
pci_unregister_driver
(
&
neofb_driver
);
}
}
...
@@ -2290,7 +1963,7 @@ static void __exit neo_done (void)
...
@@ -2290,7 +1963,7 @@ static void __exit neo_done (void)
/* ************************* init in-kernel code ************************** */
/* ************************* init in-kernel code ************************** */
int
__init
neofb_setup
(
char
*
options
)
int
__init
neofb_setup
(
char
*
options
)
{
{
char
*
this_opt
;
char
*
this_opt
;
...
@@ -2299,9 +1972,9 @@ int __init neofb_setup (char *options)
...
@@ -2299,9 +1972,9 @@ int __init neofb_setup (char *options)
if
(
!
options
||
!*
options
)
if
(
!
options
||
!*
options
)
return
0
;
return
0
;
while
((
this_opt
=
strsep
(
&
options
,
","
))
!=
NULL
)
while
((
this_opt
=
strsep
(
&
options
,
","
))
!=
NULL
)
{
{
if
(
!*
this_opt
)
if
(
!*
this_opt
)
continue
;
continue
;
if
(
!
strncmp
(
this_opt
,
"disabled"
,
8
))
if
(
!
strncmp
(
this_opt
,
"disabled"
,
8
))
disabled
=
1
;
disabled
=
1
;
...
@@ -2327,8 +2000,7 @@ int __init neofb_init(void)
...
@@ -2327,8 +2000,7 @@ int __init neofb_init(void)
if
(
disabled
)
if
(
disabled
)
return
-
ENXIO
;
return
-
ENXIO
;
if
(
!
initialized
)
if
(
!
initialized
)
{
{
initialized
=
1
;
initialized
=
1
;
neo_init
();
neo_init
();
}
}
...
...
drivers/video/neofb
.h
→
include/video/neo_reg
.h
View file @
66749d48
/*
/*
* linux/
drivers/video/neofb
.h -- NeoMagic Framebuffer Driver
* linux/
include/video/neo_reg
.h -- NeoMagic Framebuffer Driver
*
*
* Copyright (c) 2001 Denis Oliver Kropp <dok@convergence.de>
* Copyright (c) 2001 Denis Oliver Kropp <dok@convergence.de>
*
*
...
@@ -8,6 +8,54 @@
...
@@ -8,6 +8,54 @@
* archive for more details.
* archive for more details.
*/
*/
#define NEO_BS0_BLT_BUSY 0x00000001
#define NEO_BS0_FIFO_AVAIL 0x00000002
#define NEO_BS0_FIFO_PEND 0x00000004
#define NEO_BC0_DST_Y_DEC 0x00000001
#define NEO_BC0_X_DEC 0x00000002
#define NEO_BC0_SRC_TRANS 0x00000004
#define NEO_BC0_SRC_IS_FG 0x00000008
#define NEO_BC0_SRC_Y_DEC 0x00000010
#define NEO_BC0_FILL_PAT 0x00000020
#define NEO_BC0_SRC_MONO 0x00000040
#define NEO_BC0_SYS_TO_VID 0x00000080
#define NEO_BC1_DEPTH8 0x00000100
#define NEO_BC1_DEPTH16 0x00000200
#define NEO_BC1_X_320 0x00000400
#define NEO_BC1_X_640 0x00000800
#define NEO_BC1_X_800 0x00000c00
#define NEO_BC1_X_1024 0x00001000
#define NEO_BC1_X_1152 0x00001400
#define NEO_BC1_X_1280 0x00001800
#define NEO_BC1_X_1600 0x00001c00
#define NEO_BC1_DST_TRANS 0x00002000
#define NEO_BC1_MSTR_BLT 0x00004000
#define NEO_BC1_FILTER_Z 0x00008000
#define NEO_BC2_WR_TR_DST 0x00800000
#define NEO_BC3_SRC_XY_ADDR 0x01000000
#define NEO_BC3_DST_XY_ADDR 0x02000000
#define NEO_BC3_CLIP_ON 0x04000000
#define NEO_BC3_FIFO_EN 0x08000000
#define NEO_BC3_BLT_ON_ADDR 0x10000000
#define NEO_BC3_SKIP_MAPPING 0x80000000
#define NEO_MODE1_DEPTH8 0x0100
#define NEO_MODE1_DEPTH16 0x0200
#define NEO_MODE1_DEPTH24 0x0300
#define NEO_MODE1_X_320 0x0400
#define NEO_MODE1_X_640 0x0800
#define NEO_MODE1_X_800 0x0c00
#define NEO_MODE1_X_1024 0x1000
#define NEO_MODE1_X_1152 0x1400
#define NEO_MODE1_X_1280 0x1800
#define NEO_MODE1_X_1600 0x1c00
#define NEO_MODE1_BLT_ON_ADDR 0x2000
#ifdef __KERNEL__
#ifdef NEOFB_DEBUG
#ifdef NEOFB_DEBUG
# define DBG(x) printk (KERN_DEBUG "neofb: %s\n", (x));
# define DBG(x) printk (KERN_DEBUG "neofb: %s\n", (x));
...
@@ -15,7 +63,6 @@
...
@@ -15,7 +63,6 @@
# define DBG(x)
# define DBG(x)
#endif
#endif
#define PCI_CHIP_NM2070 0x0001
#define PCI_CHIP_NM2070 0x0001
#define PCI_CHIP_NM2090 0x0002
#define PCI_CHIP_NM2090 0x0002
#define PCI_CHIP_NM2093 0x0003
#define PCI_CHIP_NM2093 0x0003
...
@@ -78,8 +125,6 @@ typedef volatile struct {
...
@@ -78,8 +125,6 @@ typedef volatile struct {
struct
neofb_par
{
struct
neofb_par
{
int
depth
;
unsigned
char
MiscOutReg
;
/* Misc */
unsigned
char
MiscOutReg
;
/* Misc */
unsigned
char
CRTC
[
25
];
/* Crtc Controller */
unsigned
char
CRTC
[
25
];
/* Crtc Controller */
unsigned
char
Sequencer
[
5
];
/* Video Sequencer */
unsigned
char
Sequencer
[
5
];
/* Video Sequencer */
...
@@ -113,31 +158,11 @@ struct neofb_par {
...
@@ -113,31 +158,11 @@ struct neofb_par {
unsigned
char
VCLK3NumeratorHigh
;
unsigned
char
VCLK3NumeratorHigh
;
unsigned
char
VCLK3Denominator
;
unsigned
char
VCLK3Denominator
;
unsigned
char
VerticalExt
;
unsigned
char
VerticalExt
;
};
struct
neofb_info
{
struct
fb_info
fb
;
struct
display_switch
*
dispsw
;
struct
pci_dev
*
pcidev
;
int
accel
;
char
*
name
;
struct
{
u8
*
vbase
;
u32
pbase
;
u32
len
;
#ifdef CONFIG_MTRR
#ifdef CONFIG_MTRR
int
mtrr
;
int
mtrr
;
#endif
#endif
}
video
;
u8
*
mmio_vbase
;
struct
{
u8
*
vbase
;
u32
pbase
;
u32
len
;
}
mmio
;
Neo2200
*
neo2200
;
Neo2200
*
neo2200
;
...
@@ -151,20 +176,14 @@ struct neofb_info {
...
@@ -151,20 +176,14 @@ struct neofb_info {
int
lcd_stretch
;
int
lcd_stretch
;
int
internal_display
;
int
internal_display
;
int
external_display
;
int
external_display
;
struct
{
u16
red
,
green
,
blue
,
transp
;
}
palette
[
NR_PALETTE
];
};
};
typedef
struct
{
typedef
struct
{
int
x_res
;
int
x_res
;
int
y_res
;
int
y_res
;
int
mode
;
int
mode
;
}
biosMode
;
}
biosMode
;
/* vga IO functions */
/* vga IO functions */
static
inline
u8
VGArCR
(
u8
index
)
static
inline
u8
VGArCR
(
u8
index
)
{
{
...
@@ -241,51 +260,5 @@ static inline void VGAwMISC (u8 value)
...
@@ -241,51 +260,5 @@ static inline void VGAwMISC (u8 value)
{
{
outb
(
value
,
0x3c2
);
outb
(
value
,
0x3c2
);
}
}
#endif
#define NEO_BS0_BLT_BUSY 0x00000001
#define NEO_BS0_FIFO_AVAIL 0x00000002
#define NEO_BS0_FIFO_PEND 0x00000004
#define NEO_BC0_DST_Y_DEC 0x00000001
#define NEO_BC0_X_DEC 0x00000002
#define NEO_BC0_SRC_TRANS 0x00000004
#define NEO_BC0_SRC_IS_FG 0x00000008
#define NEO_BC0_SRC_Y_DEC 0x00000010
#define NEO_BC0_FILL_PAT 0x00000020
#define NEO_BC0_SRC_MONO 0x00000040
#define NEO_BC0_SYS_TO_VID 0x00000080
#define NEO_BC1_DEPTH8 0x00000100
#define NEO_BC1_DEPTH16 0x00000200
#define NEO_BC1_X_320 0x00000400
#define NEO_BC1_X_640 0x00000800
#define NEO_BC1_X_800 0x00000c00
#define NEO_BC1_X_1024 0x00001000
#define NEO_BC1_X_1152 0x00001400
#define NEO_BC1_X_1280 0x00001800
#define NEO_BC1_X_1600 0x00001c00
#define NEO_BC1_DST_TRANS 0x00002000
#define NEO_BC1_MSTR_BLT 0x00004000
#define NEO_BC1_FILTER_Z 0x00008000
#define NEO_BC2_WR_TR_DST 0x00800000
#define NEO_BC3_SRC_XY_ADDR 0x01000000
#define NEO_BC3_DST_XY_ADDR 0x02000000
#define NEO_BC3_CLIP_ON 0x04000000
#define NEO_BC3_FIFO_EN 0x08000000
#define NEO_BC3_BLT_ON_ADDR 0x10000000
#define NEO_BC3_SKIP_MAPPING 0x80000000
#define NEO_MODE1_DEPTH8 0x0100
#define NEO_MODE1_DEPTH16 0x0200
#define NEO_MODE1_DEPTH24 0x0300
#define NEO_MODE1_X_320 0x0400
#define NEO_MODE1_X_640 0x0800
#define NEO_MODE1_X_800 0x0c00
#define NEO_MODE1_X_1024 0x1000
#define NEO_MODE1_X_1152 0x1400
#define NEO_MODE1_X_1280 0x1800
#define NEO_MODE1_X_1600 0x1c00
#define NEO_MODE1_BLT_ON_ADDR 0x2000
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