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