Commit 87520e1e authored by James Simmons's avatar James Simmons

Porting Mach 64 drive over to new api.

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