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
87520e1e
Commit
87520e1e
authored
Jul 12, 2002
by
James Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Porting Mach 64 drive over to new api.
parent
4ec16d90
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
3321 additions
and
3098 deletions
+3321
-3098
drivers/video/Config.in
drivers/video/Config.in
+15
-16
drivers/video/Makefile
drivers/video/Makefile
+1
-1
drivers/video/aty/Makefile
drivers/video/aty/Makefile
+1
-1
drivers/video/aty/atyfb.h
drivers/video/aty/atyfb.h
+134
-147
drivers/video/aty/atyfb_base.c
drivers/video/aty/atyfb_base.c
+1995
-1813
drivers/video/aty/mach64_accel.c
drivers/video/aty/mach64_accel.c
+246
-234
drivers/video/aty/mach64_ct.c
drivers/video/aty/mach64_ct.c
+193
-184
drivers/video/aty/mach64_cursor.c
drivers/video/aty/mach64_cursor.c
+107
-100
drivers/video/aty/mach64_gx.c
drivers/video/aty/mach64_gx.c
+629
-602
No files found.
drivers/video/Config.in
View file @
87520e1e
...
...
@@ -254,7 +254,7 @@ if [ "$CONFIG_FB" = "y" ]; then
fi
fi
if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \
"$CONFIG_FB_
ATY
" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
"$CONFIG_FB_
P9100
" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
"$CONFIG_FB_RADEON" = "y" -o "$CONFIG_FB_TGA" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_PM3" = "y" -o \
"$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \
...
...
@@ -264,11 +264,11 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
"$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
"$CONFIG_FB_
P9100
" = "y" ]; then
"$CONFIG_FB_
ATY
" = "y" ]; then
define_tristate CONFIG_FBCON_CFB8 y
else
if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
"$CONFIG_FB_
ATY
" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \
"$CONFIG_FB_
P9100
" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \
"$CONFIG_FB_RADEON" = "m" -o "$CONFIG_FB_TGA" = "m" -o \
"$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_PM3" = "m" -o \
"$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \
...
...
@@ -277,12 +277,11 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
"$CONFIG_FB_P9100" = "m" ]; then
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" ]; then
define_tristate CONFIG_FBCON_CFB8 m
fi
fi
if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_
ATY
" = "y" -o \
if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_
PM3
" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \
"$CONFIG_FB_TRIDENT" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \
"$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
...
...
@@ -291,10 +290,10 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
"$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
"$CONFIG_FB_
PM3" = "y" ]; then
"$CONFIG_FB_
ATY" = "y" ]; then
define_tristate CONFIG_FBCON_CFB16 y
else
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_
ATY
" = "m" -o \
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_
SIS
" = "m" -o \
"$CONFIG_FB_RADEON" = "m" -o "$CONFIG_FB_PVR2" = "m" -o \
"$CONFIG_FB_TRIDENT" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \
"$CONFIG_FB_VOODOO1" = "m" -o "$CONFIG_FB_PM3" = "m" -o \
...
...
@@ -302,8 +301,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
"$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \
"$CONFIG_FB_SIS" = "m" ]; then
"$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_CYBER2000" = "m" ]; then
define_tristate CONFIG_FBCON_CFB16 m
fi
fi
...
...
@@ -324,22 +322,22 @@ if [ "$CONFIG_FB" = "y" ]; then
define_tristate CONFIG_FBCON_CFB24 m
fi
fi
if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_
ATY
" = "y" -o \
if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_
RADEON
" = "y" -o \
"$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_TRIDENT" = "y" -o \
"$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
"$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
"$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_PM3" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_
RADEON
" = "y" ]; then
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_
ATY
" = "y" ]; then
define_tristate CONFIG_FBCON_CFB32 y
else
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_
ATY
" = "m" -o \
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_
RADEON
" = "m" -o \
"$CONFIG_FB_VOODOO1" = "m" -o "$CONFIG_FB_TRIDENT" = "m" -o \
"$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
"$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
"$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_PVR2" = "m" -o \
"$CONFIG_FB_PM3" = "m"
-o "$CONFIG_FB_RADEON" = "m"
]; then
"$CONFIG_FB_PM3" = "m" ]; then
define_tristate CONFIG_FBCON_CFB32 m
fi
fi
...
...
@@ -353,14 +351,15 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_APOLLO" = "y" -o \
"$CONFIG_FB_ATY128" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
"$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \
"$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_SGIVW" = "y" ]; then
"$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
"$CONFIG_FB_ATY" = "y" ]; then
define_tristate CONFIG_FBCON_ACCEL y
else
if [ "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_HIT" = "m" -o \
"$CONFIG_FB_G364" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
"$CONFIG_FB_CLPS711X" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
"$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
"$CONFIG_FB_SGIVW" = "m" ]; then
"$CONFIG_FB_SGIVW" = "m"
-o "$CONFIG_FB_ATY" = "m"
]; then
define_tristate CONFIG_FBCON_ACCEL m
fi
fi
...
...
drivers/video/Makefile
View file @
87520e1e
...
...
@@ -44,7 +44,7 @@ obj-$(CONFIG_FB_PM3) += pm3fb.o
obj-$(CONFIG_FB_APOLLO)
+=
dnfb.o cfbfillrect.o cfbimgblt.o
obj-$(CONFIG_FB_Q40)
+=
q40fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_ATARI)
+=
atafb.o
obj-$(CONFIG_FB_ATY128)
+=
aty128fb.o
cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_ATY128)
+=
aty128fb.o
obj-$(CONFIG_FB_RADEON)
+=
radeonfb.o
obj-$(CONFIG_FB_NEOMAGIC)
+=
neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_IGA)
+=
igafb.o
...
...
drivers/video/aty/Makefile
View file @
87520e1e
...
...
@@ -3,7 +3,7 @@ export-objs := atyfb_base.o mach64_accel.o
obj-$(CONFIG_FB_ATY)
+=
atyfb.o
atyfb-y
:=
atyfb_base.o mach64_accel.o
atyfb-y
:=
atyfb_base.o mach64_accel.o
../cfbimgblt.o
atyfb-$(CONFIG_FB_ATY_GX)
+=
mach64_gx.o
atyfb-$(CONFIG_FB_ATY_CT)
+=
mach64_ct.o mach64_cursor.o
atyfb-objs
:=
$
(
atyfb-y
)
...
...
drivers/video/aty/atyfb.h
View file @
87520e1e
...
...
@@ -30,8 +30,7 @@ struct pll_514 {
u8
n
;
};
struct
pll_18818
{
struct
pll_18818
{
u32
program_bits
;
u32
locationAddr
;
u32
period_in_ps
;
...
...
@@ -58,17 +57,10 @@ union aty_pll {
struct
pll_18818
ics2595
;
};
/*
* The hardware parameters for each card
*/
struct
atyfb_par
{
struct
crtc
crtc
;
union
aty_pll
pll
;
u32
accel_flags
;
};
struct
aty_cursor
{
int
enable
;
int
on
;
...
...
@@ -85,16 +77,15 @@ struct aty_cursor {
struct
timer_list
*
timer
;
};
struct
fb_info_aty
{
struct
fb_info
fb_info
;
struct
fb_info_aty
*
next
;
struct
atyfb_par
{
struct
aty_cmap_regs
*
aty_cmap_regs
;
const
struct
aty_dac_ops
*
dac_ops
;
const
struct
aty_pll_ops
*
pll_ops
;
struct
aty_cursor
*
cursor
;
unsigned
long
ati_regbase
;
unsigned
long
clk_wr_offset
;
struct
pci_mmap_map
*
mmap_map
;
struct
aty_cursor
*
cursor
;
struct
aty_cmap_regs
*
aty_cmap_regs
;
struct
atyfb_par
default_par
;
struct
atyfb_par
current_par
;
struct
crtc
crtc
;
union
aty_pll
pll
;
u32
features
;
u32
ref_clk_per
;
u32
pll_per
;
...
...
@@ -102,15 +93,14 @@ struct fb_info_aty {
u8
bus_type
;
u8
ram_type
;
u8
mem_refresh_rate
;
const
struct
aty_dac_ops
*
dac_ops
;
const
struct
aty_pll_ops
*
pll_ops
;
struct
display_switch
dispsw
;
u8
blitter_may_be_busy
;
u32
accel_flags
;
#ifdef __sparc__
struct
pci_mmap_map
*
mmap_map
;
int
consolecnt
;
int
vtconsole
;
u8
mmaped
;
int
open
;
int
vtconsole
;
int
consolecnt
;
#endif
#ifdef CONFIG_PMAC_PBOOK
unsigned
char
*
save_framebuffer
;
...
...
@@ -118,12 +108,11 @@ struct fb_info_aty {
#endif
};
/*
* ATI Mach64 features
*/
#define M64_HAS(feature) ((
info
)->features & (M64F_##feature))
#define M64_HAS(feature) ((
par
)->features & (M64F_##feature))
#define M64F_RESET_3D 0x00000001
#define M64F_MAGIC_FIFO 0x00000002
...
...
@@ -151,62 +140,62 @@ struct fb_info_aty {
* Register access
*/
static
inline
u32
aty_ld_le32
(
int
regindex
,
const
struct
fb_info_aty
*
info
)
static
inline
u32
aty_ld_le32
(
int
regindex
,
const
struct
atyfb_par
*
par
)
{
/* Hack for bloc 1, should be cleanly optimized by compiler */
if
(
regindex
>=
0x400
)
regindex
-=
0x800
;
#if defined(__mc68000__)
return
le32_to_cpu
(
*
((
volatile
u32
*
)(
info
->
ati_regbase
+
regindex
)));
return
le32_to_cpu
(
*
((
volatile
u32
*
)
(
par
->
ati_regbase
+
regindex
)));
#else
return
readl
(
info
->
ati_regbase
+
regindex
);
return
readl
(
par
->
ati_regbase
+
regindex
);
#endif
}
static
inline
void
aty_st_le32
(
int
regindex
,
u32
val
,
const
struct
fb_info_aty
*
info
)
const
struct
atyfb_par
*
par
)
{
/* Hack for bloc 1, should be cleanly optimized by compiler */
if
(
regindex
>=
0x400
)
regindex
-=
0x800
;
#if defined(__mc68000__)
*
((
volatile
u32
*
)(
info
->
ati_regbase
+
regindex
))
=
cpu_to_le32
(
val
);
*
((
volatile
u32
*
)
(
par
->
ati_regbase
+
regindex
))
=
cpu_to_le32
(
val
);
#else
writel
(
val
,
info
->
ati_regbase
+
regindex
);
writel
(
val
,
par
->
ati_regbase
+
regindex
);
#endif
}
static
inline
u8
aty_ld_8
(
int
regindex
,
const
struct
fb_info_aty
*
info
)
static
inline
u8
aty_ld_8
(
int
regindex
,
const
struct
atyfb_par
*
par
)
{
/* Hack for bloc 1, should be cleanly optimized by compiler */
if
(
regindex
>=
0x400
)
regindex
-=
0x800
;
return
readb
(
info
->
ati_regbase
+
regindex
);
return
readb
(
par
->
ati_regbase
+
regindex
);
}
static
inline
void
aty_st_8
(
int
regindex
,
u8
val
,
const
struct
fb_info_aty
*
info
)
const
struct
atyfb_par
*
par
)
{
/* Hack for bloc 1, should be cleanly optimized by compiler */
if
(
regindex
>=
0x400
)
regindex
-=
0x800
;
writeb
(
val
,
info
->
ati_regbase
+
regindex
);
writeb
(
val
,
par
->
ati_regbase
+
regindex
);
}
static
inline
u8
aty_ld_pll
(
int
offset
,
const
struct
fb_info_aty
*
info
)
static
inline
u8
aty_ld_pll
(
int
offset
,
const
struct
atyfb_par
*
par
)
{
u8
res
;
/* write addr byte */
aty_st_8
(
CLOCK_CNTL
+
1
,
(
offset
<<
2
),
info
);
aty_st_8
(
CLOCK_CNTL
+
1
,
(
offset
<<
2
),
par
);
/* read the register value */
res
=
aty_ld_8
(
CLOCK_CNTL
+
2
,
info
);
res
=
aty_ld_8
(
CLOCK_CNTL
+
2
,
par
);
return
res
;
}
...
...
@@ -216,8 +205,8 @@ static inline u8 aty_ld_pll(int offset, const struct fb_info_aty *info)
*/
struct
aty_dac_ops
{
int
(
*
set_dac
)(
const
struct
fb_info_aty
*
info
,
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
);
int
(
*
set_dac
)
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
);
};
extern
const
struct
aty_dac_ops
aty_dac_ibm514
;
/* IBM RGB514 */
...
...
@@ -232,11 +221,12 @@ extern const struct aty_dac_ops aty_dac_ct; /* Integrated */
*/
struct
aty_pll_ops
{
int
(
*
var_to_pll
)(
const
struct
fb_info_aty
*
info
,
u32
vclk_per
,
u8
bpp
,
union
aty_pll
*
pll
);
u32
(
*
pll_to_var
)(
const
struct
fb_info_aty
*
info
,
const
union
aty_pll
*
pll
);
void
(
*
set_pll
)(
const
struct
fb_info_aty
*
info
,
const
union
aty_pll
*
pll
);
int
(
*
var_to_pll
)
(
const
struct
fb_info
*
info
,
u32
vclk_per
,
u8
bpp
,
union
aty_pll
*
pll
);
u32
(
*
pll_to_var
)
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
);
void
(
*
set_pll
)
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
);
};
extern
const
struct
aty_pll_ops
aty_pll_ati18818_1
;
/* ATI 18818 */
...
...
@@ -248,9 +238,9 @@ extern const struct aty_pll_ops aty_pll_unsupported; /* unsupported */
extern
const
struct
aty_pll_ops
aty_pll_ct
;
/* Integrated */
extern
void
aty_set_pll_ct
(
const
struct
fb_info
_aty
*
info
,
extern
void
aty_set_pll_ct
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
);
extern
void
aty_calc_pll_ct
(
const
struct
fb_info
_aty
*
info
,
extern
void
aty_calc_pll_ct
(
const
struct
fb_info
*
info
,
struct
pll_ct
*
pll
);
...
...
@@ -258,10 +248,10 @@ extern void aty_calc_pll_ct(const struct fb_info_aty *info,
* Hardware cursor support
*/
extern
struct
aty_cursor
*
aty_init_cursor
(
struct
fb_info
_aty
*
fb
);
extern
struct
aty_cursor
*
aty_init_cursor
(
struct
fb_info
*
info
);
extern
void
atyfb_cursor
(
struct
display
*
p
,
int
mode
,
int
x
,
int
y
);
extern
void
aty_set_cursor_color
(
struct
fb_info
_aty
*
fb
);
extern
void
aty_set_cursor_shape
(
struct
fb_info
_aty
*
fb
);
extern
void
aty_set_cursor_color
(
struct
fb_info
*
info
);
extern
void
aty_set_cursor_shape
(
struct
fb_info
*
info
);
extern
int
atyfb_set_font
(
struct
display
*
d
,
int
width
,
int
height
);
...
...
@@ -269,25 +259,23 @@ extern int atyfb_set_font(struct display *d, int width, int height);
* Hardware acceleration
*/
static
inline
void
wait_for_fifo
(
u16
entries
,
const
struct
fb_info_aty
*
info
)
static
inline
void
wait_for_fifo
(
u16
entries
,
const
struct
atyfb_par
*
par
)
{
while
((
aty_ld_le32
(
FIFO_STAT
,
info
)
&
0xffff
)
>
((
u32
)
(
0x8000
>>
entries
)));
while
((
aty_ld_le32
(
FIFO_STAT
,
par
)
&
0xffff
)
>
((
u32
)
(
0x8000
>>
entries
)));
}
static
inline
void
wait_for_idle
(
struct
fb_info_aty
*
info
)
static
inline
void
wait_for_idle
(
struct
atyfb_par
*
par
)
{
wait_for_fifo
(
16
,
info
);
while
((
aty_ld_le32
(
GUI_STAT
,
info
)
&
1
)
!=
0
);
info
->
blitter_may_be_busy
=
0
;
wait_for_fifo
(
16
,
par
);
while
((
aty_ld_le32
(
GUI_STAT
,
par
)
&
1
)
!=
0
);
par
->
blitter_may_be_busy
=
0
;
}
extern
void
aty_reset_engine
(
const
struct
fb_info_aty
*
info
);
extern
void
aty_init_engine
(
const
struct
atyfb_par
*
par
,
struct
fb_info_aty
*
info
);
extern
void
aty_rectfill
(
int
dstx
,
int
dsty
,
u_int
width
,
u_int
height
,
u_int
color
,
struct
fb_info_aty
*
info
);
extern
void
aty_reset_engine
(
const
struct
atyfb_par
*
par
);
extern
void
aty_init_engine
(
struct
atyfb_par
*
par
,
struct
fb_info
*
info
);
extern
void
atyfb_fillrect
(
struct
fb_info
*
info
,
struct
fb_fillrect
*
rect
);
/*
* Text console acceleration
...
...
@@ -297,4 +285,3 @@ extern const struct display_switch fbcon_aty8;
extern
const
struct
display_switch
fbcon_aty16
;
extern
const
struct
display_switch
fbcon_aty24
;
extern
const
struct
display_switch
fbcon_aty32
;
drivers/video/aty/atyfb_base.c
View file @
87520e1e
...
...
@@ -137,10 +137,8 @@ static struct fb_fix_screeninfo atyfb_fix __initdata = {
id:
"ATY Mach64"
,
type:
FB_TYPE_PACKED_PIXELS
,
visual:
FB_VISUAL_PSEUDOCOLOR
,
xpanstep:
1
,
xpanstep:
8
,
ypanstep:
1
,
ywrapstep:
1
,
accel:
FB_ACCEL_NONE
,
};
/*
...
...
@@ -150,16 +148,16 @@ static struct fb_fix_screeninfo atyfb_fix __initdata = {
static
int
atyfb_open
(
struct
fb_info
*
info
,
int
user
);
static
int
atyfb_release
(
struct
fb_info
*
info
,
int
user
);
static
int
atyfb_get_fix
(
struct
fb_fix_screeninfo
*
fix
,
int
con
,
struct
fb_info
*
fb
);
struct
fb_info
*
info
);
static
int
atyfb_get_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
fb
);
struct
fb_info
*
info
);
static
int
atyfb_set_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
fb
);
struct
fb_info
*
info
);
static
int
atyfb_setcolreg
(
u_int
regno
,
u_int
red
,
u_int
green
,
u_int
blue
,
u_int
transp
,
struct
fb_info
*
fb
);
u_int
transp
,
struct
fb_info
*
info
);
static
int
atyfb_pan_display
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
fb
);
static
int
atyfb_blank
(
int
blank
,
struct
fb_info
*
fb
);
struct
fb_info
*
info
);
static
int
atyfb_blank
(
int
blank
,
struct
fb_info
*
info
);
static
int
atyfb_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
u_int
cmd
,
u_long
arg
,
int
con
,
struct
fb_info
*
info
);
#ifdef __sparc__
...
...
@@ -173,42 +171,42 @@ static int atyfb_rasterimg(struct fb_info *info, int start);
* Interface to the low level console driver
*/
static
int
atyfbcon_updatevar
(
int
con
,
struct
fb_info
*
fb
);
static
int
atyfbcon_updatevar
(
int
con
,
struct
fb_info
*
info
);
/*
* Internal routines
*/
static
int
aty_init
(
struct
fb_info
_aty
*
info
,
const
char
*
name
);
static
int
aty_init
(
struct
fb_info
*
info
,
const
char
*
name
);
#ifdef CONFIG_ATARI
static
int
store_video_par
(
char
*
videopar
,
unsigned
char
m64_num
);
#endif
static
void
aty_set_crtc
(
const
struct
fb_info_aty
*
info
,
static
void
aty_set_crtc
(
const
struct
atyfb_par
*
par
,
const
struct
crtc
*
crtc
);
static
int
aty_var_to_crtc
(
const
struct
fb_info
_aty
*
info
,
static
int
aty_var_to_crtc
(
const
struct
fb_info
*
info
,
const
struct
fb_var_screeninfo
*
var
,
struct
crtc
*
crtc
);
static
int
aty_crtc_to_var
(
const
struct
crtc
*
crtc
,
struct
fb_var_screeninfo
*
var
);
static
void
atyfb_set_par
(
const
struct
atyfb_par
*
par
,
struct
fb_info
_aty
*
info
);
static
void
atyfb_set_par
(
struct
atyfb_par
*
par
,
struct
fb_info
*
info
);
static
int
atyfb_decode_var
(
const
struct
fb_var_screeninfo
*
var
,
struct
atyfb_par
*
par
,
const
struct
fb_info
_aty
*
info
);
const
struct
fb_info
*
info
);
static
int
atyfb_encode_var
(
struct
fb_var_screeninfo
*
var
,
const
struct
atyfb_par
*
par
,
const
struct
fb_info
_aty
*
info
);
const
struct
fb_info
*
info
);
static
void
set_off_pitch
(
struct
atyfb_par
*
par
,
const
struct
fb_info
_aty
*
info
);
const
struct
fb_info
*
info
);
static
int
encode_fix
(
struct
fb_fix_screeninfo
*
fix
,
const
struct
atyfb_par
*
par
,
const
struct
fb_info
_aty
*
info
);
static
void
atyfb_set_dispsw
(
struct
display
*
disp
,
struct
fb_info_aty
*
info
,
int
bpp
,
int
accel
);
const
struct
fb_info
*
info
);
static
void
atyfb_set_dispsw
(
struct
display
*
disp
,
struct
fb_info
*
info
);
#ifdef CONFIG_PPC
static
int
read_aty_sense
(
const
struct
fb_info
_aty
*
info
);
static
int
read_aty_sense
(
const
struct
fb_info
*
info
);
#endif
...
...
@@ -218,26 +216,26 @@ static int read_aty_sense(const struct fb_info_aty *info);
int
atyfb_init
(
void
);
#ifndef MODULE
int
atyfb_setup
(
char
*
);
int
atyfb_setup
(
char
*
);
#endif
static
struct
fb_ops
atyfb_ops
=
{
owner:
THIS_MODULE
,
fb_open:
atyfb_open
,
fb_release:
atyfb_release
,
fb_get_fix:
atyfb_get_fix
,
fb_get_var:
atyfb_get_var
,
fb_set_var:
atyfb_set_var
,
fb_get_cmap:
gen_get_cmap
,
fb_set_cmap:
gen_set_cmap
,
fb_setcolreg:
atyfb_setcolreg
,
fb_pan_display:
atyfb_pan_display
,
fb_blank:
atyfb_blank
,
fb_ioctl:
atyfb_ioctl
,
owner:
THIS_MODULE
,
fb_open:
atyfb_open
,
fb_release:
atyfb_release
,
fb_get_fix:
atyfb_get_fix
,
fb_get_var:
atyfb_get_var
,
fb_set_var:
atyfb_set_var
,
fb_get_cmap:
gen_get_cmap
,
fb_set_cmap:
gen_set_cmap
,
fb_setcolreg:
atyfb_setcolreg
,
fb_pan_display:
atyfb_pan_display
,
fb_blank:
atyfb_blank
,
fb_ioctl:
atyfb_ioctl
,
#ifdef __sparc__
fb_mmap:
atyfb_mmap
,
fb_mmap:
atyfb_mmap
,
#endif
fb_rasterimg:
atyfb_rasterimg
,
fb_rasterimg:
atyfb_rasterimg
,
};
static
char
atyfb_name
[
16
]
=
"ATY Mach64"
;
...
...
@@ -287,7 +285,8 @@ static char m64n_gtc_ba[] __initdata = "3D RAGE PRO (BGA, AGP)";
static
char
m64n_gtc_ba1
[]
__initdata
=
"3D RAGE PRO (BGA, AGP, 1x only)"
;
static
char
m64n_gtc_bp
[]
__initdata
=
"3D RAGE PRO (BGA, PCI)"
;
static
char
m64n_gtc_pp
[]
__initdata
=
"3D RAGE PRO (PQFP, PCI)"
;
static
char
m64n_gtc_ppl
[]
__initdata
=
"3D RAGE PRO (PQFP, PCI, limited 3D)"
;
static
char
m64n_gtc_ppl
[]
__initdata
=
"3D RAGE PRO (PQFP, PCI, limited 3D)"
;
static
char
m64n_xl
[]
__initdata
=
"3D RAGE (XL)"
;
static
char
m64n_ltp_a
[]
__initdata
=
"3D RAGE LT PRO (AGP)"
;
static
char
m64n_ltp_p
[]
__initdata
=
"3D RAGE LT PRO (PCI)"
;
...
...
@@ -304,54 +303,123 @@ static struct {
}
aty_chips
[]
__initdata
=
{
#ifdef CONFIG_FB_ATY_GX
/* Mach64 GX */
{
0x4758
,
0x00d7
,
0x00
,
0x00
,
m64n_gx
,
135
,
50
,
M64F_GX
},
{
0x4358
,
0x0057
,
0x00
,
0x00
,
m64n_cx
,
135
,
50
,
M64F_GX
},
{
0x4758
,
0x00d7
,
0x00
,
0x00
,
m64n_gx
,
135
,
50
,
M64F_GX
},
{
0x4358
,
0x0057
,
0x00
,
0x00
,
m64n_cx
,
135
,
50
,
M64F_GX
},
#endif
/* CONFIG_FB_ATY_GX */
#ifdef CONFIG_FB_ATY_CT
/* Mach64 CT */
{
0x4354
,
0x4354
,
0x00
,
0x00
,
m64n_ct
,
135
,
60
,
M64F_CT
|
M64F_INTEGRATED
|
M64F_CT_BUS
|
M64F_MAGIC_FIFO
},
{
0x4554
,
0x4554
,
0x00
,
0x00
,
m64n_et
,
135
,
60
,
M64F_CT
|
M64F_INTEGRATED
|
M64F_CT_BUS
|
M64F_MAGIC_FIFO
},
{
0x4354
,
0x4354
,
0x00
,
0x00
,
m64n_ct
,
135
,
60
,
M64F_CT
|
M64F_INTEGRATED
|
M64F_CT_BUS
|
M64F_MAGIC_FIFO
},
{
0x4554
,
0x4554
,
0x00
,
0x00
,
m64n_et
,
135
,
60
,
M64F_CT
|
M64F_INTEGRATED
|
M64F_CT_BUS
|
M64F_MAGIC_FIFO
},
/* Mach64 VT */
{
0x5654
,
0x5654
,
0xc7
,
0x00
,
m64n_vta3
,
170
,
67
,
M64F_VT
|
M64F_INTEGRATED
|
M64F_VT_BUS
|
M64F_MAGIC_FIFO
|
M64F_FIFO_24
},
{
0x5654
,
0x5654
,
0xc7
,
0x40
,
m64n_vta4
,
200
,
67
,
M64F_VT
|
M64F_INTEGRATED
|
M64F_VT_BUS
|
M64F_MAGIC_FIFO
|
M64F_FIFO_24
|
M64F_MAGIC_POSTDIV
},
{
0x5654
,
0x5654
,
0x00
,
0x00
,
m64n_vtb
,
200
,
67
,
M64F_VT
|
M64F_INTEGRATED
|
M64F_VT_BUS
|
M64F_GTB_DSP
|
M64F_FIFO_24
},
{
0x5655
,
0x5655
,
0x00
,
0x00
,
m64n_vtb
,
200
,
67
,
M64F_VT
|
M64F_INTEGRATED
|
M64F_VT_BUS
|
M64F_GTB_DSP
|
M64F_FIFO_24
|
M64F_SDRAM_MAGIC_PLL
},
{
0x5656
,
0x5656
,
0x00
,
0x00
,
m64n_vt4
,
230
,
83
,
M64F_VT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
},
{
0x5654
,
0x5654
,
0xc7
,
0x00
,
m64n_vta3
,
170
,
67
,
M64F_VT
|
M64F_INTEGRATED
|
M64F_VT_BUS
|
M64F_MAGIC_FIFO
|
M64F_FIFO_24
},
{
0x5654
,
0x5654
,
0xc7
,
0x40
,
m64n_vta4
,
200
,
67
,
M64F_VT
|
M64F_INTEGRATED
|
M64F_VT_BUS
|
M64F_MAGIC_FIFO
|
M64F_FIFO_24
|
M64F_MAGIC_POSTDIV
},
{
0x5654
,
0x5654
,
0x00
,
0x00
,
m64n_vtb
,
200
,
67
,
M64F_VT
|
M64F_INTEGRATED
|
M64F_VT_BUS
|
M64F_GTB_DSP
|
M64F_FIFO_24
},
{
0x5655
,
0x5655
,
0x00
,
0x00
,
m64n_vtb
,
200
,
67
,
M64F_VT
|
M64F_INTEGRATED
|
M64F_VT_BUS
|
M64F_GTB_DSP
|
M64F_FIFO_24
|
M64F_SDRAM_MAGIC_PLL
},
{
0x5656
,
0x5656
,
0x00
,
0x00
,
m64n_vt4
,
230
,
83
,
M64F_VT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
},
/* Mach64 GT (3D RAGE) */
{
0x4754
,
0x4754
,
0x07
,
0x00
,
m64n_gt
,
135
,
63
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_MAGIC_FIFO
|
M64F_FIFO_24
|
M64F_EXTRA_BRIGHT
},
{
0x4754
,
0x4754
,
0x07
,
0x01
,
m64n_gt
,
170
,
67
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
|
M64F_FIFO_24
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4754
,
0x4754
,
0x07
,
0x02
,
m64n_gt
,
200
,
67
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
|
M64F_FIFO_24
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4755
,
0x4755
,
0x00
,
0x00
,
m64n_gtb
,
200
,
67
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
|
M64F_FIFO_24
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4756
,
0x4756
,
0x00
,
0x00
,
m64n_iic_p
,
230
,
83
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
|
M64F_FIFO_24
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4757
,
0x4757
,
0x00
,
0x00
,
m64n_iic_a
,
230
,
83
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
|
M64F_FIFO_24
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x475a
,
0x475a
,
0x00
,
0x00
,
m64n_iic_a
,
230
,
83
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
|
M64F_FIFO_24
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4754
,
0x4754
,
0x07
,
0x00
,
m64n_gt
,
135
,
63
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_MAGIC_FIFO
|
M64F_FIFO_24
|
M64F_EXTRA_BRIGHT
},
{
0x4754
,
0x4754
,
0x07
,
0x01
,
m64n_gt
,
170
,
67
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
|
M64F_FIFO_24
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4754
,
0x4754
,
0x07
,
0x02
,
m64n_gt
,
200
,
67
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
|
M64F_FIFO_24
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4755
,
0x4755
,
0x00
,
0x00
,
m64n_gtb
,
200
,
67
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
|
M64F_FIFO_24
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4756
,
0x4756
,
0x00
,
0x00
,
m64n_iic_p
,
230
,
83
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
|
M64F_FIFO_24
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4757
,
0x4757
,
0x00
,
0x00
,
m64n_iic_a
,
230
,
83
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
|
M64F_FIFO_24
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x475a
,
0x475a
,
0x00
,
0x00
,
m64n_iic_a
,
230
,
83
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
|
M64F_FIFO_24
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
/* Mach64 LT */
{
0x4c54
,
0x4c54
,
0x00
,
0x00
,
m64n_lt
,
135
,
63
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
},
{
0x4c47
,
0x4c47
,
0x00
,
0x00
,
m64n_ltg
,
230
,
63
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
|
M64F_LT_SLEEP
|
M64F_G3_PB_1024x768
},
{
0x4c54
,
0x4c54
,
0x00
,
0x00
,
m64n_lt
,
135
,
63
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
},
{
0x4c47
,
0x4c47
,
0x00
,
0x00
,
m64n_ltg
,
230
,
63
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_GTB_DSP
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
|
M64F_LT_SLEEP
|
M64F_G3_PB_1024x768
},
/* Mach64 GTC (3D RAGE PRO) */
{
0x4742
,
0x4742
,
0x00
,
0x00
,
m64n_gtc_ba
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4744
,
0x4744
,
0x00
,
0x00
,
m64n_gtc_ba1
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4749
,
0x4749
,
0x00
,
0x00
,
m64n_gtc_bp
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
|
M64F_MAGIC_VRAM_SIZE
},
{
0x4750
,
0x4750
,
0x00
,
0x00
,
m64n_gtc_pp
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4751
,
0x4751
,
0x00
,
0x00
,
m64n_gtc_ppl
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4742
,
0x4742
,
0x00
,
0x00
,
m64n_gtc_ba
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4744
,
0x4744
,
0x00
,
0x00
,
m64n_gtc_ba1
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4749
,
0x4749
,
0x00
,
0x00
,
m64n_gtc_bp
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
|
M64F_MAGIC_VRAM_SIZE
},
{
0x4750
,
0x4750
,
0x00
,
0x00
,
m64n_gtc_pp
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
{
0x4751
,
0x4751
,
0x00
,
0x00
,
m64n_gtc_ppl
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
},
/* 3D RAGE XL */
{
0x4752
,
0x4752
,
0x00
,
0x00
,
m64n_xl
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
|
M64F_XL_DLL
},
{
0x4752
,
0x4752
,
0x00
,
0x00
,
m64n_xl
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_SDRAM_MAGIC_PLL
|
M64F_EXTRA_BRIGHT
|
M64F_XL_DLL
},
/* Mach64 LT PRO */
{
0x4c42
,
0x4c42
,
0x00
,
0x00
,
m64n_ltp_a
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
},
{
0x4c44
,
0x4c44
,
0x00
,
0x00
,
m64n_ltp_p
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
},
{
0x4c49
,
0x4c49
,
0x00
,
0x00
,
m64n_ltp_p
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_EXTRA_BRIGHT
|
M64F_G3_PB_1_1
|
M64F_G3_PB_1024x768
},
{
0x4c50
,
0x4c50
,
0x00
,
0x00
,
m64n_ltp_p
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
},
{
0x4c42
,
0x4c42
,
0x00
,
0x00
,
m64n_ltp_a
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
},
{
0x4c44
,
0x4c44
,
0x00
,
0x00
,
m64n_ltp_p
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
},
{
0x4c49
,
0x4c49
,
0x00
,
0x00
,
m64n_ltp_p
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_EXTRA_BRIGHT
|
M64F_G3_PB_1_1
|
M64F_G3_PB_1024x768
},
{
0x4c50
,
0x4c50
,
0x00
,
0x00
,
m64n_ltp_p
,
230
,
100
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
},
/* 3D RAGE Mobility */
{
0x4c4d
,
0x4c4d
,
0x00
,
0x00
,
m64n_mob_p
,
230
,
50
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_MOBIL_BUS
},
{
0x4c4e
,
0x4c4e
,
0x00
,
0x00
,
m64n_mob_a
,
230
,
50
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_MOBIL_BUS
},
{
0x4c4d
,
0x4c4d
,
0x00
,
0x00
,
m64n_mob_p
,
230
,
50
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_MOBIL_BUS
},
{
0x4c4e
,
0x4c4e
,
0x00
,
0x00
,
m64n_mob_a
,
230
,
50
,
M64F_GT
|
M64F_INTEGRATED
|
M64F_RESET_3D
|
M64F_GTB_DSP
|
M64F_MOBIL_BUS
},
#endif
/* CONFIG_FB_ATY_CT */
};
...
...
@@ -387,7 +455,7 @@ static char *aty_ct_ram[8] __initdata = {
* Apple monitor sense
*/
static
int
__init
read_aty_sense
(
const
struct
fb_info
_aty
*
info
)
static
int
__init
read_aty_sense
(
const
struct
fb_info
*
info
)
{
int
sense
,
i
;
...
...
@@ -424,7 +492,7 @@ static int __init read_aty_sense(const struct fb_info_aty *info)
#endif
/* defined(CONFIG_PPC) */
#if defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_PMAC_BACKLIGHT)
static
void
aty_st_lcd
(
int
index
,
u32
val
,
const
struct
fb_info
_aty
*
info
)
static
void
aty_st_lcd
(
int
index
,
u32
val
,
const
struct
fb_info
*
info
)
{
unsigned
long
temp
;
...
...
@@ -435,7 +503,7 @@ static void aty_st_lcd(int index, u32 val, const struct fb_info_aty *info)
aty_st_le32
(
LCD_DATA
,
val
,
info
);
}
static
u32
aty_ld_lcd
(
int
index
,
const
struct
fb_info
_aty
*
info
)
static
u32
aty_ld_lcd
(
int
index
,
const
struct
fb_info
*
info
)
{
unsigned
long
temp
;
...
...
@@ -453,25 +521,27 @@ static u32 aty_ld_lcd(int index, const struct fb_info_aty *info)
* CRTC programming
*/
static
void
aty_set_crtc
(
const
struct
fb_info_aty
*
info
,
static
void
aty_set_crtc
(
const
struct
atyfb_par
*
par
,
const
struct
crtc
*
crtc
)
{
aty_st_le32
(
CRTC_H_TOTAL_DISP
,
crtc
->
h_tot_disp
,
info
);
aty_st_le32
(
CRTC_H_SYNC_STRT_WID
,
crtc
->
h_sync_strt_wid
,
info
);
aty_st_le32
(
CRTC_V_TOTAL_DISP
,
crtc
->
v_tot_disp
,
info
);
aty_st_le32
(
CRTC_V_SYNC_STRT_WID
,
crtc
->
v_sync_strt_wid
,
info
);
aty_st_le32
(
CRTC_VLINE_CRNT_VLINE
,
0
,
info
);
aty_st_le32
(
CRTC_OFF_PITCH
,
crtc
->
off_pitch
,
info
);
aty_st_le32
(
CRTC_GEN_CNTL
,
crtc
->
gen_cntl
,
info
);
aty_st_le32
(
CRTC_H_TOTAL_DISP
,
crtc
->
h_tot_disp
,
par
);
aty_st_le32
(
CRTC_H_SYNC_STRT_WID
,
crtc
->
h_sync_strt_wid
,
par
);
aty_st_le32
(
CRTC_V_TOTAL_DISP
,
crtc
->
v_tot_disp
,
par
);
aty_st_le32
(
CRTC_V_SYNC_STRT_WID
,
crtc
->
v_sync_strt_wid
,
par
);
aty_st_le32
(
CRTC_VLINE_CRNT_VLINE
,
0
,
par
);
aty_st_le32
(
CRTC_OFF_PITCH
,
crtc
->
off_pitch
,
par
);
aty_st_le32
(
CRTC_GEN_CNTL
,
crtc
->
gen_cntl
,
par
);
}
static
int
aty_var_to_crtc
(
const
struct
fb_info
_aty
*
info
,
static
int
aty_var_to_crtc
(
const
struct
fb_info
*
info
,
const
struct
fb_var_screeninfo
*
var
,
struct
crtc
*
crtc
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
xres
,
yres
,
vxres
,
vyres
,
xoffset
,
yoffset
,
bpp
;
u32
left
,
right
,
upper
,
lower
,
hslen
,
vslen
,
sync
,
vmode
;
u32
h_total
,
h_disp
,
h_sync_strt
,
h_sync_dly
,
h_sync_wid
,
h_sync_pol
;
u32
h_total
,
h_disp
,
h_sync_strt
,
h_sync_dly
,
h_sync_wid
,
h_sync_pol
;
u32
v_total
,
v_disp
,
v_sync_strt
,
v_sync_wid
,
v_sync_pol
,
c_sync
;
u32
pix_width
,
dp_pix_width
,
dp_chain_mask
;
...
...
@@ -493,38 +563,38 @@ static int aty_var_to_crtc(const struct fb_info_aty *info,
vmode
=
var
->
vmode
;
/* convert (and round up) and validate */
xres
=
(
xres
+
7
)
&
~
7
;
xoffset
=
(
xoffset
+
7
)
&
~
7
;
vxres
=
(
vxres
+
7
)
&
~
7
;
if
(
vxres
<
xres
+
xoffset
)
vxres
=
xres
+
xoffset
;
h_disp
=
xres
/
8
-
1
;
xres
=
(
xres
+
7
)
&
~
7
;
xoffset
=
(
xoffset
+
7
)
&
~
7
;
vxres
=
(
vxres
+
7
)
&
~
7
;
if
(
vxres
<
xres
+
xoffset
)
vxres
=
xres
+
xoffset
;
h_disp
=
xres
/
8
-
1
;
if
(
h_disp
>
0xff
)
FAIL
(
"h_disp too large"
);
h_sync_strt
=
h_disp
+
(
right
/
8
);
h_sync_strt
=
h_disp
+
(
right
/
8
);
if
(
h_sync_strt
>
0x1ff
)
FAIL
(
"h_sync_start too large"
);
h_sync_dly
=
right
&
7
;
h_sync_wid
=
(
hslen
+
7
)
/
8
;
h_sync_wid
=
(
hslen
+
7
)
/
8
;
if
(
h_sync_wid
>
0x1f
)
FAIL
(
"h_sync_wid too large"
);
h_total
=
h_sync_strt
+
h_sync_wid
+
(
h_sync_dly
+
left
+
7
)
/
8
;
h_total
=
h_sync_strt
+
h_sync_wid
+
(
h_sync_dly
+
left
+
7
)
/
8
;
if
(
h_total
>
0x1ff
)
FAIL
(
"h_total too large"
);
h_sync_pol
=
sync
&
FB_SYNC_HOR_HIGH_ACT
?
0
:
1
;
if
(
vyres
<
yres
+
yoffset
)
vyres
=
yres
+
yoffset
;
v_disp
=
yres
-
1
;
if
(
vyres
<
yres
+
yoffset
)
vyres
=
yres
+
yoffset
;
v_disp
=
yres
-
1
;
if
(
v_disp
>
0x7ff
)
FAIL
(
"v_disp too large"
);
v_sync_strt
=
v_disp
+
lower
;
v_sync_strt
=
v_disp
+
lower
;
if
(
v_sync_strt
>
0x7ff
)
FAIL
(
"v_sync_strt too large"
);
v_sync_wid
=
vslen
;
if
(
v_sync_wid
>
0x1f
)
FAIL
(
"v_sync_wid too large"
);
v_total
=
v_sync_strt
+
v_sync_wid
+
upper
;
v_total
=
v_sync_strt
+
v_sync_wid
+
upper
;
if
(
v_total
>
0x7ff
)
FAIL
(
"v_total too large"
);
v_sync_pol
=
sync
&
FB_SYNC_VERT_HIGH_ACT
?
0
:
1
;
...
...
@@ -534,7 +604,9 @@ static int aty_var_to_crtc(const struct fb_info_aty *info,
if
(
bpp
<=
8
)
{
bpp
=
8
;
pix_width
=
CRTC_PIX_WIDTH_8BPP
;
dp_pix_width
=
HOST_8BPP
|
SRC_8BPP
|
DST_8BPP
|
BYTE_ORDER_LSB_TO_MSB
;
dp_pix_width
=
HOST_8BPP
|
SRC_8BPP
|
DST_8BPP
|
BYTE_ORDER_LSB_TO_MSB
;
dp_chain_mask
=
0x8080
;
}
else
if
(
bpp
<=
16
)
{
bpp
=
16
;
...
...
@@ -545,7 +617,9 @@ static int aty_var_to_crtc(const struct fb_info_aty *info,
}
else
if
(
bpp
<=
24
&&
M64_HAS
(
INTEGRATED
))
{
bpp
=
24
;
pix_width
=
CRTC_PIX_WIDTH_24BPP
;
dp_pix_width
=
HOST_8BPP
|
SRC_8BPP
|
DST_8BPP
|
BYTE_ORDER_LSB_TO_MSB
;
dp_pix_width
=
HOST_8BPP
|
SRC_8BPP
|
DST_8BPP
|
BYTE_ORDER_LSB_TO_MSB
;
dp_chain_mask
=
0x8080
;
}
else
if
(
bpp
<=
32
)
{
bpp
=
32
;
...
...
@@ -556,7 +630,7 @@ static int aty_var_to_crtc(const struct fb_info_aty *info,
}
else
FAIL
(
"invalid bpp"
);
if
(
vxres
*
vyres
*
bpp
/
8
>
info
->
fb_info
.
fix
.
smem_len
)
if
(
vxres
*
vyres
*
bpp
/
8
>
info
->
fix
.
smem_len
)
FAIL
(
"not enough video RAM"
);
if
((
vmode
&
FB_VMODE_MASK
)
!=
FB_VMODE_NONINTERLACED
)
...
...
@@ -568,18 +642,22 @@ static int aty_var_to_crtc(const struct fb_info_aty *info,
crtc
->
xoffset
=
xoffset
;
crtc
->
yoffset
=
yoffset
;
crtc
->
bpp
=
bpp
;
crtc
->
h_tot_disp
=
h_total
|
(
h_disp
<<
16
);
crtc
->
h_sync_strt_wid
=
(
h_sync_strt
&
0xff
)
|
(
h_sync_dly
<<
8
)
|
((
h_sync_strt
&
0x100
)
<<
4
)
|
(
h_sync_wid
<<
16
)
|
(
h_sync_pol
<<
21
);
crtc
->
v_tot_disp
=
v_total
|
(
v_disp
<<
16
);
crtc
->
v_sync_strt_wid
=
v_sync_strt
|
(
v_sync_wid
<<
16
)
|
(
v_sync_pol
<<
21
);
crtc
->
off_pitch
=
((
yoffset
*
vxres
+
xoffset
)
*
bpp
/
64
)
|
(
vxres
<<
19
);
crtc
->
gen_cntl
=
pix_width
|
c_sync
|
CRTC_EXT_DISP_EN
|
CRTC_ENABLE
;
crtc
->
h_tot_disp
=
h_total
|
(
h_disp
<<
16
);
crtc
->
h_sync_strt_wid
=
(
h_sync_strt
&
0xff
)
|
(
h_sync_dly
<<
8
)
|
((
h_sync_strt
&
0x100
)
<<
4
)
|
(
h_sync_wid
<<
16
)
|
(
h_sync_pol
<<
21
);
crtc
->
v_tot_disp
=
v_total
|
(
v_disp
<<
16
);
crtc
->
v_sync_strt_wid
=
v_sync_strt
|
(
v_sync_wid
<<
16
)
|
(
v_sync_pol
<<
21
);
crtc
->
off_pitch
=
((
yoffset
*
vxres
+
xoffset
)
*
bpp
/
64
)
|
(
vxres
<<
19
);
crtc
->
gen_cntl
=
pix_width
|
c_sync
|
CRTC_EXT_DISP_EN
|
CRTC_ENABLE
;
if
(
M64_HAS
(
MAGIC_FIFO
))
{
/* Not VTB/GTB */
/* FIXME: magic FIFO values */
crtc
->
gen_cntl
|=
aty_ld_le32
(
CRTC_GEN_CNTL
,
info
)
&
0x000e0000
;
crtc
->
gen_cntl
|=
aty_ld_le32
(
CRTC_GEN_CNTL
,
par
)
&
0x000e0000
;
}
crtc
->
dp_pix_width
=
dp_pix_width
;
crtc
->
dp_chain_mask
=
dp_chain_mask
;
...
...
@@ -592,34 +670,35 @@ static int aty_crtc_to_var(const struct crtc *crtc,
struct
fb_var_screeninfo
*
var
)
{
u32
xres
,
yres
,
bpp
,
left
,
right
,
upper
,
lower
,
hslen
,
vslen
,
sync
;
u32
h_total
,
h_disp
,
h_sync_strt
,
h_sync_dly
,
h_sync_wid
,
h_sync_pol
;
u32
h_total
,
h_disp
,
h_sync_strt
,
h_sync_dly
,
h_sync_wid
,
h_sync_pol
;
u32
v_total
,
v_disp
,
v_sync_strt
,
v_sync_wid
,
v_sync_pol
,
c_sync
;
u32
pix_width
;
/* input */
h_total
=
crtc
->
h_tot_disp
&
0x1ff
;
h_disp
=
(
crtc
->
h_tot_disp
>>
16
)
&
0xff
;
h_disp
=
(
crtc
->
h_tot_disp
>>
16
)
&
0xff
;
h_sync_strt
=
(
crtc
->
h_sync_strt_wid
&
0xff
)
|
((
crtc
->
h_sync_strt_wid
>>
4
)
&
0x100
);
h_sync_dly
=
(
crtc
->
h_sync_strt_wid
>>
8
)
&
0x7
;
h_sync_wid
=
(
crtc
->
h_sync_strt_wid
>>
16
)
&
0x1f
;
h_sync_pol
=
(
crtc
->
h_sync_strt_wid
>>
21
)
&
0x1
;
((
crtc
->
h_sync_strt_wid
>>
4
)
&
0x100
);
h_sync_dly
=
(
crtc
->
h_sync_strt_wid
>>
8
)
&
0x7
;
h_sync_wid
=
(
crtc
->
h_sync_strt_wid
>>
16
)
&
0x1f
;
h_sync_pol
=
(
crtc
->
h_sync_strt_wid
>>
21
)
&
0x1
;
v_total
=
crtc
->
v_tot_disp
&
0x7ff
;
v_disp
=
(
crtc
->
v_tot_disp
>>
16
)
&
0x7ff
;
v_disp
=
(
crtc
->
v_tot_disp
>>
16
)
&
0x7ff
;
v_sync_strt
=
crtc
->
v_sync_strt_wid
&
0x7ff
;
v_sync_wid
=
(
crtc
->
v_sync_strt_wid
>>
16
)
&
0x1f
;
v_sync_pol
=
(
crtc
->
v_sync_strt_wid
>>
21
)
&
0x1
;
v_sync_wid
=
(
crtc
->
v_sync_strt_wid
>>
16
)
&
0x1f
;
v_sync_pol
=
(
crtc
->
v_sync_strt_wid
>>
21
)
&
0x1
;
c_sync
=
crtc
->
gen_cntl
&
CRTC_CSYNC_EN
?
1
:
0
;
pix_width
=
crtc
->
gen_cntl
&
CRTC_PIX_WIDTH_MASK
;
/* convert */
xres
=
(
h_disp
+
1
)
*
8
;
yres
=
v_disp
+
1
;
left
=
(
h_total
-
h_sync_strt
-
h_sync_wid
)
*
8
-
h_sync_dly
;
right
=
(
h_sync_strt
-
h_disp
)
*
8
+
h_sync_dly
;
hslen
=
h_sync_wid
*
8
;
upper
=
v_total
-
v_sync_strt
-
v_sync_wid
;
lower
=
v_sync_strt
-
v_disp
;
xres
=
(
h_disp
+
1
)
*
8
;
yres
=
v_disp
+
1
;
left
=
(
h_total
-
h_sync_strt
-
h_sync_wid
)
*
8
-
h_sync_dly
;
right
=
(
h_sync_strt
-
h_disp
)
*
8
+
h_sync_dly
;
hslen
=
h_sync_wid
*
8
;
upper
=
v_total
-
v_sync_strt
-
v_sync_wid
;
lower
=
v_sync_strt
-
v_disp
;
vslen
=
v_sync_wid
;
sync
=
(
h_sync_pol
?
0
:
FB_SYNC_HOR_HIGH_ACT
)
|
(
v_sync_pol
?
0
:
FB_SYNC_VERT_HIGH_ACT
)
|
...
...
@@ -722,8 +801,8 @@ static int aty_crtc_to_var(const struct crtc *crtc,
/* ------------------------------------------------------------------------- */
static
void
atyfb_set_par
(
const
struct
atyfb_par
*
par
,
struct
fb_info
_aty
*
info
)
static
void
atyfb_set_par
(
struct
atyfb_par
*
par
,
struct
fb_info
*
info
)
{
u32
i
;
int
accelmode
;
...
...
@@ -731,22 +810,20 @@ static void atyfb_set_par(const struct atyfb_par *par,
accelmode
=
par
->
accel_flags
;
/* hack */
info
->
current_par
=
*
par
;
if
(
info
->
blitter_may_be_busy
)
wait_for_idle
(
info
);
tmp
=
aty_ld_8
(
CRTC_GEN_CNTL
+
3
,
info
);
aty_set_crtc
(
info
,
&
par
->
crtc
);
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
0
,
info
);
if
(
par
->
blitter_may_be_busy
)
wait_for_idle
(
par
);
tmp
=
aty_ld_8
(
CRTC_GEN_CNTL
+
3
,
par
);
aty_set_crtc
(
par
,
&
par
->
crtc
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
0
,
par
);
/* better call aty_StrobeClock ?? */
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
CLOCK_STROBE
,
info
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
CLOCK_STROBE
,
par
);
info
->
dac_ops
->
set_dac
(
info
,
&
par
->
pll
,
par
->
crtc
.
bpp
,
accelmode
);
info
->
pll_ops
->
set_pll
(
info
,
&
par
->
pll
);
par
->
dac_ops
->
set_dac
(
info
,
&
par
->
pll
,
par
->
crtc
.
bpp
,
accelmode
);
par
->
pll_ops
->
set_pll
(
info
,
&
par
->
pll
);
if
(
!
M64_HAS
(
INTEGRATED
))
{
/* Don't forget MEM_CNTL */
i
=
aty_ld_le32
(
MEM_CNTL
,
info
)
&
0xf0ffffff
;
i
=
aty_ld_le32
(
MEM_CNTL
,
par
)
&
0xf0ffffff
;
switch
(
par
->
crtc
.
bpp
)
{
case
8
:
i
|=
0x02000000
;
...
...
@@ -758,11 +835,11 @@ static void atyfb_set_par(const struct atyfb_par *par,
i
|=
0x06000000
;
break
;
}
aty_st_le32
(
MEM_CNTL
,
i
,
info
);
aty_st_le32
(
MEM_CNTL
,
i
,
par
);
}
else
{
i
=
aty_ld_le32
(
MEM_CNTL
,
info
)
&
0xf00fffff
;
i
=
aty_ld_le32
(
MEM_CNTL
,
par
)
&
0xf00fffff
;
if
(
!
M64_HAS
(
MAGIC_POSTDIV
))
i
|=
info
->
mem_refresh_rate
<<
20
;
i
|=
par
->
mem_refresh_rate
<<
20
;
switch
(
par
->
crtc
.
bpp
)
{
case
8
:
case
24
:
...
...
@@ -776,46 +853,49 @@ static void atyfb_set_par(const struct atyfb_par *par,
break
;
}
if
(
M64_HAS
(
CT_BUS
))
{
aty_st_le32
(
DAC_CNTL
,
0x87010184
,
info
);
aty_st_le32
(
BUS_CNTL
,
0x680000f9
,
info
);
aty_st_le32
(
DAC_CNTL
,
0x87010184
,
par
);
aty_st_le32
(
BUS_CNTL
,
0x680000f9
,
par
);
}
else
if
(
M64_HAS
(
VT_BUS
))
{
aty_st_le32
(
DAC_CNTL
,
0x87010184
,
info
);
aty_st_le32
(
BUS_CNTL
,
0x680000f9
,
info
);
aty_st_le32
(
DAC_CNTL
,
0x87010184
,
par
);
aty_st_le32
(
BUS_CNTL
,
0x680000f9
,
par
);
}
else
if
(
M64_HAS
(
MOBIL_BUS
))
{
aty_st_le32
(
DAC_CNTL
,
0x80010102
,
info
);
aty_st_le32
(
BUS_CNTL
,
0x7b33a040
,
info
);
aty_st_le32
(
DAC_CNTL
,
0x80010102
,
par
);
aty_st_le32
(
BUS_CNTL
,
0x7b33a040
,
par
);
}
else
{
/* GT */
aty_st_le32
(
DAC_CNTL
,
0x86010102
,
info
);
aty_st_le32
(
BUS_CNTL
,
0x7b23a040
,
info
);
aty_st_le32
(
DAC_CNTL
,
0x86010102
,
par
);
aty_st_le32
(
BUS_CNTL
,
0x7b23a040
,
par
);
aty_st_le32
(
EXT_MEM_CNTL
,
aty_ld_le32
(
EXT_MEM_CNTL
,
info
)
|
0x5000001
,
info
);
aty_ld_le32
(
EXT_MEM_CNTL
,
par
)
|
0x5000001
,
par
);
}
aty_st_le32
(
MEM_CNTL
,
i
,
info
);
aty_st_le32
(
MEM_CNTL
,
i
,
par
);
}
aty_st_8
(
DAC_MASK
,
0xff
,
info
);
aty_st_8
(
DAC_MASK
,
0xff
,
par
);
/* Initialize the graphics engine */
if
(
par
->
accel_flags
&
FB_ACCELF_TEXT
)
aty_init_engine
(
par
,
info
);
#ifdef CONFIG_BOOTX_TEXT
btext_update_display
(
info
->
fb_info
.
fix
.
smem_start
,
(((
par
->
crtc
.
h_tot_disp
>>
16
)
&
0xff
)
+
1
)
*
8
,
((
par
->
crtc
.
v_tot_disp
>>
16
)
&
0x7ff
)
+
1
,
btext_update_display
(
info
->
fix
.
smem_start
,
(((
par
->
crtc
.
h_tot_disp
>>
16
)
&
0xff
)
+
1
)
*
8
,
((
par
->
crtc
.
v_tot_disp
>>
16
)
&
0x7ff
)
+
1
,
par
->
crtc
.
bpp
,
par
->
crtc
.
vxres
*
par
->
crtc
.
bpp
/
8
);
par
->
crtc
.
vxres
*
par
->
crtc
.
bpp
/
8
);
#endif
/* CONFIG_BOOTX_TEXT */
}
static
int
atyfb_decode_var
(
const
struct
fb_var_screeninfo
*
var
,
struct
atyfb_par
*
par
,
const
struct
fb_info
_aty
*
info
)
const
struct
fb_info
*
info
)
{
int
err
;
if
((
err
=
aty_var_to_crtc
(
info
,
var
,
&
par
->
crtc
))
||
(
err
=
info
->
pll_ops
->
var_to_pll
(
info
,
var
->
pixclock
,
par
->
crtc
.
bpp
,
(
err
=
par
->
pll_ops
->
var_to_pll
(
info
,
var
->
pixclock
,
par
->
crtc
.
bpp
,
&
par
->
pll
)))
return
err
;
...
...
@@ -834,7 +914,7 @@ static int atyfb_decode_var(const struct fb_var_screeninfo *var,
static
int
atyfb_encode_var
(
struct
fb_var_screeninfo
*
var
,
const
struct
atyfb_par
*
par
,
const
struct
fb_info
_aty
*
info
)
const
struct
fb_info
*
info
)
{
int
err
;
...
...
@@ -842,7 +922,7 @@ static int atyfb_encode_var(struct fb_var_screeninfo *var,
if
((
err
=
aty_crtc_to_var
(
&
par
->
crtc
,
var
)))
return
err
;
var
->
pixclock
=
info
->
pll_ops
->
pll_to_var
(
info
,
&
par
->
pll
);
var
->
pixclock
=
par
->
pll_ops
->
pll_to_var
(
info
,
&
par
->
pll
);
var
->
height
=
-
1
;
var
->
width
=
-
1
;
...
...
@@ -854,15 +934,16 @@ static int atyfb_encode_var(struct fb_var_screeninfo *var,
static
void
set_off_pitch
(
struct
atyfb_par
*
par
,
const
struct
fb_info
_aty
*
info
)
const
struct
fb_info
*
info
)
{
u32
xoffset
=
par
->
crtc
.
xoffset
;
u32
yoffset
=
par
->
crtc
.
yoffset
;
u32
vxres
=
par
->
crtc
.
vxres
;
u32
bpp
=
par
->
crtc
.
bpp
;
par
->
crtc
.
off_pitch
=
((
yoffset
*
vxres
+
xoffset
)
*
bpp
/
64
)
|
(
vxres
<<
19
);
aty_st_le32
(
CRTC_OFF_PITCH
,
par
->
crtc
.
off_pitch
,
info
);
par
->
crtc
.
off_pitch
=
((
yoffset
*
vxres
+
xoffset
)
*
bpp
/
64
)
|
(
vxres
<<
19
);
aty_st_le32
(
CRTC_OFF_PITCH
,
par
->
crtc
.
off_pitch
,
par
);
}
...
...
@@ -871,20 +952,19 @@ static void set_off_pitch(struct atyfb_par *par,
*/
static
int
atyfb_open
(
struct
fb_info
*
info
,
int
user
)
{
#ifdef __sparc__
struct
fb_info_aty
*
fb
=
(
struct
fb_info_aty
*
)
info
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
if
(
user
)
{
fb
->
open
++
;
fb
->
mmaped
=
0
;
fb
->
vtconsole
=
-
1
;
par
->
open
++
;
par
->
mmaped
=
0
;
par
->
vtconsole
=
-
1
;
}
else
{
fb
->
consolecnt
++
;
par
->
consolecnt
++
;
}
#endif
return
(
0
);
return
(
0
);
}
struct
fb_var_screeninfo
default_var
=
{
...
...
@@ -898,19 +978,19 @@ struct fb_var_screeninfo default_var = {
static
int
atyfb_release
(
struct
fb_info
*
info
,
int
user
)
{
#ifdef __sparc__
struct
fb_info_aty
*
fb
=
(
struct
fb_info_aty
*
)
info
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
if
(
user
)
{
fb
->
open
--
;
par
->
open
--
;
mdelay
(
1
);
wait_for_idle
(
fb
);
if
(
!
fb
->
open
)
{
int
was_mmaped
=
fb
->
mmaped
;
wait_for_idle
(
par
);
if
(
!
par
->
open
)
{
int
was_mmaped
=
par
->
mmaped
;
fb
->
mmaped
=
0
;
if
(
fb
->
vtconsole
!=
-
1
)
vt_cons
[
fb
->
vtconsole
]
->
vc_mode
=
KD_TEXT
;
fb
->
vtconsole
=
-
1
;
par
->
mmaped
=
0
;
if
(
par
->
vtconsole
!=
-
1
)
vt_cons
[
par
->
vtconsole
]
->
vc_mode
=
KD_TEXT
;
par
->
vtconsole
=
-
1
;
if
(
was_mmaped
)
{
struct
fb_var_screeninfo
var
;
...
...
@@ -926,63 +1006,62 @@ static int atyfb_release(struct fb_info *info, int user)
else
var
.
accel_flags
|=
FB_ACCELF_TEXT
;
if
(
var
.
yres
==
var
.
yres_virtual
)
{
u32
vram
=
(
fb
->
fb_info
.
fix
.
smem_len
-
(
PAGE_SIZE
<<
2
));
var
.
yres_virtual
=
((
vram
*
8
)
/
var
.
bits_per_pixel
)
/
u32
vram
=
(
info
->
fix
.
smem_len
-
(
PAGE_SIZE
<<
2
));
var
.
yres_virtual
=
((
vram
*
8
)
/
var
.
bits_per_pixel
)
/
var
.
xres_virtual
;
if
(
var
.
yres_virtual
<
var
.
yres
)
var
.
yres_virtual
=
var
.
yres
;
var
.
yres_virtual
=
var
.
yres
;
}
atyfb_set_var
(
&
var
,
-
1
,
&
fb
->
fb_
info
);
atyfb_set_var
(
&
var
,
-
1
,
info
);
}
}
}
else
{
fb
->
consolecnt
--
;
par
->
consolecnt
--
;
}
#endif
return
(
0
);
return
(
0
);
}
static
int
encode_fix
(
struct
fb_fix_screeninfo
*
fix
,
const
struct
atyfb_par
*
par
,
const
struct
fb_info
_aty
*
info
)
const
struct
fb_info
*
info
)
{
memset
(
fix
,
0
,
sizeof
(
struct
fb_fix_screeninfo
));
strcpy
(
fix
->
id
,
atyfb_name
);
fix
->
smem_start
=
info
->
fb_info
.
fix
.
smem_start
;
fix
->
smem_len
=
info
->
fb_info
.
fix
.
smem_len
;
fix
->
mmio_start
=
info
->
fb_info
.
fix
.
mmio_start
;
fix
->
mmio_len
=
info
->
fb_info
.
fix
.
mmio_len
;
fix
->
accel
=
info
->
fb_info
.
fix
.
accel
;
fix
->
type
=
FB_TYPE_PACKED_PIXELS
;
fix
->
type_aux
=
0
;
fix
->
line_length
=
par
->
crtc
.
vxres
*
par
->
crtc
.
bpp
/
8
;
fix
->
smem_start
=
info
->
fix
.
smem_start
;
fix
->
smem_len
=
info
->
fix
.
smem_len
;
fix
->
mmio_start
=
info
->
fix
.
mmio_start
;
fix
->
mmio_len
=
info
->
fix
.
mmio_len
;
fix
->
accel
=
info
->
fix
.
accel
;
fix
->
type
=
info
->
fix
.
type
;
fix
->
type_aux
=
info
->
fix
.
type_aux
;
fix
->
line_length
=
par
->
crtc
.
vxres
*
par
->
crtc
.
bpp
/
8
;
fix
->
visual
=
par
->
crtc
.
bpp
<=
8
?
FB_VISUAL_PSEUDOCOLOR
:
FB_VISUAL_DIRECTCOLOR
;
fix
->
ywrapstep
=
0
;
fix
->
xpanstep
=
8
;
fix
->
ypanstep
=
1
;
fix
->
ywrapstep
=
info
->
fix
.
ywrapstep
;
fix
->
xpanstep
=
info
->
fix
.
xpanstep
;
fix
->
ypanstep
=
info
->
fix
.
ypanstep
;
return
0
;
}
/*
* Get the Fixed Part of the Display
*/
static
int
atyfb_get_fix
(
struct
fb_fix_screeninfo
*
fix
,
int
con
,
struct
fb_info
*
fb
)
struct
fb_info
*
info
)
{
const
struct
fb_info_aty
*
info
=
(
struct
fb_info_aty
*
)
fb
;
struct
atyfb_par
par
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
if
(
con
==
-
1
)
par
=
info
->
default_par
;
else
atyfb_decode_var
(
&
fb_display
[
con
].
var
,
&
par
,
info
);
encode_fix
(
fix
,
&
par
,
info
);
atyfb_decode_var
(
&
fb_display
[
con
].
var
,
par
,
info
);
encode_fix
(
fix
,
par
,
info
);
return
0
;
}
...
...
@@ -992,57 +1071,47 @@ static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,
*/
static
int
atyfb_get_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
fb
)
struct
fb_info
*
info
)
{
const
struct
fb_info_aty
*
info
=
(
struct
fb_info_aty
*
)
fb
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
if
(
con
==
-
1
)
atyfb_encode_var
(
var
,
&
info
->
default_
par
,
info
);
atyfb_encode_var
(
var
,
par
,
info
);
else
*
var
=
fb_display
[
con
].
var
;
return
0
;
}
static
void
atyfb_set_dispsw
(
struct
display
*
disp
,
struct
fb_info_aty
*
info
,
int
bpp
,
int
accel
)
static
void
atyfb_set_dispsw
(
struct
display
*
disp
,
struct
fb_info
*
info
)
{
switch
(
bpp
)
{
#ifdef FBCON_HAS_CFB8
switch
(
info
->
var
.
bits_per_pixel
)
{
case
8
:
info
->
dispsw
=
accel
?
fbcon_aty8
:
fbcon_cfb8
;
disp
->
dispsw
=
&
info
->
dispsw
;
disp
->
dispsw
=
&
fbcon_aty8
;
break
;
#endif
#ifdef FBCON_HAS_CFB16
case
16
:
info
->
dispsw
=
accel
?
fbcon_aty16
:
fbcon_cfb16
;
disp
->
dispsw
=
&
info
->
dispsw
;
disp
->
dispsw_data
=
info
->
fb_info
.
pseudo_palette
;
disp
->
dispsw
=
&
fbcon_aty16
;
disp
->
dispsw_data
=
info
->
pseudo_palette
;
break
;
#endif
#ifdef FBCON_HAS_CFB24
case
24
:
info
->
dispsw
=
accel
?
fbcon_aty24
:
fbcon_cfb24
;
disp
->
dispsw
=
&
info
->
dispsw
;
disp
->
dispsw_data
=
info
->
fb_info
.
pseudo_palette
;
disp
->
dispsw
=
&
fbcon_aty24
;
disp
->
dispsw_data
=
info
->
pseudo_palette
;
break
;
#endif
#ifdef FBCON_HAS_CFB32
case
32
:
info
->
dispsw
=
accel
?
fbcon_aty32
:
fbcon_cfb32
;
disp
->
dispsw
=
&
info
->
dispsw
;
disp
->
dispsw_data
=
info
->
fb_info
.
pseudo_palette
;
disp
->
dispsw
=
&
fbcon_aty32
;
disp
->
dispsw_data
=
info
->
pseudo_palette
;
break
;
#endif
default:
disp
->
dispsw
=
&
fbcon_dummy
;
}
#ifdef CONFIG_FB_ATY_CT
/*
if (info->cursor) {
info
->
dispsw
.
cursor
=
atyfb_cursor
;
info
->
dispsw
.
set_font
=
atyfb_set_font
;
&disp
->dispsw.cursor = atyfb_cursor;
&disp
->dispsw.set_font = atyfb_set_font;
}
*/
#endif
/* CONFIG_FB_ATY_CT */
}
...
...
@@ -1052,23 +1121,23 @@ static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info,
*/
static
int
atyfb_set_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
fb
)
struct
fb_info
*
info
)
{
struct
fb_info_aty
*
info
=
(
struct
fb_info_aty
*
)
fb
;
struct
atyfb_par
par
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
struct
display
*
display
;
int
oldxres
,
oldyres
,
oldvxres
,
oldvyres
,
oldbpp
,
oldaccel
,
accel
,
err
;
int
oldxres
,
oldyres
,
oldvxres
,
oldvyres
,
oldbpp
,
oldaccel
,
accel
,
err
;
int
activate
=
var
->
activate
;
if
(
con
>=
0
)
display
=
&
fb_display
[
con
];
else
display
=
fb
->
disp
;
/* used during initialization */
display
=
info
->
disp
;
/* used during initialization */
if
((
err
=
atyfb_decode_var
(
var
,
&
par
,
info
)))
if
((
err
=
atyfb_decode_var
(
var
,
par
,
info
)))
return
err
;
atyfb_encode_var
(
var
,
&
par
,
(
struct
fb_info_aty
*
)
info
);
atyfb_encode_var
(
var
,
par
,
info
);
if
((
activate
&
FB_ACTIVATE_MASK
)
==
FB_ACTIVATE_NOW
)
{
oldxres
=
display
->
var
.
xres
;
...
...
@@ -1080,11 +1149,13 @@ static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
display
->
var
=
*
var
;
accel
=
var
->
accel_flags
&
FB_ACCELF_TEXT
;
if
(
oldxres
!=
var
->
xres
||
oldyres
!=
var
->
yres
||
oldvxres
!=
var
->
xres_virtual
||
oldvyres
!=
var
->
yres_virtual
||
oldbpp
!=
var
->
bits_per_pixel
||
oldaccel
!=
var
->
accel_flags
)
{
oldvxres
!=
var
->
xres_virtual
||
oldvyres
!=
var
->
yres_virtual
||
oldbpp
!=
var
->
bits_per_pixel
||
oldaccel
!=
var
->
accel_flags
)
{
struct
fb_fix_screeninfo
fix
;
encode_fix
(
&
fix
,
&
par
,
info
);
encode_fix
(
&
fix
,
par
,
info
);
display
->
visual
=
fix
.
visual
;
display
->
type
=
fix
.
type
;
display
->
type_aux
=
fix
.
type_aux
;
...
...
@@ -1094,24 +1165,25 @@ static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
display
->
can_soft_blank
=
1
;
display
->
inverse
=
0
;
if
(
accel
)
display
->
scrollmode
=
(
info
->
bus_type
==
PCI
)
?
SCROLL_YNOMOVE
:
0
;
display
->
scrollmode
=
(
par
->
bus_type
==
PCI
)
?
SCROLL_YNOMOVE
:
0
;
else
display
->
scrollmode
=
SCROLL_YREDRAW
;
if
(
info
->
fb_info
.
changevar
)
(
*
info
->
fb_info
.
changevar
)
(
con
);
if
(
info
->
changevar
)
(
*
info
->
changevar
)
(
con
);
}
if
(
!
info
->
fb_info
.
display_fg
||
info
->
fb_info
.
display_fg
->
vc_num
==
con
)
{
atyfb_set_par
(
&
par
,
info
);
atyfb_set_dispsw
(
display
,
info
,
par
.
crtc
.
bpp
,
accel
);
if
(
!
info
->
display_fg
||
info
->
display_fg
->
vc_num
==
con
)
{
atyfb_set_par
(
par
,
info
);
atyfb_set_dispsw
(
display
,
info
);
}
if
(
oldbpp
!=
var
->
bits_per_pixel
)
{
if
((
err
=
fb_alloc_cmap
(
&
display
->
cmap
,
0
,
0
)))
return
err
;
do_install_cmap
(
con
,
&
info
->
fb_
info
);
do_install_cmap
(
con
,
info
);
}
}
return
0
;
}
...
...
@@ -1123,17 +1195,17 @@ static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
*/
static
int
atyfb_pan_display
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
fb
)
struct
fb_info
*
info
)
{
struct
fb_info_aty
*
info
=
(
struct
fb_info_aty
*
)
fb
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
xres
,
yres
,
xoffset
,
yoffset
;
struct
atyfb_par
*
par
=
&
info
->
current_par
;
xres
=
(((
par
->
crtc
.
h_tot_disp
>>
16
)
&
0xff
)
+
1
)
*
8
;
yres
=
((
par
->
crtc
.
v_tot_disp
>>
16
)
&
0x7ff
)
+
1
;
xoffset
=
(
var
->
xoffset
+
7
)
&
~
7
;
xres
=
(((
par
->
crtc
.
h_tot_disp
>>
16
)
&
0xff
)
+
1
)
*
8
;
yres
=
((
par
->
crtc
.
v_tot_disp
>>
16
)
&
0x7ff
)
+
1
;
xoffset
=
(
var
->
xoffset
+
7
)
&
~
7
;
yoffset
=
var
->
yoffset
;
if
(
xoffset
+
xres
>
par
->
crtc
.
vxres
||
yoffset
+
yres
>
par
->
crtc
.
vyres
)
if
(
xoffset
+
xres
>
par
->
crtc
.
vxres
||
yoffset
+
yres
>
par
->
crtc
.
vyres
)
return
-
EINVAL
;
par
->
crtc
.
xoffset
=
xoffset
;
par
->
crtc
.
yoffset
=
yoffset
;
...
...
@@ -1164,10 +1236,10 @@ struct atyclk {
#endif
static
int
atyfb_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
u_int
cmd
,
u_long
arg
,
int
con
,
struct
fb_info
*
info
2
)
u_long
arg
,
int
con
,
struct
fb_info
*
info
)
{
#if defined(__sparc__) || (defined(DEBUG) && defined(CONFIG_FB_ATY_CT))
struct
fb_info_aty
*
info
=
(
struct
fb_info_aty
*
)
info2
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
#endif
/* __sparc__ || DEBUG */
#ifdef __sparc__
struct
fbtype
fbtyp
;
...
...
@@ -1183,12 +1255,13 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
#ifdef __sparc__
case
FBIOGTYPE
:
fbtyp
.
fb_type
=
FBTYPE_PCI_GENERIC
;
fbtyp
.
fb_width
=
info
->
current_par
.
crtc
.
vxres
;
fbtyp
.
fb_height
=
info
->
current_par
.
crtc
.
vyres
;
fbtyp
.
fb_depth
=
info
->
current_par
.
crtc
.
bpp
;
fbtyp
.
fb_width
=
par
->
crtc
.
vxres
;
fbtyp
.
fb_height
=
par
->
crtc
.
vyres
;
fbtyp
.
fb_depth
=
par
->
crtc
.
bpp
;
fbtyp
.
fb_cmsize
=
disp
->
cmap
.
len
;
fbtyp
.
fb_size
=
info
->
fb_info
.
fix
.
smem_len
;
if
(
copy_to_user
((
struct
fbtype
*
)
arg
,
&
fbtyp
,
sizeof
(
fbtyp
)))
fbtyp
.
fb_size
=
info
->
fix
.
smem_len
;
if
(
copy_to_user
((
struct
fbtype
*
)
arg
,
&
fbtyp
,
sizeof
(
fbtyp
)))
return
-
EFAULT
;
break
;
#endif
/* __sparc__ */
...
...
@@ -1196,21 +1269,22 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
case
ATYIO_CLKR
:
if
(
M64_HAS
(
INTEGRATED
))
{
struct
atyclk
clk
;
union
aty_pll
*
pll
=
&
info
->
current_par
.
pll
;
union
aty_pll
*
pll
=
par
->
pll
;
u32
dsp_config
=
pll
->
ct
.
dsp_config
;
u32
dsp_on_off
=
pll
->
ct
.
dsp_on_off
;
clk
.
ref_clk_per
=
info
->
ref_clk_per
;
clk
.
ref_clk_per
=
par
->
ref_clk_per
;
clk
.
pll_ref_div
=
pll
->
ct
.
pll_ref_div
;
clk
.
mclk_fb_div
=
pll
->
ct
.
mclk_fb_div
;
clk
.
mclk_post_div
=
pll
->
ct
.
mclk_post_div_real
;
clk
.
vclk_fb_div
=
pll
->
ct
.
vclk_fb_div
;
clk
.
vclk_post_div
=
pll
->
ct
.
vclk_post_div_real
;
clk
.
dsp_xclks_per_row
=
dsp_config
&
0x3fff
;
clk
.
dsp_loop_latency
=
(
dsp_config
>>
16
)
&
0xf
;
clk
.
dsp_precision
=
(
dsp_config
>>
20
)
&
7
;
clk
.
dsp_loop_latency
=
(
dsp_config
>>
16
)
&
0xf
;
clk
.
dsp_precision
=
(
dsp_config
>>
20
)
&
7
;
clk
.
dsp_on
=
dsp_on_off
&
0x7ff
;
clk
.
dsp_off
=
(
dsp_on_off
>>
16
)
&
0x7ff
;
if
(
copy_to_user
((
struct
atyclk
*
)
arg
,
&
clk
,
sizeof
(
clk
)))
clk
.
dsp_off
=
(
dsp_on_off
>>
16
)
&
0x7ff
;
if
(
copy_to_user
((
struct
atyclk
*
)
arg
,
&
clk
,
sizeof
(
clk
)))
return
-
EFAULT
;
}
else
return
-
EINVAL
;
...
...
@@ -1218,31 +1292,37 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
case
ATYIO_CLKW
:
if
(
M64_HAS
(
INTEGRATED
))
{
struct
atyclk
clk
;
union
aty_pll
*
pll
=
&
info
->
current_par
.
pll
;
if
(
copy_from_user
(
&
clk
,
(
struct
atyclk
*
)
arg
,
sizeof
(
clk
)))
union
aty_pll
*
pll
=
par
->
pll
;
if
(
copy_from_user
(
&
clk
,
(
struct
atyclk
*
)
arg
,
sizeof
(
clk
)))
return
-
EFAULT
;
info
->
ref_clk_per
=
clk
.
ref_clk_per
;
par
->
ref_clk_per
=
clk
.
ref_clk_per
;
pll
->
ct
.
pll_ref_div
=
clk
.
pll_ref_div
;
pll
->
ct
.
mclk_fb_div
=
clk
.
mclk_fb_div
;
pll
->
ct
.
mclk_post_div_real
=
clk
.
mclk_post_div
;
pll
->
ct
.
vclk_fb_div
=
clk
.
vclk_fb_div
;
pll
->
ct
.
vclk_post_div_real
=
clk
.
vclk_post_div
;
pll
->
ct
.
dsp_config
=
(
clk
.
dsp_xclks_per_row
&
0x3fff
)
|
((
clk
.
dsp_loop_latency
&
0xf
)
<<
16
)
|
((
clk
.
dsp_precision
&
7
)
<<
20
);
pll
->
ct
.
dsp_on_off
=
(
clk
.
dsp_on
&
0x7ff
)
|
((
clk
.
dsp_off
&
0x7ff
)
<<
16
);
pll
->
ct
.
dsp_config
=
(
clk
.
dsp_xclks_per_row
&
0x3fff
)
|
((
clk
.
dsp_loop_latency
&
0xf
)
<<
16
)
|
((
clk
.
dsp_precision
&
7
)
<<
20
);
pll
->
ct
.
dsp_on_off
=
(
clk
.
dsp_on
&
0x7ff
)
|
((
clk
.
dsp_off
&
0x7ff
)
<<
16
);
aty_calc_pll_ct
(
info
,
&
pll
->
ct
);
aty_set_pll_ct
(
info
,
pll
);
}
else
return
-
EINVAL
;
break
;
case
ATYIO_FEATR
:
if
(
get_user
(
info
->
features
,
(
u32
*
)
arg
))
if
(
get_user
(
par
->
features
,
(
u32
*
)
arg
))
return
-
EFAULT
;
break
;
case
ATYIO_FEATW
:
if
(
put_user
(
info
->
features
,
(
u32
*
)
arg
))
if
(
put_user
(
par
->
features
,
(
u32
*
)
arg
))
return
-
EFAULT
;
break
;
#endif
/* DEBUG && CONFIG_FB_ATY_CT */
...
...
@@ -1254,10 +1334,10 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
static
int
atyfb_rasterimg
(
struct
fb_info
*
info
,
int
start
)
{
struct
fb_info_aty
*
fb
=
(
struct
fb_info_aty
*
)
info
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
if
(
fb
->
blitter_may_be_busy
)
wait_for_idle
(
fb
);
if
(
par
->
blitter_may_be_busy
)
wait_for_idle
(
par
);
return
0
;
}
...
...
@@ -1265,13 +1345,13 @@ static int atyfb_rasterimg(struct fb_info *info, int start)
static
int
atyfb_mmap
(
struct
fb_info
*
info
,
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
{
struct
fb_info_aty
*
fb
=
(
struct
fb_info_aty
*
)
info
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
unsigned
int
size
,
page
,
map_size
=
0
;
unsigned
long
map_offset
=
0
;
unsigned
long
off
;
int
i
;
if
(
!
fb
->
mmap_map
)
if
(
!
par
->
mmap_map
)
return
-
ENXIO
;
if
(
vma
->
vm_pgoff
>
(
~
0UL
>>
PAGE_SHIFT
))
...
...
@@ -1283,18 +1363,18 @@ static int atyfb_mmap(struct fb_info *info, struct file *file,
/* To stop the swapper from even considering these pages. */
vma
->
vm_flags
|=
(
VM_SHM
|
VM_LOCKED
);
if
(((
vma
->
vm_pgoff
==
0
)
&&
(
size
==
fb
->
fb_info
.
fix
.
smem_len
))
||
((
off
==
fb
->
fb_info
.
fix
.
smem_len
)
&&
(
size
==
PAGE_SIZE
)))
if
(((
vma
->
vm_pgoff
==
0
)
&&
(
size
==
info
->
fix
.
smem_len
))
||
((
off
==
info
->
fix
.
smem_len
)
&&
(
size
==
PAGE_SIZE
)))
off
+=
0x8000000000000000UL
;
vma
->
vm_pgoff
=
off
>>
PAGE_SHIFT
;
/* propagate off changes */
/* Each page, see which map applies */
for
(
page
=
0
;
page
<
size
;
)
{
for
(
page
=
0
;
page
<
size
;)
{
map_size
=
0
;
for
(
i
=
0
;
fb
->
mmap_map
[
i
].
size
;
i
++
)
{
unsigned
long
start
=
fb
->
mmap_map
[
i
].
voff
;
unsigned
long
end
=
start
+
fb
->
mmap_map
[
i
].
size
;
for
(
i
=
0
;
par
->
mmap_map
[
i
].
size
;
i
++
)
{
unsigned
long
start
=
par
->
mmap_map
[
i
].
voff
;
unsigned
long
end
=
start
+
par
->
mmap_map
[
i
].
size
;
unsigned
long
offset
=
off
+
page
;
if
(
start
>
offset
)
...
...
@@ -1302,8 +1382,9 @@ static int atyfb_mmap(struct fb_info *info, struct file *file,
if
(
offset
>=
end
)
continue
;
map_size
=
fb
->
mmap_map
[
i
].
size
-
(
offset
-
start
);
map_offset
=
fb
->
mmap_map
[
i
].
poff
+
(
offset
-
start
);
map_size
=
par
->
mmap_map
[
i
].
size
-
(
offset
-
start
);
map_offset
=
par
->
mmap_map
[
i
].
poff
+
(
offset
-
start
);
break
;
}
if
(
!
map_size
)
{
...
...
@@ -1313,8 +1394,9 @@ static int atyfb_mmap(struct fb_info *info, struct file *file,
if
(
page
+
map_size
>
size
)
map_size
=
size
-
page
;
pgprot_val
(
vma
->
vm_page_prot
)
&=
~
(
fb
->
mmap_map
[
i
].
prot_mask
);
pgprot_val
(
vma
->
vm_page_prot
)
|=
fb
->
mmap_map
[
i
].
prot_flag
;
pgprot_val
(
vma
->
vm_page_prot
)
&=
~
(
par
->
mmap_map
[
i
].
prot_mask
);
pgprot_val
(
vma
->
vm_page_prot
)
|=
par
->
mmap_map
[
i
].
prot_flag
;
if
(
remap_page_range
(
vma
,
vma
->
vm_start
+
page
,
map_offset
,
map_size
,
vma
->
vm_page_prot
))
...
...
@@ -1328,14 +1410,15 @@ static int atyfb_mmap(struct fb_info *info, struct file *file,
vma
->
vm_flags
|=
VM_IO
;
if
(
!
fb
->
mmaped
)
{
if
(
!
par
->
mmaped
)
{
int
lastconsole
=
0
;
if
(
info
->
display_fg
)
lastconsole
=
info
->
display_fg
->
vc_num
;
fb
->
mmaped
=
1
;
if
(
fb
->
consolecnt
&&
fb_display
[
lastconsole
].
fb_info
==
info
)
{
fb
->
vtconsole
=
lastconsole
;
par
->
mmaped
=
1
;
if
(
par
->
consolecnt
&&
fb_display
[
lastconsole
].
fb_info
==
info
)
{
par
->
vtconsole
=
lastconsole
;
vt_cons
[
lastconsole
]
->
vc_mode
=
KD_GRAPHICS
;
}
}
...
...
@@ -1349,9 +1432,8 @@ static struct {
u8
b
[
2
][
256
];
}
atyfb_save
;
static
void
atyfb_save_palette
(
struct
fb_info
*
fb
,
int
enter
)
static
void
atyfb_save_palette
(
struct
fb_info
*
info
,
int
enter
)
{
struct
fb_info_aty
*
info
=
(
struct
fb_info_aty
*
)
fb
;
int
i
,
tmp
;
for
(
i
=
0
;
i
<
256
;
i
++
)
{
...
...
@@ -1361,20 +1443,23 @@ static void atyfb_save_palette(struct fb_info *fb, int enter)
aty_st_8
(
DAC_CNTL
,
tmp
,
info
);
aty_st_8
(
DAC_MASK
,
0xff
,
info
);
writeb
(
i
,
&
info
->
aty_cmap_regs
->
rindex
);
atyfb_save
.
r
[
enter
][
i
]
=
readb
(
&
info
->
aty_cmap_regs
->
lut
);
atyfb_save
.
g
[
enter
][
i
]
=
readb
(
&
info
->
aty_cmap_regs
->
lut
);
atyfb_save
.
b
[
enter
][
i
]
=
readb
(
&
info
->
aty_cmap_regs
->
lut
);
writeb
(
i
,
&
info
->
aty_cmap_regs
->
windex
);
writeb
(
atyfb_save
.
r
[
1
-
enter
][
i
],
&
info
->
aty_cmap_regs
->
lut
);
writeb
(
atyfb_save
.
g
[
1
-
enter
][
i
],
&
info
->
aty_cmap_regs
->
lut
);
writeb
(
atyfb_save
.
b
[
1
-
enter
][
i
],
&
info
->
aty_cmap_regs
->
lut
);
writeb
(
i
,
&
par
->
aty_cmap_regs
->
rindex
);
atyfb_save
.
r
[
enter
][
i
]
=
readb
(
&
par
->
aty_cmap_regs
->
lut
);
atyfb_save
.
g
[
enter
][
i
]
=
readb
(
&
par
->
aty_cmap_regs
->
lut
);
atyfb_save
.
b
[
enter
][
i
]
=
readb
(
&
par
->
aty_cmap_regs
->
lut
);
writeb
(
i
,
&
par
->
aty_cmap_regs
->
windex
);
writeb
(
atyfb_save
.
r
[
1
-
enter
][
i
],
&
par
->
aty_cmap_regs
->
lut
);
writeb
(
atyfb_save
.
g
[
1
-
enter
][
i
],
&
par
->
aty_cmap_regs
->
lut
);
writeb
(
atyfb_save
.
b
[
1
-
enter
][
i
],
&
par
->
aty_cmap_regs
->
lut
);
}
}
static
void
atyfb_palette
(
int
enter
)
{
struct
fb_info
_aty
*
info
;
struct
fb_info
*
info
;
struct
atyfb_par
*
par
;
struct
display
*
d
;
int
i
;
...
...
@@ -1386,8 +1471,8 @@ static void atyfb_palette(int enter)
d
->
fb_info
->
display_fg
&&
d
->
fb_info
->
display_fg
->
vc_num
==
i
)
{
atyfb_save_palette
(
d
->
fb_info
,
enter
);
info
=
(
struct
fb_info_aty
*
)
d
->
fb_info
;
par
=
&
info
->
current_
par
;
info
=
d
->
fb_info
;
par
=
(
struct
atyfb_par
*
)
info
->
par
;
if
(
enter
)
{
atyfb_save
.
yoffset
=
par
->
crtc
.
yoffset
;
par
->
crtc
.
yoffset
=
0
;
...
...
@@ -1406,7 +1491,7 @@ static void atyfb_palette(int enter)
#ifdef CONFIG_PMAC_PBOOK
static
struct
fb_info
_aty
*
first_display
=
NULL
;
static
struct
fb_info
*
first_display
=
NULL
;
/* Power management routines. Those are used for PowerBook sleep.
*
...
...
@@ -1414,7 +1499,7 @@ static struct fb_info_aty* first_display = NULL;
* management registers. There's is some confusion about which
* chipID is a Rage LT or LT pro :(
*/
static
int
aty_power_mgmt_LT
(
int
sleep
,
struct
fb_info
_aty
*
info
)
static
int
aty_power_mgmt_LT
(
int
sleep
,
struct
fb_info
*
info
)
{
unsigned
int
pm
;
int
timeout
;
...
...
@@ -1443,7 +1528,8 @@ static int aty_power_mgmt_LT(int sleep, struct fb_info_aty *info)
udelay
(
10
);
if
((
--
timeout
)
==
0
)
break
;
}
while
((
pm
&
PWR_MGT_STATUS_MASK
)
!=
PWR_MGT_STATUS_SUSPEND
);
}
while
((
pm
&
PWR_MGT_STATUS_MASK
)
!=
PWR_MGT_STATUS_SUSPEND
);
}
else
{
/* Wakeup */
pm
&=
~
PWR_MGT_ON
;
...
...
@@ -1469,7 +1555,7 @@ static int aty_power_mgmt_LT(int sleep, struct fb_info_aty *info)
return
timeout
?
PBOOK_SLEEP_OK
:
PBOOK_SLEEP_REFUSE
;
}
static
int
aty_power_mgmt_LTPro
(
int
sleep
,
struct
fb_info
_aty
*
info
)
static
int
aty_power_mgmt_LTPro
(
int
sleep
,
struct
fb_info
*
info
)
{
unsigned
int
pm
;
int
timeout
;
...
...
@@ -1498,7 +1584,8 @@ static int aty_power_mgmt_LTPro(int sleep, struct fb_info_aty *info)
mdelay
(
1
);
if
((
--
timeout
)
==
0
)
break
;
}
while
((
pm
&
PWR_MGT_STATUS_MASK
)
!=
PWR_MGT_STATUS_SUSPEND
);
}
while
((
pm
&
PWR_MGT_STATUS_MASK
)
!=
PWR_MGT_STATUS_SUSPEND
);
}
else
{
/* Wakeup */
pm
&=
~
PWR_MGT_ON
;
...
...
@@ -1523,7 +1610,7 @@ static int aty_power_mgmt_LTPro(int sleep, struct fb_info_aty *info)
return
timeout
?
PBOOK_SLEEP_OK
:
PBOOK_SLEEP_REFUSE
;
}
static
int
aty_power_mgmt
(
int
sleep
,
struct
fb_info
_aty
*
info
)
static
int
aty_power_mgmt
(
int
sleep
,
struct
fb_info
*
info
)
{
return
M64_HAS
(
LT_SLEEP
)
?
aty_power_mgmt_LT
(
sleep
,
info
)
:
aty_power_mgmt_LTPro
(
sleep
,
info
);
...
...
@@ -1535,7 +1622,8 @@ static int aty_power_mgmt(int sleep, struct fb_info_aty *info)
*/
static
int
aty_sleep_notify
(
struct
pmu_sleep_notifier
*
self
,
int
when
)
{
struct
fb_info_aty
*
info
;
struct
fb_info
*
info
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
fb
.
par
;
int
result
;
result
=
PBOOK_SLEEP_OK
;
...
...
@@ -1544,35 +1632,35 @@ static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
struct
fb_fix_screeninfo
fix
;
int
nb
;
atyfb_get_fix
(
&
fix
,
fg_console
,
(
struct
fb_info
*
)
info
);
atyfb_get_fix
(
&
fix
,
fg_console
,
info
);
nb
=
fb_display
[
fg_console
].
var
.
yres
*
fix
.
line_length
;
switch
(
when
)
{
case
PBOOK_SLEEP_REQUEST
:
info
->
save_framebuffer
=
vmalloc
(
nb
);
if
(
info
->
save_framebuffer
==
NULL
)
par
->
save_framebuffer
=
vmalloc
(
nb
);
if
(
par
->
save_framebuffer
==
NULL
)
return
PBOOK_SLEEP_REFUSE
;
break
;
case
PBOOK_SLEEP_REJECT
:
if
(
info
->
save_framebuffer
)
{
vfree
(
info
->
save_framebuffer
);
info
->
save_framebuffer
=
0
;
if
(
par
->
save_framebuffer
)
{
vfree
(
par
->
save_framebuffer
);
par
->
save_framebuffer
=
0
;
}
break
;
case
PBOOK_SLEEP_NOW
:
if
(
info
->
blitter_may_be_busy
)
wait_for_idle
(
info
);
if
(
par
->
blitter_may_be_busy
)
wait_for_idle
(
par
);
/* Stop accel engine (stop bus mastering) */
if
(
info
->
current_par
.
accel_flags
&
FB_ACCELF_TEXT
)
if
(
par
->
accel_flags
&
FB_ACCELF_TEXT
)
aty_reset_engine
(
info
);
/* Backup fb content */
if
(
info
->
save_framebuffer
)
memcpy_fromio
(
info
->
save_framebuffer
,
(
void
*
)
info
->
fb_info
.
screen_base
,
nb
);
if
(
par
->
save_framebuffer
)
memcpy_fromio
(
par
->
save_framebuffer
,
(
void
*
)
info
->
screen_base
,
nb
);
/* Blank display and LCD */
atyfb_blank
(
VESA_POWERDOWN
+
1
,
(
struct
fb_info
*
)
info
);
atyfb_blank
(
VESA_POWERDOWN
+
1
,
info
);
/* Set chip to "suspend" mode */
result
=
aty_power_mgmt
(
1
,
info
);
...
...
@@ -1582,15 +1670,15 @@ static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
result
=
aty_power_mgmt
(
0
,
info
);
/* Restore fb content */
if
(
info
->
save_framebuffer
)
{
memcpy_toio
((
void
*
)
info
->
fb_info
.
screen_base
,
info
->
save_framebuffer
,
nb
);
vfree
(
info
->
save_framebuffer
);
info
->
save_framebuffer
=
0
;
if
(
par
->
save_framebuffer
)
{
memcpy_toio
((
void
*
)
info
->
screen_base
,
par
->
save_framebuffer
,
nb
);
vfree
(
par
->
save_framebuffer
);
par
->
save_framebuffer
=
0
;
}
/* Restore display */
atyfb_set_par
(
&
info
->
current_
par
,
info
);
atyfb_blank
(
0
,
(
struct
fb_info
*
)
info
);
atyfb_set_par
(
par
->
par
,
info
);
atyfb_blank
(
0
,
info
);
break
;
}
}
...
...
@@ -1613,10 +1701,9 @@ static int backlight_conv[] = {
0x9a
,
0xa7
,
0xb4
,
0xc1
,
0xcf
,
0xdc
,
0xe9
,
0xff
};
static
int
aty_set_backlight_enable
(
int
on
,
int
level
,
void
*
data
)
static
int
aty_set_backlight_enable
(
int
on
,
int
level
,
void
*
data
)
{
struct
fb_info
_aty
*
info
=
(
struct
fb_info_aty
*
)
data
;
struct
fb_info
*
info
=
(
struct
fb_info
*
)
data
;
unsigned
int
reg
=
aty_ld_lcd
(
LCD_MISC_CNTL
,
info
);
reg
|=
(
BLMOD_EN
|
BIASMOD_EN
);
...
...
@@ -1632,8 +1719,7 @@ aty_set_backlight_enable(int on, int level, void* data)
return
0
;
}
static
int
aty_set_backlight_level
(
int
level
,
void
*
data
)
static
int
aty_set_backlight_level
(
int
level
,
void
*
data
)
{
return
aty_set_backlight_enable
(
1
,
level
,
data
);
}
...
...
@@ -1650,57 +1736,62 @@ static struct backlight_controller aty_backlight_controller = {
* Initialisation
*/
static
struct
fb_info
_aty
*
fb_list
=
NULL
;
static
struct
fb_info
*
fb_list
=
NULL
;
static
int
__init
aty_init
(
struct
fb_info
_aty
*
info
,
const
char
*
name
)
static
int
__init
aty_init
(
struct
fb_info
*
info
,
const
char
*
name
)
{
u32
chip_id
,
i
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
const
char
*
chipname
=
NULL
,
*
ramname
=
NULL
,
*
xtal
;
int
j
,
pll
,
mclk
,
gtb_memsize
;
struct
fb_var_screeninfo
var
;
struct
display
*
disp
;
u32
chip_id
,
i
;
u16
type
;
u8
rev
;
const
char
*
chipname
=
NULL
,
*
ramname
=
NULL
,
*
xtal
;
int
j
,
pll
,
mclk
,
gtb_memsize
;
#if defined(CONFIG_PPC)
int
sense
;
#endif
u8
pll_ref_div
;
info
->
aty_cmap_regs
=
(
struct
aty_cmap_regs
*
)(
info
->
ati_regbase
+
0xc0
);
chip_id
=
aty_ld_le32
(
CONFIG_CHIP_ID
,
info
);
par
->
aty_cmap_regs
=
(
struct
aty_cmap_regs
*
)
(
par
->
ati_regbase
+
0xc0
);
chip_id
=
aty_ld_le32
(
CONFIG_CHIP_ID
,
par
);
type
=
chip_id
&
CFG_CHIP_TYPE
;
rev
=
(
chip_id
&
CFG_CHIP_REV
)
>>
24
;
for
(
j
=
0
;
j
<
(
sizeof
(
aty_chips
)
/
sizeof
(
*
aty_chips
));
j
++
)
rev
=
(
chip_id
&
CFG_CHIP_REV
)
>>
24
;
for
(
j
=
0
;
j
<
(
sizeof
(
aty_chips
)
/
sizeof
(
*
aty_chips
));
j
++
)
if
(
type
==
aty_chips
[
j
].
chip_type
&&
(
rev
&
aty_chips
[
j
].
rev_mask
)
==
aty_chips
[
j
].
rev_val
)
{
(
rev
&
aty_chips
[
j
].
rev_mask
)
==
aty_chips
[
j
].
rev_val
)
{
chipname
=
aty_chips
[
j
].
name
;
pll
=
aty_chips
[
j
].
pll
;
mclk
=
aty_chips
[
j
].
mclk
;
info
->
features
=
aty_chips
[
j
].
features
;
par
->
features
=
aty_chips
[
j
].
features
;
goto
found
;
}
printk
(
"atyfb: Unknown mach64 0x%04x rev 0x%04x
\n
"
,
type
,
rev
);
return
0
;
found:
found:
printk
(
"atyfb: %s [0x%04x rev 0x%02x] "
,
chipname
,
type
,
rev
);
#ifdef CONFIG_FB_ATY_GX
if
(
!
M64_HAS
(
INTEGRATED
))
{
u32
stat0
;
u8
dac_type
,
dac_subtype
,
clk_type
;
stat0
=
aty_ld_le32
(
CONFIG_STAT0
,
info
);
info
->
bus_type
=
(
stat0
>>
0
)
&
0x07
;
info
->
ram_type
=
(
stat0
>>
3
)
&
0x07
;
ramname
=
aty_gx_ram
[
info
->
ram_type
];
par
->
bus_type
=
(
stat0
>>
0
)
&
0x07
;
par
->
ram_type
=
(
stat0
>>
3
)
&
0x07
;
ramname
=
aty_gx_ram
[
par
->
ram_type
];
/* FIXME: clockchip/RAMDAC probing? */
dac_type
=
(
aty_ld_le32
(
DAC_CNTL
,
info
)
>>
16
)
&
0x07
;
dac_type
=
(
aty_ld_le32
(
DAC_CNTL
,
par
)
>>
16
)
&
0x07
;
#ifdef CONFIG_ATARI
clk_type
=
CLK_ATI18818_1
;
dac_type
=
(
stat0
>>
9
)
&
0x07
;
if
(
dac_type
==
0x07
)
dac_subtype
=
DAC_ATT20C408
;
else
dac_subtype
=
(
aty_ld_8
(
SCRATCH_REG1
+
1
,
info
)
&
0xF0
)
|
dac_type
;
dac_subtype
=
(
aty_ld_8
(
SCRATCH_REG1
+
1
,
par
)
&
0xF0
)
|
dac_type
;
#else
dac_type
=
DAC_IBMRGB514
;
dac_subtype
=
DAC_IBMRGB514
;
...
...
@@ -1708,143 +1799,145 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
#endif
switch
(
dac_subtype
)
{
case
DAC_IBMRGB514
:
info
->
dac_ops
=
&
aty_dac_ibm514
;
par
->
dac_ops
=
&
aty_dac_ibm514
;
break
;
case
DAC_ATI68860_B
:
case
DAC_ATI68860_C
:
info
->
dac_ops
=
&
aty_dac_ati68860b
;
par
->
dac_ops
=
&
aty_dac_ati68860b
;
break
;
case
DAC_ATT20C408
:
case
DAC_ATT21C498
:
info
->
dac_ops
=
&
aty_dac_att21c498
;
par
->
dac_ops
=
&
aty_dac_att21c498
;
break
;
default:
printk
(
" atyfb_set_par: DAC type not implemented yet!
\n
"
);
info
->
dac_ops
=
&
aty_dac_unsupported
;
printk
(
" atyfb_set_par: DAC type not implemented yet!
\n
"
);
par
->
dac_ops
=
&
aty_dac_unsupported
;
break
;
}
switch
(
clk_type
)
{
case
CLK_ATI18818_1
:
info
->
pll_ops
=
&
aty_pll_ati18818_1
;
par
->
pll_ops
=
&
aty_pll_ati18818_1
;
break
;
case
CLK_STG1703
:
info
->
pll_ops
=
&
aty_pll_stg1703
;
par
->
pll_ops
=
&
aty_pll_stg1703
;
break
;
case
CLK_CH8398
:
info
->
pll_ops
=
&
aty_pll_ch8398
;
par
->
pll_ops
=
&
aty_pll_ch8398
;
break
;
case
CLK_ATT20C408
:
info
->
pll_ops
=
&
aty_pll_att20c408
;
par
->
pll_ops
=
&
aty_pll_att20c408
;
break
;
case
CLK_IBMRGB514
:
info
->
pll_ops
=
&
aty_pll_ibm514
;
par
->
pll_ops
=
&
aty_pll_ibm514
;
break
;
default:
printk
(
" atyfb_set_par: CLK type not implemented yet!"
);
info
->
pll_ops
=
&
aty_pll_unsupported
;
printk
(
" atyfb_set_par: CLK type not implemented yet!"
);
par
->
pll_ops
=
&
aty_pll_unsupported
;
break
;
}
}
#endif
/* CONFIG_FB_ATY_GX */
#ifdef CONFIG_FB_ATY_CT
if
(
M64_HAS
(
INTEGRATED
))
{
info
->
bus_type
=
PCI
;
info
->
ram_type
=
(
aty_ld_le32
(
CONFIG_STAT0
,
info
)
&
0x07
);
ramname
=
aty_ct_ram
[
info
->
ram_type
];
info
->
dac_ops
=
&
aty_dac_ct
;
info
->
pll_ops
=
&
aty_pll_ct
;
par
->
bus_type
=
PCI
;
par
->
ram_type
=
(
aty_ld_le32
(
CONFIG_STAT0
,
par
)
&
0x07
);
ramname
=
aty_ct_ram
[
par
->
ram_type
];
par
->
dac_ops
=
&
aty_dac_ct
;
par
->
pll_ops
=
&
aty_pll_ct
;
/* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
if
(
mclk
==
67
&&
info
->
ram_type
<
SDRAM
)
if
(
mclk
==
67
&&
par
->
ram_type
<
SDRAM
)
mclk
=
63
;
}
#endif
/* CONFIG_FB_ATY_CT */
info
->
ref_clk_per
=
1000000000000ULL
/
14318180
;
par
->
ref_clk_per
=
1000000000000ULL
/
14318180
;
xtal
=
"14.31818"
;
if
(
M64_HAS
(
GTB_DSP
)
&&
(
pll_ref_div
=
aty_ld_pll
(
PLL_REF_DIV
,
info
)))
{
if
(
M64_HAS
(
GTB_DSP
)
&&
(
pll_ref_div
=
aty_ld_pll
(
PLL_REF_DIV
,
par
)))
{
int
diff1
,
diff2
;
diff1
=
510
*
14
/
pll_ref_div
-
pll
;
diff2
=
510
*
29
/
pll_ref_div
-
pll
;
diff1
=
510
*
14
/
pll_ref_div
-
pll
;
diff2
=
510
*
29
/
pll_ref_div
-
pll
;
if
(
diff1
<
0
)
diff1
=
-
diff1
;
if
(
diff2
<
0
)
diff2
=
-
diff2
;
if
(
diff2
<
diff1
)
{
info
->
ref_clk_per
=
1000000000000ULL
/
29498928
;
par
->
ref_clk_per
=
1000000000000ULL
/
29498928
;
xtal
=
"29.498928"
;
}
}
i
=
aty_ld_le32
(
MEM_CNTL
,
info
);
i
=
aty_ld_le32
(
MEM_CNTL
,
par
);
gtb_memsize
=
M64_HAS
(
GTB_DSP
);
if
(
gtb_memsize
)
switch
(
i
&
0xF
)
{
/* 0xF used instead of MEM_SIZE_ALIAS */
case
MEM_SIZE_512K
:
info
->
fb_info
.
fix
.
smem_len
=
0x80000
;
info
->
fix
.
smem_len
=
0x80000
;
break
;
case
MEM_SIZE_1M
:
info
->
fb_info
.
fix
.
smem_len
=
0x100000
;
info
->
fix
.
smem_len
=
0x100000
;
break
;
case
MEM_SIZE_2M_GTB
:
info
->
fb_info
.
fix
.
smem_len
=
0x200000
;
info
->
fix
.
smem_len
=
0x200000
;
break
;
case
MEM_SIZE_4M_GTB
:
info
->
fb_info
.
fix
.
smem_len
=
0x400000
;
info
->
fix
.
smem_len
=
0x400000
;
break
;
case
MEM_SIZE_6M_GTB
:
info
->
fb_info
.
fix
.
smem_len
=
0x600000
;
info
->
fix
.
smem_len
=
0x600000
;
break
;
case
MEM_SIZE_8M_GTB
:
info
->
fb_info
.
fix
.
smem_len
=
0x800000
;
info
->
fix
.
smem_len
=
0x800000
;
break
;
default:
info
->
fb_info
.
fix
.
smem_len
=
0x80000
;
}
else
info
->
fix
.
smem_len
=
0x80000
;
}
else
switch
(
i
&
MEM_SIZE_ALIAS
)
{
case
MEM_SIZE_512K
:
info
->
fb_info
.
fix
.
smem_len
=
0x80000
;
info
->
fix
.
smem_len
=
0x80000
;
break
;
case
MEM_SIZE_1M
:
info
->
fb_info
.
fix
.
smem_len
=
0x100000
;
info
->
fix
.
smem_len
=
0x100000
;
break
;
case
MEM_SIZE_2M
:
info
->
fb_info
.
fix
.
smem_len
=
0x200000
;
info
->
fix
.
smem_len
=
0x200000
;
break
;
case
MEM_SIZE_4M
:
info
->
fb_info
.
fix
.
smem_len
=
0x400000
;
info
->
fix
.
smem_len
=
0x400000
;
break
;
case
MEM_SIZE_6M
:
info
->
fb_info
.
fix
.
smem_len
=
0x600000
;
info
->
fix
.
smem_len
=
0x600000
;
break
;
case
MEM_SIZE_8M
:
info
->
fb_info
.
fix
.
smem_len
=
0x800000
;
info
->
fix
.
smem_len
=
0x800000
;
break
;
default:
info
->
fb_info
.
fix
.
smem_len
=
0x80000
;
info
->
fix
.
smem_len
=
0x80000
;
}
if
(
M64_HAS
(
MAGIC_VRAM_SIZE
))
{
if
(
aty_ld_le32
(
CONFIG_STAT1
,
info
)
&
0x40000000
)
info
->
fb_info
.
fix
.
smem_len
+=
0x400000
;
if
(
aty_ld_le32
(
CONFIG_STAT1
,
par
)
&
0x40000000
)
info
->
fix
.
smem_len
+=
0x400000
;
}
if
(
default_vram
)
{
info
->
fb_info
.
fix
.
smem_len
=
default_vram
*
1024
;
info
->
fix
.
smem_len
=
default_vram
*
1024
;
i
=
i
&
~
(
gtb_memsize
?
0xF
:
MEM_SIZE_ALIAS
);
if
(
info
->
fb_info
.
fix
.
smem_len
<=
0x80000
)
if
(
info
->
fix
.
smem_len
<=
0x80000
)
i
|=
MEM_SIZE_512K
;
else
if
(
info
->
fb_info
.
fix
.
smem_len
<=
0x100000
)
else
if
(
info
->
fix
.
smem_len
<=
0x100000
)
i
|=
MEM_SIZE_1M
;
else
if
(
info
->
fb_info
.
fix
.
smem_len
<=
0x200000
)
else
if
(
info
->
fix
.
smem_len
<=
0x200000
)
i
|=
gtb_memsize
?
MEM_SIZE_2M_GTB
:
MEM_SIZE_2M
;
else
if
(
info
->
fb_info
.
fix
.
smem_len
<=
0x400000
)
else
if
(
info
->
fix
.
smem_len
<=
0x400000
)
i
|=
gtb_memsize
?
MEM_SIZE_4M_GTB
:
MEM_SIZE_4M
;
else
if
(
info
->
fb_info
.
fix
.
smem_len
<=
0x600000
)
else
if
(
info
->
fix
.
smem_len
<=
0x600000
)
i
|=
gtb_memsize
?
MEM_SIZE_6M_GTB
:
MEM_SIZE_6M
;
else
i
|=
gtb_memsize
?
MEM_SIZE_8M_GTB
:
MEM_SIZE_8M
;
aty_st_le32
(
MEM_CNTL
,
i
,
info
);
aty_st_le32
(
MEM_CNTL
,
i
,
par
);
}
/*
...
...
@@ -1852,19 +1945,20 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
* Reg Block 1 (multimedia extensions) is at mmio_start - 0x400
*/
if
(
M64_HAS
(
GX
))
{
info
->
fb_info
.
fix
.
mmio_len
=
0x400
;
info
->
fb_info
.
fix
.
accel
=
FB_ACCEL_ATI_MACH64GX
;
info
->
fix
.
mmio_len
=
0x400
;
info
->
fix
.
accel
=
FB_ACCEL_ATI_MACH64GX
;
}
else
if
(
M64_HAS
(
CT
))
{
info
->
fb_info
.
fix
.
mmio_len
=
0x400
;
info
->
fb_info
.
fix
.
accel
=
FB_ACCEL_ATI_MACH64CT
;
info
->
fix
.
mmio_len
=
0x400
;
info
->
fix
.
accel
=
FB_ACCEL_ATI_MACH64CT
;
}
else
if
(
M64_HAS
(
VT
))
{
info
->
fb_info
.
fix
.
mmio_start
=-
0x400
;
info
->
fb_info
.
fix
.
mmio_len
=
0x800
;
info
->
fb_info
.
fix
.
accel
=
FB_ACCEL_ATI_MACH64VT
;
}
else
/* if (M64_HAS(GT)) */
{
info
->
fb_info
.
fix
.
mmio_start
=-
0x400
;
info
->
fb_info
.
fix
.
mmio_len
=
0x800
;
info
->
fb_info
.
fix
.
accel
=
FB_ACCEL_ATI_MACH64GT
;
info
->
fix
.
mmio_start
=
-
0x400
;
info
->
fix
.
mmio_len
=
0x800
;
info
->
fix
.
accel
=
FB_ACCEL_ATI_MACH64VT
;
}
else
{
/* if (M64_HAS(GT)) */
info
->
fix
.
mmio_start
=
-
0x400
;
info
->
fix
.
mmio_len
=
0x800
;
info
->
fix
.
accel
=
FB_ACCEL_ATI_MACH64GT
;
}
if
(
default_pll
)
...
...
@@ -1873,41 +1967,46 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
mclk
=
default_mclk
;
printk
(
"%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK
\n
"
,
info
->
fb_info
.
fix
.
smem_len
==
0x80000
?
512
:
(
info
->
fb_info
.
fix
.
smem_len
>>
20
),
info
->
fb_info
.
fix
.
smem_len
==
0x80000
?
'K'
:
'M'
,
ramname
,
xtal
,
pll
,
mclk
);
info
->
fix
.
smem_len
==
0x80000
?
512
:
(
info
->
fix
.
smem_len
>>
20
),
info
->
fix
.
smem_len
==
0x80000
?
'K'
:
'M'
,
ramname
,
xtal
,
pll
,
mclk
);
if
(
mclk
<
44
)
info
->
mem_refresh_rate
=
0
;
/* 000 = 10 Mhz - 43 Mhz */
par
->
mem_refresh_rate
=
0
;
/* 000 = 10 Mhz - 43 Mhz */
else
if
(
mclk
<
50
)
info
->
mem_refresh_rate
=
1
;
/* 001 = 44 Mhz - 49 Mhz */
par
->
mem_refresh_rate
=
1
;
/* 001 = 44 Mhz - 49 Mhz */
else
if
(
mclk
<
55
)
info
->
mem_refresh_rate
=
2
;
/* 010 = 50 Mhz - 54 Mhz */
par
->
mem_refresh_rate
=
2
;
/* 010 = 50 Mhz - 54 Mhz */
else
if
(
mclk
<
66
)
info
->
mem_refresh_rate
=
3
;
/* 011 = 55 Mhz - 65 Mhz */
par
->
mem_refresh_rate
=
3
;
/* 011 = 55 Mhz - 65 Mhz */
else
if
(
mclk
<
75
)
info
->
mem_refresh_rate
=
4
;
/* 100 = 66 Mhz - 74 Mhz */
par
->
mem_refresh_rate
=
4
;
/* 100 = 66 Mhz - 74 Mhz */
else
if
(
mclk
<
80
)
info
->
mem_refresh_rate
=
5
;
/* 101 = 75 Mhz - 79 Mhz */
par
->
mem_refresh_rate
=
5
;
/* 101 = 75 Mhz - 79 Mhz */
else
if
(
mclk
<
100
)
info
->
mem_refresh_rate
=
6
;
/* 110 = 80 Mhz - 100 Mhz */
par
->
mem_refresh_rate
=
6
;
/* 110 = 80 Mhz - 100 Mhz */
else
info
->
mem_refresh_rate
=
7
;
/* 111 = 100 Mhz and above */
info
->
pll_per
=
1000000
/
pll
;
info
->
mclk_per
=
1000000
/
mclk
;
par
->
mem_refresh_rate
=
7
;
/* 111 = 100 Mhz and above */
par
->
pll_per
=
1000000
/
pll
;
par
->
mclk_per
=
1000000
/
mclk
;
#ifdef DEBUG
if
(
M64_HAS
(
INTEGRATED
))
{
int
i
;
printk
(
"BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
printk
(
"BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
"DSP_CONFIG DSP_ON_OFF
\n
"
"%08x %08x %08x %08x %08x %08x %08x
\n
"
"PLL"
,
aty_ld_le32
(
BUS_CNTL
,
info
),
aty_ld_le32
(
DAC_CNTL
,
info
),
aty_ld_le32
(
MEM_CNTL
,
info
),
aty_ld_le32
(
EXT_MEM_CNTL
,
info
),
aty_ld_le32
(
CRTC_GEN_CNTL
,
info
),
aty_ld_le32
(
DSP_CONFIG
,
info
),
aty_ld_le32
(
DSP_ON_OFF
,
info
));
"PLL"
,
aty_ld_le32
(
BUS_CNTL
,
par
),
aty_ld_le32
(
DAC_CNTL
,
par
),
aty_ld_le32
(
MEM_CNTL
,
par
),
aty_ld_le32
(
EXT_MEM_CNTL
,
par
),
aty_ld_le32
(
CRTC_GEN_CNTL
,
par
),
aty_ld_le32
(
DSP_CONFIG
,
par
),
aty_ld_le32
(
DSP_ON_OFF
,
par
));
for
(
i
=
0
;
i
<
16
;
i
++
)
printk
(
" %02x"
,
aty_ld_pll
(
i
,
info
));
printk
(
" %02x"
,
aty_ld_pll
(
i
,
par
));
printk
(
"
\n
"
);
}
#endif
...
...
@@ -1917,35 +2016,39 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
* FIXME: we should use the auxiliary aperture instead so we can access
* the full 8 MB of video RAM on 8 MB boards
*/
if
(
info
->
fb_info
.
fix
.
smem_len
==
0x800000
||
(
info
->
bus_type
==
ISA
&&
info
->
fb_info
.
fix
.
smem_len
==
0x400000
))
info
->
fb_info
.
fix
.
smem_len
-=
GUI_RESERVE
;
if
(
info
->
fix
.
smem_len
==
0x800000
||
(
par
->
bus_type
==
ISA
&&
info
->
fix
.
smem_len
==
0x400000
))
info
->
fix
.
smem_len
-=
GUI_RESERVE
;
/* Clear the video memory */
fb_memset
((
void
*
)
info
->
fb_info
.
screen_base
,
0
,
info
->
fb_info
.
fix
.
smem_len
);
disp
=
info
->
fb_info
.
disp
;
strcpy
(
info
->
fb_info
.
modename
,
atyfb_name
);
info
->
fb_info
.
node
=
NODEV
;
info
->
fb_info
.
fbops
=
&
atyfb_ops
;
info
->
fb_info
.
disp
=
disp
;
info
->
fb_info
.
pseudo_palette
=
pseudo_palette
;
info
->
fb_info
.
currcon
=
-
1
;
strcpy
(
info
->
fb_info
.
fontname
,
fontname
);
info
->
fb_info
.
changevar
=
NULL
;
info
->
fb_info
.
switch_con
=
gen_switch
;
info
->
fb_info
.
updatevar
=
&
atyfbcon_updatevar
;
info
->
fb_info
.
flags
=
FBINFO_FLAG_DEFAULT
;
fb_memset
((
void
*
)
info
->
screen_base
,
0
,
info
->
fix
.
smem_len
);
disp
=
info
->
disp
;
strcpy
(
info
->
modename
,
atyfb_name
);
info
->
node
=
NODEV
;
info
->
fbops
=
&
atyfb_ops
;
info
->
disp
=
disp
;
info
->
pseudo_palette
=
pseudo_palette
;
info
->
currcon
=
-
1
;
strcpy
(
info
->
fontname
,
fontname
);
info
->
changevar
=
NULL
;
info
->
switch_con
=
gen_switch
;
info
->
updatevar
=
&
atyfbcon_updatevar
;
info
->
flags
=
FBINFO_FLAG_DEFAULT
;
#ifdef CONFIG_PMAC_BACKLIGHT
if
(
M64_HAS
(
G3_PB_1_1
)
&&
machine_is_compatible
(
"PowerBook1,1"
))
{
/* these bits let the 101 powerbook wake up from sleep -- paulus */
aty_st_lcd
(
POWER_MANAGEMENT
,
aty_ld_lcd
(
POWER_MANAGEMENT
,
info
)
|
(
USE_F32KHZ
|
TRISTATE_MEM_EN
),
info
);
aty_st_lcd
(
POWER_MANAGEMENT
,
aty_ld_lcd
(
POWER_MANAGEMENT
,
par
)
|
(
USE_F32KHZ
|
TRISTATE_MEM_EN
),
par
);
}
if
(
M64_HAS
(
MOBIL_BUS
))
register_backlight_controller
(
&
aty_backlight_controller
,
info
,
"ati"
);
register_backlight_controller
(
&
aty_backlight_controller
,
info
,
"ati"
);
#endif
/* CONFIG_PMAC_BACKLIGHT */
#ifdef MODULE
...
...
@@ -1959,13 +2062,15 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
* applies to all Mac video cards
*/
if
(
mode_option
)
{
if
(
!
mac_find_mode
(
&
var
,
&
info
->
fb_info
,
mode_option
,
8
))
if
(
!
mac_find_mode
(
&
var
,
info
,
mode_option
,
8
))
var
=
default_var
;
}
else
{
#ifdef CONFIG_NVRAM
if
(
default_vmode
==
VMODE_NVRAM
)
{
default_vmode
=
nvram_read_byte
(
NV_VMODE
);
if
(
default_vmode
<=
0
||
default_vmode
>
VMODE_MAX
)
if
(
default_vmode
<=
0
||
default_vmode
>
VMODE_MAX
)
default_vmode
=
VMODE_CHOOSE
;
}
#endif
...
...
@@ -1975,38 +2080,47 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
default_vmode
=
VMODE_1024_768_60
;
else
if
(
machine_is_compatible
(
"iMac"
))
default_vmode
=
VMODE_1024_768_75
;
else
if
(
machine_is_compatible
(
"PowerBook2,1"
))
else
if
(
machine_is_compatible
(
"PowerBook2,1"
))
/* iBook with 800x600 LCD */
default_vmode
=
VMODE_800_600_60
;
else
default_vmode
=
VMODE_640_480_67
;
sense
=
read_aty_sense
(
info
);
printk
(
KERN_INFO
"atyfb: monitor sense=%x, mode %d
\n
"
,
sense
,
mac_map_monitor_sense
(
sense
));
printk
(
KERN_INFO
"atyfb: monitor sense=%x, mode %d
\n
"
,
sense
,
mac_map_monitor_sense
(
sense
));
}
if
(
default_vmode
<=
0
||
default_vmode
>
VMODE_MAX
)
if
(
default_vmode
<=
0
||
default_vmode
>
VMODE_MAX
)
default_vmode
=
VMODE_640_480_60
;
#ifdef CONFIG_NVRAM
if
(
default_cmode
==
CMODE_NVRAM
)
default_cmode
=
nvram_read_byte
(
NV_CMODE
);
#endif
if
(
default_cmode
<
CMODE_8
||
default_cmode
>
CMODE_32
)
if
(
default_cmode
<
CMODE_8
||
default_cmode
>
CMODE_32
)
default_cmode
=
CMODE_8
;
if
(
mac_vmode_to_var
(
default_vmode
,
default_cmode
,
&
var
))
if
(
mac_vmode_to_var
(
default_vmode
,
default_cmode
,
&
var
))
var
=
default_var
;
}
}
else
if
(
!
fb_find_mode
(
&
var
,
&
info
->
fb_info
,
mode_option
,
NULL
,
0
,
NULL
,
8
))
}
else
if
(
!
fb_find_mode
(
&
var
,
info
,
mode_option
,
NULL
,
0
,
NULL
,
8
))
var
=
default_var
;
#else
/* !CONFIG_PPC */
#ifdef __sparc__
if
(
mode_option
)
{
if
(
!
fb_find_mode
(
&
var
,
&
info
->
fb_info
,
mode_option
,
NULL
,
0
,
NULL
,
8
))
if
(
!
fb_find_mode
(
&
var
,
info
,
mode_option
,
NULL
,
0
,
NULL
,
8
))
var
=
default_var
;
}
else
var
=
default_var
;
#else
if
(
!
fb_find_mode
(
&
var
,
&
info
->
fb_info
,
mode_option
,
NULL
,
0
,
NULL
,
8
))
if
(
!
fb_find_mode
(
&
var
,
info
,
mode_option
,
NULL
,
0
,
NULL
,
8
))
var
=
default_var
;
#endif
/* !__sparc__ */
#endif
/* !CONFIG_PPC */
...
...
@@ -2017,44 +2131,45 @@ static int __init aty_init(struct fb_info_aty *info, const char *name)
var
.
accel_flags
|=
FB_ACCELF_TEXT
;
if
(
var
.
yres
==
var
.
yres_virtual
)
{
u32
vram
=
(
info
->
fb_info
.
fix
.
smem_len
-
(
PAGE_SIZE
<<
2
));
var
.
yres_virtual
=
((
vram
*
8
)
/
var
.
bits_per_pixel
)
/
var
.
xres_virtual
;
u32
vram
=
(
info
->
fix
.
smem_len
-
(
PAGE_SIZE
<<
2
));
var
.
yres_virtual
=
((
vram
*
8
)
/
var
.
bits_per_pixel
)
/
var
.
xres_virtual
;
if
(
var
.
yres_virtual
<
var
.
yres
)
var
.
yres_virtual
=
var
.
yres
;
}
if
(
atyfb_decode_var
(
&
var
,
&
info
->
default_
par
,
info
))
{
if
(
atyfb_decode_var
(
&
var
,
par
,
info
))
{
printk
(
"atyfb: can't set default video mode
\n
"
);
return
0
;
}
#ifdef __sparc__
atyfb_save_palette
(
&
info
->
fb_
info
,
0
);
atyfb_save_palette
(
info
,
0
);
#endif
#ifdef CONFIG_FB_ATY_CT
if
(
curblink
&&
M64_HAS
(
INTEGRATED
))
{
info
->
cursor
=
aty_init_cursor
(
info
);
if
(
info
->
cursor
)
{
info
->
dispsw
.
cursor
=
atyfb_cursor
;
info
->
dispsw
.
set_font
=
atyfb_set_font
;
par
->
cursor
=
aty_init_cursor
(
info
);
if
(
par
->
cursor
)
{
/*
disp->dispsw.cursor = atyfb_cursor;
disp->dispsw.set_font = atyfb_set_font;
*/
}
}
#endif
/* CONFIG_FB_ATY_CT */
info
->
fb_info
.
var
=
var
;
info
->
var
=
var
;
fb_alloc_cmap
(
&
info
->
fb_info
.
cmap
,
256
,
0
);
fb_alloc_cmap
(
&
info
->
cmap
,
256
,
0
);
atyfb_set_var
(
&
var
,
-
1
,
&
info
->
fb_
info
);
atyfb_set_var
(
&
var
,
-
1
,
info
);
if
(
register_framebuffer
(
&
info
->
fb_
info
)
<
0
)
if
(
register_framebuffer
(
info
)
<
0
)
return
0
;
info
->
next
=
fb_list
;
fb_list
=
info
;
printk
(
"fb%d: %s frame buffer device on %s
\n
"
,
GET_FB_IDX
(
info
->
fb_info
.
node
),
atyfb_name
,
name
);
GET_FB_IDX
(
info
->
node
),
atyfb_name
,
name
);
return
1
;
}
...
...
@@ -2062,7 +2177,7 @@ int __init atyfb_init(void)
{
#if defined(CONFIG_PCI)
struct
pci_dev
*
pdev
=
NULL
;
struct
fb_info_aty
*
info
;
struct
fb_info
*
info
;
unsigned
long
addr
,
res_start
,
res_size
;
int
i
;
#ifdef __sparc__
...
...
@@ -2079,25 +2194,45 @@ int __init atyfb_init(void)
#else
u16
tmp
;
#endif
struct
atyfb_par
*
default_par
;
while
((
pdev
=
pci_find_device
(
PCI_VENDOR_ID_ATI
,
PCI_ANY_ID
,
pdev
)))
{
while
((
pdev
=
pci_find_device
(
PCI_VENDOR_ID_ATI
,
PCI_ANY_ID
,
pdev
)))
{
if
((
pdev
->
class
>>
16
)
==
PCI_BASE_CLASS_DISPLAY
)
{
struct
resource
*
rp
;
for
(
i
=
sizeof
(
aty_chips
)
/
sizeof
(
*
aty_chips
)
-
1
;
i
>=
0
;
i
--
)
for
(
i
=
sizeof
(
aty_chips
)
/
sizeof
(
*
aty_chips
)
-
1
;
i
>=
0
;
i
--
)
if
(
pdev
->
device
==
aty_chips
[
i
].
pci_id
)
break
;
if
(
i
<
0
)
continue
;
info
=
kmalloc
(
sizeof
(
struct
fb_info_aty
)
+
sizeof
(
struct
display
),
GFP_ATOMIC
);
info
=
kmalloc
(
sizeof
(
struct
fb_info
)
+
sizeof
(
struct
display
),
GFP_ATOMIC
);
if
(
!
info
)
{
printk
(
"atyfb_init: can't alloc fb_info_aty
\n
"
);
printk
(
"atyfb_init: can't alloc fb_info
\n
"
);
return
-
ENXIO
;
}
memset
(
info
,
0
,
sizeof
(
struct
fb_info_aty
)
+
sizeof
(
struct
display
));
memset
(
info
,
0
,
sizeof
(
struct
fb_info
)
+
sizeof
(
struct
display
));
info
->
fb_info
.
disp
=
(
struct
display
*
)
(
info
+
1
);
default_par
=
kmalloc
(
sizeof
(
struct
atyfb_par
),
GFP_ATOMIC
);
if
(
!
default_par
)
{
printk
(
"atyfb_init: can't alloc atyfb_par
\n
"
);
kfree
(
info
);
return
-
ENXIO
;
}
memset
(
default_par
,
0
,
sizeof
(
struct
atyfb_par
));
info
->
disp
=
(
struct
display
*
)
(
info
+
1
);
info
->
par
=
default_par
;
rp
=
&
pdev
->
resource
[
0
];
if
(
rp
->
flags
&
IORESOURCE_IO
)
...
...
@@ -2107,43 +2242,51 @@ int __init atyfb_init(void)
continue
;
res_start
=
rp
->
start
;
res_size
=
rp
->
end
-
rp
->
start
+
1
;
if
(
!
request_mem_region
(
res_start
,
res_size
,
"atyfb"
))
res_size
=
rp
->
end
-
rp
->
start
+
1
;
if
(
!
request_mem_region
(
res_start
,
res_size
,
"atyfb"
))
continue
;
#ifdef __sparc__
/*
* Map memory-mapped registers.
*/
info
->
ati_regbase
=
addr
+
0x7ffc00UL
;
info
->
fb_info
.
fix
.
mmio_start
=
addr
+
0x7ffc00UL
;
par
->
ati_regbase
=
addr
+
0x7ffc00UL
;
info
->
fix
.
mmio_start
=
addr
+
0x7ffc00UL
;
/*
* Map in big-endian aperture.
*/
info
->
fb_info
.
screen_base
=
(
unsigned
long
)
addr
+
0x800000UL
;
info
->
fb_info
.
fix
.
smem_start
=
addr
+
0x800000UL
;
info
->
screen_base
=
(
unsigned
long
)
addr
+
0x800000UL
;
info
->
fix
.
smem_start
=
addr
+
0x800000UL
;
/*
* Figure mmap addresses from PCI config space.
* Split Framebuffer in big- and little-endian halfs.
*/
for
(
i
=
0
;
i
<
6
&&
pdev
->
resource
[
i
].
start
;
i
++
)
/* nothing */
;
/* nothing */
;
j
=
i
+
4
;
info
->
mmap_map
=
kmalloc
(
j
*
sizeof
(
*
info
->
mmap_map
),
GFP_ATOMIC
);
if
(
!
info
->
mmap_map
)
{
printk
(
"atyfb_init: can't alloc mmap_map
\n
"
);
default_par
->
mmap_map
=
kmalloc
(
j
*
sizeof
(
*
default_par
->
mmap_map
),
GFP_ATOMIC
);
if
(
!
default_par
->
mmap_map
)
{
printk
(
"atyfb_init: can't alloc mmap_map
\n
"
);
kfree
(
info
);
release_mem_region
(
res_start
,
res_size
);
return
-
ENXIO
;
}
memset
(
info
->
mmap_map
,
0
,
j
*
sizeof
(
*
info
->
mmap_map
));
memset
(
default_par
->
mmap_map
,
0
,
j
*
sizeof
(
*
default_par
->
mmap_map
));
for
(
i
=
0
,
j
=
2
;
i
<
6
&&
pdev
->
resource
[
i
].
start
;
i
++
)
{
for
(
i
=
0
,
j
=
2
;
i
<
6
&&
pdev
->
resource
[
i
].
start
;
i
++
)
{
struct
resource
*
rp
=
&
pdev
->
resource
[
i
];
int
io
,
breg
=
PCI_BASE_ADDRESS_0
+
(
i
<<
2
);
int
io
,
breg
=
PCI_BASE_ADDRESS_0
+
(
i
<<
2
);
unsigned
long
base
;
u32
size
,
pbase
;
...
...
@@ -2165,11 +2308,18 @@ int __init atyfb_init(void)
* to stay compatible with older ones...
*/
if
(
base
==
addr
)
{
info
->
mmap_map
[
j
].
voff
=
(
pbase
+
0x10000000
)
&
PAGE_MASK
;
info
->
mmap_map
[
j
].
poff
=
base
&
PAGE_MASK
;
info
->
mmap_map
[
j
].
size
=
(
size
+
~
PAGE_MASK
)
&
PAGE_MASK
;
info
->
mmap_map
[
j
].
prot_mask
=
_PAGE_CACHE
;
info
->
mmap_map
[
j
].
prot_flag
=
_PAGE_E
;
default_par
->
mmap_map
[
j
].
voff
=
(
pbase
+
0x10000000
)
&
PAGE_MASK
;
default_par
->
mmap_map
[
j
].
poff
=
base
&
PAGE_MASK
;
default_par
->
mmap_map
[
j
].
size
=
(
size
+
~
PAGE_MASK
)
&
PAGE_MASK
;
default_par
->
mmap_map
[
j
].
prot_mask
=
_PAGE_CACHE
;
default_par
->
mmap_map
[
j
].
prot_flag
=
_PAGE_E
;
j
++
;
}
...
...
@@ -2178,20 +2328,25 @@ int __init atyfb_init(void)
* set for the big endian half of the framebuffer...
*/
if
(
base
==
addr
)
{
info
->
mmap_map
[
j
].
voff
=
(
pbase
+
0x800000
)
&
PAGE_MASK
;
info
->
mmap_map
[
j
].
poff
=
(
base
+
0x800000
)
&
PAGE_MASK
;
info
->
mmap_map
[
j
].
size
=
0x800000
;
info
->
mmap_map
[
j
].
prot_mask
=
_PAGE_CACHE
;
info
->
mmap_map
[
j
].
prot_flag
=
_PAGE_E
|
_PAGE_IE
;
default_par
->
mmap_map
[
j
].
voff
=
(
pbase
+
0x800000
)
&
PAGE_MASK
;
default_par
->
mmap_map
[
j
].
poff
=
(
base
+
0x800000
)
&
PAGE_MASK
;
default_par
->
mmap_map
[
j
].
size
=
0x800000
;
default_par
->
mmap_map
[
j
].
prot_mask
=
_PAGE_CACHE
;
default_par
->
mmap_map
[
j
].
prot_flag
=
_PAGE_E
|
_PAGE_IE
;
size
-=
0x800000
;
j
++
;
}
info
->
mmap_map
[
j
].
voff
=
pbase
&
PAGE_MASK
;
info
->
mmap_map
[
j
].
poff
=
base
&
PAGE_MASK
;
info
->
mmap_map
[
j
].
size
=
(
size
+
~
PAGE_MASK
)
&
PAGE_MASK
;
info
->
mmap_map
[
j
].
prot_mask
=
_PAGE_CACHE
;
info
->
mmap_map
[
j
].
prot_flag
=
_PAGE_E
;
default_par
->
mmap_map
[
j
].
voff
=
pbase
&
PAGE_MASK
;
default_par
->
mmap_map
[
j
].
poff
=
base
&
PAGE_MASK
;
default_par
->
mmap_map
[
j
].
size
=
(
size
+
~
PAGE_MASK
)
&
PAGE_MASK
;
default_par
->
mmap_map
[
j
].
prot_mask
=
_PAGE_CACHE
;
default_par
->
mmap_map
[
j
].
prot_flag
=
_PAGE_E
;
j
++
;
}
...
...
@@ -2200,9 +2355,11 @@ int __init atyfb_init(void)
* Fix PROMs idea of MEM_CNTL settings...
*/
mem
=
aty_ld_le32
(
MEM_CNTL
,
info
);
chip_id
=
aty_ld_le32
(
CONFIG_CHIP_ID
,
info
);
if
(((
chip_id
&
CFG_CHIP_TYPE
)
==
VT_CHIP_ID
)
&&
!
((
chip_id
>>
24
)
&
1
))
{
chip_id
=
aty_ld_le32
(
CONFIG_CHIP_ID
,
info
);
if
(((
chip_id
&
CFG_CHIP_TYPE
)
==
VT_CHIP_ID
)
&&
!
((
chip_id
>>
24
)
&
1
))
{
switch
(
mem
&
0x0f
)
{
case
3
:
mem
=
(
mem
&
~
(
0x0f
))
|
2
;
...
...
@@ -2219,7 +2376,9 @@ int __init atyfb_init(void)
default:
break
;
}
if
((
aty_ld_le32
(
CONFIG_STAT0
,
info
)
&
7
)
>=
SDRAM
)
if
((
aty_ld_le32
(
CONFIG_STAT0
,
info
)
&
7
)
>=
SDRAM
)
mem
&=
~
(
0x00700000
);
}
mem
&=
~
(
0xcf80e000
);
/* Turn off all undocumented bits. */
...
...
@@ -2233,7 +2392,9 @@ int __init atyfb_init(void)
node
=
prom_getchild
(
prom_root_node
);
node
=
prom_searchsiblings
(
node
,
"aliases"
);
if
(
node
)
{
len
=
prom_getproperty
(
node
,
"screen"
,
prop
,
sizeof
(
prop
));
len
=
prom_getproperty
(
node
,
"screen"
,
prop
,
sizeof
(
prop
));
if
(
len
>
0
)
{
prop
[
len
]
=
'\0'
;
node
=
prom_finddevice
(
prop
);
...
...
@@ -2245,22 +2406,35 @@ int __init atyfb_init(void)
pcp
=
pdev
->
sysdata
;
if
(
node
==
pcp
->
prom_node
)
{
struct
fb_var_screeninfo
*
var
=
&
default_var
;
struct
fb_var_screeninfo
*
var
=
&
default_var
;
unsigned
int
N
,
P
,
Q
,
M
,
T
,
R
;
u32
v_total
,
h_total
;
struct
crtc
crtc
;
u8
pll_regs
[
16
];
u8
clock_cntl
;
crtc
.
vxres
=
prom_getintdefault
(
node
,
"width"
,
1024
);
crtc
.
vyres
=
prom_getintdefault
(
node
,
"height"
,
768
);
crtc
.
bpp
=
prom_getintdefault
(
node
,
"depth"
,
8
);
crtc
.
vxres
=
prom_getintdefault
(
node
,
"width"
,
1024
);
crtc
.
vyres
=
prom_getintdefault
(
node
,
"height"
,
768
);
crtc
.
bpp
=
prom_getintdefault
(
node
,
"depth"
,
8
);
crtc
.
xoffset
=
crtc
.
yoffset
=
0
;
crtc
.
h_tot_disp
=
aty_ld_le32
(
CRTC_H_TOTAL_DISP
,
info
);
crtc
.
h_sync_strt_wid
=
aty_ld_le32
(
CRTC_H_SYNC_STRT_WID
,
info
);
crtc
.
v_tot_disp
=
aty_ld_le32
(
CRTC_V_TOTAL_DISP
,
info
);
crtc
.
v_sync_strt_wid
=
aty_ld_le32
(
CRTC_V_SYNC_STRT_WID
,
info
);
crtc
.
gen_cntl
=
aty_ld_le32
(
CRTC_GEN_CNTL
,
info
);
crtc
.
h_tot_disp
=
aty_ld_le32
(
CRTC_H_TOTAL_DISP
,
info
);
crtc
.
h_sync_strt_wid
=
aty_ld_le32
(
CRTC_H_SYNC_STRT_WID
,
info
);
crtc
.
v_tot_disp
=
aty_ld_le32
(
CRTC_V_TOTAL_DISP
,
info
);
crtc
.
v_sync_strt_wid
=
aty_ld_le32
(
CRTC_V_SYNC_STRT_WID
,
info
);
crtc
.
gen_cntl
=
aty_ld_le32
(
CRTC_GEN_CNTL
,
info
);
aty_crtc_to_var
(
&
crtc
,
var
);
h_total
=
var
->
xres
+
var
->
right_margin
+
...
...
@@ -2289,7 +2463,8 @@ int __init atyfb_init(void)
/*
* PLL Post Divider P (Dependant on CLOCK_CNTL):
*/
P
=
1
<<
(
pll_regs
[
6
]
>>
((
clock_cntl
&
3
)
<<
1
));
P
=
1
<<
(
pll_regs
[
6
]
>>
((
clock_cntl
&
3
)
<<
1
));
/*
* PLL Divider Q:
...
...
@@ -2316,18 +2491,19 @@ int __init atyfb_init(void)
}
#else
/* __sparc__ */
info
->
fb_info
.
fix
.
mmio_start
=
0x7ff000
+
addr
;
info
->
ati_regbase
=
(
unsigned
long
)
ioremap
(
info
->
fb_info
.
fix
.
mmio_start
,
0x1000
);
info
->
fix
.
mmio_start
=
0x7ff000
+
addr
;
default_par
->
ati_regbase
=
(
unsigned
long
)
ioremap
(
info
->
fix
.
mmio_start
,
0x1000
);
if
(
!
info
->
ati_regbase
)
{
if
(
!
default_par
->
ati_regbase
)
{
kfree
(
default_par
);
kfree
(
info
);
release_mem_region
(
res_start
,
res_size
);
return
-
ENOMEM
;
}
info
->
fb_info
.
fix
.
mmio_start
+=
0xc00
;
info
->
ati_regbase
+=
0xc00
;
info
->
fix
.
mmio_start
+=
0xc00
;
default_par
->
ati_regbase
+=
0xc00
;
/*
* Enable memory-space accesses using config-space
...
...
@@ -2336,34 +2512,35 @@ int __init atyfb_init(void)
pci_read_config_word
(
pdev
,
PCI_COMMAND
,
&
tmp
);
if
(
!
(
tmp
&
PCI_COMMAND_MEMORY
))
{
tmp
|=
PCI_COMMAND_MEMORY
;
pci_write_config_word
(
pdev
,
PCI_COMMAND
,
tmp
);
pci_write_config_word
(
pdev
,
PCI_COMMAND
,
tmp
);
}
#ifdef __BIG_ENDIAN
/* Use the big-endian aperture */
addr
+=
0x800000
;
#endif
/* Map in frame buffer */
info
->
fb_info
.
fix
.
smem_start
=
addr
;
info
->
fb_info
.
screen_base
=
(
char
*
)
ioremap
(
addr
,
0x800000
);
info
->
fix
.
smem_start
=
addr
;
info
->
screen_base
=
(
char
*
)
ioremap
(
addr
,
0x800000
);
if
(
!
info
->
fb_info
.
screen_base
)
{
if
(
!
info
->
screen_base
)
{
kfree
(
info
);
release_mem_region
(
res_start
,
res_size
);
return
-
ENXIO
;
}
#endif
/* __sparc__ */
if
(
!
aty_init
(
info
,
"PCI"
))
{
if
(
info
->
mmap_map
)
kfree
(
info
->
mmap_map
);
#ifdef __sparc__
if
(
default_par
->
mmap_map
)
kfree
(
default_par
->
mmap_map
);
#endif
kfree
(
info
);
release_mem_region
(
res_start
,
res_size
);
return
-
ENXIO
;
}
#ifdef __sparc__
if
(
!
prom_palette
)
prom_palette
=
atyfb_palette
;
...
...
@@ -2371,22 +2548,28 @@ int __init atyfb_init(void)
/*
* Add /dev/fb mmap values.
*/
info
->
mmap_map
[
0
].
voff
=
0x8000000000000000UL
;
info
->
mmap_map
[
0
].
poff
=
info
->
fb_info
.
screen_base
&
PAGE_MASK
;
info
->
mmap_map
[
0
].
size
=
info
->
fb_info
.
fix
.
smem_len
;
info
->
mmap_map
[
0
].
prot_mask
=
_PAGE_CACHE
;
info
->
mmap_map
[
0
].
prot_flag
=
_PAGE_E
;
info
->
mmap_map
[
1
].
voff
=
info
->
mmap_map
[
0
].
voff
+
info
->
fb_info
.
fix
.
smem_len
;
info
->
mmap_map
[
1
].
poff
=
info
->
ati_regbase
&
PAGE_MASK
;
info
->
mmap_map
[
1
].
size
=
PAGE_SIZE
;
info
->
mmap_map
[
1
].
prot_mask
=
_PAGE_CACHE
;
info
->
mmap_map
[
1
].
prot_flag
=
_PAGE_E
;
par
->
mmap_map
[
0
].
voff
=
0x8000000000000000UL
;
par
->
mmap_map
[
0
].
poff
=
info
->
screen_base
&
PAGE_MASK
;
par
->
mmap_map
[
0
].
size
=
info
->
fix
.
smem_len
;
par
->
mmap_map
[
0
].
prot_mask
=
_PAGE_CACHE
;
par
->
mmap_map
[
0
].
prot_flag
=
_PAGE_E
;
par
->
mmap_map
[
1
].
voff
=
par
->
mmap_map
[
0
].
voff
+
info
->
fix
.
smem_len
;
par
->
mmap_map
[
1
].
poff
=
par
->
ati_regbase
&
PAGE_MASK
;
par
->
mmap_map
[
1
].
size
=
PAGE_SIZE
;
par
->
mmap_map
[
1
].
prot_mask
=
_PAGE_CACHE
;
par
->
mmap_map
[
1
].
prot_flag
=
_PAGE_E
;
#endif
/* __sparc__ */
#ifdef CONFIG_PMAC_PBOOK
if
(
first_display
==
NULL
)
pmu_register_sleep_notifier
(
&
aty_sleep_notifier
);
info
->
next
=
first_display
;
pmu_register_sleep_notifier
(
&
aty_sleep_notifier
);
/* FIXME info->next = first_display; */
first_display
=
info
;
#endif
}
...
...
@@ -2395,47 +2578,50 @@ int __init atyfb_init(void)
#elif defined(CONFIG_ATARI)
u32
clock_r
;
int
m64_num
;
struct
fb_info_aty
*
info
;
struct
fb_info
*
info
;
for
(
m64_num
=
0
;
m64_num
<
mach64_count
;
m64_num
++
)
{
if
(
!
phys_vmembase
[
m64_num
]
||
!
phys_size
[
m64_num
]
||
!
phys_guiregbase
[
m64_num
])
{
printk
(
" phys_*[%d] parameters not set => returning early.
\n
"
,
printk
(
" phys_*[%d] parameters not set => returning early.
\n
"
,
m64_num
);
continue
;
}
info
=
kmalloc
(
sizeof
(
struct
fb_info_aty
),
GFP_ATOMIC
);
info
=
kmalloc
(
sizeof
(
struct
fb_info
),
GFP_ATOMIC
);
if
(
!
info
)
{
printk
(
"atyfb_init: can't alloc fb_info_aty
\n
"
);
printk
(
"atyfb_init: can't alloc fb_info
\n
"
);
return
-
ENOMEM
;
}
memset
(
info
,
0
,
sizeof
(
struct
fb_info_aty
));
memset
(
info
,
0
,
sizeof
(
struct
fb_info
));
/*
* Map the video memory (physical address given) to somewhere in the
* kernel address space.
*/
info
->
fb_info
.
screen_base
=
ioremap
(
phys_vmembase
[
m64_num
],
phys_size
[
m64_num
]);
info
->
fb_info
.
fix
.
smem_start
=
info
->
fb_info
.
screen_base
;
/* Fake! */
info
->
ati_regbase
=
ioremap
(
phys_guiregbase
[
m64_num
],
0x10000
)
+
0xFC00ul
;
info
->
fb_info
.
fix
.
mmio_start
=
info
->
ati_regbase
;
/* Fake! */
info
->
screen_base
=
ioremap
(
phys_vmembase
[
m64_num
],
phys_size
[
m64_num
]);
info
->
fix
.
smem_start
=
info
->
screen_base
;
/* Fake! */
par
->
ati_regbase
=
ioremap
(
phys_guiregbase
[
m64_num
],
0x10000
)
+
0xFC00ul
;
info
->
fix
.
mmio_start
=
par
->
ati_regbase
;
/* Fake! */
aty_st_le32
(
CLOCK_CNTL
,
0x12345678
,
info
);
clock_r
=
aty_ld_le32
(
CLOCK_CNTL
,
info
);
switch
(
clock_r
&
0x003F
)
{
case
0x12
:
info
->
clk_wr_offset
=
3
;
/* */
par
->
clk_wr_offset
=
3
;
/* */
break
;
case
0x34
:
info
->
clk_wr_offset
=
2
;
/* Medusa ST-IO ISA Adapter etc. */
par
->
clk_wr_offset
=
2
;
/* Medusa ST-IO ISA Adapter etc. */
break
;
case
0x16
:
info
->
clk_wr_offset
=
1
;
/* */
par
->
clk_wr_offset
=
1
;
/* */
break
;
case
0x38
:
info
->
clk_wr_offset
=
0
;
/* Panther 1 ISA Adapter (Gerald) */
par
->
clk_wr_offset
=
0
;
/* Panther 1 ISA Adapter (Gerald) */
break
;
}
...
...
@@ -2473,18 +2659,23 @@ int __init atyfb_setup(char *options)
}
else
if
(
!
strncmp
(
this_opt
,
"noaccel"
,
7
))
{
noaccel
=
1
;
}
else
if
(
!
strncmp
(
this_opt
,
"vram:"
,
5
))
default_vram
=
simple_strtoul
(
this_opt
+
5
,
NULL
,
0
);
default_vram
=
simple_strtoul
(
this_opt
+
5
,
NULL
,
0
);
else
if
(
!
strncmp
(
this_opt
,
"pll:"
,
4
))
default_pll
=
simple_strtoul
(
this_opt
+
4
,
NULL
,
0
);
default_pll
=
simple_strtoul
(
this_opt
+
4
,
NULL
,
0
);
else
if
(
!
strncmp
(
this_opt
,
"mclk:"
,
5
))
default_mclk
=
simple_strtoul
(
this_opt
+
5
,
NULL
,
0
);
default_mclk
=
simple_strtoul
(
this_opt
+
5
,
NULL
,
0
);
#ifdef CONFIG_PPC
else
if
(
!
strncmp
(
this_opt
,
"vmode:"
,
6
))
{
unsigned
int
vmode
=
simple_strtoul
(
this_opt
+
6
,
NULL
,
0
);
unsigned
int
vmode
=
simple_strtoul
(
this_opt
+
6
,
NULL
,
0
);
if
(
vmode
>
0
&&
vmode
<=
VMODE_MAX
)
default_vmode
=
vmode
;
}
else
if
(
!
strncmp
(
this_opt
,
"cmode:"
,
6
))
{
unsigned
int
cmode
=
simple_strtoul
(
this_opt
+
6
,
NULL
,
0
);
unsigned
int
cmode
=
simple_strtoul
(
this_opt
+
6
,
NULL
,
0
);
switch
(
cmode
)
{
case
0
:
case
8
:
...
...
@@ -2506,10 +2697,11 @@ int __init atyfb_setup(char *options)
* Why do we need this silly Mach64 argument?
* We are already here because of mach64= so its redundant.
*/
else
if
(
MACH_IS_ATARI
&&
(
!
strncmp
(
this_opt
,
"Mach64:"
,
7
)))
{
else
if
(
MACH_IS_ATARI
&&
(
!
strncmp
(
this_opt
,
"Mach64:"
,
7
)))
{
static
unsigned
char
m64_num
;
static
char
mach64_str
[
80
];
strncpy
(
mach64_str
,
this_opt
+
7
,
80
);
strncpy
(
mach64_str
,
this_opt
+
7
,
80
);
if
(
!
store_video_par
(
mach64_str
,
m64_num
))
{
m64_num
++
;
mach64_count
=
m64_num
;
...
...
@@ -2548,7 +2740,7 @@ static int __init store_video_par(char *video_str, unsigned char m64_num)
guiregbase
);
return
0
;
mach64_invalid:
mach64_invalid:
phys_vmembase
[
m64_num
]
=
0
;
return
-
1
;
}
...
...
@@ -2557,14 +2749,14 @@ static int __init store_video_par(char *video_str, unsigned char m64_num)
/*
#ifdef CONFIG_FB_ATY_CT
* Erase HW Cursor *
if (
info->cursor && (fb
->currcon >= 0))
atyfb_cursor(&fb_display[
fb
->currcon], CM_ERASE,
info->cursor->pos.x, info
->cursor->pos.y);
if (
par->cursor && (info
->currcon >= 0))
atyfb_cursor(&fb_display[
par
->currcon], CM_ERASE,
par->cursor->pos.x, par
->cursor->pos.y);
#endif * CONFIG_FB_ATY_CT *
#ifdef CONFIG_FB_ATY_CT
* Install hw cursor *
if (
info
->cursor) {
if (
par
->cursor) {
aty_set_cursor_color(info);
aty_set_cursor_shape(info);
}
...
...
@@ -2574,9 +2766,9 @@ static int __init store_video_par(char *video_str, unsigned char m64_num)
* Blank the display.
*/
static
int
atyfb_blank
(
int
blank
,
struct
fb_info
*
fb
)
static
int
atyfb_blank
(
int
blank
,
struct
fb_info
*
info
)
{
struct
fb_info_aty
*
info
=
(
struct
fb_info_aty
*
)
fb
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u8
gen_cntl
;
#ifdef CONFIG_PMAC_BACKLIGHT
...
...
@@ -2584,9 +2776,9 @@ static int atyfb_blank(int blank, struct fb_info *fb)
set_backlight_enable
(
0
);
#endif
/* CONFIG_PMAC_BACKLIGHT */
gen_cntl
=
aty_ld_8
(
CRTC_GEN_CNTL
,
info
);
gen_cntl
=
aty_ld_8
(
CRTC_GEN_CNTL
,
par
);
if
(
blank
>
0
)
switch
(
blank
-
1
)
{
switch
(
blank
-
1
)
{
case
VESA_NO_BLANKING
:
gen_cntl
|=
0x40
;
break
;
...
...
@@ -2599,10 +2791,9 @@ static int atyfb_blank(int blank, struct fb_info *fb)
case
VESA_POWERDOWN
:
gen_cntl
|=
0x4c
;
break
;
}
else
}
else
gen_cntl
&=
~
(
0x4c
);
aty_st_8
(
CRTC_GEN_CNTL
,
gen_cntl
,
info
);
aty_st_8
(
CRTC_GEN_CNTL
,
gen_cntl
,
par
);
#ifdef CONFIG_PMAC_BACKLIGHT
if
((
_machine
==
_MACH_Pmac
)
&&
!
blank
)
...
...
@@ -2618,9 +2809,9 @@ static int atyfb_blank(int blank, struct fb_info *fb)
*/
static
int
atyfb_setcolreg
(
u_int
regno
,
u_int
red
,
u_int
green
,
u_int
blue
,
u_int
transp
,
struct
fb_info
*
fb
)
u_int
transp
,
struct
fb_info
*
info
)
{
struct
fb_info_aty
*
info
=
(
struct
fb_info_aty
*
)
fb
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
int
i
,
scale
;
if
(
regno
>
255
)
...
...
@@ -2628,34 +2819,31 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
red
>>=
8
;
green
>>=
8
;
blue
>>=
8
;
i
=
aty_ld_8
(
DAC_CNTL
,
info
)
&
0xfc
;
i
=
aty_ld_8
(
DAC_CNTL
,
par
)
&
0xfc
;
if
(
M64_HAS
(
EXTRA_BRIGHT
))
i
|=
0x2
;
/*DAC_CNTL|0x2 turns off the extra brightness for gt
*/
aty_st_8
(
DAC_CNTL
,
i
,
info
);
aty_st_8
(
DAC_MASK
,
0xff
,
info
);
scale
=
(
M64_HAS
(
INTEGRATED
)
&&
info
->
current_par
.
crtc
.
bpp
==
16
)
?
3
:
0
;
writeb
(
regno
<<
scale
,
&
info
->
aty_cmap_regs
->
windex
);
writeb
(
red
,
&
info
->
aty_cmap_regs
->
lut
);
writeb
(
green
,
&
info
->
aty_cmap_regs
->
lut
);
writeb
(
blue
,
&
info
->
aty_cmap_regs
->
lut
);
i
|=
0x2
;
/*DAC_CNTL|0x2 turns off the extra brightness for gt
*/
aty_st_8
(
DAC_CNTL
,
i
,
par
);
aty_st_8
(
DAC_MASK
,
0xff
,
par
);
scale
=
(
M64_HAS
(
INTEGRATED
)
&&
par
->
crtc
.
bpp
==
16
)
?
3
:
0
;
writeb
(
regno
<<
scale
,
&
par
->
aty_cmap_regs
->
windex
);
writeb
(
red
,
&
par
->
aty_cmap_regs
->
lut
);
writeb
(
green
,
&
par
->
aty_cmap_regs
->
lut
);
writeb
(
blue
,
&
par
->
aty_cmap_regs
->
lut
);
if
(
regno
<
16
)
switch
(
info
->
current_par
.
crtc
.
bpp
)
{
#ifdef FBCON_HAS_CFB16
switch
(
par
->
crtc
.
bpp
)
{
case
16
:
((
u16
*
)
(
info
->
fb_info
.
pseudo_palette
))[
regno
]
=
(
regno
<<
10
)
|
(
regno
<<
5
)
|
regno
;
((
u16
*
)
(
info
->
pseudo_palette
))[
regno
]
=
(
regno
<<
10
)
|
(
regno
<<
5
)
|
regno
;
break
;
#endif
#ifdef FBCON_HAS_CFB24
case
24
:
((
u32
*
)
(
info
->
fb_info
.
pseudo_palette
))[
regno
]
=
(
regno
<<
16
)
|
(
regno
<<
8
)
|
regno
;
((
u32
*
)
(
info
->
pseudo_palette
))[
regno
]
=
(
regno
<<
16
)
|
(
regno
<<
8
)
|
regno
;
break
;
#endif
#ifdef FBCON_HAS_CFB32
case
32
:
i
=
(
regno
<<
8
)
|
regno
;
((
u32
*
)
(
info
->
fb_info
.
pseudo_palette
))[
regno
]
=
(
i
<<
16
)
|
i
;
((
u32
*
)
(
info
->
pseudo_palette
))[
regno
]
=
(
i
<<
16
)
|
i
;
break
;
#endif
}
return
0
;
}
...
...
@@ -2664,10 +2852,9 @@ static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
* Update the `var' structure (called by fbcon.c)
*/
static
int
atyfbcon_updatevar
(
int
con
,
struct
fb_info
*
fb
)
static
int
atyfbcon_updatevar
(
int
con
,
struct
fb_info
*
info
)
{
struct
fb_info_aty
*
info
=
(
struct
fb_info_aty
*
)
fb
;
struct
atyfb_par
*
par
=
&
info
->
current_par
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
struct
display
*
p
=
&
fb_display
[
con
];
struct
vc_data
*
conp
=
p
->
conp
;
u32
yres
,
yoffset
,
sy
,
height
;
...
...
@@ -2679,31 +2866,29 @@ static int atyfbcon_updatevar(int con, struct fb_info *fb)
height
=
yres
-
conp
->
vc_rows
*
fontheight
(
p
);
if
(
height
&&
(
yoffset
+
yres
>
sy
))
{
u32
xres
,
xoffset
;
u32
bgx
;
xres
=
(((
par
->
crtc
.
h_tot_disp
>>
16
)
&
0xff
)
+
1
)
*
8
;
xoffset
=
fb_display
[
con
].
var
.
xoffset
;
struct
fb_fillrect
area
;
bgx
=
attr_bgcol_ec
(
p
,
conp
);
bgx
|=
(
bgx
<<
8
);
bgx
|=
(
bgx
<<
16
);
area
.
dx
=
fb_display
[
con
].
var
.
xoffset
;
area
.
dy
=
sy
;
area
.
height
=
height
;
area
.
width
=
(((
par
->
crtc
.
h_tot_disp
>>
16
)
&
0xff
)
+
1
)
*
8
;
area
.
color
=
attr_bgcol_ec
(
p
,
conp
);
area
.
rop
=
ROP_COPY
;
if
(
sy
+
height
>
par
->
crtc
.
vyres
)
{
wait_for_fifo
(
1
,
info
);
aty_st_le32
(
SC_BOTTOM
,
sy
+
height
-
1
,
info
);
wait_for_fifo
(
1
,
par
);
aty_st_le32
(
SC_BOTTOM
,
sy
+
height
-
1
,
par
);
}
aty_rectfill
(
xoffset
,
sy
,
xres
,
height
,
bgx
,
info
);
atyfb_fillrect
(
info
,
&
area
);
}
#ifdef CONFIG_FB_ATY_CT
if
(
info
->
cursor
&&
(
yoffset
+
yres
<=
sy
))
atyfb_cursor
(
p
,
CM_ERASE
,
info
->
cursor
->
pos
.
x
,
info
->
cursor
->
pos
.
y
);
if
(
par
->
cursor
&&
(
yoffset
+
yres
<=
sy
))
atyfb_cursor
(
p
,
CM_ERASE
,
par
->
cursor
->
pos
.
x
,
par
->
cursor
->
pos
.
y
);
#endif
/* CONFIG_FB_ATY_CT */
info
->
current_par
.
crtc
.
yoffset
=
yoffset
;
set_off_pitch
(
&
info
->
current_
par
,
info
);
par
->
crtc
.
yoffset
=
yoffset
;
set_off_pitch
(
par
,
info
);
return
0
;
}
...
...
@@ -2718,17 +2903,15 @@ int __init init_module(void)
void
cleanup_module
(
void
)
{
while
(
fb_list
)
{
struct
fb_info_aty
*
info
=
fb_list
;
fb_list
=
info
->
next
;
unregister_framebuffer
(
&
info
->
fb_info
);
struct
fb_info
*
info
=
fb_list
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
unregister_framebuffer
(
info
);
#ifndef __sparc__
if
(
info
->
ati_regbase
)
iounmap
((
void
*
)
info
->
ati_regbase
);
if
(
info
->
fb_info
.
screen_base
)
iounmap
((
void
*
)
info
->
fb_info
.
screen_base
);
if
(
par
->
ati_regbase
)
iounmap
((
void
*
)
par
->
ati_regbase
);
if
(
info
->
screen_base
)
iounmap
((
void
*
)
info
->
screen_base
);
#ifdef __BIG_ENDIAN
if
(
info
->
cursor
&&
info
->
cursor
->
ram
)
iounmap
(
info
->
cursor
->
ram
);
...
...
@@ -2741,11 +2924,10 @@ void cleanup_module(void)
kfree
(
info
->
cursor
);
}
#ifdef __sparc__
if
(
info
->
mmap_map
)
kfree
(
info
->
mmap_map
);
if
(
par
->
mmap_map
)
kfree
(
par
->
mmap_map
);
#endif
kfree
(
info
);
}
}
#endif
...
...
drivers/video/aty/mach64_accel.c
View file @
87520e1e
...
...
@@ -20,41 +20,45 @@
* Text console acceleration
*/
static
void
fbcon_aty_bmove
(
struct
display
*
p
,
int
sy
,
int
sx
,
int
dy
,
int
dx
,
int
height
,
int
width
);
static
void
fbcon_aty_clear
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
sy
,
int
sx
,
int
height
,
int
width
);
static
void
fbcon_aty_bmove
(
struct
display
*
p
,
int
sy
,
int
sx
,
int
dy
,
int
dx
,
int
height
,
int
width
);
static
void
fbcon_aty_clear
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
s
y
,
int
s
x
,
int
height
,
int
width
);
/*
* Generic Mach64 routines
*/
void
aty_reset_engine
(
const
struct
fb_info_aty
*
info
)
void
aty_reset_engine
(
const
struct
atyfb_par
*
par
)
{
/* reset engine */
aty_st_le32
(
GEN_TEST_CNTL
,
aty_ld_le32
(
GEN_TEST_CNTL
,
info
)
&
~
GUI_ENGINE_ENABLE
,
info
);
aty_ld_le32
(
GEN_TEST_CNTL
,
par
)
&
~
GUI_ENGINE_ENABLE
,
par
);
/* enable engine */
aty_st_le32
(
GEN_TEST_CNTL
,
aty_ld_le32
(
GEN_TEST_CNTL
,
info
)
|
GUI_ENGINE_ENABLE
,
info
);
aty_ld_le32
(
GEN_TEST_CNTL
,
par
)
|
GUI_ENGINE_ENABLE
,
par
);
/* ensure engine is not locked up by clearing any FIFO or */
/* HOST errors */
aty_st_le32
(
BUS_CNTL
,
aty_ld_le32
(
BUS_CNTL
,
info
)
|
BUS_HOST_ERR_ACK
|
BUS_FIFO_ERR_ACK
,
info
);
aty_st_le32
(
BUS_CNTL
,
aty_ld_le32
(
BUS_CNTL
,
par
)
|
BUS_HOST_ERR_ACK
|
BUS_FIFO_ERR_ACK
,
par
);
}
static
void
reset_GTC_3D_engine
(
const
struct
fb_info_aty
*
info
)
static
void
reset_GTC_3D_engine
(
const
struct
atyfb_par
*
par
)
{
aty_st_le32
(
SCALE_3D_CNTL
,
0xc0
,
info
);
aty_st_le32
(
SCALE_3D_CNTL
,
0xc0
,
par
);
mdelay
(
GTC_3D_RESET_DELAY
);
aty_st_le32
(
SETUP_CNTL
,
0x00
,
info
);
aty_st_le32
(
SETUP_CNTL
,
0x00
,
par
);
mdelay
(
GTC_3D_RESET_DELAY
);
aty_st_le32
(
SCALE_3D_CNTL
,
0x00
,
info
);
aty_st_le32
(
SCALE_3D_CNTL
,
0x00
,
par
);
mdelay
(
GTC_3D_RESET_DELAY
);
}
void
aty_init_engine
(
const
struct
atyfb_par
*
par
,
struct
fb_info_aty
*
info
)
void
aty_init_engine
(
struct
atyfb_par
*
par
,
struct
fb_info
*
info
)
{
u32
pitch_value
;
...
...
@@ -69,238 +73,246 @@ void aty_init_engine(const struct atyfb_par *par, struct fb_info_aty *info)
/* On GTC (RagePro), we need to reset the 3D engine before */
if
(
M64_HAS
(
RESET_3D
))
reset_GTC_3D_engine
(
info
);
reset_GTC_3D_engine
(
par
);
/* Reset engine, enable, and clear any engine errors */
aty_reset_engine
(
info
);
aty_reset_engine
(
par
);
/* Ensure that vga page pointers are set to zero - the upper */
/* page pointers are set to 1 to handle overflows in the */
/* lower page */
aty_st_le32
(
MEM_VGA_WP_SEL
,
0x00010000
,
info
);
aty_st_le32
(
MEM_VGA_RP_SEL
,
0x00010000
,
info
);
aty_st_le32
(
MEM_VGA_WP_SEL
,
0x00010000
,
par
);
aty_st_le32
(
MEM_VGA_RP_SEL
,
0x00010000
,
par
);
/* ---- Setup standard engine context ---- */
/* All GUI registers here are FIFOed - therefore, wait for */
/* the appropriate number of empty FIFO entries */
wait_for_fifo
(
14
,
info
);
wait_for_fifo
(
14
,
par
);
/* enable all registers to be loaded for context loads */
aty_st_le32
(
CONTEXT_MASK
,
0xFFFFFFFF
,
info
);
aty_st_le32
(
CONTEXT_MASK
,
0xFFFFFFFF
,
par
);
/* set destination pitch to modal pitch, set offset to zero */
aty_st_le32
(
DST_OFF_PITCH
,
(
pitch_value
/
8
)
<<
22
,
info
);
aty_st_le32
(
DST_OFF_PITCH
,
(
pitch_value
/
8
)
<<
22
,
par
);
/* zero these registers (set them to a known state) */
aty_st_le32
(
DST_Y_X
,
0
,
info
);
aty_st_le32
(
DST_HEIGHT
,
0
,
info
);
aty_st_le32
(
DST_BRES_ERR
,
0
,
info
);
aty_st_le32
(
DST_BRES_INC
,
0
,
info
);
aty_st_le32
(
DST_BRES_DEC
,
0
,
info
);
aty_st_le32
(
DST_Y_X
,
0
,
par
);
aty_st_le32
(
DST_HEIGHT
,
0
,
par
);
aty_st_le32
(
DST_BRES_ERR
,
0
,
par
);
aty_st_le32
(
DST_BRES_INC
,
0
,
par
);
aty_st_le32
(
DST_BRES_DEC
,
0
,
par
);
/* set destination drawing attributes */
aty_st_le32
(
DST_CNTL
,
DST_LAST_PEL
|
DST_Y_TOP_TO_BOTTOM
|
DST_X_LEFT_TO_RIGHT
,
info
);
DST_X_LEFT_TO_RIGHT
,
par
);
/* set source pitch to modal pitch, set offset to zero */
aty_st_le32
(
SRC_OFF_PITCH
,
(
pitch_value
/
8
)
<<
22
,
info
);
aty_st_le32
(
SRC_OFF_PITCH
,
(
pitch_value
/
8
)
<<
22
,
par
);
/* set these registers to a known state */
aty_st_le32
(
SRC_Y_X
,
0
,
info
);
aty_st_le32
(
SRC_HEIGHT1_WIDTH1
,
1
,
info
);
aty_st_le32
(
SRC_Y_X_START
,
0
,
info
);
aty_st_le32
(
SRC_HEIGHT2_WIDTH2
,
1
,
info
);
aty_st_le32
(
SRC_Y_X
,
0
,
par
);
aty_st_le32
(
SRC_HEIGHT1_WIDTH1
,
1
,
par
);
aty_st_le32
(
SRC_Y_X_START
,
0
,
par
);
aty_st_le32
(
SRC_HEIGHT2_WIDTH2
,
1
,
par
);
/* set source pixel retrieving attributes */
aty_st_le32
(
SRC_CNTL
,
SRC_LINE_X_LEFT_TO_RIGHT
,
info
);
aty_st_le32
(
SRC_CNTL
,
SRC_LINE_X_LEFT_TO_RIGHT
,
par
);
/* set host attributes */
wait_for_fifo
(
13
,
info
);
aty_st_le32
(
HOST_CNTL
,
0
,
info
);
wait_for_fifo
(
13
,
par
);
aty_st_le32
(
HOST_CNTL
,
0
,
par
);
/* set pattern attributes */
aty_st_le32
(
PAT_REG0
,
0
,
info
);
aty_st_le32
(
PAT_REG1
,
0
,
info
);
aty_st_le32
(
PAT_CNTL
,
0
,
info
);
aty_st_le32
(
PAT_REG0
,
0
,
par
);
aty_st_le32
(
PAT_REG1
,
0
,
par
);
aty_st_le32
(
PAT_CNTL
,
0
,
par
);
/* set scissors to modal size */
aty_st_le32
(
SC_LEFT
,
0
,
info
);
aty_st_le32
(
SC_TOP
,
0
,
info
);
aty_st_le32
(
SC_BOTTOM
,
par
->
crtc
.
vyres
-
1
,
info
);
aty_st_le32
(
SC_RIGHT
,
pitch_value
-
1
,
info
);
aty_st_le32
(
SC_LEFT
,
0
,
par
);
aty_st_le32
(
SC_TOP
,
0
,
par
);
aty_st_le32
(
SC_BOTTOM
,
par
->
crtc
.
vyres
-
1
,
par
);
aty_st_le32
(
SC_RIGHT
,
pitch_value
-
1
,
par
);
/* set background color to minimum value (usually BLACK) */
aty_st_le32
(
DP_BKGD_CLR
,
0
,
info
);
aty_st_le32
(
DP_BKGD_CLR
,
0
,
par
);
/* set foreground color to maximum value (usually WHITE) */
aty_st_le32
(
DP_FRGD_CLR
,
0xFFFFFFFF
,
info
);
aty_st_le32
(
DP_FRGD_CLR
,
0xFFFFFFFF
,
par
);
/* set write mask to effect all pixel bits */
aty_st_le32
(
DP_WRITE_MASK
,
0xFFFFFFFF
,
info
);
aty_st_le32
(
DP_WRITE_MASK
,
0xFFFFFFFF
,
par
);
/* set foreground mix to overpaint and background mix to */
/* no-effect */
aty_st_le32
(
DP_MIX
,
FRGD_MIX_S
|
BKGD_MIX_D
,
info
);
aty_st_le32
(
DP_MIX
,
FRGD_MIX_S
|
BKGD_MIX_D
,
par
);
/* set primary source pixel channel to foreground color */
/* register */
aty_st_le32
(
DP_SRC
,
FRGD_SRC_FRGD_CLR
,
info
);
aty_st_le32
(
DP_SRC
,
FRGD_SRC_FRGD_CLR
,
par
);
/* set compare functionality to false (no-effect on */
/* destination) */
wait_for_fifo
(
3
,
info
);
aty_st_le32
(
CLR_CMP_CLR
,
0
,
info
);
aty_st_le32
(
CLR_CMP_MASK
,
0xFFFFFFFF
,
info
);
aty_st_le32
(
CLR_CMP_CNTL
,
0
,
info
);
wait_for_fifo
(
3
,
par
);
aty_st_le32
(
CLR_CMP_CLR
,
0
,
par
);
aty_st_le32
(
CLR_CMP_MASK
,
0xFFFFFFFF
,
par
);
aty_st_le32
(
CLR_CMP_CNTL
,
0
,
par
);
/* set pixel depth */
wait_for_fifo
(
2
,
info
);
aty_st_le32
(
DP_PIX_WIDTH
,
par
->
crtc
.
dp_pix_width
,
info
);
aty_st_le32
(
DP_CHAIN_MASK
,
par
->
crtc
.
dp_chain_mask
,
info
);
wait_for_fifo
(
2
,
par
);
aty_st_le32
(
DP_PIX_WIDTH
,
par
->
crtc
.
dp_pix_width
,
par
);
aty_st_le32
(
DP_CHAIN_MASK
,
par
->
crtc
.
dp_chain_mask
,
par
);
wait_for_fifo
(
5
,
info
);
aty_st_le32
(
SCALE_3D_CNTL
,
0
,
info
);
aty_st_le32
(
Z_CNTL
,
0
,
info
);
aty_st_le32
(
CRTC_INT_CNTL
,
aty_ld_le32
(
CRTC_INT_CNTL
,
info
)
&
~
0x20
,
info
);
aty_st_le32
(
GUI_TRAJ_CNTL
,
0x100023
,
info
);
wait_for_fifo
(
5
,
par
);
aty_st_le32
(
SCALE_3D_CNTL
,
0
,
par
);
aty_st_le32
(
Z_CNTL
,
0
,
par
);
aty_st_le32
(
CRTC_INT_CNTL
,
aty_ld_le32
(
CRTC_INT_CNTL
,
par
)
&
~
0x20
,
par
);
aty_st_le32
(
GUI_TRAJ_CNTL
,
0x100023
,
par
);
/* insure engine is idle before leaving */
wait_for_idle
(
info
);
wait_for_idle
(
par
);
}
/*
* Accelerated functions
*/
static
inline
void
draw_rect
(
s16
x
,
s16
y
,
u16
width
,
u16
height
,
struct
fb_info_aty
*
info
)
struct
atyfb_par
*
par
)
{
/* perform rectangle fill */
wait_for_fifo
(
2
,
info
);
aty_st_le32
(
DST_Y_X
,
(
x
<<
16
)
|
y
,
info
);
aty_st_le32
(
DST_HEIGHT_WIDTH
,
(
width
<<
16
)
|
height
,
info
);
info
->
blitter_may_be_busy
=
1
;
wait_for_fifo
(
2
,
par
);
aty_st_le32
(
DST_Y_X
,
(
x
<<
16
)
|
y
,
par
);
aty_st_le32
(
DST_HEIGHT_WIDTH
,
(
width
<<
16
)
|
height
,
par
);
par
->
blitter_may_be_busy
=
1
;
}
static
inline
void
aty_rectcopy
(
int
srcx
,
int
srcy
,
int
dstx
,
int
dsty
,
u_int
width
,
u_int
height
,
struct
fb_info_aty
*
info
)
static
void
atyfb_copyarea
(
struct
fb_info
*
info
,
struct
fb_copyarea
*
area
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
direction
=
DST_LAST_PEL
;
u32
pitch_value
;
if
(
!
width
||
!
height
)
if
(
!
area
->
width
||
!
area
->
height
)
return
;
pitch_value
=
info
->
current_par
.
crtc
.
vxres
;
if
(
info
->
current_par
.
crtc
.
bpp
==
24
)
{
pitch_value
=
par
->
crtc
.
vxres
;
if
(
par
->
crtc
.
bpp
==
24
)
{
/* In 24 bpp, the engine is in 8 bpp - this requires that all */
/* horizontal coordinates and widths must be adjusted */
pitch_value
*=
3
;
src
x
*=
3
;
dst
x
*=
3
;
width
*=
3
;
area
->
s
x
*=
3
;
area
->
d
x
*=
3
;
area
->
width
*=
3
;
}
if
(
srcy
<
dst
y
)
{
dsty
+=
height
-
1
;
srcy
+=
height
-
1
;
if
(
area
->
sy
<
area
->
d
y
)
{
area
->
dy
+=
area
->
height
-
1
;
area
->
sy
+=
area
->
height
-
1
;
}
else
direction
|=
DST_Y_TOP_TO_BOTTOM
;
if
(
srcx
<
dst
x
)
{
dstx
+=
width
-
1
;
srcx
+=
width
-
1
;
if
(
area
->
sx
<
area
->
d
x
)
{
area
->
dx
+=
area
->
width
-
1
;
area
->
sx
+=
area
->
width
-
1
;
}
else
direction
|=
DST_X_LEFT_TO_RIGHT
;
wait_for_fifo
(
4
,
info
);
aty_st_le32
(
DP_SRC
,
FRGD_SRC_BLIT
,
info
);
aty_st_le32
(
SRC_Y_X
,
(
srcx
<<
16
)
|
srcy
,
info
);
aty_st_le32
(
SRC_HEIGHT1_WIDTH1
,
(
width
<<
16
)
|
height
,
info
);
aty_st_le32
(
DST_CNTL
,
direction
,
info
);
draw_rect
(
dstx
,
dsty
,
width
,
height
,
info
);
wait_for_fifo
(
4
,
par
);
aty_st_le32
(
DP_SRC
,
FRGD_SRC_BLIT
,
par
);
aty_st_le32
(
SRC_Y_X
,
(
area
->
sx
<<
16
)
|
area
->
sy
,
par
);
aty_st_le32
(
SRC_HEIGHT1_WIDTH1
,
(
area
->
width
<<
16
)
|
area
->
height
,
par
);
aty_st_le32
(
DST_CNTL
,
direction
,
par
);
draw_rect
(
area
->
dx
,
area
->
dy
,
area
->
width
,
area
->
height
,
par
);
}
void
aty_rectfill
(
int
dstx
,
int
dsty
,
u_int
width
,
u_int
height
,
u_int
color
,
struct
fb_info_aty
*
info
)
void
atyfb_fillrect
(
struct
fb_info
*
info
,
struct
fb_fillrect
*
rect
)
{
if
(
!
width
||
!
height
)
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
if
(
!
rect
->
width
||
!
rect
->
height
)
return
;
if
(
info
->
current_par
.
crtc
.
bpp
==
24
)
{
rect
->
color
|=
(
rect
->
color
<<
8
);
rect
->
color
|=
(
rect
->
color
<<
16
);
if
(
par
->
crtc
.
bpp
==
24
)
{
/* In 24 bpp, the engine is in 8 bpp - this requires that all */
/* horizontal coordinates and widths must be adjusted */
dst
x
*=
3
;
width
*=
3
;
rect
->
d
x
*=
3
;
rect
->
width
*=
3
;
}
wait_for_fifo
(
3
,
info
);
aty_st_le32
(
DP_FRGD_CLR
,
color
,
info
);
aty_st_le32
(
DP_SRC
,
BKGD_SRC_BKGD_CLR
|
FRGD_SRC_FRGD_CLR
|
MONO_SRC_ONE
,
info
);
aty_st_le32
(
DST_CNTL
,
DST_LAST_PEL
|
DST_Y_TOP_TO_BOTTOM
|
DST_X_LEFT_TO_RIGHT
,
info
);
draw_rect
(
dstx
,
dsty
,
width
,
height
,
info
);
wait_for_fifo
(
3
,
par
);
aty_st_le32
(
DP_FRGD_CLR
,
rect
->
color
,
par
);
aty_st_le32
(
DP_SRC
,
BKGD_SRC_BKGD_CLR
|
FRGD_SRC_FRGD_CLR
|
MONO_SRC_ONE
,
par
);
aty_st_le32
(
DST_CNTL
,
DST_LAST_PEL
|
DST_Y_TOP_TO_BOTTOM
|
DST_X_LEFT_TO_RIGHT
,
par
);
draw_rect
(
rect
->
dx
,
rect
->
dy
,
rect
->
width
,
rect
->
height
,
par
);
}
/*
* Text console acceleration
*/
static
void
fbcon_aty_bmove
(
struct
display
*
p
,
int
sy
,
int
sx
,
int
dy
,
int
dx
,
int
height
,
int
width
)
static
void
fbcon_aty_bmove
(
struct
display
*
p
,
int
sy
,
int
sx
,
int
dy
,
int
dx
,
int
height
,
int
width
)
{
struct
fb_info
*
info
=
p
->
fb_info
;
struct
fb_copyarea
area
;
#ifdef __sparc__
struct
fb_info_aty
*
fb
=
(
struct
fb_info_aty
*
)(
p
->
fb_info
);
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
(
info
->
par
);
if
(
fb
->
mmaped
&&
(
!
fb
->
fb_info
.
display_fg
||
fb
->
fb_info
.
display_fg
->
vc_num
==
fb
->
vtconsole
))
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
info
->
display_fg
->
vc_num
==
par
->
vtconsole
))
return
;
#endif
sx
*=
fontwidth
(
p
);
sy
*=
fontheight
(
p
);
dx
*=
fontwidth
(
p
);
dy
*=
fontheight
(
p
);
width
*=
fontwidth
(
p
);
height
*=
fontheight
(
p
);
area
.
sx
=
sx
*
fontwidth
(
p
);
area
.
sy
=
sy
*
fontheight
(
p
);
area
.
dx
=
dx
*
fontwidth
(
p
);
area
.
dy
=
dy
*
fontheight
(
p
);
area
.
width
=
width
*
fontwidth
(
p
);
area
.
height
=
height
*
fontheight
(
p
);
aty_rectcopy
(
sx
,
sy
,
dx
,
dy
,
width
,
height
,
(
struct
fb_info_aty
*
)
p
->
fb_info
);
atyfb_copyarea
(
info
,
&
area
);
}
static
void
fbcon_aty_clear
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
sy
,
int
sx
,
int
height
,
int
width
)
static
void
fbcon_aty_clear
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
s
y
,
int
s
x
,
int
height
,
int
width
)
{
u32
bgx
;
struct
fb_info
*
info
=
p
->
fb_info
;
struct
fb_fillrect
region
;
#ifdef __sparc__
struct
fb_info_aty
*
fb
=
(
struct
fb_info_aty
*
)(
p
->
fb_info
);
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
(
info
->
par
);
if
(
fb
->
mmaped
&&
(
!
fb
->
fb_info
.
display_fg
||
fb
->
fb_info
.
display_fg
->
vc_num
==
fb
->
vtconsole
))
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
info
->
display_fg
->
vc_num
==
par
->
vtconsole
))
return
;
#endif
region
.
color
=
attr_bgcol_ec
(
p
,
conp
);
region
.
color
|=
(
region
.
color
<<
8
);
region
.
color
|=
(
region
.
color
<<
16
);
bgx
=
attr_bgcol_ec
(
p
,
conp
);
bgx
|=
(
bgx
<<
8
);
bgx
|=
(
bgx
<<
16
);
region
.
dx
=
sx
*
fontwidth
(
p
);
region
.
dy
=
sy
*
fontheight
(
p
);
region
.
width
=
width
*
fontwidth
(
p
);
region
.
height
=
height
*
fontheight
(
p
);
region
.
rop
=
ROP_COPY
;
sx
*=
fontwidth
(
p
);
sy
*=
fontheight
(
p
);
width
*=
fontwidth
(
p
);
height
*=
fontheight
(
p
);
aty_rectfill
(
sx
,
sy
,
width
,
height
,
bgx
,
(
struct
fb_info_aty
*
)
p
->
fb_info
);
atyfb_fillrect
(
info
,
&
region
);
}
#ifdef __sparc__
#define check_access \
if (
fb->mmaped && (!fb->fb_info.
display_fg \
||
fb->fb_info.display_fg->vc_num == fb
->vtconsole)) \
if (
par->mmaped && (!info->
display_fg \
||
info->display_fg->vc_num == par
->vtconsole)) \
return;
#else
#define check_access do { } while (0)
...
...
@@ -309,10 +321,11 @@ static void fbcon_aty_clear(struct vc_data *conp, struct display *p, int sy,
#define DEF_FBCON_ATY_OP(name, call, args...) \
static void name(struct vc_data *conp, struct display *p, args) \
{ \
struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info); \
struct fb_info *info = p->fb_info; \
struct atyfb_par *par = (struct atyfb_par *) info->par; \
check_access; \
if (
fb
->blitter_may_be_busy) \
wait_for_idle(
(struct fb_info_aty *)p->fb_info
); \
if (
par
->blitter_may_be_busy) \
wait_for_idle(
par
); \
call; \
}
...
...
@@ -342,12 +355,11 @@ const struct display_switch fbcon_aty##width = { \
DEF_FBCON_ATY
(
8
)
#endif
#ifdef FBCON_HAS_CFB16
DEF_FBCON_ATY
(
16
)
DEF_FBCON_ATY
(
16
)
#endif
#ifdef FBCON_HAS_CFB24
DEF_FBCON_ATY
(
24
)
DEF_FBCON_ATY
(
24
)
#endif
#ifdef FBCON_HAS_CFB32
DEF_FBCON_ATY
(
32
)
DEF_FBCON_ATY
(
32
)
#endif
drivers/video/aty/mach64_ct.c
View file @
87520e1e
...
...
@@ -16,26 +16,25 @@
/* FIXME: remove the FAIL definition */
#define FAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)
static
void
aty_st_pll
(
int
offset
,
u8
val
,
const
struct
fb_info_aty
*
info
);
static
int
aty_valid_pll_ct
(
const
struct
fb_info_aty
*
info
,
u32
vclk_per
,
static
void
aty_st_pll
(
int
offset
,
u8
val
,
const
struct
atyfb_par
*
par
);
static
int
aty_valid_pll_ct
(
const
struct
fb_info
*
info
,
u32
vclk_per
,
struct
pll_ct
*
pll
);
static
int
aty_dsp_gt
(
const
struct
fb_info
_aty
*
info
,
u8
bpp
,
static
int
aty_dsp_gt
(
const
struct
fb_info
*
info
,
u8
bpp
,
struct
pll_ct
*
pll
);
static
int
aty_var_to_pll_ct
(
const
struct
fb_info
_aty
*
info
,
u32
vclk_per
,
static
int
aty_var_to_pll_ct
(
const
struct
fb_info
*
info
,
u32
vclk_per
,
u8
bpp
,
union
aty_pll
*
pll
);
static
u32
aty_pll_ct_to_var
(
const
struct
fb_info
_aty
*
info
,
static
u32
aty_pll_ct_to_var
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
);
static
void
aty_st_pll
(
int
offset
,
u8
val
,
const
struct
fb_info_aty
*
info
)
static
void
aty_st_pll
(
int
offset
,
u8
val
,
const
struct
atyfb_par
*
par
)
{
/* write addr byte */
aty_st_8
(
CLOCK_CNTL
+
1
,
(
offset
<<
2
)
|
PLL_WR_EN
,
info
);
aty_st_8
(
CLOCK_CNTL
+
1
,
(
offset
<<
2
)
|
PLL_WR_EN
,
par
);
/* write the register value */
aty_st_8
(
CLOCK_CNTL
+
2
,
val
,
info
);
aty_st_8
(
CLOCK_CNTL
+
1
,
(
offset
<<
2
)
&
~
PLL_WR_EN
,
info
);
aty_st_8
(
CLOCK_CNTL
+
2
,
val
,
par
);
aty_st_8
(
CLOCK_CNTL
+
1
,
(
offset
<<
2
)
&
~
PLL_WR_EN
,
par
);
}
...
...
@@ -45,16 +44,19 @@ static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info)
* PLL programming (Mach64 CT family)
*/
static
int
aty_dsp_gt
(
const
struct
fb_info
_aty
*
info
,
u8
bpp
,
static
int
aty_dsp_gt
(
const
struct
fb_info
*
info
,
u8
bpp
,
struct
pll_ct
*
pll
)
{
u32
dsp_xclks_per_row
,
dsp_loop_latency
,
dsp_precision
,
dsp_off
,
dsp_on
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
dsp_xclks_per_row
,
dsp_loop_latency
,
dsp_precision
,
dsp_off
,
dsp_on
;
u32
xclks_per_row
,
fifo_off
,
fifo_on
,
y
,
fifo_size
,
page_size
;
/* xclocks_per_row<<11 */
xclks_per_row
=
(
pll
->
mclk_fb_div
*
pll
->
vclk_post_div_real
*
64
<<
11
)
/
(
pll
->
vclk_fb_div
*
pll
->
mclk_post_div_real
*
bpp
);
if
(
xclks_per_row
<
(
1
<<
11
))
xclks_per_row
=
(
pll
->
mclk_fb_div
*
pll
->
vclk_post_div_real
*
64
<<
11
)
/
(
pll
->
vclk_fb_div
*
pll
->
mclk_post_div_real
*
bpp
);
if
(
xclks_per_row
<
(
1
<<
11
))
FAIL
(
"Dotclock to high"
);
if
(
M64_HAS
(
FIFO_24
))
{
fifo_size
=
24
;
...
...
@@ -64,17 +66,17 @@ static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
dsp_loop_latency
=
2
;
}
dsp_precision
=
0
;
y
=
(
xclks_per_row
*
fifo_size
)
>>
11
;
y
=
(
xclks_per_row
*
fifo_size
)
>>
11
;
while
(
y
)
{
y
>>=
1
;
dsp_precision
++
;
}
dsp_precision
-=
5
;
/* fifo_off<<6 */
fifo_off
=
((
xclks_per_row
*
(
fifo_size
-
1
))
>>
5
)
+
(
3
<<
6
);
fifo_off
=
((
xclks_per_row
*
(
fifo_size
-
1
))
>>
5
)
+
(
3
<<
6
);
if
(
info
->
fb_info
.
fix
.
smem_len
>
1
*
1024
*
1024
)
{
if
(
info
->
ram_type
>=
SDRAM
)
{
if
(
info
->
fix
.
smem_len
>
1
*
1024
*
1024
)
{
if
(
par
->
ram_type
>=
SDRAM
)
{
/* >1 MB SDRAM */
dsp_loop_latency
+=
8
;
page_size
=
8
;
...
...
@@ -84,7 +86,7 @@ static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
page_size
=
9
;
}
}
else
{
if
(
info
->
ram_type
>=
SDRAM
)
{
if
(
par
->
ram_type
>=
SDRAM
)
{
/* <2 MB SDRAM */
dsp_loop_latency
+=
9
;
page_size
=
10
;
...
...
@@ -95,66 +97,68 @@ static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
}
}
/* fifo_on<<6 */
if
(
xclks_per_row
>=
(
page_size
<<
11
))
fifo_on
=
((
2
*
page_size
+
1
)
<<
6
)
+
(
xclks_per_row
>>
5
);
if
(
xclks_per_row
>=
(
page_size
<<
11
))
fifo_on
=
((
2
*
page_size
+
1
)
<<
6
)
+
(
xclks_per_row
>>
5
);
else
fifo_on
=
(
3
*
page_size
+
2
)
<<
6
;
fifo_on
=
(
3
*
page_size
+
2
)
<<
6
;
dsp_xclks_per_row
=
xclks_per_row
>>
dsp_precision
;
dsp_on
=
fifo_on
>>
dsp_precision
;
dsp_off
=
fifo_off
>>
dsp_precision
;
dsp_xclks_per_row
=
xclks_per_row
>>
dsp_precision
;
dsp_on
=
fifo_on
>>
dsp_precision
;
dsp_off
=
fifo_off
>>
dsp_precision
;
pll
->
dsp_config
=
(
dsp_xclks_per_row
&
0x3fff
)
|
((
dsp_loop_latency
&
0xf
)
<<
16
)
|
((
dsp_precision
&
7
)
<<
20
);
pll
->
dsp_on_off
=
(
dsp_on
&
0x7ff
)
|
((
dsp_off
&
0x7ff
)
<<
16
);
((
dsp_loop_latency
&
0xf
)
<<
16
)
|
((
dsp_precision
&
7
)
<<
20
);
pll
->
dsp_on_off
=
(
dsp_on
&
0x7ff
)
|
((
dsp_off
&
0x7ff
)
<<
16
);
return
0
;
}
static
int
aty_valid_pll_ct
(
const
struct
fb_info
_aty
*
info
,
u32
vclk_per
,
static
int
aty_valid_pll_ct
(
const
struct
fb_info
*
info
,
u32
vclk_per
,
struct
pll_ct
*
pll
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
q
,
x
;
/* x is a workaround for sparc64-linux-gcc */
x
=
x
;
/* x is a workaround for sparc64-linux-gcc */
pll
->
pll_ref_div
=
info
->
pll_per
*
2
*
255
/
info
->
ref_clk_per
;
pll
->
pll_ref_div
=
par
->
pll_per
*
2
*
255
/
par
->
ref_clk_per
;
/* FIXME: use the VTB/GTB /3 post divider if it's better suited */
q
=
info
->
ref_clk_per
*
pll
->
pll_ref_div
*
4
/
info
->
mclk_per
;
/* actually 8*q */
if
(
q
<
16
*
8
||
q
>
255
*
8
)
q
=
par
->
ref_clk_per
*
pll
->
pll_ref_div
*
4
/
par
->
mclk_per
;
/* actually 8*q */
if
(
q
<
16
*
8
||
q
>
255
*
8
)
FAIL
(
"mclk out of range"
);
else
if
(
q
<
32
*
8
)
else
if
(
q
<
32
*
8
)
pll
->
mclk_post_div_real
=
8
;
else
if
(
q
<
64
*
8
)
else
if
(
q
<
64
*
8
)
pll
->
mclk_post_div_real
=
4
;
else
if
(
q
<
128
*
8
)
else
if
(
q
<
128
*
8
)
pll
->
mclk_post_div_real
=
2
;
else
pll
->
mclk_post_div_real
=
1
;
pll
->
mclk_fb_div
=
q
*
pll
->
mclk_post_div_real
/
8
;
pll
->
mclk_fb_div
=
q
*
pll
->
mclk_post_div_real
/
8
;
/* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */
q
=
info
->
ref_clk_per
*
pll
->
pll_ref_div
*
4
/
vclk_per
;
/* actually 8*q */
if
(
q
<
16
*
8
||
q
>
255
*
8
)
q
=
par
->
ref_clk_per
*
pll
->
pll_ref_div
*
4
/
vclk_per
;
/* actually 8*q */
if
(
q
<
16
*
8
||
q
>
255
*
8
)
FAIL
(
"vclk out of range"
);
else
if
(
q
<
32
*
8
)
else
if
(
q
<
32
*
8
)
pll
->
vclk_post_div_real
=
8
;
else
if
(
q
<
64
*
8
)
else
if
(
q
<
64
*
8
)
pll
->
vclk_post_div_real
=
4
;
else
if
(
q
<
128
*
8
)
else
if
(
q
<
128
*
8
)
pll
->
vclk_post_div_real
=
2
;
else
pll
->
vclk_post_div_real
=
1
;
pll
->
vclk_fb_div
=
q
*
pll
->
vclk_post_div_real
/
8
;
pll
->
vclk_fb_div
=
q
*
pll
->
vclk_post_div_real
/
8
;
return
0
;
}
void
aty_calc_pll_ct
(
const
struct
fb_info
_aty
*
info
,
struct
pll_ct
*
pll
)
void
aty_calc_pll_ct
(
const
struct
fb_info
*
info
,
struct
pll_ct
*
pll
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u8
mpostdiv
=
0
;
u8
vpostdiv
=
0
;
if
(
M64_HAS
(
SDRAM_MAGIC_PLL
)
&&
(
info
->
ram_type
>=
SDRAM
))
if
(
M64_HAS
(
SDRAM_MAGIC_PLL
)
&&
(
par
->
ram_type
>=
SDRAM
))
pll
->
pll_gen_cntl
=
0x04
;
else
pll
->
pll_gen_cntl
=
0x84
;
...
...
@@ -176,7 +180,7 @@ void aty_calc_pll_ct(const struct fb_info_aty *info, struct pll_ct *pll)
mpostdiv
=
3
;
break
;
}
pll
->
pll_gen_cntl
|=
mpostdiv
<<
4
;
/* mclk */
pll
->
pll_gen_cntl
|=
mpostdiv
<<
4
;
/* mclk */
if
(
M64_HAS
(
MAGIC_POSTDIV
))
pll
->
pll_ext_cntl
=
0
;
...
...
@@ -208,9 +212,10 @@ void aty_calc_pll_ct(const struct fb_info_aty *info, struct pll_ct *pll)
pll
->
vclk_post_div
=
vpostdiv
;
}
static
int
aty_var_to_pll_ct
(
const
struct
fb_info
_aty
*
info
,
u32
vclk_per
,
static
int
aty_var_to_pll_ct
(
const
struct
fb_info
*
info
,
u32
vclk_per
,
u8
bpp
,
union
aty_pll
*
pll
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
int
err
;
if
((
err
=
aty_valid_pll_ct
(
info
,
vclk_per
,
&
pll
->
ct
)))
...
...
@@ -221,37 +226,42 @@ static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
return
0
;
}
static
u32
aty_pll_ct_to_var
(
const
struct
fb_info
_aty
*
info
,
static
u32
aty_pll_ct_to_var
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
)
{
u32
ref_clk_per
=
info
->
ref_clk_per
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
ref_clk_per
=
par
->
ref_clk_per
;
u8
pll_ref_div
=
pll
->
ct
.
pll_ref_div
;
u8
vclk_fb_div
=
pll
->
ct
.
vclk_fb_div
;
u8
vclk_post_div
=
pll
->
ct
.
vclk_post_div_real
;
return
ref_clk_per
*
pll_ref_div
*
vclk_post_div
/
vclk_fb_div
/
2
;
return
ref_clk_per
*
pll_ref_div
*
vclk_post_div
/
vclk_fb_div
/
2
;
}
void
aty_set_pll_ct
(
const
struct
fb_info_aty
*
info
,
const
union
aty_pll
*
pll
)
void
aty_set_pll_ct
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
)
{
aty_st_pll
(
PLL_REF_DIV
,
pll
->
ct
.
pll_ref_div
,
info
);
aty_st_pll
(
PLL_GEN_CNTL
,
pll
->
ct
.
pll_gen_cntl
,
info
);
aty_st_pll
(
MCLK_FB_DIV
,
pll
->
ct
.
mclk_fb_div
,
info
);
aty_st_pll
(
PLL_VCLK_CNTL
,
pll
->
ct
.
pll_vclk_cntl
,
info
);
aty_st_pll
(
VCLK_POST_DIV
,
pll
->
ct
.
vclk_post_div
,
info
);
aty_st_pll
(
VCLK0_FB_DIV
,
pll
->
ct
.
vclk_fb_div
,
info
);
aty_st_pll
(
PLL_EXT_CNTL
,
pll
->
ct
.
pll_ext_cntl
,
info
);
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
aty_st_pll
(
PLL_REF_DIV
,
pll
->
ct
.
pll_ref_div
,
par
);
aty_st_pll
(
PLL_GEN_CNTL
,
pll
->
ct
.
pll_gen_cntl
,
par
);
aty_st_pll
(
MCLK_FB_DIV
,
pll
->
ct
.
mclk_fb_div
,
par
);
aty_st_pll
(
PLL_VCLK_CNTL
,
pll
->
ct
.
pll_vclk_cntl
,
par
);
aty_st_pll
(
VCLK_POST_DIV
,
pll
->
ct
.
vclk_post_div
,
par
);
aty_st_pll
(
VCLK0_FB_DIV
,
pll
->
ct
.
vclk_fb_div
,
par
);
aty_st_pll
(
PLL_EXT_CNTL
,
pll
->
ct
.
pll_ext_cntl
,
par
);
if
(
M64_HAS
(
GTB_DSP
))
{
if
(
M64_HAS
(
XL_DLL
))
aty_st_pll
(
DLL_CNTL
,
0x80
,
info
);
else
if
(
info
->
ram_type
>=
SDRAM
)
aty_st_pll
(
DLL_CNTL
,
0xa6
,
info
);
aty_st_pll
(
DLL_CNTL
,
0x80
,
par
);
else
if
(
par
->
ram_type
>=
SDRAM
)
aty_st_pll
(
DLL_CNTL
,
0xa6
,
par
);
else
aty_st_pll
(
DLL_CNTL
,
0xa0
,
info
);
aty_st_pll
(
VFC_CNTL
,
0x1b
,
info
);
aty_st_le32
(
DSP_CONFIG
,
pll
->
ct
.
dsp_config
,
info
);
aty_st_le32
(
DSP_ON_OFF
,
pll
->
ct
.
dsp_on_off
,
info
);
aty_st_pll
(
DLL_CNTL
,
0xa0
,
par
);
aty_st_pll
(
VFC_CNTL
,
0x1b
,
par
);
aty_st_le32
(
DSP_CONFIG
,
pll
->
ct
.
dsp_config
,
par
);
aty_st_le32
(
DSP_ON_OFF
,
pll
->
ct
.
dsp_on_off
,
par
);
}
}
...
...
@@ -261,12 +271,11 @@ static int dummy(void)
}
const
struct
aty_dac_ops
aty_dac_ct
=
{
set_dac:
(
void
*
)
dummy
,
set_dac:
(
void
*
)
dummy
,
};
const
struct
aty_pll_ops
aty_pll_ct
=
{
var_to_pll:
aty_var_to_pll_ct
,
pll_to_var:
aty_pll_ct_to_var
,
set_pll:
aty_set_pll_ct
,
var_to_pll:
aty_var_to_pll_ct
,
pll_to_var:
aty_pll_ct_to_var
,
set_pll:
aty_set_pll_ct
,
};
drivers/video/aty/mach64_cursor.c
View file @
87520e1e
...
...
@@ -33,21 +33,20 @@
static
const
u8
cursor_pixel_map
[
2
]
=
{
0
,
15
};
static
const
u8
cursor_color_map
[
2
]
=
{
0
,
0xff
};
static
const
u8
cursor_bits_lookup
[
16
]
=
{
static
const
u8
cursor_bits_lookup
[
16
]
=
{
0x00
,
0x40
,
0x10
,
0x50
,
0x04
,
0x44
,
0x14
,
0x54
,
0x01
,
0x41
,
0x11
,
0x51
,
0x05
,
0x45
,
0x15
,
0x55
};
static
const
u8
cursor_mask_lookup
[
16
]
=
{
static
const
u8
cursor_mask_lookup
[
16
]
=
{
0xaa
,
0x2a
,
0x8a
,
0x0a
,
0xa2
,
0x22
,
0x82
,
0x02
,
0xa8
,
0x28
,
0x88
,
0x08
,
0xa0
,
0x20
,
0x80
,
0x00
};
void
aty_set_cursor_color
(
struct
fb_info
_aty
*
fb
)
void
aty_set_cursor_color
(
struct
fb_info
*
info
)
{
struct
aty_cursor
*
c
=
fb
->
cursor
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
struct
aty_cursor
*
c
=
par
->
cursor
;
const
u8
*
pixel
=
cursor_pixel_map
;
/* ++Geert: Why?? */
const
u8
*
red
=
cursor_color_map
;
const
u8
*
green
=
cursor_color_map
;
...
...
@@ -58,26 +57,28 @@ void aty_set_cursor_color(struct fb_info_aty *fb)
return
;
#ifdef __sparc__
if
(
fb
->
mmaped
&&
(
!
fb
->
fb_info
.
display_fg
||
fb
->
fb_info
.
display_fg
->
vc_num
==
fb
->
vtconsole
))
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
info
->
display_fg
->
vc_num
==
par
->
vtconsole
))
return
;
#endif
for
(
i
=
0
;
i
<
2
;
i
++
)
{
c
->
color
[
i
]
=
(
u32
)
red
[
i
]
<<
24
;
c
->
color
[
i
]
|=
(
u32
)
green
[
i
]
<<
16
;
c
->
color
[
i
]
|=
(
u32
)
blue
[
i
]
<<
8
;
c
->
color
[
i
]
|=
(
u32
)
pixel
[
i
];
c
->
color
[
i
]
=
(
u32
)
red
[
i
]
<<
24
;
c
->
color
[
i
]
|=
(
u32
)
green
[
i
]
<<
16
;
c
->
color
[
i
]
|=
(
u32
)
blue
[
i
]
<<
8
;
c
->
color
[
i
]
|=
(
u32
)
pixel
[
i
];
}
wait_for_fifo
(
2
,
fb
);
aty_st_le32
(
CUR_CLR0
,
c
->
color
[
0
],
fb
);
aty_st_le32
(
CUR_CLR1
,
c
->
color
[
1
],
fb
);
wait_for_fifo
(
2
,
par
);
aty_st_le32
(
CUR_CLR0
,
c
->
color
[
0
],
par
);
aty_st_le32
(
CUR_CLR1
,
c
->
color
[
1
],
par
);
}
void
aty_set_cursor_shape
(
struct
fb_info
_aty
*
fb
)
void
aty_set_cursor_shape
(
struct
fb_info
*
info
)
{
struct
aty_cursor
*
c
=
fb
->
cursor
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
struct
aty_cursor
*
c
=
par
->
cursor
;
u8
*
ram
,
m
,
b
;
int
x
,
y
;
...
...
@@ -85,8 +86,9 @@ void aty_set_cursor_shape(struct fb_info_aty *fb)
return
;
#ifdef __sparc__
if
(
fb
->
mmaped
&&
(
!
fb
->
fb_info
.
display_fg
||
fb
->
fb_info
.
display_fg
->
vc_num
==
fb
->
vtconsole
))
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
info
->
display_fg
->
vc_num
==
par
->
vtconsole
))
return
;
#endif
...
...
@@ -95,26 +97,24 @@ void aty_set_cursor_shape(struct fb_info_aty *fb)
for
(
x
=
0
;
x
<
c
->
size
.
x
>>
2
;
x
++
)
{
m
=
c
->
mask
[
x
][
y
];
b
=
c
->
bits
[
x
][
y
];
fb_writeb
(
cursor_mask_lookup
[
m
>>
4
]
|
cursor_bits_lookup
[(
b
&
m
)
>>
4
],
ram
++
);
fb_writeb
(
cursor_mask_lookup
[
m
&
0x0f
]
|
fb_writeb
(
cursor_mask_lookup
[
m
>>
4
]
|
cursor_bits_lookup
[(
b
&
m
)
>>
4
],
ram
++
);
fb_writeb
(
cursor_mask_lookup
[
m
&
0x0f
]
|
cursor_bits_lookup
[(
b
&
m
)
&
0x0f
],
ram
++
);
}
for
(
;
x
<
8
;
x
++
)
{
fb_writeb
(
0xaa
,
ram
++
);
fb_writeb
(
0xaa
,
ram
++
);
for
(;
x
<
8
;
x
++
)
{
fb_writeb
(
0xaa
,
ram
++
);
fb_writeb
(
0xaa
,
ram
++
);
}
}
fb_memset
(
ram
,
0xaa
,
(
64
-
c
->
size
.
y
)
*
16
);
fb_memset
(
ram
,
0xaa
,
(
64
-
c
->
size
.
y
)
*
16
);
}
static
void
aty_set_cursor
(
struct
fb_info_aty
*
fb
,
int
on
)
static
void
aty_set_cursor
(
struct
fb_info
*
info
,
int
on
)
{
struct
atyfb_par
*
par
=
&
fb
->
current_
par
;
struct
aty_cursor
*
c
=
fb
->
cursor
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
struct
aty_cursor
*
c
=
par
->
cursor
;
u16
xoff
,
yoff
;
int
x
,
y
;
...
...
@@ -122,8 +122,9 @@ aty_set_cursor(struct fb_info_aty *fb, int on)
return
;
#ifdef __sparc__
if
(
fb
->
mmaped
&&
(
!
fb
->
fb_info
.
display_fg
||
fb
->
fb_info
.
display_fg
->
vc_num
==
fb
->
vtconsole
))
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
info
->
display_fg
->
vc_num
==
par
->
vtconsole
))
return
;
#endif
...
...
@@ -144,67 +145,72 @@ aty_set_cursor(struct fb_info_aty *fb, int on)
yoff
=
0
;
}
wait_for_fifo
(
4
,
fb
);
aty_st_le32
(
CUR_OFFSET
,
(
c
->
offset
>>
3
)
+
(
yoff
<<
1
),
fb
);
wait_for_fifo
(
4
,
par
);
aty_st_le32
(
CUR_OFFSET
,
(
c
->
offset
>>
3
)
+
(
yoff
<<
1
),
par
);
aty_st_le32
(
CUR_HORZ_VERT_OFF
,
((
u32
)(
64
-
c
->
size
.
y
+
yoff
)
<<
16
)
|
xoff
,
fb
);
aty_st_le32
(
CUR_HORZ_VERT_POSN
,
((
u32
)
y
<<
16
)
|
x
,
fb
);
aty_st_le32
(
GEN_TEST_CNTL
,
aty_ld_le32
(
GEN_TEST_CNTL
,
fb
)
|
HWCURSOR_ENABLE
,
fb
);
((
u32
)
(
64
-
c
->
size
.
y
+
yoff
)
<<
16
)
|
xoff
,
par
);
aty_st_le32
(
CUR_HORZ_VERT_POSN
,
((
u32
)
y
<<
16
)
|
x
,
par
);
aty_st_le32
(
GEN_TEST_CNTL
,
aty_ld_le32
(
GEN_TEST_CNTL
,
par
)
|
HWCURSOR_ENABLE
,
par
);
}
else
{
wait_for_fifo
(
1
,
fb
);
wait_for_fifo
(
1
,
par
);
aty_st_le32
(
GEN_TEST_CNTL
,
aty_ld_le32
(
GEN_TEST_CNTL
,
fb
)
&
~
HWCURSOR_ENABLE
,
fb
);
aty_ld_le32
(
GEN_TEST_CNTL
,
par
)
&
~
HWCURSOR_ENABLE
,
par
);
}
if
(
fb
->
blitter_may_be_busy
)
wait_for_idle
(
fb
);
if
(
par
->
blitter_may_be_busy
)
wait_for_idle
(
par
);
}
static
void
aty_cursor_timer_handler
(
unsigned
long
dev_addr
)
static
void
aty_cursor_timer_handler
(
unsigned
long
dev_addr
)
{
struct
fb_info_aty
*
fb
=
(
struct
fb_info_aty
*
)
dev_addr
;
struct
fb_info
*
info
=
(
struct
fb_info
*
)
dev_addr
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
if
(
!
fb
->
cursor
)
if
(
!
par
->
cursor
)
return
;
if
(
!
fb
->
cursor
->
enable
)
if
(
!
par
->
cursor
->
enable
)
goto
out
;
if
(
fb
->
cursor
->
vbl_cnt
&&
--
fb
->
cursor
->
vbl_cnt
==
0
)
{
fb
->
cursor
->
on
^=
1
;
aty_set_cursor
(
fb
,
fb
->
cursor
->
on
);
fb
->
cursor
->
vbl_cnt
=
fb
->
cursor
->
blink_rate
;
if
(
par
->
cursor
->
vbl_cnt
&&
--
par
->
cursor
->
vbl_cnt
==
0
)
{
par
->
cursor
->
on
^=
1
;
aty_set_cursor
(
info
,
par
->
cursor
->
on
);
par
->
cursor
->
vbl_cnt
=
par
->
cursor
->
blink_rate
;
}
out:
fb
->
cursor
->
timer
->
expires
=
jiffies
+
(
HZ
/
50
);
add_timer
(
fb
->
cursor
->
timer
);
out:
par
->
cursor
->
timer
->
expires
=
jiffies
+
(
HZ
/
50
);
add_timer
(
par
->
cursor
->
timer
);
}
void
atyfb_cursor
(
struct
display
*
p
,
int
mode
,
int
x
,
int
y
)
{
struct
fb_info_aty
*
fb
=
(
struct
fb_info_aty
*
)
p
->
fb_info
;
struct
aty_cursor
*
c
=
fb
->
cursor
;
struct
fb_info
*
info
=
p
->
fb_info
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
struct
aty_cursor
*
c
=
par
->
cursor
;
if
(
!
c
)
return
;
#ifdef __sparc__
if
(
fb
->
mmaped
&&
(
!
fb
->
fb_info
.
display_fg
||
fb
->
fb_info
.
display_fg
->
vc_num
==
fb
->
vtconsole
))
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
info
->
display_fg
->
vc_num
==
par
->
vtconsole
))
return
;
#endif
x
*=
fontwidth
(
p
);
y
*=
fontheight
(
p
);
if
(
c
->
pos
.
x
==
x
&&
c
->
pos
.
y
==
y
&&
(
mode
==
CM_ERASE
)
==
!
c
->
enable
)
if
(
c
->
pos
.
x
==
x
&&
c
->
pos
.
y
==
y
&&
(
mode
==
CM_ERASE
)
==
!
c
->
enable
)
return
;
c
->
enable
=
0
;
if
(
c
->
on
)
aty_set_cursor
(
fb
,
0
);
aty_set_cursor
(
info
,
0
);
c
->
pos
.
x
=
x
;
c
->
pos
.
y
=
y
;
...
...
@@ -216,7 +222,7 @@ void atyfb_cursor(struct display *p, int mode, int x, int y)
case
CM_DRAW
:
case
CM_MOVE
:
if
(
c
->
on
)
aty_set_cursor
(
fb
,
1
);
aty_set_cursor
(
info
,
1
);
else
c
->
vbl_cnt
=
CURSOR_DRAW_DELAY
;
c
->
enable
=
1
;
...
...
@@ -224,7 +230,7 @@ void atyfb_cursor(struct display *p, int mode, int x, int y)
}
}
struct
aty_cursor
*
__init
aty_init_cursor
(
struct
fb_info_aty
*
fb
)
struct
aty_cursor
*
__init
aty_init_cursor
(
struct
fb_info
*
info
)
{
struct
aty_cursor
*
cursor
;
unsigned
long
addr
;
...
...
@@ -242,19 +248,19 @@ struct aty_cursor * __init aty_init_cursor(struct fb_info_aty *fb)
memset
(
cursor
->
timer
,
0
,
sizeof
(
*
cursor
->
timer
));
cursor
->
blink_rate
=
DEFAULT_CURSOR_BLINK_RATE
;
fb
->
fb_info
.
fix
.
smem_len
-=
PAGE_SIZE
;
cursor
->
offset
=
fb
->
fb_info
.
fix
.
smem_len
;
info
->
fix
.
smem_len
-=
PAGE_SIZE
;
cursor
->
offset
=
info
->
fix
.
smem_len
;
#ifdef __sparc__
addr
=
fb
->
fb_info
.
screen_base
-
0x800000
+
cursor
->
offset
;
cursor
->
ram
=
(
u8
*
)
addr
;
addr
=
info
->
screen_base
-
0x800000
+
cursor
->
offset
;
cursor
->
ram
=
(
u8
*
)
addr
;
#else
#ifdef __BIG_ENDIAN
addr
=
fb
->
fb_info
.
fix
.
smem_start
-
0x800000
+
cursor
->
offset
;
cursor
->
ram
=
(
u8
*
)
ioremap
(
addr
,
1024
);
addr
=
info
->
fix
.
smem_start
-
0x800000
+
cursor
->
offset
;
cursor
->
ram
=
(
u8
*
)
ioremap
(
addr
,
1024
);
#else
addr
=
(
unsigned
long
)
fb
->
fb_info
.
screen_base
+
cursor
->
offset
;
cursor
->
ram
=
(
u8
*
)
addr
;
addr
=
(
unsigned
long
)
info
->
screen_base
+
cursor
->
offset
;
cursor
->
ram
=
(
u8
*
)
addr
;
#endif
#endif
...
...
@@ -265,17 +271,17 @@ struct aty_cursor * __init aty_init_cursor(struct fb_info_aty *fb)
init_timer
(
cursor
->
timer
);
cursor
->
timer
->
expires
=
jiffies
+
(
HZ
/
50
);
cursor
->
timer
->
data
=
(
unsigned
long
)
fb
;
cursor
->
timer
->
data
=
(
unsigned
long
)
info
;
cursor
->
timer
->
function
=
aty_cursor_timer_handler
;
add_timer
(
cursor
->
timer
);
return
cursor
;
}
int
atyfb_set_font
(
struct
display
*
d
,
int
width
,
int
height
)
{
struct
fb_info_aty
*
fb
=
(
struct
fb_info_aty
*
)
d
->
fb_info
;
struct
aty_cursor
*
c
=
fb
->
cursor
;
struct
fb_info
*
info
=
d
->
fb_info
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
struct
aty_cursor
*
c
=
par
->
cursor
;
int
i
,
j
;
if
(
c
)
{
...
...
@@ -293,13 +299,14 @@ int atyfb_set_font(struct display *d, int width, int height)
memset
(
c
->
mask
,
0
,
sizeof
(
c
->
mask
));
for
(
i
=
0
,
j
=
width
;
j
>=
0
;
j
-=
8
,
i
++
)
{
c
->
mask
[
i
][
height
-
2
]
=
(
j
>=
8
)
?
0xff
:
(
0xff
<<
(
8
-
j
));
c
->
mask
[
i
][
height
-
1
]
=
(
j
>=
8
)
?
0xff
:
(
0xff
<<
(
8
-
j
));
c
->
mask
[
i
][
height
-
2
]
=
(
j
>=
8
)
?
0xff
:
(
0xff
<<
(
8
-
j
));
c
->
mask
[
i
][
height
-
1
]
=
(
j
>=
8
)
?
0xff
:
(
0xff
<<
(
8
-
j
));
}
aty_set_cursor_color
(
fb
);
aty_set_cursor_shape
(
fb
);
aty_set_cursor_color
(
info
);
aty_set_cursor_shape
(
info
);
}
return
1
;
}
drivers/video/aty/mach64_gx.c
View file @
87520e1e
...
...
@@ -42,25 +42,24 @@
* Support Functions
*/
static
void
aty_dac_waste4
(
const
struct
fb_info_aty
*
info
)
static
void
aty_dac_waste4
(
const
struct
atyfb_par
*
par
)
{
(
void
)
aty_ld_8
(
DAC_REGS
,
info
);
(
void
)
aty_ld_8
(
DAC_REGS
,
par
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
info
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
info
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
info
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
info
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
par
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
par
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
par
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
par
);
}
static
void
aty_StrobeClock
(
const
struct
fb_info_aty
*
info
)
static
void
aty_StrobeClock
(
const
struct
atyfb_par
*
par
)
{
u8
tmp
;
udelay
(
26
);
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
info
);
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
tmp
|
CLOCK_STROBE
,
info
);
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
par
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
tmp
|
CLOCK_STROBE
,
par
);
return
;
}
...
...
@@ -69,20 +68,21 @@ static void aty_StrobeClock(const struct fb_info_aty *info)
* IBM RGB514 DAC and Clock Chip
*/
static
void
aty_st_514
(
int
offset
,
u8
val
,
const
struct
fb_info_aty
*
info
)
static
void
aty_st_514
(
int
offset
,
u8
val
,
const
struct
atyfb_par
*
par
)
{
aty_st_8
(
DAC_CNTL
,
1
,
info
);
aty_st_8
(
DAC_CNTL
,
1
,
par
);
/* right addr byte */
aty_st_8
(
DAC_W_INDEX
,
offset
&
0xff
,
info
);
aty_st_8
(
DAC_W_INDEX
,
offset
&
0xff
,
par
);
/* left addr byte */
aty_st_8
(
DAC_DATA
,
(
offset
>>
8
)
&
0xff
,
info
);
aty_st_8
(
DAC_MASK
,
val
,
info
);
aty_st_8
(
DAC_CNTL
,
0
,
info
);
aty_st_8
(
DAC_DATA
,
(
offset
>>
8
)
&
0xff
,
par
);
aty_st_8
(
DAC_MASK
,
val
,
par
);
aty_st_8
(
DAC_CNTL
,
0
,
par
);
}
static
int
aty_set_dac_514
(
const
struct
fb_info
_aty
*
info
,
static
int
aty_set_dac_514
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
static
struct
{
u8
pixel_dly
;
u8
misc2_cntl
;
...
...
@@ -90,9 +90,12 @@ static int aty_set_dac_514(const struct fb_info_aty *info,
u8
pixel_cntl_index
;
u8
pixel_cntl_v1
;
}
tab
[
3
]
=
{
{
0
,
0x41
,
0x03
,
0x71
,
0x45
},
/* 8 bpp */
{
0
,
0x45
,
0x04
,
0x0c
,
0x01
},
/* 555 */
{
0
,
0x45
,
0x06
,
0x0e
,
0x00
},
/* XRGB */
{
0
,
0x41
,
0x03
,
0x71
,
0x45
},
/* 8 bpp */
{
0
,
0x45
,
0x04
,
0x0c
,
0x01
},
/* 555 */
{
0
,
0x45
,
0x06
,
0x0e
,
0x00
},
/* XRGB */
};
int
i
;
...
...
@@ -108,18 +111,18 @@ static int aty_set_dac_514(const struct fb_info_aty *info,
i
=
2
;
break
;
}
aty_st_514
(
0x90
,
0x00
,
info
);
/* VRAM Mask Low */
aty_st_514
(
0x04
,
tab
[
i
].
pixel_dly
,
info
);
/* Horizontal Sync Control */
aty_st_514
(
0x05
,
0x00
,
info
);
/* Power Management */
aty_st_514
(
0x02
,
0x01
,
info
);
/* Misc Clock Control */
aty_st_514
(
0x71
,
tab
[
i
].
misc2_cntl
,
info
);
/* Misc Control 2 */
aty_st_514
(
0x0a
,
tab
[
i
].
pixel_rep
,
info
);
/* Pixel Format */
aty_st_514
(
tab
[
i
].
pixel_cntl_index
,
tab
[
i
].
pixel_cntl_v1
,
info
);
aty_st_514
(
0x90
,
0x00
,
par
);
/* VRAM Mask Low */
aty_st_514
(
0x04
,
tab
[
i
].
pixel_dly
,
par
);
/* Horizontal Sync Control */
aty_st_514
(
0x05
,
0x00
,
par
);
/* Power Management */
aty_st_514
(
0x02
,
0x01
,
par
);
/* Misc Clock Control */
aty_st_514
(
0x71
,
tab
[
i
].
misc2_cntl
,
par
);
/* Misc Control 2 */
aty_st_514
(
0x0a
,
tab
[
i
].
pixel_rep
,
par
);
/* Pixel Format */
aty_st_514
(
tab
[
i
].
pixel_cntl_index
,
tab
[
i
].
pixel_cntl_v1
,
par
);
/* Misc Control 2 / 16 BPP Control / 32 BPP Control */
return
0
;
}
static
int
aty_var_to_pll_514
(
const
struct
fb_info
_aty
*
info
,
u32
vclk_per
,
static
int
aty_var_to_pll_514
(
const
struct
fb_info
*
info
,
u32
vclk_per
,
u8
bpp
,
union
aty_pll
*
pll
)
{
/*
...
...
@@ -131,17 +134,25 @@ static int aty_var_to_pll_514(const struct fb_info_aty *info, u32 vclk_per,
u8
m
;
/* (df<<6) | vco_div_count */
u8
n
;
/* ref_div_count */
}
RGB514_clocks
[
7
]
=
{
{
8000
,
(
3
<<
6
)
|
20
,
9
},
/* 7395 ps / 135.2273 MHz */
{
10000
,
(
1
<<
6
)
|
19
,
3
},
/* 9977 ps / 100.2273 MHz */
{
13000
,
(
1
<<
6
)
|
2
,
3
},
/* 12509 ps / 79.9432 MHz */
{
14000
,
(
2
<<
6
)
|
8
,
7
},
/* 13394 ps / 74.6591 MHz */
{
16000
,
(
1
<<
6
)
|
44
,
6
},
/* 15378 ps / 65.0284 MHz */
{
25000
,
(
1
<<
6
)
|
15
,
5
},
/* 17460 ps / 57.2727 MHz */
{
50000
,
(
0
<<
6
)
|
53
,
7
},
/* 33145 ps / 30.1705 MHz */
{
8000
,
(
3
<<
6
)
|
20
,
9
},
/* 7395 ps / 135.2273 MHz */
{
10000
,
(
1
<<
6
)
|
19
,
3
},
/* 9977 ps / 100.2273 MHz */
{
13000
,
(
1
<<
6
)
|
2
,
3
},
/* 12509 ps / 79.9432 MHz */
{
14000
,
(
2
<<
6
)
|
8
,
7
},
/* 13394 ps / 74.6591 MHz */
{
16000
,
(
1
<<
6
)
|
44
,
6
},
/* 15378 ps / 65.0284 MHz */
{
25000
,
(
1
<<
6
)
|
15
,
5
},
/* 17460 ps / 57.2727 MHz */
{
50000
,
(
0
<<
6
)
|
53
,
7
},
/* 33145 ps / 30.1705 MHz */
};
int
i
;
for
(
i
=
0
;
i
<
sizeof
(
RGB514_clocks
)
/
sizeof
(
*
RGB514_clocks
);
i
++
)
for
(
i
=
0
;
i
<
sizeof
(
RGB514_clocks
)
/
sizeof
(
*
RGB514_clocks
);
i
++
)
if
(
vclk_per
<=
RGB514_clocks
[
i
].
limit
)
{
pll
->
ibm514
.
m
=
RGB514_clocks
[
i
].
m
;
pll
->
ibm514
.
n
=
RGB514_clocks
[
i
].
n
;
...
...
@@ -150,39 +161,43 @@ static int aty_var_to_pll_514(const struct fb_info_aty *info, u32 vclk_per,
return
-
EINVAL
;
}
static
u32
aty_pll_514_to_var
(
const
struct
fb_info
_aty
*
info
,
static
u32
aty_pll_514_to_var
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u8
df
,
vco_div_count
,
ref_div_count
;
df
=
pll
->
ibm514
.
m
>>
6
;
vco_div_count
=
pll
->
ibm514
.
m
&
0x3f
;
ref_div_count
=
pll
->
ibm514
.
n
;
return
((
info
->
ref_clk_per
*
ref_div_count
)
<<
(
3
-
df
))
/
(
vco_div_count
+
65
);
return
((
par
->
ref_clk_per
*
ref_div_count
)
<<
(
3
-
df
))
/
(
vco_div_count
+
65
);
}
static
void
aty_set_pll_514
(
const
struct
fb_info
_aty
*
info
,
static
void
aty_set_pll_514
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
)
{
aty_st_514
(
0x06
,
0x02
,
info
);
/* DAC Operation */
aty_st_514
(
0x10
,
0x01
,
info
);
/* PLL Control 1 */
aty_st_514
(
0x70
,
0x01
,
info
);
/* Misc Control 1 */
aty_st_514
(
0x8f
,
0x1f
,
info
);
/* PLL Ref. Divider Input */
aty_st_514
(
0x03
,
0x00
,
info
);
/* Sync Control */
aty_st_514
(
0x05
,
0x00
,
info
);
/* Power Management */
aty_st_514
(
0x20
,
pll
->
ibm514
.
m
,
info
);
/* F0 / M0 */
aty_st_514
(
0x21
,
pll
->
ibm514
.
n
,
info
);
/* F1 / N0 */
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
aty_st_514
(
0x06
,
0x02
,
par
);
/* DAC Operation */
aty_st_514
(
0x10
,
0x01
,
par
);
/* PLL Control 1 */
aty_st_514
(
0x70
,
0x01
,
par
);
/* Misc Control 1 */
aty_st_514
(
0x8f
,
0x1f
,
par
);
/* PLL Ref. Divider Input */
aty_st_514
(
0x03
,
0x00
,
par
);
/* Sync Control */
aty_st_514
(
0x05
,
0x00
,
par
);
/* Power Management */
aty_st_514
(
0x20
,
pll
->
ibm514
.
m
,
par
);
/* F0 / M0 */
aty_st_514
(
0x21
,
pll
->
ibm514
.
n
,
par
);
/* F1 / N0 */
}
const
struct
aty_dac_ops
aty_dac_ibm514
=
{
set_dac:
aty_set_dac_514
,
set_dac:
aty_set_dac_514
,
};
const
struct
aty_pll_ops
aty_pll_ibm514
=
{
var_to_pll:
aty_var_to_pll_514
,
pll_to_var:
aty_pll_514_to_var
,
set_pll:
aty_set_pll_514
,
var_to_pll:
aty_var_to_pll_514
,
pll_to_var:
aty_pll_514_to_var
,
set_pll:
aty_set_pll_514
,
};
...
...
@@ -190,9 +205,11 @@ const struct aty_pll_ops aty_pll_ibm514 = {
* ATI 68860-B DAC
*/
static
int
aty_set_dac_ATI68860_B
(
const
struct
fb_info_aty
*
info
,
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
)
static
int
aty_set_dac_ATI68860_B
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
gModeReg
,
devSetupRegA
,
temp
,
mask
;
gModeReg
=
0
;
...
...
@@ -201,7 +218,8 @@ static int aty_set_dac_ATI68860_B(const struct fb_info_aty *info,
switch
(
bpp
)
{
case
8
:
gModeReg
=
0x83
;
devSetupRegA
=
0x60
|
0x00
/*(info->mach64DAC8Bit ? 0x00 : 0x01) */
;
devSetupRegA
=
0x60
|
0x00
/*(info->mach64DAC8Bit ? 0x00 : 0x01) */
;
break
;
case
15
:
gModeReg
=
0xA0
;
...
...
@@ -226,19 +244,20 @@ static int aty_set_dac_ATI68860_B(const struct fb_info_aty *info,
devSetupRegA
=
0x61
;
}
temp
=
aty_ld_8
(
DAC_CNTL
,
info
);
aty_st_8
(
DAC_CNTL
,
(
temp
&
~
DAC_EXT_SEL_RS2
)
|
DAC_EXT_SEL_RS3
,
info
);
temp
=
aty_ld_8
(
DAC_CNTL
,
par
);
aty_st_8
(
DAC_CNTL
,
(
temp
&
~
DAC_EXT_SEL_RS2
)
|
DAC_EXT_SEL_RS3
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
0x1D
,
info
);
aty_st_8
(
DAC_REGS
+
3
,
gModeReg
,
info
);
aty_st_8
(
DAC_REGS
,
0x02
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
0x1D
,
par
);
aty_st_8
(
DAC_REGS
+
3
,
gModeReg
,
par
);
aty_st_8
(
DAC_REGS
,
0x02
,
par
);
temp
=
aty_ld_8
(
DAC_CNTL
,
info
);
aty_st_8
(
DAC_CNTL
,
temp
|
DAC_EXT_SEL_RS2
|
DAC_EXT_SEL_RS3
,
info
);
temp
=
aty_ld_8
(
DAC_CNTL
,
par
);
aty_st_8
(
DAC_CNTL
,
temp
|
DAC_EXT_SEL_RS2
|
DAC_EXT_SEL_RS3
,
par
);
if
(
info
->
total_vram
<
MEM_SIZE_1M
)
if
(
info
->
fix
.
smem_len
<
MEM_SIZE_1M
)
mask
=
0x04
;
else
if
(
info
->
total_vram
==
MEM_SIZE_1M
)
else
if
(
info
->
fix
.
smem_len
==
MEM_SIZE_1M
)
mask
=
0x08
;
else
mask
=
0x0C
;
...
...
@@ -248,19 +267,20 @@ static int aty_set_dac_ATI68860_B(const struct fb_info_aty *info,
*/
#define A860_DELAY_L 0x80
temp
=
aty_ld_8
(
DAC_REGS
,
info
);
aty_st_8
(
DAC_REGS
,
(
devSetupRegA
|
mask
)
|
(
temp
&
A860_DELAY_L
),
info
);
temp
=
aty_ld_8
(
DAC_CNTL
,
info
);
aty_st_8
(
DAC_CNTL
,
(
temp
&
~
(
DAC_EXT_SEL_RS2
|
DAC_EXT_SEL_RS3
)),
info
);
aty_st_le32
(
BUS_CNTL
,
0x890e20f1
,
info
);
aty_st_le32
(
DAC_CNTL
,
0x47052100
,
info
);
temp
=
aty_ld_8
(
DAC_REGS
,
par
);
aty_st_8
(
DAC_REGS
,
(
devSetupRegA
|
mask
)
|
(
temp
&
A860_DELAY_L
),
par
);
temp
=
aty_ld_8
(
DAC_CNTL
,
par
);
aty_st_8
(
DAC_CNTL
,
(
temp
&
~
(
DAC_EXT_SEL_RS2
|
DAC_EXT_SEL_RS3
)),
par
);
aty_st_le32
(
BUS_CNTL
,
0x890e20f1
,
par
);
aty_st_le32
(
DAC_CNTL
,
0x47052100
,
par
);
return
0
;
}
const
struct
aty_dac_ops
aty_dac_ati68860b
=
{
set_dac:
aty_set_dac_ATI68860_B
,
set_dac:
aty_set_dac_ATI68860_B
,
};
...
...
@@ -268,9 +288,11 @@ const struct aty_dac_ops aty_dac_ati68860b = {
* AT&T 21C498 DAC
*/
static
int
aty_set_dac_ATT21C498
(
const
struct
fb_info_aty
*
info
,
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
)
static
int
aty_set_dac_ATT21C498
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
dotClock
;
int
muxmode
=
0
;
int
DACMask
=
0
;
...
...
@@ -299,14 +321,14 @@ static int aty_set_dac_ATT21C498(const struct fb_info_aty *info,
break
;
}
if
(
1
/* info->mach64DAC8Bit */
)
if
(
1
/* info->mach64DAC8Bit */
)
DACMask
|=
0x02
;
aty_dac_waste4
(
info
);
aty_st_8
(
DAC_REGS
+
2
,
DACMask
,
info
);
aty_dac_waste4
(
par
);
aty_st_8
(
DAC_REGS
+
2
,
DACMask
,
par
);
aty_st_le32
(
BUS_CNTL
,
0x890e20f1
,
info
);
aty_st_le32
(
DAC_CNTL
,
0x00072000
,
info
);
aty_st_le32
(
BUS_CNTL
,
0x890e20f1
,
par
);
aty_st_le32
(
DAC_CNTL
,
0x00072000
,
par
);
return
muxmode
;
}
...
...
@@ -319,8 +341,8 @@ const struct aty_dac_ops aty_dac_att21c498 = {
* ATI 18818 / ICS 2595 Clock Chip
*/
static
int
aty_var_to_pll_18818
(
const
struct
fb_info
_aty
*
info
,
u32
vclk_per
,
u8
bpp
,
union
aty_pll
*
pll
)
static
int
aty_var_to_pll_18818
(
const
struct
fb_info
*
info
,
u
32
vclk_per
,
u
8
bpp
,
union
aty_pll
*
pll
)
{
u32
MHz100
;
/* in 0.01 MHz */
u32
program_bits
;
...
...
@@ -378,37 +400,39 @@ static int aty_var_to_pll_18818(const struct fb_info_aty *info, u32 vclk_per,
return
0
;
}
static
u32
aty_pll_18818_to_var
(
const
struct
fb_info
_aty
*
info
,
static
u32
aty_pll_18818_to_var
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
)
{
return
(
pll
->
ics2595
.
period_in_ps
);
/* default for now */
return
(
pll
->
ics2595
.
period_in_ps
);
/* default for now */
}
static
void
aty_ICS2595_put1bit
(
u8
data
,
const
struct
fb_info_aty
*
info
)
static
void
aty_ICS2595_put1bit
(
u8
data
,
const
struct
atyfb_par
*
par
)
{
u8
tmp
;
data
&=
0x01
;
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
info
);
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
(
tmp
&
~
0x04
)
|
(
data
<<
2
),
info
);
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
info
);
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
(
tmp
&
~
0x08
)
|
(
0
<<
3
),
info
);
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
par
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
(
tmp
&
~
0x04
)
|
(
data
<<
2
),
par
);
aty_StrobeClock
(
info
);
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
par
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
(
tmp
&
~
0x08
)
|
(
0
<<
3
),
par
);
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
info
);
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
(
tmp
&
~
0x08
)
|
(
1
<<
3
),
info
);
aty_StrobeClock
(
par
);
aty_StrobeClock
(
info
);
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
par
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
(
tmp
&
~
0x08
)
|
(
1
<<
3
),
par
);
aty_StrobeClock
(
par
);
return
;
}
static
void
aty_set_pll18818
(
const
struct
fb_info
_aty
*
info
,
static
void
aty_set_pll18818
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
program_bits
;
u32
locationAddr
;
...
...
@@ -417,12 +441,12 @@ static void aty_set_pll18818(const struct fb_info_aty *info,
u8
old_clock_cntl
;
u8
old_crtc_ext_disp
;
old_clock_cntl
=
aty_ld_8
(
CLOCK_CNTL
,
info
);
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
0
,
info
);
old_clock_cntl
=
aty_ld_8
(
CLOCK_CNTL
,
par
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
0
,
par
);
old_crtc_ext_disp
=
aty_ld_8
(
CRTC_GEN_CNTL
+
3
,
info
);
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
|
(
CRTC_EXT_DISP_EN
>>
24
)
,
info
);
old_crtc_ext_disp
=
aty_ld_8
(
CRTC_GEN_CNTL
+
3
,
par
);
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
|
(
CRTC_EXT_DISP_EN
>>
24
),
par
);
mdelay
(
15
);
/* delay for 50 (15) ms */
...
...
@@ -430,43 +454,42 @@ static void aty_set_pll18818(const struct fb_info_aty *info,
locationAddr
=
pll
->
ics2595
.
locationAddr
;
/* Program the clock chip */
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
0
,
info
);
/* Strobe = 0 */
aty_StrobeClock
(
info
);
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
1
,
info
);
/* Strobe = 0 */
aty_StrobeClock
(
info
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
0
,
par
);
/* Strobe = 0 */
aty_StrobeClock
(
par
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
1
,
par
);
/* Strobe = 0 */
aty_StrobeClock
(
par
);
aty_ICS2595_put1bit
(
1
,
info
);
/* Send start bits */
aty_ICS2595_put1bit
(
0
,
info
);
/* Start bit */
aty_ICS2595_put1bit
(
0
,
info
);
/* Read / ~Write */
aty_ICS2595_put1bit
(
1
,
par
);
/* Send start bits */
aty_ICS2595_put1bit
(
0
,
par
);
/* Start bit */
aty_ICS2595_put1bit
(
0
,
par
);
/* Read / ~Write */
for
(
i
=
0
;
i
<
5
;
i
++
)
{
/* Location 0..4 */
aty_ICS2595_put1bit
(
locationAddr
&
1
,
info
);
aty_ICS2595_put1bit
(
locationAddr
&
1
,
par
);
locationAddr
>>=
1
;
}
for
(
i
=
0
;
i
<
8
+
1
+
2
+
2
;
i
++
)
{
aty_ICS2595_put1bit
(
program_bits
&
1
,
info
);
aty_ICS2595_put1bit
(
program_bits
&
1
,
par
);
program_bits
>>=
1
;
}
mdelay
(
1
);
/* delay for 1 ms */
(
void
)
aty_ld_8
(
DAC_REGS
,
info
);
/* Clear DAC Counter */
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
info
);
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
old_clock_cntl
|
CLOCK_STROBE
,
info
);
(
void
)
aty_ld_8
(
DAC_REGS
,
par
);
/* Clear DAC Counter */
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
par
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
old_clock_cntl
|
CLOCK_STROBE
,
par
);
mdelay
(
50
);
/* delay for 50 (15) ms */
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
((
pll
->
ics2595
.
locationAddr
&
0x0F
)
|
CLOCK_STROBE
),
info
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
((
pll
->
ics2595
.
locationAddr
&
0x0F
)
|
CLOCK_STROBE
),
par
);
return
;
}
const
struct
aty_pll_ops
aty_pll_ati18818_1
=
{
var_to_pll:
aty_var_to_pll_18818
,
pll_to_var:
aty_pll_18818_to_var
,
set_pll:
aty_set_pll18818
,
var_to_pll:
aty_var_to_pll_18818
,
pll_to_var:
aty_pll_18818_to_var
,
set_pll:
aty_set_pll18818
,
};
...
...
@@ -474,8 +497,8 @@ const struct aty_pll_ops aty_pll_ati18818_1 = {
* STG 1703 Clock Chip
*/
static
int
aty_var_to_pll_1703
(
const
struct
fb_info
_aty
*
info
,
u32
vclk_per
,
u8
bpp
,
union
aty_pll
*
pll
)
static
int
aty_var_to_pll_1703
(
const
struct
fb_info
*
info
,
u
32
vclk_per
,
u
8
bpp
,
union
aty_pll
*
pll
)
{
u32
mhz100
;
/* in 0.01 MHz */
u32
program_bits
;
...
...
@@ -506,9 +529,9 @@ static int aty_var_to_pll_1703(const struct fb_info_aty *info, u32 vclk_per,
divider
+=
0x20
;
}
temp
=
(
unsigned
int
)
(
mhz100
);
temp
=
(
unsigned
int
)
(
temp
*
(
MIN_N_1703
+
2
));
temp
-=
(
short
)
(
mach64RefFreq
<<
1
);
temp
=
(
unsigned
int
)
(
mhz100
);
temp
=
(
unsigned
int
)
(
temp
*
(
MIN_N_1703
+
2
));
temp
-=
(
short
)
(
mach64RefFreq
<<
1
);
tempA
=
MIN_N_1703
;
preRemainder
=
0xffff
;
...
...
@@ -518,11 +541,14 @@ static int aty_var_to_pll_1703(const struct fb_info_aty *info, u32 vclk_per,
remainder
=
tempB
%
mach64RefFreq
;
tempB
=
tempB
/
mach64RefFreq
;
if
((
tempB
&
0xffff
)
<=
127
&&
(
remainder
<=
preRemainder
))
{
if
((
tempB
&
0xffff
)
<=
127
&&
(
remainder
<=
preRemainder
))
{
preRemainder
=
remainder
;
divider
&=
~
0x1f
;
divider
|=
tempA
;
divider
=
(
divider
&
0x00ff
)
+
((
tempB
&
0xff
)
<<
8
);
divider
=
(
divider
&
0x00ff
)
+
((
tempB
&
0xff
)
<<
8
);
}
temp
+=
mhz100
;
...
...
@@ -540,46 +566,46 @@ static int aty_var_to_pll_1703(const struct fb_info_aty *info, u32 vclk_per,
return
0
;
}
static
u32
aty_pll_1703_to_var
(
const
struct
fb_info
_aty
*
info
,
static
u32
aty_pll_1703_to_var
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
)
{
return
(
pll
->
ics2595
.
period_in_ps
);
/* default for now */
return
(
pll
->
ics2595
.
period_in_ps
);
/* default for now */
}
static
void
aty_set_pll_1703
(
const
struct
fb_info
_aty
*
info
,
static
void
aty_set_pll_1703
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
program_bits
;
u32
locationAddr
;
char
old_crtc_ext_disp
;
old_crtc_ext_disp
=
aty_ld_8
(
CRTC_GEN_CNTL
+
3
,
info
);
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
|
(
CRTC_EXT_DISP_EN
>>
24
)
,
info
);
old_crtc_ext_disp
=
aty_ld_8
(
CRTC_GEN_CNTL
+
3
,
par
);
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
|
(
CRTC_EXT_DISP_EN
>>
24
),
par
);
program_bits
=
pll
->
ics2595
.
program_bits
;
locationAddr
=
pll
->
ics2595
.
locationAddr
;
/* Program clock */
aty_dac_waste4
(
info
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
(
locationAddr
<<
1
)
+
0x20
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
0
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
(
program_bits
&
0xFF00
)
>>
8
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
(
program_bits
&
0xFF
),
info
);
aty_dac_waste4
(
par
);
(
void
)
aty_ld_8
(
DAC_REGS
,
info
);
/* Clear DAC Counter */
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
info
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
(
locationAddr
<<
1
)
+
0x20
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
0
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
(
program_bits
&
0xFF00
)
>>
8
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
(
program_bits
&
0xFF
),
par
);
(
void
)
aty_ld_8
(
DAC_REGS
,
par
);
/* Clear DAC Counter */
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
par
);
return
;
}
const
struct
aty_pll_ops
aty_pll_stg1703
=
{
var_to_pll:
aty_var_to_pll_1703
,
pll_to_var:
aty_pll_1703_to_var
,
set_pll:
aty_set_pll_1703
,
var_to_pll:
aty_var_to_pll_1703
,
pll_to_var:
aty_pll_1703_to_var
,
set_pll:
aty_set_pll_1703
,
};
...
...
@@ -587,8 +613,8 @@ const struct aty_pll_ops aty_pll_stg1703 = {
* Chrontel 8398 Clock Chip
*/
static
int
aty_var_to_pll_8398
(
const
struct
fb_info
_aty
*
info
,
u32
vclk_per
,
u8
bpp
,
union
aty_pll
*
pll
)
static
int
aty_var_to_pll_8398
(
const
struct
fb_info
*
info
,
u
32
vclk_per
,
u
8
bpp
,
union
aty_pll
*
pll
)
{
u32
tempA
,
tempB
,
fOut
,
longMHz100
,
diff
,
preDiff
;
...
...
@@ -596,7 +622,7 @@ static int aty_var_to_pll_8398(const struct fb_info_aty *info, u32 vclk_per,
u32
program_bits
;
/* u32 post_divider; */
u32
mach64MinFreq
,
mach64MaxFreq
,
mach64RefFreq
;
u16
m
,
n
,
k
=
0
,
save_m
,
save_n
,
twoToKth
;
u16
m
,
n
,
k
=
0
,
save_m
,
save_n
,
twoToKth
;
/* Calculate the programming word */
mhz100
=
100000000
/
vclk_per
;
...
...
@@ -610,8 +636,7 @@ static int aty_var_to_pll_8398(const struct fb_info_aty *info, u32 vclk_per,
/* Calculate program word */
if
(
mhz100
==
0
)
program_bits
=
0xE0
;
else
{
else
{
if
(
mhz100
<
mach64MinFreq
)
mhz100
=
mach64MinFreq
;
if
(
mhz100
>
mach64MaxFreq
)
...
...
@@ -619,8 +644,7 @@ static int aty_var_to_pll_8398(const struct fb_info_aty *info, u32 vclk_per,
longMHz100
=
mhz100
*
256
/
100
;
/* 8 bit scale this */
while
(
mhz100
<
(
mach64MinFreq
<<
3
))
{
while
(
mhz100
<
(
mach64MinFreq
<<
3
))
{
mhz100
<<=
1
;
k
++
;
}
...
...
@@ -629,10 +653,8 @@ static int aty_var_to_pll_8398(const struct fb_info_aty *info, u32 vclk_per,
diff
=
0
;
preDiff
=
0xFFFFFFFF
;
for
(
m
=
MIN_M
;
m
<=
MAX_M
;
m
++
)
{
for
(
n
=
MIN_N
;
n
<=
MAX_N
;
n
++
)
{
for
(
m
=
MIN_M
;
m
<=
MAX_M
;
m
++
)
{
for
(
n
=
MIN_N
;
n
<=
MAX_N
;
n
++
)
{
tempA
=
(
14
.
31818
*
65536
);
tempA
*=
(
n
+
8
);
/* 43..256 */
tempB
=
twoToKth
*
256
;
...
...
@@ -644,8 +666,7 @@ static int aty_var_to_pll_8398(const struct fb_info_aty *info, u32 vclk_per,
else
diff
=
fOut
-
longMHz100
;
if
(
diff
<
preDiff
)
{
if
(
diff
<
preDiff
)
{
save_m
=
m
;
save_n
=
n
;
preDiff
=
diff
;
...
...
@@ -664,49 +685,51 @@ static int aty_var_to_pll_8398(const struct fb_info_aty *info, u32 vclk_per,
return
0
;
}
static
u32
aty_pll_8398_to_var
(
const
struct
fb_info
_aty
*
info
,
static
u32
aty_pll_8398_to_var
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
)
{
return
(
pll
->
ics2595
.
period_in_ps
);
/* default for now */
return
(
pll
->
ics2595
.
period_in_ps
);
/* default for now */
}
static
void
aty_set_pll_8398
(
const
struct
fb_info
_aty
*
info
,
static
void
aty_set_pll_8398
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
program_bits
;
u32
locationAddr
;
char
old_crtc_ext_disp
;
char
tmp
;
old_crtc_ext_disp
=
aty_ld_8
(
CRTC_GEN_CNTL
+
3
,
info
);
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
|
(
CRTC_EXT_DISP_EN
>>
24
)
,
info
);
old_crtc_ext_disp
=
aty_ld_8
(
CRTC_GEN_CNTL
+
3
,
par
);
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
|
(
CRTC_EXT_DISP_EN
>>
24
),
par
);
program_bits
=
pll
->
ics2595
.
program_bits
;
locationAddr
=
pll
->
ics2595
.
locationAddr
;
/* Program clock */
tmp
=
aty_ld_8
(
DAC_CNTL
,
info
);
aty_st_8
(
DAC_CNTL
,
tmp
|
DAC_EXT_SEL_RS2
|
DAC_EXT_SEL_RS3
,
info
);
tmp
=
aty_ld_8
(
DAC_CNTL
,
par
);
aty_st_8
(
DAC_CNTL
,
tmp
|
DAC_EXT_SEL_RS2
|
DAC_EXT_SEL_RS3
,
par
);
aty_st_8
(
DAC_REGS
,
locationAddr
,
info
);
aty_st_8
(
DAC_REGS
+
1
,
(
program_bits
&
0xff00
)
>>
8
,
info
);
aty_st_8
(
DAC_REGS
+
1
,
(
program_bits
&
0xff
),
info
);
aty_st_8
(
DAC_REGS
,
locationAddr
,
par
);
aty_st_8
(
DAC_REGS
+
1
,
(
program_bits
&
0xff00
)
>>
8
,
par
);
aty_st_8
(
DAC_REGS
+
1
,
(
program_bits
&
0xff
),
par
);
tmp
=
aty_ld_8
(
DAC_CNTL
,
info
);
aty_st_8
(
DAC_CNTL
,
(
tmp
&
~
DAC_EXT_SEL_RS2
)
|
DAC_EXT_SEL_RS3
,
info
);
tmp
=
aty_ld_8
(
DAC_CNTL
,
par
);
aty_st_8
(
DAC_CNTL
,
(
tmp
&
~
DAC_EXT_SEL_RS2
)
|
DAC_EXT_SEL_RS3
,
par
);
(
void
)
aty_ld_8
(
DAC_REGS
,
info
);
/* Clear DAC Counter */
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
info
);
(
void
)
aty_ld_8
(
DAC_REGS
,
par
);
/* Clear DAC Counter */
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
par
);
return
;
}
const
struct
aty_pll_ops
aty_pll_ch8398
=
{
var_to_pll:
aty_var_to_pll_8398
,
pll_to_var:
aty_pll_8398_to_var
,
set_pll:
aty_set_pll_8398
,
var_to_pll:
aty_var_to_pll_8398
,
pll_to_var:
aty_pll_8398_to_var
,
set_pll:
aty_set_pll_8398
,
};
...
...
@@ -714,7 +737,7 @@ const struct aty_pll_ops aty_pll_ch8398 = {
* AT&T 20C408 Clock Chip
*/
static
int
aty_var_to_pll_408
(
const
struct
fb_info
_aty
*
info
,
u32
vclk_per
,
static
int
aty_var_to_pll_408
(
const
struct
fb_info
*
info
,
u32
vclk_per
,
u8
bpp
,
union
aty_pll
*
pll
)
{
u32
mhz100
;
/* in 0.01 MHz */
...
...
@@ -745,9 +768,9 @@ static int aty_var_to_pll_408(const struct fb_info_aty *info, u32 vclk_per,
divider
+=
0x40
;
}
temp
=
(
unsigned
int
)
mhz100
;
temp
=
(
unsigned
int
)
(
temp
*
(
MIN_N_408
+
2
));
temp
-=
((
short
)
(
mach64RefFreq
<<
1
));
temp
=
(
unsigned
int
)
mhz100
;
temp
=
(
unsigned
int
)
(
temp
*
(
MIN_N_408
+
2
));
temp
-=
((
short
)
(
mach64RefFreq
<<
1
));
tempA
=
MIN_N_408
;
preRemainder
=
0xFFFF
;
...
...
@@ -756,15 +779,18 @@ static int aty_var_to_pll_408(const struct fb_info_aty *info, u32 vclk_per,
tempB
=
temp
;
remainder
=
tempB
%
mach64RefFreq
;
tempB
=
tempB
/
mach64RefFreq
;
if
(((
tempB
&
0xFFFF
)
<=
255
)
&&
(
remainder
<=
preRemainder
))
{
if
(((
tempB
&
0xFFFF
)
<=
255
)
&&
(
remainder
<=
preRemainder
))
{
preRemainder
=
remainder
;
divider
&=
~
0x3f
;
divider
|=
tempA
;
divider
=
(
divider
&
0x00FF
)
+
((
tempB
&
0xFF
)
<<
8
);
divider
=
(
divider
&
0x00FF
)
+
((
tempB
&
0xFF
)
<<
8
);
}
temp
+=
mhz100
;
tempA
++
;
}
while
(
tempA
<=
32
);
}
while
(
tempA
<=
32
);
program_bits
=
divider
;
}
...
...
@@ -777,41 +803,42 @@ static int aty_var_to_pll_408(const struct fb_info_aty *info, u32 vclk_per,
return
0
;
}
static
u32
aty_pll_408_to_var
(
const
struct
fb_info
_aty
*
info
,
static
u32
aty_pll_408_to_var
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
)
{
return
(
pll
->
ics2595
.
period_in_ps
);
/* default for now */
return
(
pll
->
ics2595
.
period_in_ps
);
/* default for now */
}
static
void
aty_set_pll_408
(
const
struct
fb_info
_aty
*
info
,
static
void
aty_set_pll_408
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
)
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
program_bits
;
u32
locationAddr
;
u8
tmpA
,
tmpB
,
tmpC
;
char
old_crtc_ext_disp
;
old_crtc_ext_disp
=
aty_ld_8
(
CRTC_GEN_CNTL
+
3
,
info
);
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
|
(
CRTC_EXT_DISP_EN
>>
24
)
,
info
);
old_crtc_ext_disp
=
aty_ld_8
(
CRTC_GEN_CNTL
+
3
,
par
);
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
|
(
CRTC_EXT_DISP_EN
>>
24
),
par
);
program_bits
=
pll
->
ics2595
.
program_bits
;
locationAddr
=
pll
->
ics2595
.
locationAddr
;
/* Program clock */
aty_dac_waste4
(
info
);
tmpB
=
aty_ld_8
(
DAC_REGS
+
2
,
info
)
|
1
;
aty_dac_waste4
(
info
);
aty_st_8
(
DAC_REGS
+
2
,
tmpB
,
info
);
aty_dac_waste4
(
par
);
tmpB
=
aty_ld_8
(
DAC_REGS
+
2
,
par
)
|
1
;
aty_dac_waste4
(
par
);
aty_st_8
(
DAC_REGS
+
2
,
tmpB
,
par
);
tmpA
=
tmpB
;
tmpC
=
tmpA
;
tmpA
|=
8
;
tmpB
=
1
;
aty_st_8
(
DAC_REGS
,
tmpB
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
info
);
aty_st_8
(
DAC_REGS
,
tmpB
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
par
);
udelay
(
400
);
/* delay for 400 us */
...
...
@@ -819,38 +846,37 @@ static void aty_set_pll_408(const struct fb_info_aty *info,
tmpB
=
locationAddr
;
tmpA
=
program_bits
>>
8
;
aty_st_8
(
DAC_REGS
,
tmpB
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
info
);
aty_st_8
(
DAC_REGS
,
tmpB
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
par
);
tmpB
=
locationAddr
+
1
;
tmpA
=
(
u8
)
program_bits
;
tmpA
=
(
u8
)
program_bits
;
aty_st_8
(
DAC_REGS
,
tmpB
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
info
);
aty_st_8
(
DAC_REGS
,
tmpB
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
par
);
tmpB
=
locationAddr
+
2
;
tmpA
=
0x77
;
aty_st_8
(
DAC_REGS
,
tmpB
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
info
);
aty_st_8
(
DAC_REGS
,
tmpB
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
par
);
udelay
(
400
);
/* delay for 400 us */
tmpA
=
tmpC
&
(
~
(
1
|
8
));
tmpB
=
1
;
aty_st_8
(
DAC_REGS
,
tmpB
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
info
);
(
void
)
aty_ld_8
(
DAC_REGS
,
info
);
/* Clear DAC Counter */
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
info
);
aty_st_8
(
DAC_REGS
,
tmpB
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
par
);
(
void
)
aty_ld_8
(
DAC_REGS
,
par
);
/* Clear DAC Counter */
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
par
);
return
;
}
const
struct
aty_pll_ops
aty_pll_att20c408
=
{
var_to_pll:
aty_var_to_pll_408
,
pll_to_var:
aty_pll_408_to_var
,
set_pll:
aty_set_pll_408
,
var_to_pll:
aty_var_to_pll_408
,
pll_to_var:
aty_pll_408_to_var
,
set_pll:
aty_set_pll_408
,
};
...
...
@@ -858,15 +884,17 @@ const struct aty_pll_ops aty_pll_att20c408 = {
* Unsupported DAC and Clock Chip
*/
static
int
aty_set_dac_unsupported
(
const
struct
fb_info
_aty
*
info
,
static
int
aty_set_dac_unsupported
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
)
{
aty_st_le32
(
BUS_CNTL
,
0x890e20f1
,
info
);
aty_st_le32
(
DAC_CNTL
,
0x47052100
,
info
);
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
aty_st_le32
(
BUS_CNTL
,
0x890e20f1
,
par
);
aty_st_le32
(
DAC_CNTL
,
0x47052100
,
par
);
/* new in 2.2.3p1 from Geert. ???????? */
aty_st_le32
(
BUS_CNTL
,
0x590e10ff
,
info
);
aty_st_le32
(
DAC_CNTL
,
0x47012100
,
info
);
aty_st_le32
(
BUS_CNTL
,
0x590e10ff
,
par
);
aty_st_le32
(
DAC_CNTL
,
0x47012100
,
par
);
return
0
;
}
...
...
@@ -876,12 +904,11 @@ static int dummy(void)
}
const
struct
aty_dac_ops
aty_dac_unsupported
=
{
set_dac:
aty_set_dac_unsupported
,
set_dac:
aty_set_dac_unsupported
,
};
const
struct
aty_pll_ops
aty_pll_unsupported
=
{
var_to_pll:
(
void
*
)
dummy
,
pll_to_var:
(
void
*
)
dummy
,
set_pll:
(
void
*
)
dummy
,
var_to_pll:
(
void
*
)
dummy
,
pll_to_var:
(
void
*
)
dummy
,
set_pll:
(
void
*
)
dummy
,
};
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