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
Hide 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
...
@@ -254,7 +254,7 @@ if [ "$CONFIG_FB" = "y" ]; then
fi
fi
fi
fi
if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \
if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \
"$CONFIG_FB_
ATY
" = "y" -o "$CONFIG_FB_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_RADEON" = "y" -o "$CONFIG_FB_TGA" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_PM3" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_PM3" = "y" -o \
"$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \
"$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \
...
@@ -264,11 +264,11 @@ if [ "$CONFIG_FB" = "y" ]; then
...
@@ -264,11 +264,11 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
"$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
"$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "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
define_tristate CONFIG_FBCON_CFB8 y
else
else
if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
"$CONFIG_FB_
ATY
" = "m" -o "$CONFIG_FB_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_RADEON" = "m" -o "$CONFIG_FB_TGA" = "m" -o \
"$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_PM3" = "m" -o \
"$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_PM3" = "m" -o \
"$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \
"$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \
...
@@ -277,12 +277,11 @@ if [ "$CONFIG_FB" = "y" ]; then
...
@@ -277,12 +277,11 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
"$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
"$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" ]; then
"$CONFIG_FB_P9100" = "m" ]; then
define_tristate CONFIG_FBCON_CFB8 m
define_tristate CONFIG_FBCON_CFB8 m
fi
fi
fi
fi
if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_
ATY
" = "y" -o \
if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_
PM3
" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \
"$CONFIG_FB_TRIDENT" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \
"$CONFIG_FB_TRIDENT" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \
"$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
"$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
...
@@ -291,10 +290,10 @@ if [ "$CONFIG_FB" = "y" ]; then
...
@@ -291,10 +290,10 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
"$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
"$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_CYBER2000" = "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
define_tristate CONFIG_FBCON_CFB16 y
else
else
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_
ATY
" = "m" -o \
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_
SIS
" = "m" -o \
"$CONFIG_FB_RADEON" = "m" -o "$CONFIG_FB_PVR2" = "m" -o \
"$CONFIG_FB_RADEON" = "m" -o "$CONFIG_FB_PVR2" = "m" -o \
"$CONFIG_FB_TRIDENT" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \
"$CONFIG_FB_TRIDENT" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \
"$CONFIG_FB_VOODOO1" = "m" -o "$CONFIG_FB_PM3" = "m" -o \
"$CONFIG_FB_VOODOO1" = "m" -o "$CONFIG_FB_PM3" = "m" -o \
...
@@ -302,8 +301,7 @@ if [ "$CONFIG_FB" = "y" ]; then
...
@@ -302,8 +301,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
"$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
"$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_CYBER2000" = "m" -o \
"$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_CYBER2000" = "m" ]; then
"$CONFIG_FB_SIS" = "m" ]; then
define_tristate CONFIG_FBCON_CFB16 m
define_tristate CONFIG_FBCON_CFB16 m
fi
fi
fi
fi
...
@@ -324,22 +322,22 @@ if [ "$CONFIG_FB" = "y" ]; then
...
@@ -324,22 +322,22 @@ if [ "$CONFIG_FB" = "y" ]; then
define_tristate CONFIG_FBCON_CFB24 m
define_tristate CONFIG_FBCON_CFB24 m
fi
fi
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_VOODOO1" = "y" -o "$CONFIG_FB_TRIDENT" = "y" -o \
"$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
"$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
"$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
"$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
"$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_PM3" = "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
define_tristate CONFIG_FBCON_CFB32 y
else
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_VOODOO1" = "m" -o "$CONFIG_FB_TRIDENT" = "m" -o \
"$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
"$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
"$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
"$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
"$CONFIG_FB_SIS" = "m" -o "$CONFIG_FB_PVR2" = "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
define_tristate CONFIG_FBCON_CFB32 m
fi
fi
fi
fi
...
@@ -353,14 +351,15 @@ if [ "$CONFIG_FB" = "y" ]; then
...
@@ -353,14 +351,15 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_APOLLO" = "y" -o \
"$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_APOLLO" = "y" -o \
"$CONFIG_FB_ATY128" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
"$CONFIG_FB_ATY128" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
"$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_SA1100" = "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
define_tristate CONFIG_FBCON_ACCEL y
else
else
if [ "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_HIT" = "m" -o \
if [ "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_HIT" = "m" -o \
"$CONFIG_FB_G364" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
"$CONFIG_FB_G364" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
"$CONFIG_FB_CLPS711X" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
"$CONFIG_FB_CLPS711X" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
"$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "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
define_tristate CONFIG_FBCON_ACCEL m
fi
fi
fi
fi
...
...
drivers/video/Makefile
View file @
87520e1e
...
@@ -44,7 +44,7 @@ obj-$(CONFIG_FB_PM3) += pm3fb.o
...
@@ -44,7 +44,7 @@ obj-$(CONFIG_FB_PM3) += pm3fb.o
obj-$(CONFIG_FB_APOLLO)
+=
dnfb.o cfbfillrect.o cfbimgblt.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_Q40)
+=
q40fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_ATARI)
+=
atafb.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_RADEON)
+=
radeonfb.o
obj-$(CONFIG_FB_NEOMAGIC)
+=
neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_NEOMAGIC)
+=
neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_IGA)
+=
igafb.o
obj-$(CONFIG_FB_IGA)
+=
igafb.o
...
...
drivers/video/aty/Makefile
View file @
87520e1e
...
@@ -3,7 +3,7 @@ export-objs := atyfb_base.o mach64_accel.o
...
@@ -3,7 +3,7 @@ export-objs := atyfb_base.o mach64_accel.o
obj-$(CONFIG_FB_ATY)
+=
atyfb.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_GX)
+=
mach64_gx.o
atyfb-$(CONFIG_FB_ATY_CT)
+=
mach64_ct.o mach64_cursor.o
atyfb-$(CONFIG_FB_ATY_CT)
+=
mach64_ct.o mach64_cursor.o
atyfb-objs
:=
$
(
atyfb-y
)
atyfb-objs
:=
$
(
atyfb-y
)
...
...
drivers/video/aty/atyfb.h
View file @
87520e1e
...
@@ -10,120 +10,109 @@
...
@@ -10,120 +10,109 @@
*/
*/
struct
crtc
{
struct
crtc
{
u32
vxres
;
u32
vxres
;
u32
vyres
;
u32
vyres
;
u32
xoffset
;
u32
xoffset
;
u32
yoffset
;
u32
yoffset
;
u32
bpp
;
u32
bpp
;
u32
h_tot_disp
;
u32
h_tot_disp
;
u32
h_sync_strt_wid
;
u32
h_sync_strt_wid
;
u32
v_tot_disp
;
u32
v_tot_disp
;
u32
v_sync_strt_wid
;
u32
v_sync_strt_wid
;
u32
off_pitch
;
u32
off_pitch
;
u32
gen_cntl
;
u32
gen_cntl
;
u32
dp_pix_width
;
/* acceleration */
u32
dp_pix_width
;
/* acceleration */
u32
dp_chain_mask
;
/* acceleration */
u32
dp_chain_mask
;
/* acceleration */
};
};
struct
pll_514
{
struct
pll_514
{
u8
m
;
u8
m
;
u8
n
;
u8
n
;
};
};
struct
pll_18818
struct
pll_18818
{
{
u32
program_bits
;
u32
program_bits
;
u32
locationAddr
;
u32
locationAddr
;
u32
period_in_ps
;
u32
period_in_ps
;
u32
post_divider
;
u32
post_divider
;
};
};
struct
pll_ct
{
struct
pll_ct
{
u8
pll_ref_div
;
u8
pll_ref_div
;
u8
pll_gen_cntl
;
u8
pll_gen_cntl
;
u8
mclk_fb_div
;
u8
mclk_fb_div
;
u8
pll_vclk_cntl
;
u8
pll_vclk_cntl
;
u8
vclk_post_div
;
u8
vclk_post_div
;
u8
vclk_fb_div
;
u8
vclk_fb_div
;
u8
pll_ext_cntl
;
u8
pll_ext_cntl
;
u32
dsp_config
;
/* Mach64 GTB DSP */
u32
dsp_config
;
/* Mach64 GTB DSP */
u32
dsp_on_off
;
/* Mach64 GTB DSP */
u32
dsp_on_off
;
/* Mach64 GTB DSP */
u8
mclk_post_div_real
;
u8
mclk_post_div_real
;
u8
vclk_post_div_real
;
u8
vclk_post_div_real
;
};
};
union
aty_pll
{
union
aty_pll
{
struct
pll_ct
ct
;
struct
pll_ct
ct
;
struct
pll_514
ibm514
;
struct
pll_514
ibm514
;
struct
pll_18818
ics2595
;
struct
pll_18818
ics2595
;
};
};
/*
/*
* The hardware parameters for each card
* The hardware parameters for each card
*/
*/
struct
atyfb_par
{
struct
crtc
crtc
;
union
aty_pll
pll
;
u32
accel_flags
;
};
struct
aty_cursor
{
struct
aty_cursor
{
int
enable
;
int
enable
;
int
on
;
int
on
;
int
vbl_cnt
;
int
vbl_cnt
;
int
blink_rate
;
int
blink_rate
;
u32
offset
;
u32
offset
;
struct
{
struct
{
u16
x
,
y
;
u16
x
,
y
;
}
pos
,
hot
,
size
;
}
pos
,
hot
,
size
;
u32
color
[
2
];
u32
color
[
2
];
u8
bits
[
8
][
64
];
u8
bits
[
8
][
64
];
u8
mask
[
8
][
64
];
u8
mask
[
8
][
64
];
u8
*
ram
;
u8
*
ram
;
struct
timer_list
*
timer
;
struct
timer_list
*
timer
;
};
};
struct
fb_info_aty
{
struct
atyfb_par
{
struct
fb_info
fb_info
;
struct
aty_cmap_regs
*
aty_cmap_regs
;
struct
fb_info_aty
*
next
;
const
struct
aty_dac_ops
*
dac_ops
;
unsigned
long
ati_regbase
;
const
struct
aty_pll_ops
*
pll_ops
;
unsigned
long
clk_wr_offset
;
struct
aty_cursor
*
cursor
;
struct
pci_mmap_map
*
mmap_map
;
unsigned
long
ati_regbase
;
struct
aty_cursor
*
cursor
;
unsigned
long
clk_wr_offset
;
struct
aty_cmap_regs
*
aty_cmap_regs
;
struct
crtc
crtc
;
struct
atyfb_par
default_par
;
union
aty_pll
pll
;
struct
atyfb_par
current_par
;
u32
features
;
u32
features
;
u32
ref_clk_per
;
u32
ref_clk_per
;
u32
pll_per
;
u32
pll_per
;
u32
mclk_per
;
u32
mclk_per
;
u8
bus_type
;
u8
bus_type
;
u8
ram_type
;
u8
ram_type
;
u8
mem_refresh_rate
;
u8
mem_refresh_rate
;
u8
blitter_may_be_busy
;
const
struct
aty_dac_ops
*
dac_ops
;
u32
accel_flags
;
const
struct
aty_pll_ops
*
pll_ops
;
struct
display_switch
dispsw
;
u8
blitter_may_be_busy
;
#ifdef __sparc__
#ifdef __sparc__
u8
mmaped
;
struct
pci_mmap_map
*
mmap_map
;
int
open
;
int
consolecnt
;
int
vtconsole
;
int
vtconsole
;
int
consolecnt
;
u8
mmaped
;
int
open
;
#endif
#endif
#ifdef CONFIG_PMAC_PBOOK
#ifdef CONFIG_PMAC_PBOOK
unsigned
char
*
save_framebuffer
;
unsigned
char
*
save_framebuffer
;
unsigned
long
save_pll
[
64
];
unsigned
long
save_pll
[
64
];
#endif
#endif
};
};
/*
/*
* ATI Mach64 features
* 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_RESET_3D 0x00000001
#define M64F_MAGIC_FIFO 0x00000002
#define M64F_MAGIC_FIFO 0x00000002
...
@@ -151,63 +140,63 @@ struct fb_info_aty {
...
@@ -151,63 +140,63 @@ struct fb_info_aty {
* Register access
* Register access
*/
*/
static
inline
u32
aty_ld_le32
(
int
regindex
,
static
inline
u32
aty_ld_le32
(
int
regindex
,
const
struct
atyfb_par
*
par
)
const
struct
fb_info_aty
*
info
)
{
{
/* Hack for bloc 1, should be cleanly optimized by compiler */
/* Hack for bloc 1, should be cleanly optimized by compiler */
if
(
regindex
>=
0x400
)
if
(
regindex
>=
0x400
)
regindex
-=
0x800
;
regindex
-=
0x800
;
#if defined(__mc68000__)
#if defined(__mc68000__)
return
le32_to_cpu
(
*
((
volatile
u32
*
)(
info
->
ati_regbase
+
regindex
)));
return
le32_to_cpu
(
*
((
volatile
u32
*
)
(
par
->
ati_regbase
+
regindex
)));
#else
#else
return
readl
(
info
->
ati_regbase
+
regindex
);
return
readl
(
par
->
ati_regbase
+
regindex
);
#endif
#endif
}
}
static
inline
void
aty_st_le32
(
int
regindex
,
u32
val
,
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 */
/* Hack for bloc 1, should be cleanly optimized by compiler */
if
(
regindex
>=
0x400
)
if
(
regindex
>=
0x400
)
regindex
-=
0x800
;
regindex
-=
0x800
;
#if defined(__mc68000__)
#if defined(__mc68000__)
*
((
volatile
u32
*
)(
info
->
ati_regbase
+
regindex
))
=
cpu_to_le32
(
val
);
*
((
volatile
u32
*
)
(
par
->
ati_regbase
+
regindex
))
=
cpu_to_le32
(
val
);
#else
#else
writel
(
val
,
info
->
ati_regbase
+
regindex
);
writel
(
val
,
par
->
ati_regbase
+
regindex
);
#endif
#endif
}
}
static
inline
u8
aty_ld_8
(
int
regindex
,
static
inline
u8
aty_ld_8
(
int
regindex
,
const
struct
atyfb_par
*
par
)
const
struct
fb_info_aty
*
info
)
{
{
/* Hack for bloc 1, should be cleanly optimized by compiler */
/* Hack for bloc 1, should be cleanly optimized by compiler */
if
(
regindex
>=
0x400
)
if
(
regindex
>=
0x400
)
regindex
-=
0x800
;
regindex
-=
0x800
;
return
readb
(
info
->
ati_regbase
+
regindex
);
return
readb
(
par
->
ati_regbase
+
regindex
);
}
}
static
inline
void
aty_st_8
(
int
regindex
,
u8
val
,
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 */
/* Hack for bloc 1, should be cleanly optimized by compiler */
if
(
regindex
>=
0x400
)
if
(
regindex
>=
0x400
)
regindex
-=
0x800
;
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
;
u8
res
;
/* write addr byte */
/* 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 */
/* read the register value */
res
=
aty_ld_8
(
CLOCK_CNTL
+
2
,
info
);
res
=
aty_ld_8
(
CLOCK_CNTL
+
2
,
par
);
return
res
;
return
res
;
}
}
...
@@ -216,15 +205,15 @@ static inline u8 aty_ld_pll(int offset, const struct fb_info_aty *info)
...
@@ -216,15 +205,15 @@ static inline u8 aty_ld_pll(int offset, const struct fb_info_aty *info)
*/
*/
struct
aty_dac_ops
{
struct
aty_dac_ops
{
int
(
*
set_dac
)(
const
struct
fb_info_aty
*
info
,
const
union
aty_pll
*
pll
,
int
(
*
set_dac
)
(
const
struct
fb_info
*
info
,
u32
bpp
,
u32
accel
);
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
);
};
};
extern
const
struct
aty_dac_ops
aty_dac_ibm514
;
/* IBM RGB514 */
extern
const
struct
aty_dac_ops
aty_dac_ibm514
;
/* IBM RGB514 */
extern
const
struct
aty_dac_ops
aty_dac_ati68860b
;
/* ATI 68860-B */
extern
const
struct
aty_dac_ops
aty_dac_ati68860b
;
/* ATI 68860-B */
extern
const
struct
aty_dac_ops
aty_dac_att21c498
;
/* AT&T 21C498 */
extern
const
struct
aty_dac_ops
aty_dac_att21c498
;
/* AT&T 21C498 */
extern
const
struct
aty_dac_ops
aty_dac_unsupported
;
/* unsupported */
extern
const
struct
aty_dac_ops
aty_dac_unsupported
;
/* unsupported */
extern
const
struct
aty_dac_ops
aty_dac_ct
;
/* Integrated */
extern
const
struct
aty_dac_ops
aty_dac_ct
;
/* Integrated */
/*
/*
...
@@ -232,25 +221,26 @@ extern const struct aty_dac_ops aty_dac_ct; /* Integrated */
...
@@ -232,25 +221,26 @@ extern const struct aty_dac_ops aty_dac_ct; /* Integrated */
*/
*/
struct
aty_pll_ops
{
struct
aty_pll_ops
{
int
(
*
var_to_pll
)(
const
struct
fb_info_aty
*
info
,
u32
vclk_per
,
u8
bpp
,
int
(
*
var_to_pll
)
(
const
struct
fb_info
*
info
,
u32
vclk_per
,
union
aty_pll
*
pll
);
u8
bpp
,
union
aty_pll
*
pll
);
u32
(
*
pll_to_var
)(
const
struct
fb_info_aty
*
info
,
u32
(
*
pll_to_var
)
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
);
const
union
aty_pll
*
pll
);
void
(
*
set_pll
)(
const
struct
fb_info_aty
*
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 */
extern
const
struct
aty_pll_ops
aty_pll_ati18818_1
;
/* ATI 18818 */
extern
const
struct
aty_pll_ops
aty_pll_stg1703
;
/* STG 1703 */
extern
const
struct
aty_pll_ops
aty_pll_stg1703
;
/* STG 1703 */
extern
const
struct
aty_pll_ops
aty_pll_ch8398
;
/* Chrontel 8398 */
extern
const
struct
aty_pll_ops
aty_pll_ch8398
;
/* Chrontel 8398 */
extern
const
struct
aty_pll_ops
aty_pll_att20c408
;
/* AT&T 20C408 */
extern
const
struct
aty_pll_ops
aty_pll_att20c408
;
/* AT&T 20C408 */
extern
const
struct
aty_pll_ops
aty_pll_ibm514
;
/* IBM RGB514 */
extern
const
struct
aty_pll_ops
aty_pll_ibm514
;
/* IBM RGB514 */
extern
const
struct
aty_pll_ops
aty_pll_unsupported
;
/* unsupported */
extern
const
struct
aty_pll_ops
aty_pll_unsupported
;
/* unsupported */
extern
const
struct
aty_pll_ops
aty_pll_ct
;
/* Integrated */
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
);
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
);
struct
pll_ct
*
pll
);
...
@@ -258,10 +248,10 @@ extern void aty_calc_pll_ct(const struct fb_info_aty *info,
...
@@ -258,10 +248,10 @@ extern void aty_calc_pll_ct(const struct fb_info_aty *info,
* Hardware cursor support
* 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
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_color
(
struct
fb_info
*
info
);
extern
void
aty_set_cursor_shape
(
struct
fb_info
_aty
*
fb
);
extern
void
aty_set_cursor_shape
(
struct
fb_info
*
info
);
extern
int
atyfb_set_font
(
struct
display
*
d
,
int
width
,
int
height
);
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);
...
@@ -269,25 +259,23 @@ extern int atyfb_set_font(struct display *d, int width, int height);
* Hardware acceleration
* 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
)
>
while
((
aty_ld_le32
(
FIFO_STAT
,
par
)
&
0xffff
)
>
((
u32
)
(
0x8000
>>
entries
)));
((
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
);
wait_for_fifo
(
16
,
par
);
while
((
aty_ld_le32
(
GUI_STAT
,
info
)
&
1
)
!=
0
);
while
((
aty_ld_le32
(
GUI_STAT
,
par
)
&
1
)
!=
0
);
info
->
blitter_may_be_busy
=
0
;
par
->
blitter_may_be_busy
=
0
;
}
}
extern
void
aty_reset_engine
(
const
struct
fb_info_aty
*
info
);
extern
void
aty_reset_engine
(
const
struct
atyfb_par
*
par
);
extern
void
aty_init_engine
(
const
struct
atyfb_par
*
par
,
extern
void
aty_init_engine
(
struct
atyfb_par
*
par
,
struct
fb_info_aty
*
info
);
struct
fb_info
*
info
);
extern
void
aty_rectfill
(
int
dstx
,
int
dsty
,
u_int
width
,
u_int
height
,
extern
void
atyfb_fillrect
(
struct
fb_info
*
info
,
struct
fb_fillrect
*
rect
);
u_int
color
,
struct
fb_info_aty
*
info
);
/*
/*
* Text console acceleration
* Text console acceleration
...
@@ -297,4 +285,3 @@ extern const struct display_switch fbcon_aty8;
...
@@ -297,4 +285,3 @@ extern const struct display_switch fbcon_aty8;
extern
const
struct
display_switch
fbcon_aty16
;
extern
const
struct
display_switch
fbcon_aty16
;
extern
const
struct
display_switch
fbcon_aty24
;
extern
const
struct
display_switch
fbcon_aty24
;
extern
const
struct
display_switch
fbcon_aty32
;
extern
const
struct
display_switch
fbcon_aty32
;
drivers/video/aty/atyfb_base.c
View file @
87520e1e
This source diff could not be displayed because it is too large. You can
view the blob
instead.
drivers/video/aty/mach64_accel.c
View file @
87520e1e
...
@@ -20,287 +20,299 @@
...
@@ -20,287 +20,299 @@
* Text console acceleration
* Text console acceleration
*/
*/
static
void
fbcon_aty_bmove
(
struct
display
*
p
,
int
sy
,
int
sx
,
int
dy
,
int
dx
,
static
void
fbcon_aty_bmove
(
struct
display
*
p
,
int
sy
,
int
sx
,
int
dy
,
int
height
,
int
width
);
int
dx
,
int
height
,
int
width
);
static
void
fbcon_aty_clear
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
sy
,
static
void
fbcon_aty_clear
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
sx
,
int
height
,
int
width
);
int
s
y
,
int
s
x
,
int
height
,
int
width
);
/*
/*
* Generic Mach64 routines
* Generic Mach64 routines
*/
*/
void
aty_reset_engine
(
const
struct
fb_info_aty
*
info
)
void
aty_reset_engine
(
const
struct
atyfb_par
*
par
)
{
{
/* reset engine */
/* reset engine */
aty_st_le32
(
GEN_TEST_CNTL
,
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
,
/* enable engine */
par
);
aty_st_le32
(
GEN_TEST_CNTL
,
/* enable engine */
aty_ld_le32
(
GEN_TEST_CNTL
,
info
)
|
GUI_ENGINE_ENABLE
,
info
);
aty_st_le32
(
GEN_TEST_CNTL
,
/* ensure engine is not locked up by clearing any FIFO or */
aty_ld_le32
(
GEN_TEST_CNTL
,
par
)
|
GUI_ENGINE_ENABLE
,
/* HOST errors */
par
);
aty_st_le32
(
BUS_CNTL
,
aty_ld_le32
(
BUS_CNTL
,
info
)
|
BUS_HOST_ERR_ACK
|
/* ensure engine is not locked up by clearing any FIFO or */
BUS_FIFO_ERR_ACK
,
info
);
/* HOST errors */
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
);
mdelay
(
GTC_3D_RESET_DELAY
);
aty_st_le32
(
SETUP_CNTL
,
0x00
,
info
);
aty_st_le32
(
SETUP_CNTL
,
0x00
,
par
);
mdelay
(
GTC_3D_RESET_DELAY
);
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
);
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
;
u32
pitch_value
;
/* determine modal information from global mode structure */
/* determine modal information from global mode structure */
pitch_value
=
par
->
crtc
.
vxres
;
pitch_value
=
par
->
crtc
.
vxres
;
if
(
par
->
crtc
.
bpp
==
24
)
{
if
(
par
->
crtc
.
bpp
==
24
)
{
/* In 24 bpp, the engine is in 8 bpp - this requires that all */
/* In 24 bpp, the engine is in 8 bpp - this requires that all */
/* horizontal coordinates and widths must be adjusted */
/* horizontal coordinates and widths must be adjusted */
pitch_value
=
pitch_value
*
3
;
pitch_value
=
pitch_value
*
3
;
}
}
/* On GTC (RagePro), we need to reset the 3D engine before */
/* On GTC (RagePro), we need to reset the 3D engine before */
if
(
M64_HAS
(
RESET_3D
))
if
(
M64_HAS
(
RESET_3D
))
reset_GTC_3D_engine
(
info
);
reset_GTC_3D_engine
(
par
);
/* Reset engine, enable, and clear any engine errors */
/* 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 */
/* Ensure that vga page pointers are set to zero - the upper */
/* page pointers are set to 1 to handle overflows in the */
/* page pointers are set to 1 to handle overflows in the */
/* lower page */
/* lower page */
aty_st_le32
(
MEM_VGA_WP_SEL
,
0x00010000
,
info
);
aty_st_le32
(
MEM_VGA_WP_SEL
,
0x00010000
,
par
);
aty_st_le32
(
MEM_VGA_RP_SEL
,
0x00010000
,
info
);
aty_st_le32
(
MEM_VGA_RP_SEL
,
0x00010000
,
par
);
/* ---- Setup standard engine context ---- */
/* ---- Setup standard engine context ---- */
/* All GUI registers here are FIFOed - therefore, wait for */
/* All GUI registers here are FIFOed - therefore, wait for */
/* the appropriate number of empty FIFO entries */
/* 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 */
/* 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 */
/* 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) */
/* zero these registers (set them to a known state) */
aty_st_le32
(
DST_Y_X
,
0
,
info
);
aty_st_le32
(
DST_Y_X
,
0
,
par
);
aty_st_le32
(
DST_HEIGHT
,
0
,
info
);
aty_st_le32
(
DST_HEIGHT
,
0
,
par
);
aty_st_le32
(
DST_BRES_ERR
,
0
,
info
);
aty_st_le32
(
DST_BRES_ERR
,
0
,
par
);
aty_st_le32
(
DST_BRES_INC
,
0
,
info
);
aty_st_le32
(
DST_BRES_INC
,
0
,
par
);
aty_st_le32
(
DST_BRES_DEC
,
0
,
info
);
aty_st_le32
(
DST_BRES_DEC
,
0
,
par
);
/* set destination drawing attributes */
/* set destination drawing attributes */
aty_st_le32
(
DST_CNTL
,
DST_LAST_PEL
|
DST_Y_TOP_TO_BOTTOM
|
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 */
/* 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 */
/* set these registers to a known state */
aty_st_le32
(
SRC_Y_X
,
0
,
info
);
aty_st_le32
(
SRC_Y_X
,
0
,
par
);
aty_st_le32
(
SRC_HEIGHT1_WIDTH1
,
1
,
info
);
aty_st_le32
(
SRC_HEIGHT1_WIDTH1
,
1
,
par
);
aty_st_le32
(
SRC_Y_X_START
,
0
,
info
);
aty_st_le32
(
SRC_Y_X_START
,
0
,
par
);
aty_st_le32
(
SRC_HEIGHT2_WIDTH2
,
1
,
info
);
aty_st_le32
(
SRC_HEIGHT2_WIDTH2
,
1
,
par
);
/* set source pixel retrieving attributes */
/* 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 */
/* set host attributes */
wait_for_fifo
(
13
,
info
);
wait_for_fifo
(
13
,
par
);
aty_st_le32
(
HOST_CNTL
,
0
,
info
);
aty_st_le32
(
HOST_CNTL
,
0
,
par
);
/* set pattern attributes */
/* set pattern attributes */
aty_st_le32
(
PAT_REG0
,
0
,
info
);
aty_st_le32
(
PAT_REG0
,
0
,
par
);
aty_st_le32
(
PAT_REG1
,
0
,
info
);
aty_st_le32
(
PAT_REG1
,
0
,
par
);
aty_st_le32
(
PAT_CNTL
,
0
,
info
);
aty_st_le32
(
PAT_CNTL
,
0
,
par
);
/* set scissors to modal size */
/* set scissors to modal size */
aty_st_le32
(
SC_LEFT
,
0
,
info
);
aty_st_le32
(
SC_LEFT
,
0
,
par
);
aty_st_le32
(
SC_TOP
,
0
,
info
);
aty_st_le32
(
SC_TOP
,
0
,
par
);
aty_st_le32
(
SC_BOTTOM
,
par
->
crtc
.
vyres
-
1
,
info
);
aty_st_le32
(
SC_BOTTOM
,
par
->
crtc
.
vyres
-
1
,
par
);
aty_st_le32
(
SC_RIGHT
,
pitch_value
-
1
,
info
);
aty_st_le32
(
SC_RIGHT
,
pitch_value
-
1
,
par
);
/* set background color to minimum value (usually BLACK) */
/* 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) */
/* 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 */
/* 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 */
/* set foreground mix to overpaint and background mix to */
/* no-effect */
/* 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 */
/* set primary source pixel channel to foreground color */
/* register */
/* 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 */
/* set compare functionality to false (no-effect on */
/* destination) */
/* destination) */
wait_for_fifo
(
3
,
info
);
wait_for_fifo
(
3
,
par
);
aty_st_le32
(
CLR_CMP_CLR
,
0
,
info
);
aty_st_le32
(
CLR_CMP_CLR
,
0
,
par
);
aty_st_le32
(
CLR_CMP_MASK
,
0xFFFFFFFF
,
info
);
aty_st_le32
(
CLR_CMP_MASK
,
0xFFFFFFFF
,
par
);
aty_st_le32
(
CLR_CMP_CNTL
,
0
,
info
);
aty_st_le32
(
CLR_CMP_CNTL
,
0
,
par
);
/* set pixel depth */
/* set pixel depth */
wait_for_fifo
(
2
,
info
);
wait_for_fifo
(
2
,
par
);
aty_st_le32
(
DP_PIX_WIDTH
,
par
->
crtc
.
dp_pix_width
,
info
);
aty_st_le32
(
DP_PIX_WIDTH
,
par
->
crtc
.
dp_pix_width
,
par
);
aty_st_le32
(
DP_CHAIN_MASK
,
par
->
crtc
.
dp_chain_mask
,
info
);
aty_st_le32
(
DP_CHAIN_MASK
,
par
->
crtc
.
dp_chain_mask
,
par
);
wait_for_fifo
(
5
,
info
);
wait_for_fifo
(
5
,
par
);
aty_st_le32
(
SCALE_3D_CNTL
,
0
,
info
);
aty_st_le32
(
SCALE_3D_CNTL
,
0
,
par
);
aty_st_le32
(
Z_CNTL
,
0
,
info
);
aty_st_le32
(
Z_CNTL
,
0
,
par
);
aty_st_le32
(
CRTC_INT_CNTL
,
aty_ld_le32
(
CRTC_INT_CNTL
,
info
)
&
~
0x20
,
info
);
aty_st_le32
(
CRTC_INT_CNTL
,
aty_ld_le32
(
CRTC_INT_CNTL
,
par
)
&
~
0x20
,
aty_st_le32
(
GUI_TRAJ_CNTL
,
0x100023
,
info
);
par
);
aty_st_le32
(
GUI_TRAJ_CNTL
,
0x100023
,
par
);
/* insure engine is idle before leaving */
wait_for_idle
(
info
);
/* insure engine is idle before leaving */
wait_for_idle
(
par
);
}
}
/*
/*
* Accelerated functions
* Accelerated functions
*/
*/
static
inline
void
draw_rect
(
s16
x
,
s16
y
,
u16
width
,
u16
height
,
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 */
/* perform rectangle fill */
wait_for_fifo
(
2
,
info
);
wait_for_fifo
(
2
,
par
);
aty_st_le32
(
DST_Y_X
,
(
x
<<
16
)
|
y
,
info
);
aty_st_le32
(
DST_Y_X
,
(
x
<<
16
)
|
y
,
par
);
aty_st_le32
(
DST_HEIGHT_WIDTH
,
(
width
<<
16
)
|
height
,
info
);
aty_st_le32
(
DST_HEIGHT_WIDTH
,
(
width
<<
16
)
|
height
,
par
);
info
->
blitter_may_be_busy
=
1
;
par
->
blitter_may_be_busy
=
1
;
}
}
static
inline
void
aty_rectcopy
(
int
srcx
,
int
srcy
,
int
dstx
,
int
dsty
,
static
void
atyfb_copyarea
(
struct
fb_info
*
info
,
struct
fb_copyarea
*
area
)
u_int
width
,
u_int
height
,
struct
fb_info_aty
*
info
)
{
{
u32
direction
=
DST_LAST_PEL
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
pitch_value
;
u32
direction
=
DST_LAST_PEL
;
if
(
!
width
||
!
height
)
u32
pitch_value
;
return
;
if
(
!
area
->
width
||
!
area
->
height
)
pitch_value
=
info
->
current_par
.
crtc
.
vxres
;
return
;
if
(
info
->
current_par
.
crtc
.
bpp
==
24
)
{
/* In 24 bpp, the engine is in 8 bpp - this requires that all */
pitch_value
=
par
->
crtc
.
vxres
;
/* horizontal coordinates and widths must be adjusted */
if
(
par
->
crtc
.
bpp
==
24
)
{
pitch_value
*=
3
;
/* In 24 bpp, the engine is in 8 bpp - this requires that all */
srcx
*=
3
;
/* horizontal coordinates and widths must be adjusted */
dstx
*=
3
;
pitch_value
*=
3
;
width
*=
3
;
area
->
sx
*=
3
;
}
area
->
dx
*=
3
;
area
->
width
*=
3
;
if
(
srcy
<
dsty
)
{
}
dsty
+=
height
-
1
;
srcy
+=
height
-
1
;
if
(
area
->
sy
<
area
->
dy
)
{
}
else
area
->
dy
+=
area
->
height
-
1
;
direction
|=
DST_Y_TOP_TO_BOTTOM
;
area
->
sy
+=
area
->
height
-
1
;
}
else
if
(
srcx
<
dstx
)
{
direction
|=
DST_Y_TOP_TO_BOTTOM
;
dstx
+=
width
-
1
;
srcx
+=
width
-
1
;
if
(
area
->
sx
<
area
->
dx
)
{
}
else
area
->
dx
+=
area
->
width
-
1
;
direction
|=
DST_X_LEFT_TO_RIGHT
;
area
->
sx
+=
area
->
width
-
1
;
}
else
wait_for_fifo
(
4
,
info
);
direction
|=
DST_X_LEFT_TO_RIGHT
;
aty_st_le32
(
DP_SRC
,
FRGD_SRC_BLIT
,
info
);
aty_st_le32
(
SRC_Y_X
,
(
srcx
<<
16
)
|
srcy
,
info
);
wait_for_fifo
(
4
,
par
);
aty_st_le32
(
SRC_HEIGHT1_WIDTH1
,
(
width
<<
16
)
|
height
,
info
);
aty_st_le32
(
DP_SRC
,
FRGD_SRC_BLIT
,
par
);
aty_st_le32
(
DST_CNTL
,
direction
,
info
);
aty_st_le32
(
SRC_Y_X
,
(
area
->
sx
<<
16
)
|
area
->
sy
,
par
);
draw_rect
(
dstx
,
dsty
,
width
,
height
,
info
);
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
,
void
atyfb_fillrect
(
struct
fb_info
*
info
,
struct
fb_fillrect
*
rect
)
struct
fb_info_aty
*
info
)
{
{
if
(
!
width
||
!
height
)
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
return
;
if
(
!
rect
->
width
||
!
rect
->
height
)
if
(
info
->
current_par
.
crtc
.
bpp
==
24
)
{
return
;
/* In 24 bpp, the engine is in 8 bpp - this requires that all */
/* horizontal coordinates and widths must be adjusted */
rect
->
color
|=
(
rect
->
color
<<
8
);
dstx
*=
3
;
rect
->
color
|=
(
rect
->
color
<<
16
);
width
*=
3
;
}
if
(
par
->
crtc
.
bpp
==
24
)
{
/* In 24 bpp, the engine is in 8 bpp - this requires that all */
wait_for_fifo
(
3
,
info
);
/* horizontal coordinates and widths must be adjusted */
aty_st_le32
(
DP_FRGD_CLR
,
color
,
info
);
rect
->
dx
*=
3
;
aty_st_le32
(
DP_SRC
,
BKGD_SRC_BKGD_CLR
|
FRGD_SRC_FRGD_CLR
|
MONO_SRC_ONE
,
rect
->
width
*=
3
;
info
);
}
aty_st_le32
(
DST_CNTL
,
DST_LAST_PEL
|
DST_Y_TOP_TO_BOTTOM
|
DST_X_LEFT_TO_RIGHT
,
info
);
wait_for_fifo
(
3
,
par
);
draw_rect
(
dstx
,
dsty
,
width
,
height
,
info
);
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
* Text console acceleration
*/
*/
static
void
fbcon_aty_bmove
(
struct
display
*
p
,
int
sy
,
int
sx
,
int
dy
,
int
dx
,
static
void
fbcon_aty_bmove
(
struct
display
*
p
,
int
sy
,
int
sx
,
int
dy
,
int
height
,
int
width
)
int
dx
,
int
height
,
int
width
)
{
{
struct
fb_info
*
info
=
p
->
fb_info
;
struct
fb_copyarea
area
;
#ifdef __sparc__
#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
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
fb
->
fb_info
.
display_fg
->
vc_num
==
fb
->
vtconsole
))
||
info
->
display_fg
->
vc_num
==
return
;
par
->
vtconsole
))
return
;
#endif
#endif
sx
*=
fontwidth
(
p
);
area
.
sx
=
sx
*
fontwidth
(
p
);
sy
*=
fontheight
(
p
);
area
.
sy
=
sy
*
fontheight
(
p
);
dx
*=
fontwidth
(
p
);
area
.
dx
=
dx
*
fontwidth
(
p
);
dy
*=
fontheight
(
p
);
area
.
dy
=
dy
*
fontheight
(
p
);
width
*=
fontwidth
(
p
);
area
.
width
=
width
*
fontwidth
(
p
);
height
*=
fontheight
(
p
);
area
.
height
=
height
*
fontheight
(
p
);
aty_rectcopy
(
sx
,
sy
,
dx
,
dy
,
width
,
height
,
atyfb_copyarea
(
info
,
&
area
);
(
struct
fb_info_aty
*
)
p
->
fb_info
);
}
}
static
void
fbcon_aty_clear
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
sy
,
static
void
fbcon_aty_clear
(
struct
vc_data
*
conp
,
struct
display
*
p
,
int
sx
,
int
height
,
int
width
)
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__
#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
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
fb
->
fb_info
.
display_fg
->
vc_num
==
fb
->
vtconsole
))
||
info
->
display_fg
->
vc_num
==
return
;
par
->
vtconsole
))
return
;
#endif
#endif
region
.
color
=
attr_bgcol_ec
(
p
,
conp
);
region
.
color
|=
(
region
.
color
<<
8
);
region
.
color
|=
(
region
.
color
<<
16
);
bgx
=
attr_bgcol_ec
(
p
,
conp
);
region
.
dx
=
sx
*
fontwidth
(
p
);
bgx
|=
(
bgx
<<
8
);
region
.
dy
=
sy
*
fontheight
(
p
);
bgx
|=
(
bgx
<<
16
);
region
.
width
=
width
*
fontwidth
(
p
);
region
.
height
=
height
*
fontheight
(
p
);
region
.
rop
=
ROP_COPY
;
sx
*=
fontwidth
(
p
);
atyfb_fillrect
(
info
,
&
region
);
sy
*=
fontheight
(
p
);
width
*=
fontwidth
(
p
);
height
*=
fontheight
(
p
);
aty_rectfill
(
sx
,
sy
,
width
,
height
,
bgx
,
(
struct
fb_info_aty
*
)
p
->
fb_info
);
}
}
#ifdef __sparc__
#ifdef __sparc__
#define check_access \
#define check_access \
if (
fb->mmaped && (!fb->fb_info.
display_fg \
if (
par->mmaped && (!info->
display_fg \
||
fb->fb_info.display_fg->vc_num == fb
->vtconsole)) \
||
info->display_fg->vc_num == par
->vtconsole)) \
return;
return;
#else
#else
#define check_access do { } while (0)
#define check_access do { } while (0)
...
@@ -309,10 +321,11 @@ static void fbcon_aty_clear(struct vc_data *conp, struct display *p, int sy,
...
@@ -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...) \
#define DEF_FBCON_ATY_OP(name, call, args...) \
static void name(struct vc_data *conp, struct display *p, 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; \
check_access; \
if (
fb
->blitter_may_be_busy) \
if (
par
->blitter_may_be_busy) \
wait_for_idle(
(struct fb_info_aty *)p->fb_info
); \
wait_for_idle(
par
); \
call; \
call; \
}
}
...
@@ -342,12 +355,11 @@ const struct display_switch fbcon_aty##width = { \
...
@@ -342,12 +355,11 @@ const struct display_switch fbcon_aty##width = { \
DEF_FBCON_ATY
(
8
)
DEF_FBCON_ATY
(
8
)
#endif
#endif
#ifdef FBCON_HAS_CFB16
#ifdef FBCON_HAS_CFB16
DEF_FBCON_ATY
(
16
)
DEF_FBCON_ATY
(
16
)
#endif
#endif
#ifdef FBCON_HAS_CFB24
#ifdef FBCON_HAS_CFB24
DEF_FBCON_ATY
(
24
)
DEF_FBCON_ATY
(
24
)
#endif
#endif
#ifdef FBCON_HAS_CFB32
#ifdef FBCON_HAS_CFB32
DEF_FBCON_ATY
(
32
)
DEF_FBCON_ATY
(
32
)
#endif
#endif
drivers/video/aty/mach64_ct.c
View file @
87520e1e
...
@@ -16,26 +16,25 @@
...
@@ -16,26 +16,25 @@
/* FIXME: remove the FAIL definition */
/* FIXME: remove the FAIL definition */
#define FAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)
#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
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
,
static
int
aty_valid_pll_ct
(
const
struct
fb_info_aty
*
info
,
u32
vclk_per
,
struct
pll_ct
*
pll
);
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
);
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
);
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
);
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 */
/* 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 */
/* write the register value */
aty_st_8
(
CLOCK_CNTL
+
2
,
val
,
info
);
aty_st_8
(
CLOCK_CNTL
+
2
,
val
,
par
);
aty_st_8
(
CLOCK_CNTL
+
1
,
(
offset
<<
2
)
&
~
PLL_WR_EN
,
info
);
aty_st_8
(
CLOCK_CNTL
+
1
,
(
offset
<<
2
)
&
~
PLL_WR_EN
,
par
);
}
}
...
@@ -45,228 +44,238 @@ static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info)
...
@@ -45,228 +44,238 @@ static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info)
* PLL programming (Mach64 CT family)
* 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
)
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
xclks_per_row
,
fifo_off
,
fifo_on
,
y
,
fifo_size
,
page_size
;
u32
dsp_xclks_per_row
,
dsp_loop_latency
,
dsp_precision
,
dsp_off
,
dsp_on
;
/* xclocks_per_row<<11 */
u32
xclks_per_row
,
fifo_off
,
fifo_on
,
y
,
fifo_size
,
page_size
;
xclks_per_row
=
(
pll
->
mclk_fb_div
*
pll
->
vclk_post_div_real
*
64
<<
11
)
/
(
pll
->
vclk_fb_div
*
pll
->
mclk_post_div_real
*
bpp
);
/* xclocks_per_row<<11 */
if
(
xclks_per_row
<
(
1
<<
11
))
xclks_per_row
=
FAIL
(
"Dotclock to high"
);
(
pll
->
mclk_fb_div
*
pll
->
vclk_post_div_real
*
64
<<
11
)
/
if
(
M64_HAS
(
FIFO_24
))
{
(
pll
->
vclk_fb_div
*
pll
->
mclk_post_div_real
*
bpp
);
fifo_size
=
24
;
if
(
xclks_per_row
<
(
1
<<
11
))
dsp_loop_latency
=
0
;
FAIL
(
"Dotclock to high"
);
}
else
{
if
(
M64_HAS
(
FIFO_24
))
{
fifo_size
=
32
;
fifo_size
=
24
;
dsp_loop_latency
=
2
;
dsp_loop_latency
=
0
;
}
dsp_precision
=
0
;
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
);
if
(
info
->
fb_info
.
fix
.
smem_len
>
1
*
1024
*
1024
)
{
if
(
info
->
ram_type
>=
SDRAM
)
{
/* >1 MB SDRAM */
dsp_loop_latency
+=
8
;
page_size
=
8
;
}
else
{
}
else
{
/* >1 MB DRAM */
fifo_size
=
32
;
dsp_loop_latency
+=
6
;
dsp_loop_latency
=
2
;
page_size
=
9
;
}
dsp_precision
=
0
;
y
=
(
xclks_per_row
*
fifo_size
)
>>
11
;
while
(
y
)
{
y
>>=
1
;
dsp_precision
++
;
}
}
}
else
{
dsp_precision
-=
5
;
if
(
info
->
ram_type
>=
SDRAM
)
{
/* fifo_off<<6 */
/* <2 MB SDRAM */
fifo_off
=
((
xclks_per_row
*
(
fifo_size
-
1
))
>>
5
)
+
(
3
<<
6
);
dsp_loop_latency
+=
9
;
page_size
=
10
;
if
(
info
->
fix
.
smem_len
>
1
*
1024
*
1024
)
{
if
(
par
->
ram_type
>=
SDRAM
)
{
/* >1 MB SDRAM */
dsp_loop_latency
+=
8
;
page_size
=
8
;
}
else
{
/* >1 MB DRAM */
dsp_loop_latency
+=
6
;
page_size
=
9
;
}
}
else
{
}
else
{
/* <2 MB DRAM */
if
(
par
->
ram_type
>=
SDRAM
)
{
dsp_loop_latency
+=
8
;
/* <2 MB SDRAM */
page_size
=
10
;
dsp_loop_latency
+=
9
;
page_size
=
10
;
}
else
{
/* <2 MB DRAM */
dsp_loop_latency
+=
8
;
page_size
=
10
;
}
}
}
}
/* fifo_on<<6 */
/* fifo_on<<6 */
if
(
xclks_per_row
>=
(
page_size
<<
11
))
if
(
xclks_per_row
>=
(
page_size
<<
11
))
fifo_on
=
fifo_on
=
((
2
*
page_size
+
1
)
<<
6
)
+
(
xclks_per_row
>>
5
);
((
2
*
page_size
+
1
)
<<
6
)
+
(
xclks_per_row
>>
5
);
else
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_xclks_per_row
=
xclks_per_row
>>
dsp_precision
;
dsp_on
=
fifo_on
>>
dsp_precision
;
dsp_on
=
fifo_on
>>
dsp_precision
;
dsp_off
=
fifo_off
>>
dsp_precision
;
dsp_off
=
fifo_off
>>
dsp_precision
;
pll
->
dsp_config
=
(
dsp_xclks_per_row
&
0x3fff
)
|
pll
->
dsp_config
=
(
dsp_xclks_per_row
&
0x3fff
)
|
((
dsp_loop_latency
&
0xf
)
<<
16
)
|
((
dsp_loop_latency
&
0xf
)
<<
16
)
|
((
dsp_precision
&
7
)
<<
20
);
((
dsp_precision
&
7
)
<<
20
);
pll
->
dsp_on_off
=
(
dsp_on
&
0x7ff
)
|
((
dsp_off
&
0x7ff
)
<<
16
);
pll
->
dsp_on_off
=
(
dsp_on
&
0x7ff
)
|
((
dsp_off
&
0x7ff
)
<<
16
);
return
0
;
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
pll_ct
*
pll
)
{
{
u32
q
,
x
;
/* x is a workaround for sparc64-linux-gcc */
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
x
=
x
;
/* x is a workaround for sparc64-linux-gcc */
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 */
/* FIXME: use the VTB/GTB /3 post divider if it's better suited */
if
(
q
<
16
*
8
||
q
>
255
*
8
)
q
=
par
->
ref_clk_per
*
pll
->
pll_ref_div
*
4
/
par
->
mclk_per
;
/* actually 8*q */
FAIL
(
"mclk out of range"
);
if
(
q
<
16
*
8
||
q
>
255
*
8
)
else
if
(
q
<
32
*
8
)
FAIL
(
"mclk out of range"
);
pll
->
mclk_post_div_real
=
8
;
else
if
(
q
<
32
*
8
)
else
if
(
q
<
64
*
8
)
pll
->
mclk_post_div_real
=
8
;
pll
->
mclk_post_div_real
=
4
;
else
if
(
q
<
64
*
8
)
else
if
(
q
<
128
*
8
)
pll
->
mclk_post_div_real
=
4
;
pll
->
mclk_post_div_real
=
2
;
else
if
(
q
<
128
*
8
)
else
pll
->
mclk_post_div_real
=
2
;
pll
->
mclk_post_div_real
=
1
;
else
pll
->
mclk_fb_div
=
q
*
pll
->
mclk_post_div_real
/
8
;
pll
->
mclk_post_div_real
=
1
;
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 */
/* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */
if
(
q
<
16
*
8
||
q
>
255
*
8
)
q
=
par
->
ref_clk_per
*
pll
->
pll_ref_div
*
4
/
vclk_per
;
/* actually 8*q */
FAIL
(
"vclk out of range"
);
if
(
q
<
16
*
8
||
q
>
255
*
8
)
else
if
(
q
<
32
*
8
)
FAIL
(
"vclk out of range"
);
pll
->
vclk_post_div_real
=
8
;
else
if
(
q
<
32
*
8
)
else
if
(
q
<
64
*
8
)
pll
->
vclk_post_div_real
=
8
;
pll
->
vclk_post_div_real
=
4
;
else
if
(
q
<
64
*
8
)
else
if
(
q
<
128
*
8
)
pll
->
vclk_post_div_real
=
4
;
pll
->
vclk_post_div_real
=
2
;
else
if
(
q
<
128
*
8
)
else
pll
->
vclk_post_div_real
=
2
;
pll
->
vclk_post_div_real
=
1
;
else
pll
->
vclk_fb_div
=
q
*
pll
->
vclk_post_div_real
/
8
;
pll
->
vclk_post_div_real
=
1
;
return
0
;
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
)
{
{
u8
mpostdiv
=
0
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u8
vpostdiv
=
0
;
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
;
pll
->
pll_gen_cntl
=
0x04
;
else
else
pll
->
pll_gen_cntl
=
0x84
;
pll
->
pll_gen_cntl
=
0x84
;
switch
(
pll
->
mclk_post_div_real
)
{
switch
(
pll
->
mclk_post_div_real
)
{
case
1
:
case
1
:
mpostdiv
=
0
;
mpostdiv
=
0
;
break
;
break
;
case
2
:
case
2
:
mpostdiv
=
1
;
mpostdiv
=
1
;
break
;
break
;
case
3
:
case
3
:
mpostdiv
=
4
;
mpostdiv
=
4
;
break
;
break
;
case
4
:
case
4
:
mpostdiv
=
2
;
mpostdiv
=
2
;
break
;
break
;
case
8
:
case
8
:
mpostdiv
=
3
;
mpostdiv
=
3
;
break
;
break
;
}
}
pll
->
pll_gen_cntl
|=
mpostdiv
<<
4
;
/* mclk */
pll
->
pll_gen_cntl
|=
mpostdiv
<<
4
;
/* mclk */
if
(
M64_HAS
(
MAGIC_POSTDIV
))
if
(
M64_HAS
(
MAGIC_POSTDIV
))
pll
->
pll_ext_cntl
=
0
;
pll
->
pll_ext_cntl
=
0
;
else
else
pll
->
pll_ext_cntl
=
mpostdiv
;
/* xclk == mclk */
pll
->
pll_ext_cntl
=
mpostdiv
;
/* xclk == mclk */
switch
(
pll
->
vclk_post_div_real
)
{
switch
(
pll
->
vclk_post_div_real
)
{
case
2
:
case
2
:
vpostdiv
=
1
;
vpostdiv
=
1
;
break
;
break
;
case
3
:
case
3
:
pll
->
pll_ext_cntl
|=
0x10
;
pll
->
pll_ext_cntl
|=
0x10
;
case
1
:
case
1
:
vpostdiv
=
0
;
vpostdiv
=
0
;
break
;
break
;
case
6
:
case
6
:
pll
->
pll_ext_cntl
|=
0x10
;
pll
->
pll_ext_cntl
|=
0x10
;
case
4
:
case
4
:
vpostdiv
=
2
;
vpostdiv
=
2
;
break
;
break
;
case
12
:
case
12
:
pll
->
pll_ext_cntl
|=
0x10
;
pll
->
pll_ext_cntl
|=
0x10
;
case
8
:
case
8
:
vpostdiv
=
3
;
vpostdiv
=
3
;
break
;
break
;
}
}
pll
->
pll_vclk_cntl
=
0x03
;
/* VCLK = PLL_VCLK/VCLKx_POST */
pll
->
pll_vclk_cntl
=
0x03
;
/* VCLK = PLL_VCLK/VCLKx_POST */
pll
->
vclk_post_div
=
vpostdiv
;
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
)
u8
bpp
,
union
aty_pll
*
pll
)
{
{
int
err
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
int
err
;
if
((
err
=
aty_valid_pll_ct
(
info
,
vclk_per
,
&
pll
->
ct
)))
return
err
;
if
((
err
=
aty_valid_pll_ct
(
info
,
vclk_per
,
&
pll
->
ct
)))
if
(
M64_HAS
(
GTB_DSP
)
&&
(
err
=
aty_dsp_gt
(
info
,
bpp
,
&
pll
->
ct
)))
return
err
;
return
err
;
if
(
M64_HAS
(
GTB_DSP
)
&&
(
err
=
aty_dsp_gt
(
info
,
bpp
,
&
pll
->
ct
)))
aty_calc_pll_ct
(
info
,
&
pll
->
ct
);
return
err
;
return
0
;
aty_calc_pll_ct
(
info
,
&
pll
->
ct
);
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
)
const
union
aty_pll
*
pll
)
{
{
u32
ref_clk_per
=
info
->
ref_clk_per
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u8
pll_ref_div
=
pll
->
ct
.
pll_ref_div
;
u8
vclk_fb_div
=
pll
->
ct
.
vclk_fb_div
;
u32
ref_clk_per
=
par
->
ref_clk_per
;
u8
vclk_post_div
=
pll
->
ct
.
vclk_post_div_real
;
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
);
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
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_REF_DIV
,
pll
->
ct
.
pll_ref_div
,
par
);
aty_st_pll
(
PLL_VCLK_CNTL
,
pll
->
ct
.
pll_vclk_cntl
,
info
);
aty_st_pll
(
PLL_GEN_CNTL
,
pll
->
ct
.
pll_gen_cntl
,
par
);
aty_st_pll
(
VCLK_POST_DIV
,
pll
->
ct
.
vclk_post_div
,
info
);
aty_st_pll
(
MCLK_FB_DIV
,
pll
->
ct
.
mclk_fb_div
,
par
);
aty_st_pll
(
VCLK0_FB_DIV
,
pll
->
ct
.
vclk_fb_div
,
info
);
aty_st_pll
(
PLL_VCLK_CNTL
,
pll
->
ct
.
pll_vclk_cntl
,
par
);
aty_st_pll
(
PLL_EXT_CNTL
,
pll
->
ct
.
pll_ext_cntl
,
info
);
aty_st_pll
(
VCLK_POST_DIV
,
pll
->
ct
.
vclk_post_div
,
par
);
aty_st_pll
(
VCLK0_FB_DIV
,
pll
->
ct
.
vclk_fb_div
,
par
);
if
(
M64_HAS
(
GTB_DSP
))
{
aty_st_pll
(
PLL_EXT_CNTL
,
pll
->
ct
.
pll_ext_cntl
,
par
);
if
(
M64_HAS
(
XL_DLL
))
aty_st_pll
(
DLL_CNTL
,
0x80
,
info
);
if
(
M64_HAS
(
GTB_DSP
))
{
else
if
(
info
->
ram_type
>=
SDRAM
)
if
(
M64_HAS
(
XL_DLL
))
aty_st_pll
(
DLL_CNTL
,
0xa6
,
info
);
aty_st_pll
(
DLL_CNTL
,
0x80
,
par
);
else
else
if
(
par
->
ram_type
>=
SDRAM
)
aty_st_pll
(
DLL_CNTL
,
0xa0
,
info
);
aty_st_pll
(
DLL_CNTL
,
0xa6
,
par
);
aty_st_pll
(
VFC_CNTL
,
0x1b
,
info
);
else
aty_st_le32
(
DSP_CONFIG
,
pll
->
ct
.
dsp_config
,
info
);
aty_st_pll
(
DLL_CNTL
,
0xa0
,
par
);
aty_st_le32
(
DSP_ON_OFF
,
pll
->
ct
.
dsp_on_off
,
info
);
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
);
}
}
}
static
int
dummy
(
void
)
static
int
dummy
(
void
)
{
{
return
0
;
return
0
;
}
}
const
struct
aty_dac_ops
aty_dac_ct
=
{
const
struct
aty_dac_ops
aty_dac_ct
=
{
set_dac:
(
void
*
)
dummy
,
set_dac:
(
void
*
)
dummy
,
};
};
const
struct
aty_pll_ops
aty_pll_ct
=
{
const
struct
aty_pll_ops
aty_pll_ct
=
{
var_to_pll:
aty_var_to_pll_ct
,
var_to_pll:
aty_var_to_pll_ct
,
pll_to_var:
aty_pll_ct_to_var
,
pll_to_var:
aty_pll_ct_to_var
,
set_pll:
aty_set_pll_ct
,
set_pll:
aty_set_pll_ct
,
};
};
drivers/video/aty/mach64_cursor.c
View file @
87520e1e
...
@@ -33,21 +33,20 @@
...
@@ -33,21 +33,20 @@
static
const
u8
cursor_pixel_map
[
2
]
=
{
0
,
15
};
static
const
u8
cursor_pixel_map
[
2
]
=
{
0
,
15
};
static
const
u8
cursor_color_map
[
2
]
=
{
0
,
0xff
};
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
,
0x00
,
0x40
,
0x10
,
0x50
,
0x04
,
0x44
,
0x14
,
0x54
,
0x01
,
0x41
,
0x11
,
0x51
,
0x05
,
0x45
,
0x15
,
0x55
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
,
0xaa
,
0x2a
,
0x8a
,
0x0a
,
0xa2
,
0x22
,
0x82
,
0x02
,
0xa8
,
0x28
,
0x88
,
0x08
,
0xa0
,
0x20
,
0x80
,
0x00
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
*
pixel
=
cursor_pixel_map
;
/* ++Geert: Why?? */
const
u8
*
red
=
cursor_color_map
;
const
u8
*
red
=
cursor_color_map
;
const
u8
*
green
=
cursor_color_map
;
const
u8
*
green
=
cursor_color_map
;
...
@@ -58,26 +57,28 @@ void aty_set_cursor_color(struct fb_info_aty *fb)
...
@@ -58,26 +57,28 @@ void aty_set_cursor_color(struct fb_info_aty *fb)
return
;
return
;
#ifdef __sparc__
#ifdef __sparc__
if
(
fb
->
mmaped
&&
(
!
fb
->
fb_info
.
display_fg
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
fb
->
fb_info
.
display_fg
->
vc_num
==
fb
->
vtconsole
))
||
info
->
display_fg
->
vc_num
==
par
->
vtconsole
))
return
;
return
;
#endif
#endif
for
(
i
=
0
;
i
<
2
;
i
++
)
{
for
(
i
=
0
;
i
<
2
;
i
++
)
{
c
->
color
[
i
]
=
(
u32
)
red
[
i
]
<<
24
;
c
->
color
[
i
]
=
(
u32
)
red
[
i
]
<<
24
;
c
->
color
[
i
]
|=
(
u32
)
green
[
i
]
<<
16
;
c
->
color
[
i
]
|=
(
u32
)
green
[
i
]
<<
16
;
c
->
color
[
i
]
|=
(
u32
)
blue
[
i
]
<<
8
;
c
->
color
[
i
]
|=
(
u32
)
blue
[
i
]
<<
8
;
c
->
color
[
i
]
|=
(
u32
)
pixel
[
i
];
c
->
color
[
i
]
|=
(
u32
)
pixel
[
i
];
}
}
wait_for_fifo
(
2
,
fb
);
wait_for_fifo
(
2
,
par
);
aty_st_le32
(
CUR_CLR0
,
c
->
color
[
0
],
fb
);
aty_st_le32
(
CUR_CLR0
,
c
->
color
[
0
],
par
);
aty_st_le32
(
CUR_CLR1
,
c
->
color
[
1
],
fb
);
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
;
u8
*
ram
,
m
,
b
;
int
x
,
y
;
int
x
,
y
;
...
@@ -85,8 +86,9 @@ void aty_set_cursor_shape(struct fb_info_aty *fb)
...
@@ -85,8 +86,9 @@ void aty_set_cursor_shape(struct fb_info_aty *fb)
return
;
return
;
#ifdef __sparc__
#ifdef __sparc__
if
(
fb
->
mmaped
&&
(
!
fb
->
fb_info
.
display_fg
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
fb
->
fb_info
.
display_fg
->
vc_num
==
fb
->
vtconsole
))
||
info
->
display_fg
->
vc_num
==
par
->
vtconsole
))
return
;
return
;
#endif
#endif
...
@@ -95,26 +97,24 @@ void aty_set_cursor_shape(struct fb_info_aty *fb)
...
@@ -95,26 +97,24 @@ void aty_set_cursor_shape(struct fb_info_aty *fb)
for
(
x
=
0
;
x
<
c
->
size
.
x
>>
2
;
x
++
)
{
for
(
x
=
0
;
x
<
c
->
size
.
x
>>
2
;
x
++
)
{
m
=
c
->
mask
[
x
][
y
];
m
=
c
->
mask
[
x
][
y
];
b
=
c
->
bits
[
x
][
y
];
b
=
c
->
bits
[
x
][
y
];
fb_writeb
(
cursor_mask_lookup
[
m
>>
4
]
|
fb_writeb
(
cursor_mask_lookup
[
m
>>
4
]
|
cursor_bits_lookup
[(
b
&
m
)
>>
4
],
cursor_bits_lookup
[(
b
&
m
)
>>
4
],
ram
++
);
ram
++
);
fb_writeb
(
cursor_mask_lookup
[
m
&
0x0f
]
|
fb_writeb
(
cursor_mask_lookup
[
m
&
0x0f
]
|
cursor_bits_lookup
[(
b
&
m
)
&
0x0f
],
cursor_bits_lookup
[(
b
&
m
)
&
0x0f
],
ram
++
);
ram
++
);
}
}
for
(
;
x
<
8
;
x
++
)
{
for
(;
x
<
8
;
x
++
)
{
fb_writeb
(
0xaa
,
ram
++
);
fb_writeb
(
0xaa
,
ram
++
);
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
static
void
aty_set_cursor
(
struct
fb_info
*
info
,
int
on
)
aty_set_cursor
(
struct
fb_info_aty
*
fb
,
int
on
)
{
{
struct
atyfb_par
*
par
=
&
fb
->
current_
par
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
struct
aty_cursor
*
c
=
fb
->
cursor
;
struct
aty_cursor
*
c
=
par
->
cursor
;
u16
xoff
,
yoff
;
u16
xoff
,
yoff
;
int
x
,
y
;
int
x
,
y
;
...
@@ -122,8 +122,9 @@ aty_set_cursor(struct fb_info_aty *fb, int on)
...
@@ -122,8 +122,9 @@ aty_set_cursor(struct fb_info_aty *fb, int on)
return
;
return
;
#ifdef __sparc__
#ifdef __sparc__
if
(
fb
->
mmaped
&&
(
!
fb
->
fb_info
.
display_fg
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
fb
->
fb_info
.
display_fg
->
vc_num
==
fb
->
vtconsole
))
||
info
->
display_fg
->
vc_num
==
par
->
vtconsole
))
return
;
return
;
#endif
#endif
...
@@ -144,67 +145,72 @@ aty_set_cursor(struct fb_info_aty *fb, int on)
...
@@ -144,67 +145,72 @@ aty_set_cursor(struct fb_info_aty *fb, int on)
yoff
=
0
;
yoff
=
0
;
}
}
wait_for_fifo
(
4
,
fb
);
wait_for_fifo
(
4
,
par
);
aty_st_le32
(
CUR_OFFSET
,
(
c
->
offset
>>
3
)
+
(
yoff
<<
1
),
fb
);
aty_st_le32
(
CUR_OFFSET
,
(
c
->
offset
>>
3
)
+
(
yoff
<<
1
),
par
);
aty_st_le32
(
CUR_HORZ_VERT_OFF
,
aty_st_le32
(
CUR_HORZ_VERT_OFF
,
((
u32
)(
64
-
c
->
size
.
y
+
yoff
)
<<
16
)
|
xoff
,
fb
);
((
u32
)
(
64
-
c
->
size
.
y
+
yoff
)
<<
16
)
|
xoff
,
aty_st_le32
(
CUR_HORZ_VERT_POSN
,
((
u32
)
y
<<
16
)
|
x
,
fb
);
par
);
aty_st_le32
(
GEN_TEST_CNTL
,
aty_ld_le32
(
GEN_TEST_CNTL
,
fb
)
aty_st_le32
(
CUR_HORZ_VERT_POSN
,
((
u32
)
y
<<
16
)
|
x
,
par
);
|
HWCURSOR_ENABLE
,
fb
);
aty_st_le32
(
GEN_TEST_CNTL
,
aty_ld_le32
(
GEN_TEST_CNTL
,
par
)
|
HWCURSOR_ENABLE
,
par
);
}
else
{
}
else
{
wait_for_fifo
(
1
,
fb
);
wait_for_fifo
(
1
,
par
);
aty_st_le32
(
GEN_TEST_CNTL
,
aty_st_le32
(
GEN_TEST_CNTL
,
aty_ld_le32
(
GEN_TEST_CNTL
,
fb
)
&
~
HWCURSOR_ENABLE
,
aty_ld_le32
(
GEN_TEST_CNTL
,
fb
);
par
)
&
~
HWCURSOR_ENABLE
,
par
);
}
}
if
(
fb
->
blitter_may_be_busy
)
if
(
par
->
blitter_may_be_busy
)
wait_for_idle
(
fb
);
wait_for_idle
(
par
);
}
}
static
void
static
void
aty_cursor_timer_handler
(
unsigned
long
dev_addr
)
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
;
return
;
if
(
!
fb
->
cursor
->
enable
)
if
(
!
par
->
cursor
->
enable
)
goto
out
;
goto
out
;
if
(
fb
->
cursor
->
vbl_cnt
&&
--
fb
->
cursor
->
vbl_cnt
==
0
)
{
if
(
par
->
cursor
->
vbl_cnt
&&
--
par
->
cursor
->
vbl_cnt
==
0
)
{
fb
->
cursor
->
on
^=
1
;
par
->
cursor
->
on
^=
1
;
aty_set_cursor
(
fb
,
fb
->
cursor
->
on
);
aty_set_cursor
(
info
,
par
->
cursor
->
on
);
fb
->
cursor
->
vbl_cnt
=
fb
->
cursor
->
blink_rate
;
par
->
cursor
->
vbl_cnt
=
par
->
cursor
->
blink_rate
;
}
}
out:
out:
fb
->
cursor
->
timer
->
expires
=
jiffies
+
(
HZ
/
50
);
par
->
cursor
->
timer
->
expires
=
jiffies
+
(
HZ
/
50
);
add_timer
(
fb
->
cursor
->
timer
);
add_timer
(
par
->
cursor
->
timer
);
}
}
void
atyfb_cursor
(
struct
display
*
p
,
int
mode
,
int
x
,
int
y
)
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
fb_info
*
info
=
p
->
fb_info
;
struct
aty_cursor
*
c
=
fb
->
cursor
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
struct
aty_cursor
*
c
=
par
->
cursor
;
if
(
!
c
)
if
(
!
c
)
return
;
return
;
#ifdef __sparc__
#ifdef __sparc__
if
(
fb
->
mmaped
&&
(
!
fb
->
fb_info
.
display_fg
if
(
par
->
mmaped
&&
(
!
info
->
display_fg
||
fb
->
fb_info
.
display_fg
->
vc_num
==
fb
->
vtconsole
))
||
info
->
display_fg
->
vc_num
==
par
->
vtconsole
))
return
;
return
;
#endif
#endif
x
*=
fontwidth
(
p
);
x
*=
fontwidth
(
p
);
y
*=
fontheight
(
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
;
return
;
c
->
enable
=
0
;
c
->
enable
=
0
;
if
(
c
->
on
)
if
(
c
->
on
)
aty_set_cursor
(
fb
,
0
);
aty_set_cursor
(
info
,
0
);
c
->
pos
.
x
=
x
;
c
->
pos
.
x
=
x
;
c
->
pos
.
y
=
y
;
c
->
pos
.
y
=
y
;
...
@@ -216,7 +222,7 @@ void atyfb_cursor(struct display *p, int mode, int x, int y)
...
@@ -216,7 +222,7 @@ void atyfb_cursor(struct display *p, int mode, int x, int y)
case
CM_DRAW
:
case
CM_DRAW
:
case
CM_MOVE
:
case
CM_MOVE
:
if
(
c
->
on
)
if
(
c
->
on
)
aty_set_cursor
(
fb
,
1
);
aty_set_cursor
(
info
,
1
);
else
else
c
->
vbl_cnt
=
CURSOR_DRAW_DELAY
;
c
->
vbl_cnt
=
CURSOR_DRAW_DELAY
;
c
->
enable
=
1
;
c
->
enable
=
1
;
...
@@ -224,7 +230,7 @@ void atyfb_cursor(struct display *p, int mode, int x, int y)
...
@@ -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
;
struct
aty_cursor
*
cursor
;
unsigned
long
addr
;
unsigned
long
addr
;
...
@@ -242,19 +248,19 @@ struct aty_cursor * __init aty_init_cursor(struct fb_info_aty *fb)
...
@@ -242,19 +248,19 @@ struct aty_cursor * __init aty_init_cursor(struct fb_info_aty *fb)
memset
(
cursor
->
timer
,
0
,
sizeof
(
*
cursor
->
timer
));
memset
(
cursor
->
timer
,
0
,
sizeof
(
*
cursor
->
timer
));
cursor
->
blink_rate
=
DEFAULT_CURSOR_BLINK_RATE
;
cursor
->
blink_rate
=
DEFAULT_CURSOR_BLINK_RATE
;
fb
->
fb_info
.
fix
.
smem_len
-=
PAGE_SIZE
;
info
->
fix
.
smem_len
-=
PAGE_SIZE
;
cursor
->
offset
=
fb
->
fb_info
.
fix
.
smem_len
;
cursor
->
offset
=
info
->
fix
.
smem_len
;
#ifdef __sparc__
#ifdef __sparc__
addr
=
fb
->
fb_info
.
screen_base
-
0x800000
+
cursor
->
offset
;
addr
=
info
->
screen_base
-
0x800000
+
cursor
->
offset
;
cursor
->
ram
=
(
u8
*
)
addr
;
cursor
->
ram
=
(
u8
*
)
addr
;
#else
#else
#ifdef __BIG_ENDIAN
#ifdef __BIG_ENDIAN
addr
=
fb
->
fb_info
.
fix
.
smem_start
-
0x800000
+
cursor
->
offset
;
addr
=
info
->
fix
.
smem_start
-
0x800000
+
cursor
->
offset
;
cursor
->
ram
=
(
u8
*
)
ioremap
(
addr
,
1024
);
cursor
->
ram
=
(
u8
*
)
ioremap
(
addr
,
1024
);
#else
#else
addr
=
(
unsigned
long
)
fb
->
fb_info
.
screen_base
+
cursor
->
offset
;
addr
=
(
unsigned
long
)
info
->
screen_base
+
cursor
->
offset
;
cursor
->
ram
=
(
u8
*
)
addr
;
cursor
->
ram
=
(
u8
*
)
addr
;
#endif
#endif
#endif
#endif
...
@@ -265,41 +271,42 @@ struct aty_cursor * __init aty_init_cursor(struct fb_info_aty *fb)
...
@@ -265,41 +271,42 @@ struct aty_cursor * __init aty_init_cursor(struct fb_info_aty *fb)
init_timer
(
cursor
->
timer
);
init_timer
(
cursor
->
timer
);
cursor
->
timer
->
expires
=
jiffies
+
(
HZ
/
50
);
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
;
cursor
->
timer
->
function
=
aty_cursor_timer_handler
;
add_timer
(
cursor
->
timer
);
add_timer
(
cursor
->
timer
);
return
cursor
;
return
cursor
;
}
}
int
atyfb_set_font
(
struct
display
*
d
,
int
width
,
int
height
)
int
atyfb_set_font
(
struct
display
*
d
,
int
width
,
int
height
)
{
{
struct
fb_info_aty
*
fb
=
(
struct
fb_info_aty
*
)
d
->
fb_info
;
struct
fb_info
*
info
=
d
->
fb_info
;
struct
aty_cursor
*
c
=
fb
->
cursor
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
int
i
,
j
;
struct
aty_cursor
*
c
=
par
->
cursor
;
int
i
,
j
;
if
(
c
)
{
if
(
!
width
||
!
height
)
{
if
(
c
)
{
width
=
8
;
if
(
!
width
||
!
height
)
{
height
=
16
;
width
=
8
;
}
height
=
16
;
}
c
->
hot
.
x
=
0
;
c
->
hot
.
x
=
0
;
c
->
hot
.
y
=
0
;
c
->
hot
.
y
=
0
;
c
->
size
.
x
=
width
;
c
->
size
.
x
=
width
;
c
->
size
.
y
=
height
;
c
->
size
.
y
=
height
;
memset
(
c
->
bits
,
0xff
,
sizeof
(
c
->
bits
));
memset
(
c
->
bits
,
0xff
,
sizeof
(
c
->
bits
));
memset
(
c
->
mask
,
0
,
sizeof
(
c
->
mask
));
memset
(
c
->
mask
,
0
,
sizeof
(
c
->
mask
));
for
(
i
=
0
,
j
=
width
;
j
>=
0
;
j
-=
8
,
i
++
)
{
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
-
2
]
=
c
->
mask
[
i
][
height
-
1
]
=
(
j
>=
8
)
?
0xff
:
(
0xff
<<
(
8
-
j
));
(
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_color
(
info
);
aty_set_cursor_shape
(
fb
);
aty_set_cursor_shape
(
info
);
}
}
return
1
;
return
1
;
}
}
drivers/video/aty/mach64_gx.c
View file @
87520e1e
...
@@ -16,13 +16,13 @@
...
@@ -16,13 +16,13 @@
/* Definitions for the ICS 2595 == ATI 18818_1 Clockchip */
/* Definitions for the ICS 2595 == ATI 18818_1 Clockchip */
#define REF_FREQ_2595 1432
/* 14.33 MHz (exact 14.31818) */
#define REF_FREQ_2595 1432
/* 14.33 MHz (exact 14.31818) */
#define REF_DIV_2595 46
/* really 43 on ICS 2595 !!! */
#define REF_DIV_2595 46
/* really 43 on ICS 2595 !!! */
/* ohne Prescaler */
/* ohne Prescaler */
#define MAX_FREQ_2595 15938
/* 159.38 MHz (really 170.486) */
#define MAX_FREQ_2595 15938
/* 159.38 MHz (really 170.486) */
#define MIN_FREQ_2595 8000
/* 80.00 MHz ( 85.565) */
#define MIN_FREQ_2595 8000
/* 80.00 MHz ( 85.565) */
/* mit Prescaler 2, 4, 8 */
/* mit Prescaler 2, 4, 8 */
#define ABS_MIN_FREQ_2595 1000
/* 10.00 MHz (really 10.697) */
#define ABS_MIN_FREQ_2595 1000
/* 10.00 MHz (really 10.697) */
#define N_ADJ_2595 257
#define N_ADJ_2595 257
#define STOP_BITS_2595 0x1800
#define STOP_BITS_2595 0x1800
...
@@ -42,26 +42,25 @@
...
@@ -42,26 +42,25 @@
* Support Functions
* 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
,
par
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
info
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
par
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
info
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
par
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
info
);
(
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
;
u8
tmp
;
udelay
(
26
);
udelay
(
26
);
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
info
);
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
par
);
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
tmp
|
CLOCK_STROBE
,
info
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
tmp
|
CLOCK_STROBE
,
par
);
return
;
return
;
}
}
...
@@ -69,120 +68,136 @@ static void aty_StrobeClock(const struct fb_info_aty *info)
...
@@ -69,120 +68,136 @@ static void aty_StrobeClock(const struct fb_info_aty *info)
* IBM RGB514 DAC and Clock Chip
* 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 */
/* right addr byte */
aty_st_8
(
DAC_W_INDEX
,
offset
&
0xff
,
info
);
aty_st_8
(
DAC_W_INDEX
,
offset
&
0xff
,
par
);
/* left addr byte */
/* left addr byte */
aty_st_8
(
DAC_DATA
,
(
offset
>>
8
)
&
0xff
,
info
);
aty_st_8
(
DAC_DATA
,
(
offset
>>
8
)
&
0xff
,
par
);
aty_st_8
(
DAC_MASK
,
val
,
info
);
aty_st_8
(
DAC_MASK
,
val
,
par
);
aty_st_8
(
DAC_CNTL
,
0
,
info
);
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
)
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
)
{
{
static
struct
{
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u8
pixel_dly
;
static
struct
{
u8
misc2_cntl
;
u8
pixel_dly
;
u8
pixel_rep
;
u8
misc2_cntl
;
u8
pixel_cntl_index
;
u8
pixel_rep
;
u8
pixel_cntl_v1
;
u8
pixel_cntl_index
;
}
tab
[
3
]
=
{
u8
pixel_cntl_v1
;
{
0
,
0x41
,
0x03
,
0x71
,
0x45
},
/* 8 bpp */
}
tab
[
3
]
=
{
{
0
,
0x45
,
0x04
,
0x0c
,
0x01
},
/* 555 */
{
{
0
,
0x45
,
0x06
,
0x0e
,
0x00
},
/* XRGB */
0
,
0x41
,
0x03
,
0x71
,
0x45
},
/* 8 bpp */
};
{
int
i
;
0
,
0x45
,
0x04
,
0x0c
,
0x01
},
/* 555 */
{
switch
(
bpp
)
{
0
,
0x45
,
0x06
,
0x0e
,
0x00
},
/* XRGB */
};
int
i
;
switch
(
bpp
)
{
case
8
:
case
8
:
default:
default:
i
=
0
;
i
=
0
;
break
;
break
;
case
16
:
case
16
:
i
=
1
;
i
=
1
;
break
;
break
;
case
32
:
case
32
:
i
=
2
;
i
=
2
;
break
;
break
;
}
}
aty_st_514
(
0x90
,
0x00
,
info
);
/* VRAM Mask Low */
aty_st_514
(
0x90
,
0x00
,
par
);
/* VRAM Mask Low */
aty_st_514
(
0x04
,
tab
[
i
].
pixel_dly
,
info
);
/* Horizontal Sync Control */
aty_st_514
(
0x04
,
tab
[
i
].
pixel_dly
,
par
);
/* Horizontal Sync Control */
aty_st_514
(
0x05
,
0x00
,
info
);
/* Power Management */
aty_st_514
(
0x05
,
0x00
,
par
);
/* Power Management */
aty_st_514
(
0x02
,
0x01
,
info
);
/* Misc Clock Control */
aty_st_514
(
0x02
,
0x01
,
par
);
/* Misc Clock Control */
aty_st_514
(
0x71
,
tab
[
i
].
misc2_cntl
,
info
);
/* Misc Control 2 */
aty_st_514
(
0x71
,
tab
[
i
].
misc2_cntl
,
par
);
/* Misc Control 2 */
aty_st_514
(
0x0a
,
tab
[
i
].
pixel_rep
,
info
);
/* Pixel Format */
aty_st_514
(
0x0a
,
tab
[
i
].
pixel_rep
,
par
);
/* Pixel Format */
aty_st_514
(
tab
[
i
].
pixel_cntl_index
,
tab
[
i
].
pixel_cntl_v1
,
info
);
aty_st_514
(
tab
[
i
].
pixel_cntl_index
,
tab
[
i
].
pixel_cntl_v1
,
par
);
/* Misc Control 2 / 16 BPP Control / 32 BPP Control */
/* Misc Control 2 / 16 BPP Control / 32 BPP Control */
return
0
;
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
)
u8
bpp
,
union
aty_pll
*
pll
)
{
{
/*
/*
* FIXME: use real calculations instead of using fixed values from the old
* FIXME: use real calculations instead of using fixed values from the old
* driver
* driver
*/
*/
static
struct
{
static
struct
{
u32
limit
;
/* pixlock rounding limit (arbitrary) */
u32
limit
;
/* pixlock rounding limit (arbitrary) */
u8
m
;
/* (df<<6) | vco_div_count */
u8
m
;
/* (df<<6) | vco_div_count */
u8
n
;
/* ref_div_count */
u8
n
;
/* ref_div_count */
}
RGB514_clocks
[
7
]
=
{
}
RGB514_clocks
[
7
]
=
{
{
8000
,
(
3
<<
6
)
|
20
,
9
},
/* 7395 ps / 135.2273 MHz */
{
{
10000
,
(
1
<<
6
)
|
19
,
3
},
/* 9977 ps / 100.2273 MHz */
8000
,
(
3
<<
6
)
|
20
,
9
},
/* 7395 ps / 135.2273 MHz */
{
13000
,
(
1
<<
6
)
|
2
,
3
},
/* 12509 ps / 79.9432 MHz */
{
{
14000
,
(
2
<<
6
)
|
8
,
7
},
/* 13394 ps / 74.6591 MHz */
10000
,
(
1
<<
6
)
|
19
,
3
},
/* 9977 ps / 100.2273 MHz */
{
16000
,
(
1
<<
6
)
|
44
,
6
},
/* 15378 ps / 65.0284 MHz */
{
{
25000
,
(
1
<<
6
)
|
15
,
5
},
/* 17460 ps / 57.2727 MHz */
13000
,
(
1
<<
6
)
|
2
,
3
},
/* 12509 ps / 79.9432 MHz */
{
50000
,
(
0
<<
6
)
|
53
,
7
},
/* 33145 ps / 30.1705 MHz */
{
};
14000
,
(
2
<<
6
)
|
8
,
7
},
/* 13394 ps / 74.6591 MHz */
int
i
;
{
16000
,
(
1
<<
6
)
|
44
,
6
},
/* 15378 ps / 65.0284 MHz */
for
(
i
=
0
;
i
<
sizeof
(
RGB514_clocks
)
/
sizeof
(
*
RGB514_clocks
);
i
++
)
{
if
(
vclk_per
<=
RGB514_clocks
[
i
].
limit
)
{
25000
,
(
1
<<
6
)
|
15
,
5
},
/* 17460 ps / 57.2727 MHz */
pll
->
ibm514
.
m
=
RGB514_clocks
[
i
].
m
;
{
pll
->
ibm514
.
n
=
RGB514_clocks
[
i
].
n
;
50000
,
(
0
<<
6
)
|
53
,
7
},
/* 33145 ps / 30.1705 MHz */
return
0
;
};
}
int
i
;
return
-
EINVAL
;
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
;
return
0
;
}
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
)
const
union
aty_pll
*
pll
)
{
{
u8
df
,
vco_div_count
,
ref_div_count
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u8
df
,
vco_div_count
,
ref_div_count
;
df
=
pll
->
ibm514
.
m
>>
6
;
df
=
pll
->
ibm514
.
m
>>
6
;
vco_div_count
=
pll
->
ibm514
.
m
&
0x3f
;
vco_div_count
=
pll
->
ibm514
.
m
&
0x3f
;
ref_div_count
=
pll
->
ibm514
.
n
;
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
)
const
union
aty_pll
*
pll
)
{
{
aty_st_514
(
0x06
,
0x02
,
info
);
/* DAC Operation */
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
aty_st_514
(
0x10
,
0x01
,
info
);
/* PLL Control 1 */
aty_st_514
(
0x70
,
0x01
,
info
);
/* Misc Control 1 */
aty_st_514
(
0x06
,
0x02
,
par
);
/* DAC Operation */
aty_st_514
(
0x8f
,
0x1f
,
info
);
/* PLL Ref. Divider Input */
aty_st_514
(
0x10
,
0x01
,
par
);
/* PLL Control 1 */
aty_st_514
(
0x03
,
0x00
,
info
);
/* Sync Control */
aty_st_514
(
0x70
,
0x01
,
par
);
/* Misc Control 1 */
aty_st_514
(
0x05
,
0x00
,
info
);
/* Power Management */
aty_st_514
(
0x8f
,
0x1f
,
par
);
/* PLL Ref. Divider Input */
aty_st_514
(
0x20
,
pll
->
ibm514
.
m
,
info
);
/* F0 / M0 */
aty_st_514
(
0x03
,
0x00
,
par
);
/* Sync Control */
aty_st_514
(
0x21
,
pll
->
ibm514
.
n
,
info
);
/* F1 / N0 */
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
=
{
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
=
{
const
struct
aty_pll_ops
aty_pll_ibm514
=
{
var_to_pll:
aty_var_to_pll_514
,
var_to_pll:
aty_var_to_pll_514
,
pll_to_var:
aty_pll_514_to_var
,
pll_to_var:
aty_pll_514_to_var
,
set_pll:
aty_set_pll_514
,
set_pll:
aty_set_pll_514
,
};
};
...
@@ -190,77 +205,82 @@ const struct aty_pll_ops aty_pll_ibm514 = {
...
@@ -190,77 +205,82 @@ const struct aty_pll_ops aty_pll_ibm514 = {
* ATI 68860-B DAC
* ATI 68860-B DAC
*/
*/
static
int
aty_set_dac_ATI68860_B
(
const
struct
fb_info_aty
*
info
,
static
int
aty_set_dac_ATI68860_B
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
)
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
)
{
{
u32
gModeReg
,
devSetupRegA
,
temp
,
mask
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
gModeReg
,
devSetupRegA
,
temp
,
mask
;
gModeReg
=
0
;
gModeReg
=
0
;
devSetupRegA
=
0
;
devSetupRegA
=
0
;
switch
(
bpp
)
{
switch
(
bpp
)
{
case
8
:
case
8
:
gModeReg
=
0x83
;
gModeReg
=
0x83
;
devSetupRegA
=
0x60
|
0x00
/*(info->mach64DAC8Bit ? 0x00 : 0x01) */
;
devSetupRegA
=
break
;
0x60
|
0x00
/*(info->mach64DAC8Bit ? 0x00 : 0x01) */
;
break
;
case
15
:
case
15
:
gModeReg
=
0xA0
;
gModeReg
=
0xA0
;
devSetupRegA
=
0x60
;
devSetupRegA
=
0x60
;
break
;
break
;
case
16
:
case
16
:
gModeReg
=
0xA1
;
gModeReg
=
0xA1
;
devSetupRegA
=
0x60
;
devSetupRegA
=
0x60
;
break
;
break
;
case
24
:
case
24
:
gModeReg
=
0xC0
;
gModeReg
=
0xC0
;
devSetupRegA
=
0x60
;
devSetupRegA
=
0x60
;
break
;
break
;
case
32
:
case
32
:
gModeReg
=
0xE3
;
gModeReg
=
0xE3
;
devSetupRegA
=
0x60
;
devSetupRegA
=
0x60
;
break
;
break
;
}
}
if
(
!
accel
)
{
if
(
!
accel
)
{
gModeReg
=
0x80
;
gModeReg
=
0x80
;
devSetupRegA
=
0x61
;
devSetupRegA
=
0x61
;
}
}
temp
=
aty_ld_8
(
DAC_CNTL
,
info
);
temp
=
aty_ld_8
(
DAC_CNTL
,
par
);
aty_st_8
(
DAC_CNTL
,
(
temp
&
~
DAC_EXT_SEL_RS2
)
|
DAC_EXT_SEL_RS3
,
info
);
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
+
2
,
0x1D
,
par
);
aty_st_8
(
DAC_REGS
,
0x02
,
info
);
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
)
mask
=
0x04
;
if
(
info
->
fix
.
smem_len
<
MEM_SIZE_1M
)
else
if
(
info
->
total_vram
==
MEM_SIZE_1M
)
mask
=
0x04
;
mask
=
0x08
;
else
if
(
info
->
fix
.
smem_len
==
MEM_SIZE_1M
)
else
mask
=
0x08
;
mask
=
0x0C
;
else
mask
=
0x0C
;
/* The following assumes that the BIOS has correctly set R7 of the
* Device Setup Register A at boot time.
*/
#define A860_DELAY_L 0x80
temp
=
aty_ld_8
(
DAC_REGS
,
info
);
/* The following assumes that the BIOS has correctly set R7 of the
aty_st_8
(
DAC_REGS
,
(
devSetupRegA
|
mask
)
|
(
temp
&
A860_DELAY_L
),
info
);
* Device Setup Register A at boot time.
temp
=
aty_ld_8
(
DAC_CNTL
,
info
);
*/
aty_st_8
(
DAC_CNTL
,
(
temp
&
~
(
DAC_EXT_SEL_RS2
|
DAC_EXT_SEL_RS3
)),
info
);
#define A860_DELAY_L 0x80
aty_st_le32
(
BUS_CNTL
,
0x890e20f1
,
info
);
temp
=
aty_ld_8
(
DAC_REGS
,
par
);
aty_st_le32
(
DAC_CNTL
,
0x47052100
,
info
);
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
);
return
0
;
aty_st_le32
(
BUS_CNTL
,
0x890e20f1
,
par
);
aty_st_le32
(
DAC_CNTL
,
0x47052100
,
par
);
return
0
;
}
}
const
struct
aty_dac_ops
aty_dac_ati68860b
=
{
const
struct
aty_dac_ops
aty_dac_ati68860b
=
{
set_dac:
aty_set_dac_ATI68860_B
,
set_dac:
aty_set_dac_ATI68860_B
,
};
};
...
@@ -268,50 +288,52 @@ const struct aty_dac_ops aty_dac_ati68860b = {
...
@@ -268,50 +288,52 @@ const struct aty_dac_ops aty_dac_ati68860b = {
* AT&T 21C498 DAC
* AT&T 21C498 DAC
*/
*/
static
int
aty_set_dac_ATT21C498
(
const
struct
fb_info_aty
*
info
,
static
int
aty_set_dac_ATT21C498
(
const
struct
fb_info
*
info
,
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
)
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
)
{
{
u32
dotClock
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
int
muxmode
=
0
;
u32
dotClock
;
int
DACMask
=
0
;
int
muxmode
=
0
;
int
DACMask
=
0
;
dotClock
=
100000000
/
pll
->
ics2595
.
period_in_ps
;
dotClock
=
100000000
/
pll
->
ics2595
.
period_in_ps
;
switch
(
bpp
)
{
switch
(
bpp
)
{
case
8
:
case
8
:
if
(
dotClock
>
8000
)
{
if
(
dotClock
>
8000
)
{
DACMask
=
0x24
;
DACMask
=
0x24
;
muxmode
=
1
;
muxmode
=
1
;
}
else
}
else
DACMask
=
0x04
;
DACMask
=
0x04
;
break
;
break
;
case
15
:
case
15
:
DACMask
=
0x16
;
DACMask
=
0x16
;
break
;
break
;
case
16
:
case
16
:
DACMask
=
0x36
;
DACMask
=
0x36
;
break
;
break
;
case
24
:
case
24
:
DACMask
=
0xE6
;
DACMask
=
0xE6
;
break
;
break
;
case
32
:
case
32
:
DACMask
=
0xE6
;
DACMask
=
0xE6
;
break
;
break
;
}
}
if
(
1
/* info->mach64DAC8Bit */
)
if
(
1
/* info->mach64DAC8Bit */
)
DACMask
|=
0x02
;
DACMask
|=
0x02
;
aty_dac_waste4
(
info
);
aty_dac_waste4
(
par
);
aty_st_8
(
DAC_REGS
+
2
,
DACMask
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
DACMask
,
par
);
aty_st_le32
(
BUS_CNTL
,
0x890e20f1
,
info
);
aty_st_le32
(
BUS_CNTL
,
0x890e20f1
,
par
);
aty_st_le32
(
DAC_CNTL
,
0x00072000
,
info
);
aty_st_le32
(
DAC_CNTL
,
0x00072000
,
par
);
return
muxmode
;
return
muxmode
;
}
}
const
struct
aty_dac_ops
aty_dac_att21c498
=
{
const
struct
aty_dac_ops
aty_dac_att21c498
=
{
set_dac:
aty_set_dac_ATT21C498
,
set_dac:
aty_set_dac_ATT21C498
,
};
};
...
@@ -319,154 +341,155 @@ const struct aty_dac_ops aty_dac_att21c498 = {
...
@@ -319,154 +341,155 @@ const struct aty_dac_ops aty_dac_att21c498 = {
* ATI 18818 / ICS 2595 Clock Chip
* ATI 18818 / ICS 2595 Clock Chip
*/
*/
static
int
aty_var_to_pll_18818
(
const
struct
fb_info
_aty
*
info
,
u32
vclk_per
,
static
int
aty_var_to_pll_18818
(
const
struct
fb_info
*
info
,
u8
bpp
,
union
aty_pll
*
pll
)
u
32
vclk_per
,
u
8
bpp
,
union
aty_pll
*
pll
)
{
{
u32
MHz100
;
/* in 0.01 MHz */
u32
MHz100
;
/* in 0.01 MHz */
u32
program_bits
;
u32
program_bits
;
u32
post_divider
;
u32
post_divider
;
/* Calculate the programming word */
/* Calculate the programming word */
MHz100
=
100000000
/
vclk_per
;
MHz100
=
100000000
/
vclk_per
;
program_bits
=
-
1
;
program_bits
=
-
1
;
post_divider
=
1
;
post_divider
=
1
;
if
(
MHz100
>
MAX_FREQ_2595
)
{
if
(
MHz100
>
MAX_FREQ_2595
)
{
MHz100
=
MAX_FREQ_2595
;
MHz100
=
MAX_FREQ_2595
;
return
-
EINVAL
;
return
-
EINVAL
;
}
else
if
(
MHz100
<
ABS_MIN_FREQ_2595
)
{
}
else
if
(
MHz100
<
ABS_MIN_FREQ_2595
)
{
program_bits
=
0
;
/* MHz100 = 257 */
program_bits
=
0
;
/* MHz100 = 257 */
return
-
EINVAL
;
return
-
EINVAL
;
}
else
{
}
else
{
while
(
MHz100
<
MIN_FREQ_2595
)
{
while
(
MHz100
<
MIN_FREQ_2595
)
{
MHz100
*=
2
;
MHz100
*=
2
;
post_divider
*=
2
;
post_divider
*=
2
;
}
}
}
}
MHz100
*=
1000
;
MHz100
*=
1000
;
MHz100
=
(
REF_DIV_2595
*
MHz100
)
/
REF_FREQ_2595
;
MHz100
=
(
REF_DIV_2595
*
MHz100
)
/
REF_FREQ_2595
;
MHz100
+=
500
;
/* + 0.5 round */
MHz100
+=
500
;
/* + 0.5 round */
MHz100
/=
1000
;
MHz100
/=
1000
;
if
(
program_bits
==
-
1
)
{
if
(
program_bits
==
-
1
)
{
program_bits
=
MHz100
-
N_ADJ_2595
;
program_bits
=
MHz100
-
N_ADJ_2595
;
switch
(
post_divider
)
{
switch
(
post_divider
)
{
case
1
:
case
1
:
program_bits
|=
0x0600
;
program_bits
|=
0x0600
;
break
;
break
;
case
2
:
case
2
:
program_bits
|=
0x0400
;
program_bits
|=
0x0400
;
break
;
break
;
case
4
:
case
4
:
program_bits
|=
0x0200
;
program_bits
|=
0x0200
;
break
;
break
;
case
8
:
case
8
:
default
:
default:
break
;
break
;
}
}
}
}
program_bits
|=
STOP_BITS_2595
;
program_bits
|=
STOP_BITS_2595
;
pll
->
ics2595
.
program_bits
=
program_bits
;
pll
->
ics2595
.
program_bits
=
program_bits
;
pll
->
ics2595
.
locationAddr
=
0
;
pll
->
ics2595
.
locationAddr
=
0
;
pll
->
ics2595
.
post_divider
=
post_divider
;
pll
->
ics2595
.
post_divider
=
post_divider
;
pll
->
ics2595
.
period_in_ps
=
vclk_per
;
pll
->
ics2595
.
period_in_ps
=
vclk_per
;
return
0
;
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
)
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
;
u8
tmp
;
data
&=
0x01
;
data
&=
0x01
;
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
info
);
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
par
);
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
(
tmp
&
~
0x04
)
|
(
data
<<
2
)
,
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
info
);
(
tmp
&
~
0x04
)
|
(
data
<<
2
),
par
);
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
info
);
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
par
);
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
(
tmp
&
~
0x08
)
|
(
0
<<
3
),
info
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
(
tmp
&
~
0x08
)
|
(
0
<<
3
),
par
);
aty_StrobeClock
(
info
);
aty_StrobeClock
(
par
);
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
info
);
tmp
=
aty_ld_8
(
CLOCK_CNTL
,
par
);
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
(
tmp
&
~
0x08
)
|
(
1
<<
3
),
info
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
(
tmp
&
~
0x08
)
|
(
1
<<
3
),
par
);
aty_StrobeClock
(
info
);
aty_StrobeClock
(
par
);
return
;
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
)
const
union
aty_pll
*
pll
)
{
{
u32
program_bits
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
locationAddr
;
u32
program_bits
;
u32
locationAddr
;
u32
i
;
u8
old_clock_cntl
;
u32
i
;
u8
old_crtc_ext_disp
;
old_clock_cntl
=
aty_ld_8
(
CLOCK_CNTL
,
info
)
;
u8
old_clock_cntl
;
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
0
,
info
)
;
u8
old_crtc_ext_disp
;
old_crtc_ext_disp
=
aty_ld_8
(
CRTC_GEN_CNTL
+
3
,
info
);
old_clock_cntl
=
aty_ld_8
(
CLOCK_CNTL
,
par
);
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
|
(
CRTC_EXT_DISP_EN
>>
24
),
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
0
,
par
);
info
);
mdelay
(
15
);
/* delay for 50 (15) ms */
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
;
mdelay
(
15
);
/* delay for 50 (15) ms */
locationAddr
=
pll
->
ics2595
.
locationAddr
;
/* Program the clock chip */
program_bits
=
pll
->
ics2595
.
program_bits
;
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
0
,
info
);
/* Strobe = 0 */
locationAddr
=
pll
->
ics2595
.
locationAddr
;
aty_StrobeClock
(
info
);
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
1
,
info
);
/* Strobe = 0 */
aty_StrobeClock
(
info
);
aty_ICS2595_put1bit
(
1
,
info
);
/* Send start bits */
/* Program the clock chip */
aty_ICS2595_put1bit
(
0
,
info
);
/* Start bit */
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
0
,
par
);
/* Strobe = 0 */
aty_ICS2595_put1bit
(
0
,
info
);
/* Read / ~Write */
aty_StrobeClock
(
par
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
1
,
par
);
/* Strobe = 0 */
aty_StrobeClock
(
par
);
for
(
i
=
0
;
i
<
5
;
i
++
)
{
/* Location 0..4 */
aty_ICS2595_put1bit
(
1
,
par
);
/* Send start bits */
aty_ICS2595_put1bit
(
locationAddr
&
1
,
info
);
aty_ICS2595_put1bit
(
0
,
par
);
/* Start bit */
locationAddr
>>=
1
;
aty_ICS2595_put1bit
(
0
,
par
);
/* Read / ~Write */
}
for
(
i
=
0
;
i
<
8
+
1
+
2
+
2
;
i
++
)
{
for
(
i
=
0
;
i
<
5
;
i
++
)
{
/* Location 0..4 */
aty_ICS2595_put1bit
(
program_bits
&
1
,
info
);
aty_ICS2595_put1bit
(
locationAddr
&
1
,
par
);
program_bits
>>=
1
;
locationAddr
>>=
1
;
}
}
mdelay
(
1
);
/* delay for 1 ms */
for
(
i
=
0
;
i
<
8
+
1
+
2
+
2
;
i
++
)
{
aty_ICS2595_put1bit
(
program_bits
&
1
,
par
);
program_bits
>>=
1
;
}
(
void
)
aty_ld_8
(
DAC_REGS
,
info
);
/* Clear DAC Counter */
mdelay
(
1
);
/* delay for 1 ms */
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
);
mdelay
(
50
);
/* delay for 50 (15) ms */
(
void
)
aty_ld_8
(
DAC_REGS
,
par
);
/* Clear DAC Counter */
aty_st_8
(
CLOCK_CNTL
+
info
->
clk_wr_offset
,
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
par
);
((
pll
->
ics2595
.
locationAddr
&
0x0F
)
|
CLOCK_STROBE
),
info
);
aty_st_8
(
CLOCK_CNTL
+
par
->
clk_wr_offset
,
old_clock_cntl
|
CLOCK_STROBE
,
par
);
return
;
mdelay
(
50
);
/* delay for 50 (15) ms */
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
=
{
const
struct
aty_pll_ops
aty_pll_ati18818_1
=
{
var_to_pll:
aty_var_to_pll_18818
,
var_to_pll:
aty_var_to_pll_18818
,
pll_to_var:
aty_pll_18818_to_var
,
pll_to_var:
aty_pll_18818_to_var
,
set_pll:
aty_set_pll18818
,
set_pll:
aty_set_pll18818
,
};
};
...
@@ -474,112 +497,115 @@ const struct aty_pll_ops aty_pll_ati18818_1 = {
...
@@ -474,112 +497,115 @@ const struct aty_pll_ops aty_pll_ati18818_1 = {
* STG 1703 Clock Chip
* STG 1703 Clock Chip
*/
*/
static
int
aty_var_to_pll_1703
(
const
struct
fb_info
_aty
*
info
,
u32
vclk_per
,
static
int
aty_var_to_pll_1703
(
const
struct
fb_info
*
info
,
u8
bpp
,
union
aty_pll
*
pll
)
u
32
vclk_per
,
u
8
bpp
,
union
aty_pll
*
pll
)
{
{
u32
mhz100
;
/* in 0.01 MHz */
u32
mhz100
;
/* in 0.01 MHz */
u32
program_bits
;
u32
program_bits
;
/* u32 post_divider; */
/* u32 post_divider; */
u32
mach64MinFreq
,
mach64MaxFreq
,
mach64RefFreq
;
u32
mach64MinFreq
,
mach64MaxFreq
,
mach64RefFreq
;
u32
temp
,
tempB
;
u32
temp
,
tempB
;
u16
remainder
,
preRemainder
;
u16
remainder
,
preRemainder
;
short
divider
=
0
,
tempA
;
short
divider
=
0
,
tempA
;
/* Calculate the programming word */
/* Calculate the programming word */
mhz100
=
100000000
/
vclk_per
;
mhz100
=
100000000
/
vclk_per
;
mach64MinFreq
=
MIN_FREQ_2595
;
mach64MinFreq
=
MIN_FREQ_2595
;
mach64MaxFreq
=
MAX_FREQ_2595
;
mach64MaxFreq
=
MAX_FREQ_2595
;
mach64RefFreq
=
REF_FREQ_2595
;
/* 14.32 MHz */
mach64RefFreq
=
REF_FREQ_2595
;
/* 14.32 MHz */
/* Calculate program word */
/* Calculate program word */
if
(
mhz100
==
0
)
if
(
mhz100
==
0
)
program_bits
=
0xE0
;
program_bits
=
0xE0
;
else
{
else
{
if
(
mhz100
<
mach64MinFreq
)
if
(
mhz100
<
mach64MinFreq
)
mhz100
=
mach64MinFreq
;
mhz100
=
mach64MinFreq
;
if
(
mhz100
>
mach64MaxFreq
)
if
(
mhz100
>
mach64MaxFreq
)
mhz100
=
mach64MaxFreq
;
mhz100
=
mach64MaxFreq
;
divider
=
0
;
divider
=
0
;
while
(
mhz100
<
(
mach64MinFreq
<<
3
))
{
while
(
mhz100
<
(
mach64MinFreq
<<
3
))
{
mhz100
<<=
1
;
mhz100
<<=
1
;
divider
+=
0x20
;
divider
+=
0x20
;
}
}
temp
=
(
unsigned
int
)(
mhz100
);
temp
=
(
unsigned
int
)(
temp
*
(
MIN_N_1703
+
2
));
temp
-=
(
short
)(
mach64RefFreq
<<
1
);
tempA
=
MIN_N_1703
;
preRemainder
=
0xffff
;
do
{
tempB
=
temp
;
remainder
=
tempB
%
mach64RefFreq
;
tempB
=
tempB
/
mach64RefFreq
;
if
((
tempB
&
0xffff
)
<=
127
&&
(
remainder
<=
preRemainder
))
{
preRemainder
=
remainder
;
divider
&=
~
0x1f
;
divider
|=
tempA
;
divider
=
(
divider
&
0x00ff
)
+
((
tempB
&
0xff
)
<<
8
);
}
temp
+=
mhz100
;
tempA
++
;
}
while
(
tempA
<=
(
MIN_N_1703
<<
1
));
program_bits
=
divider
;
temp
=
(
unsigned
int
)
(
mhz100
);
}
temp
=
(
unsigned
int
)
(
temp
*
(
MIN_N_1703
+
2
));
temp
-=
(
short
)
(
mach64RefFreq
<<
1
);
tempA
=
MIN_N_1703
;
preRemainder
=
0xffff
;
do
{
tempB
=
temp
;
remainder
=
tempB
%
mach64RefFreq
;
tempB
=
tempB
/
mach64RefFreq
;
if
((
tempB
&
0xffff
)
<=
127
&&
(
remainder
<=
preRemainder
))
{
preRemainder
=
remainder
;
divider
&=
~
0x1f
;
divider
|=
tempA
;
divider
=
(
divider
&
0x00ff
)
+
((
tempB
&
0xff
)
<<
8
);
}
temp
+=
mhz100
;
tempA
++
;
}
while
(
tempA
<=
(
MIN_N_1703
<<
1
));
program_bits
=
divider
;
}
pll
->
ics2595
.
program_bits
=
program_bits
;
pll
->
ics2595
.
program_bits
=
program_bits
;
pll
->
ics2595
.
locationAddr
=
0
;
pll
->
ics2595
.
locationAddr
=
0
;
pll
->
ics2595
.
post_divider
=
divider
;
/* fuer nix */
pll
->
ics2595
.
post_divider
=
divider
;
/* fuer nix */
pll
->
ics2595
.
period_in_ps
=
vclk_per
;
pll
->
ics2595
.
period_in_ps
=
vclk_per
;
return
0
;
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
)
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
)
const
union
aty_pll
*
pll
)
{
{
u32
program_bits
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
locationAddr
;
u32
program_bits
;
u32
locationAddr
;
char
old_crtc_ext_disp
;
char
old_crtc_ext_disp
;
old_crtc_ext_disp
=
aty_ld_8
(
CRTC_GEN_CNTL
+
3
,
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
)
,
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
info
);
old_crtc_ext_disp
|
(
CRTC_EXT_DISP_EN
>>
24
),
par
);
program_bits
=
pll
->
ics2595
.
program_bits
;
program_bits
=
pll
->
ics2595
.
program_bits
;
locationAddr
=
pll
->
ics2595
.
locationAddr
;
locationAddr
=
pll
->
ics2595
.
locationAddr
;
/* Program clock */
/* Program clock */
aty_dac_waste4
(
info
);
aty_dac_waste4
(
par
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
info
);
(
void
)
aty_ld_8
(
DAC_REGS
+
2
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
(
locationAddr
<<
1
)
+
0x20
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
(
locationAddr
<<
1
)
+
0x20
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
0
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
0
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
(
program_bits
&
0xFF00
)
>>
8
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
(
program_bits
&
0xFF00
)
>>
8
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
(
program_bits
&
0xFF
),
info
);
aty_st_8
(
DAC_REGS
+
2
,
(
program_bits
&
0xFF
),
par
);
(
void
)
aty_ld_8
(
DAC_REGS
,
info
);
/* Clear DAC Counter */
(
void
)
aty_ld_8
(
DAC_REGS
,
par
);
/* Clear DAC Counter */
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
info
);
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
par
);
return
;
return
;
}
}
const
struct
aty_pll_ops
aty_pll_stg1703
=
{
const
struct
aty_pll_ops
aty_pll_stg1703
=
{
var_to_pll:
aty_var_to_pll_1703
,
var_to_pll:
aty_var_to_pll_1703
,
pll_to_var:
aty_pll_1703_to_var
,
pll_to_var:
aty_pll_1703_to_var
,
set_pll:
aty_set_pll_1703
,
set_pll:
aty_set_pll_1703
,
};
};
...
@@ -587,126 +613,123 @@ const struct aty_pll_ops aty_pll_stg1703 = {
...
@@ -587,126 +613,123 @@ const struct aty_pll_ops aty_pll_stg1703 = {
* Chrontel 8398 Clock Chip
* Chrontel 8398 Clock Chip
*/
*/
static
int
aty_var_to_pll_8398
(
const
struct
fb_info
_aty
*
info
,
u32
vclk_per
,
static
int
aty_var_to_pll_8398
(
const
struct
fb_info
*
info
,
u8
bpp
,
union
aty_pll
*
pll
)
u
32
vclk_per
,
u
8
bpp
,
union
aty_pll
*
pll
)
{
{
u32
tempA
,
tempB
,
fOut
,
longMHz100
,
diff
,
preDiff
;
u32
tempA
,
tempB
,
fOut
,
longMHz100
,
diff
,
preDiff
;
u32
mhz100
;
/* in 0.01 MHz */
u32
mhz100
;
/* in 0.01 MHz */
u32
program_bits
;
u32
program_bits
;
/* u32 post_divider; */
/* u32 post_divider; */
u32
mach64MinFreq
,
mach64MaxFreq
,
mach64RefFreq
;
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 */
/* Calculate the programming word */
mhz100
=
100000000
/
vclk_per
;
mhz100
=
100000000
/
vclk_per
;
mach64MinFreq
=
MIN_FREQ_2595
;
mach64MinFreq
=
MIN_FREQ_2595
;
mach64MaxFreq
=
MAX_FREQ_2595
;
mach64MaxFreq
=
MAX_FREQ_2595
;
mach64RefFreq
=
REF_FREQ_2595
;
/* 14.32 MHz */
mach64RefFreq
=
REF_FREQ_2595
;
/* 14.32 MHz */
save_m
=
0
;
save_m
=
0
;
save_n
=
0
;
save_n
=
0
;
/* Calculate program word */
/* Calculate program word */
if
(
mhz100
==
0
)
if
(
mhz100
==
0
)
program_bits
=
0xE0
;
program_bits
=
0xE0
;
else
else
{
{
if
(
mhz100
<
mach64MinFreq
)
if
(
mhz100
<
mach64MinFreq
)
mhz100
=
mach64MinFreq
;
mhz100
=
mach64MinFreq
;
if
(
mhz100
>
mach64MaxFreq
)
if
(
mhz100
>
mach64MaxFreq
)
mhz100
=
mach64MaxFreq
;
mhz100
=
mach64MaxFreq
;
longMHz100
=
mhz100
*
256
/
100
;
/* 8 bit scale this */
longMHz100
=
mhz100
*
256
/
100
;
/* 8 bit scale this */
while
(
mhz100
<
(
mach64MinFreq
<<
3
))
{
while
(
mhz100
<
(
mach64MinFreq
<<
3
))
mhz100
<<=
1
;
{
k
++
;
mhz100
<<=
1
;
}
k
++
;
}
twoToKth
=
1
<<
k
;
twoToKth
=
1
<<
k
;
diff
=
0
;
diff
=
0
;
preDiff
=
0xFFFFFFFF
;
preDiff
=
0xFFFFFFFF
;
for
(
m
=
MIN_M
;
m
<=
MAX_M
;
m
++
)
for
(
m
=
MIN_M
;
m
<=
MAX_M
;
m
++
)
{
{
for
(
n
=
MIN_N
;
n
<=
MAX_N
;
n
++
)
{
for
(
n
=
MIN_N
;
n
<=
MAX_N
;
n
++
)
tempA
=
(
14
.
31818
*
65536
);
{
tempA
*=
(
n
+
8
);
/* 43..256 */
tempA
=
(
14
.
31818
*
65536
);
tempB
=
twoToKth
*
256
;
tempA
*=
(
n
+
8
);
/* 43..256 */
tempB
*=
(
m
+
2
);
/* 4..32 */
tempB
=
twoToKth
*
256
;
fOut
=
tempA
/
tempB
;
/* 8 bit scale */
tempB
*=
(
m
+
2
);
/* 4..32 */
fOut
=
tempA
/
tempB
;
/* 8 bit scale */
if
(
longMHz100
>
fOut
)
diff
=
longMHz100
-
fOut
;
if
(
longMHz100
>
fOut
)
else
diff
=
longMHz100
-
fOut
;
diff
=
fOut
-
longMHz100
;
else
diff
=
fOut
-
longMHz100
;
if
(
diff
<
preDiff
)
{
save_m
=
m
;
if
(
diff
<
preDiff
)
save_n
=
n
;
{
preDiff
=
diff
;
save_m
=
m
;
}
save_n
=
n
;
}
preDiff
=
diff
;
}
}
}
}
program_bits
=
(
k
<<
6
)
+
(
save_m
)
+
(
save_n
<<
8
);
program_bits
=
(
k
<<
6
)
+
(
save_m
)
+
(
save_n
<<
8
);
}
}
pll
->
ics2595
.
program_bits
=
program_bits
;
pll
->
ics2595
.
program_bits
=
program_bits
;
pll
->
ics2595
.
locationAddr
=
0
;
pll
->
ics2595
.
locationAddr
=
0
;
pll
->
ics2595
.
post_divider
=
0
;
pll
->
ics2595
.
post_divider
=
0
;
pll
->
ics2595
.
period_in_ps
=
vclk_per
;
pll
->
ics2595
.
period_in_ps
=
vclk_per
;
return
0
;
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
)
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
)
const
union
aty_pll
*
pll
)
{
{
u32
program_bits
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
locationAddr
;
u32
program_bits
;
u32
locationAddr
;
char
old_crtc_ext_disp
;
char
old_crtc_ext_disp
;
char
tmp
;
char
tmp
;
old_crtc_ext_disp
=
aty_ld_8
(
CRTC_GEN_CNTL
+
3
,
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
)
,
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
info
);
old_crtc_ext_disp
|
(
CRTC_EXT_DISP_EN
>>
24
),
par
);
program_bits
=
pll
->
ics2595
.
program_bits
;
program_bits
=
pll
->
ics2595
.
program_bits
;
locationAddr
=
pll
->
ics2595
.
locationAddr
;
locationAddr
=
pll
->
ics2595
.
locationAddr
;
/* Program clock */
/* Program clock */
tmp
=
aty_ld_8
(
DAC_CNTL
,
info
);
tmp
=
aty_ld_8
(
DAC_CNTL
,
par
);
aty_st_8
(
DAC_CNTL
,
tmp
|
DAC_EXT_SEL_RS2
|
DAC_EXT_SEL_RS3
,
info
);
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
,
locationAddr
,
par
);
aty_st_8
(
DAC_REGS
+
1
,
(
program_bits
&
0xff00
)
>>
8
,
info
);
aty_st_8
(
DAC_REGS
+
1
,
(
program_bits
&
0xff00
)
>>
8
,
par
);
aty_st_8
(
DAC_REGS
+
1
,
(
program_bits
&
0xff
),
info
);
aty_st_8
(
DAC_REGS
+
1
,
(
program_bits
&
0xff
),
par
);
tmp
=
aty_ld_8
(
DAC_CNTL
,
info
);
tmp
=
aty_ld_8
(
DAC_CNTL
,
par
);
aty_st_8
(
DAC_CNTL
,
(
tmp
&
~
DAC_EXT_SEL_RS2
)
|
DAC_EXT_SEL_RS3
,
info
);
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 */
(
void
)
aty_ld_8
(
DAC_REGS
,
par
);
/* Clear DAC Counter */
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
info
);
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
par
);
return
;
return
;
}
}
const
struct
aty_pll_ops
aty_pll_ch8398
=
{
const
struct
aty_pll_ops
aty_pll_ch8398
=
{
var_to_pll:
aty_var_to_pll_8398
,
var_to_pll:
aty_var_to_pll_8398
,
pll_to_var:
aty_pll_8398_to_var
,
pll_to_var:
aty_pll_8398_to_var
,
set_pll:
aty_set_pll_8398
,
set_pll:
aty_set_pll_8398
,
};
};
...
@@ -714,143 +737,146 @@ const struct aty_pll_ops aty_pll_ch8398 = {
...
@@ -714,143 +737,146 @@ const struct aty_pll_ops aty_pll_ch8398 = {
* AT&T 20C408 Clock Chip
* 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
)
u8
bpp
,
union
aty_pll
*
pll
)
{
{
u32
mhz100
;
/* in 0.01 MHz */
u32
mhz100
;
/* in 0.01 MHz */
u32
program_bits
;
u32
program_bits
;
/* u32 post_divider; */
/* u32 post_divider; */
u32
mach64MinFreq
,
mach64MaxFreq
,
mach64RefFreq
;
u32
mach64MinFreq
,
mach64MaxFreq
,
mach64RefFreq
;
u32
temp
,
tempB
;
u32
temp
,
tempB
;
u16
remainder
,
preRemainder
;
u16
remainder
,
preRemainder
;
short
divider
=
0
,
tempA
;
short
divider
=
0
,
tempA
;
/* Calculate the programming word */
/* Calculate the programming word */
mhz100
=
100000000
/
vclk_per
;
mhz100
=
100000000
/
vclk_per
;
mach64MinFreq
=
MIN_FREQ_2595
;
mach64MinFreq
=
MIN_FREQ_2595
;
mach64MaxFreq
=
MAX_FREQ_2595
;
mach64MaxFreq
=
MAX_FREQ_2595
;
mach64RefFreq
=
REF_FREQ_2595
;
/* 14.32 MHz */
mach64RefFreq
=
REF_FREQ_2595
;
/* 14.32 MHz */
/* Calculate program word */
/* Calculate program word */
if
(
mhz100
==
0
)
if
(
mhz100
==
0
)
program_bits
=
0xFF
;
program_bits
=
0xFF
;
else
{
else
{
if
(
mhz100
<
mach64MinFreq
)
if
(
mhz100
<
mach64MinFreq
)
mhz100
=
mach64MinFreq
;
mhz100
=
mach64MinFreq
;
if
(
mhz100
>
mach64MaxFreq
)
if
(
mhz100
>
mach64MaxFreq
)
mhz100
=
mach64MaxFreq
;
mhz100
=
mach64MaxFreq
;
while
(
mhz100
<
(
mach64MinFreq
<<
3
))
{
while
(
mhz100
<
(
mach64MinFreq
<<
3
))
{
mhz100
<<=
1
;
mhz100
<<=
1
;
divider
+=
0x40
;
divider
+=
0x40
;
}
temp
=
(
unsigned
int
)
mhz100
;
temp
=
(
unsigned
int
)
(
temp
*
(
MIN_N_408
+
2
));
temp
-=
((
short
)
(
mach64RefFreq
<<
1
));
tempA
=
MIN_N_408
;
preRemainder
=
0xFFFF
;
do
{
tempB
=
temp
;
remainder
=
tempB
%
mach64RefFreq
;
tempB
=
tempB
/
mach64RefFreq
;
if
(((
tempB
&
0xFFFF
)
<=
255
)
&&
(
remainder
<=
preRemainder
))
{
preRemainder
=
remainder
;
divider
&=
~
0x3f
;
divider
|=
tempA
;
divider
=
(
divider
&
0x00FF
)
+
((
tempB
&
0xFF
)
<<
8
);
}
temp
+=
mhz100
;
tempA
++
;
}
while
(
tempA
<=
32
);
program_bits
=
divider
;
}
}
temp
=
(
unsigned
int
)
mhz100
;
pll
->
ics2595
.
program_bits
=
program_bits
;
temp
=
(
unsigned
int
)(
temp
*
(
MIN_N_408
+
2
));
pll
->
ics2595
.
locationAddr
=
0
;
temp
-=
((
short
)(
mach64RefFreq
<<
1
));
pll
->
ics2595
.
post_divider
=
divider
;
/* fuer nix */
pll
->
ics2595
.
period_in_ps
=
vclk_per
;
tempA
=
MIN_N_408
;
preRemainder
=
0xFFFF
;
return
0
;
do
{
tempB
=
temp
;
remainder
=
tempB
%
mach64RefFreq
;
tempB
=
tempB
/
mach64RefFreq
;
if
(((
tempB
&
0xFFFF
)
<=
255
)
&&
(
remainder
<=
preRemainder
))
{
preRemainder
=
remainder
;
divider
&=
~
0x3f
;
divider
|=
tempA
;
divider
=
(
divider
&
0x00FF
)
+
((
tempB
&
0xFF
)
<<
8
);
}
temp
+=
mhz100
;
tempA
++
;
}
while
(
tempA
<=
32
);
program_bits
=
divider
;
}
pll
->
ics2595
.
program_bits
=
program_bits
;
pll
->
ics2595
.
locationAddr
=
0
;
pll
->
ics2595
.
post_divider
=
divider
;
/* fuer nix */
pll
->
ics2595
.
period_in_ps
=
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
)
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
)
const
union
aty_pll
*
pll
)
{
{
u32
program_bits
;
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
u32
locationAddr
;
u32
program_bits
;
u32
locationAddr
;
u8
tmpA
,
tmpB
,
tmpC
;
u8
tmpA
,
tmpB
,
tmpC
;
char
old_crtc_ext_disp
;
char
old_crtc_ext_disp
;
old_crtc_ext_disp
=
aty_ld_8
(
CRTC_GEN_CNTL
+
3
,
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
)
,
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
info
);
old_crtc_ext_disp
|
(
CRTC_EXT_DISP_EN
>>
24
),
par
);
program_bits
=
pll
->
ics2595
.
program_bits
;
program_bits
=
pll
->
ics2595
.
program_bits
;
locationAddr
=
pll
->
ics2595
.
locationAddr
;
locationAddr
=
pll
->
ics2595
.
locationAddr
;
/* Program clock */
/* Program clock */
aty_dac_waste4
(
info
);
aty_dac_waste4
(
par
);
tmpB
=
aty_ld_8
(
DAC_REGS
+
2
,
info
)
|
1
;
tmpB
=
aty_ld_8
(
DAC_REGS
+
2
,
par
)
|
1
;
aty_dac_waste4
(
info
);
aty_dac_waste4
(
par
);
aty_st_8
(
DAC_REGS
+
2
,
tmpB
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
tmpB
,
par
);
tmpA
=
tmpB
;
tmpA
=
tmpB
;
tmpC
=
tmpA
;
tmpC
=
tmpA
;
tmpA
|=
8
;
tmpA
|=
8
;
tmpB
=
1
;
tmpB
=
1
;
aty_st_8
(
DAC_REGS
,
tmpB
,
info
);
aty_st_8
(
DAC_REGS
,
tmpB
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
par
);
udelay
(
400
);
/* delay for 400 us */
udelay
(
400
);
/* delay for 400 us */
locationAddr
=
(
locationAddr
<<
2
)
+
0x40
;
locationAddr
=
(
locationAddr
<<
2
)
+
0x40
;
tmpB
=
locationAddr
;
tmpB
=
locationAddr
;
tmpA
=
program_bits
>>
8
;
tmpA
=
program_bits
>>
8
;
aty_st_8
(
DAC_REGS
,
tmpB
,
info
);
aty_st_8
(
DAC_REGS
,
tmpB
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
par
);
tmpB
=
locationAddr
+
1
;
tmpB
=
locationAddr
+
1
;
tmpA
=
(
u8
)
program_bits
;
tmpA
=
(
u8
)
program_bits
;
aty_st_8
(
DAC_REGS
,
tmpB
,
info
);
aty_st_8
(
DAC_REGS
,
tmpB
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
par
);
tmpB
=
locationAddr
+
2
;
tmpB
=
locationAddr
+
2
;
tmpA
=
0x77
;
tmpA
=
0x77
;
aty_st_8
(
DAC_REGS
,
tmpB
,
info
);
aty_st_8
(
DAC_REGS
,
tmpB
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
par
);
udelay
(
400
);
/* delay for 400 us */
udelay
(
400
);
/* delay for 400 us */
tmpA
=
tmpC
&
(
~
(
1
|
8
));
tmpA
=
tmpC
&
(
~
(
1
|
8
));
tmpB
=
1
;
tmpB
=
1
;
aty_st_8
(
DAC_REGS
,
tmpB
,
info
);
aty_st_8
(
DAC_REGS
,
tmpB
,
par
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
info
);
aty_st_8
(
DAC_REGS
+
2
,
tmpA
,
par
);
(
void
)
aty_ld_8
(
DAC_REGS
,
info
);
/* Clear DAC Counter */
(
void
)
aty_ld_8
(
DAC_REGS
,
par
);
/* Clear DAC Counter */
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
info
);
aty_st_8
(
CRTC_GEN_CNTL
+
3
,
old_crtc_ext_disp
,
par
);
return
;
return
;
}
}
const
struct
aty_pll_ops
aty_pll_att20c408
=
{
const
struct
aty_pll_ops
aty_pll_att20c408
=
{
var_to_pll:
aty_var_to_pll_408
,
var_to_pll:
aty_var_to_pll_408
,
pll_to_var:
aty_pll_408_to_var
,
pll_to_var:
aty_pll_408_to_var
,
set_pll:
aty_set_pll_408
,
set_pll:
aty_set_pll_408
,
};
};
...
@@ -858,30 +884,31 @@ const struct aty_pll_ops aty_pll_att20c408 = {
...
@@ -858,30 +884,31 @@ const struct aty_pll_ops aty_pll_att20c408 = {
* Unsupported DAC and Clock Chip
* 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
,
const
union
aty_pll
*
pll
,
u32
bpp
,
u32
accel
)
u32
accel
)
{
{
aty_st_le32
(
BUS_CNTL
,
0x890e20f1
,
info
);
struct
atyfb_par
*
par
=
(
struct
atyfb_par
*
)
info
->
par
;
aty_st_le32
(
DAC_CNTL
,
0x47052100
,
info
);
/* new in 2.2.3p1 from Geert. ???????? */
aty_st_le32
(
BUS_CNTL
,
0x890e20f1
,
par
);
aty_st_le32
(
BUS_CNTL
,
0x590e10ff
,
info
);
aty_st_le32
(
DAC_CNTL
,
0x47052100
,
par
);
aty_st_le32
(
DAC_CNTL
,
0x47012100
,
info
);
/* new in 2.2.3p1 from Geert. ???????? */
return
0
;
aty_st_le32
(
BUS_CNTL
,
0x590e10ff
,
par
);
aty_st_le32
(
DAC_CNTL
,
0x47012100
,
par
);
return
0
;
}
}
static
int
dummy
(
void
)
static
int
dummy
(
void
)
{
{
return
0
;
return
0
;
}
}
const
struct
aty_dac_ops
aty_dac_unsupported
=
{
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
=
{
const
struct
aty_pll_ops
aty_pll_unsupported
=
{
var_to_pll:
(
void
*
)
dummy
,
var_to_pll:
(
void
*
)
dummy
,
pll_to_var:
(
void
*
)
dummy
,
pll_to_var:
(
void
*
)
dummy
,
set_pll:
(
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