Commit ba7d0db1 authored by Antonino Daplas's avatar Antonino Daplas Committed by Linus Torvalds

[PATCH] fbdev: Various mach64 changes

  Alexander Kern <alex.kern@gmx.de>
  [PATCH] port Daniel Mantione 2.4 driver to 2.6
  [PATCH] add more pci_id number
  [PATCH] add accelerated imgblit
  [PATCH] revert SDRAM_MAGIC_PLL to old behaviour
  [PATCH] do a "from BIOS" initialisation only by __i386__

  Arnaud FONTAINE <arnaud.fontaine@free.fr>
  [PATCH atyfb] correction for 3D Rage Mobility L

  Geert Uytterhoeven <geert@linux-m68k.org>
  [PATCH atyfb] Atari Atyfb fixes
  [PATCH atyfb] Atyfb on Mach64 GX or Atari
  [PATCH 468] m68k sparse floating point

  James Simmons <jsimmons@infradead.org>
  [PATCH add] port to framebuffer_alloc api

  Nicolas Souchu <nsouch@free.fr>
  [PATCH] I do not found a copy, but it was incorporated too

  Ville Syrjälä <syrjala@sci.fi>
  [PATCH] fix pan with doublescan
  [PATCH] another double scan fix
  [PATCH] disable linear aperture register access
  [PATCH] Memory type correction
  [PATCH] atyfb (2.6): Fix mmio_start
  [PATCH] atyfb (2.6): Fix mem_refresh_rate for Mobility
  [PATCH] atyfb (2.6): Add RGB565 support
  [PATCH] atyfb: Blank LCD by turning off backlight voltage
  [PATCH] atyfb: Rage LT LCD register access
  [PATCH] atyfb: vblank irq support
  [PATCH] atyfb: MTRR support


Antonino Daplas <adaplas@pol.net>
   remove/modify all references to info->cursor
Signed-off-by: default avatarAntonino Daplas <adaplas@pol.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b9a30828
...@@ -750,6 +750,19 @@ config FB_ATY_CT ...@@ -750,6 +750,19 @@ config FB_ATY_CT
framebuffer device. The ATI product support page for these boards framebuffer device. The ATI product support page for these boards
is at <http://support.ati.com/products/pc/mach64/>. is at <http://support.ati.com/products/pc/mach64/>.
config FB_ATY_GENERIC_LCD
bool "Mach64 generic LCD support (EXPERIMENTAL)"
depends on FB_ATY_CT
help
Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility,
Rage XC, or Rage XL chipset.
config FB_ATY_XL_INIT
bool "Rage XL No-BIOS Init support"
depends on FB_ATY_CT
help
Say Y here to support booting a Rage XL without BIOS support.
config FB_ATY_GX config FB_ATY_GX
bool "Mach64 GX support" if PCI bool "Mach64 GX support" if PCI
depends on FB_ATY depends on FB_ATY
...@@ -761,12 +774,6 @@ config FB_ATY_GX ...@@ -761,12 +774,6 @@ config FB_ATY_GX
is at is at
<http://support.ati.com/products/pc/mach64/graphics_xpression.html>. <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
config FB_ATY_XL_INIT
bool " Rage XL No-BIOS Init support" if FB_ATY_CT
depends on FB_ATY
help
Say Y here to support booting a Rage XL without BIOS support.
config FB_SIS config FB_SIS
tristate "SiS acceleration" tristate "SiS acceleration"
depends on FB && PCI depends on FB && PCI
......
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
#define PCI_CHIP_MACH64LQ 0x4C51 #define PCI_CHIP_MACH64LQ 0x4C51
#define PCI_CHIP_MACH64LR 0x4C52 #define PCI_CHIP_MACH64LR 0x4C52
#define PCI_CHIP_MACH64LS 0x4C53 #define PCI_CHIP_MACH64LS 0x4C53
#define PCI_CHIP_MACH64LT 0x4C54
#define PCI_CHIP_RADEON_LW 0x4C57 #define PCI_CHIP_RADEON_LW 0x4C57
#define PCI_CHIP_RADEON_LX 0x4C58 #define PCI_CHIP_RADEON_LX 0x4C58
#define PCI_CHIP_RADEON_LY 0x4C59 #define PCI_CHIP_RADEON_LY 0x4C59
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
/* /*
* Elements of the hardware specific atyfb_par structure * Elements of the hardware specific atyfb_par structure
*/ */
...@@ -10,16 +12,60 @@ ...@@ -10,16 +12,60 @@
struct crtc { struct crtc {
u32 vxres; u32 vxres;
u32 vyres; u32 vyres;
u32 xoffset;
u32 yoffset;
u32 bpp;
u32 h_tot_disp; u32 h_tot_disp;
u32 h_sync_strt_wid; u32 h_sync_strt_wid;
u32 v_tot_disp; u32 v_tot_disp;
u32 v_sync_strt_wid; u32 v_sync_strt_wid;
u32 vline_crnt_vline;
u32 off_pitch; u32 off_pitch;
u32 gen_cntl; u32 gen_cntl;
u32 dp_pix_width; /* acceleration */ u32 dp_pix_width; /* acceleration */
u32 dp_chain_mask; /* acceleration */ u32 dp_chain_mask; /* acceleration */
#ifdef CONFIG_FB_ATY_GENERIC_LCD
u32 horz_stretching;
u32 vert_stretching;
u32 ext_vert_stretch;
u32 shadow_h_tot_disp;
u32 shadow_h_sync_strt_wid;
u32 shadow_v_tot_disp;
u32 shadow_v_sync_strt_wid;
u32 lcd_gen_cntl;
u32 lcd_config_panel;
u32 lcd_index;
#endif
};
struct aty_interrupt {
wait_queue_head_t wait;
unsigned int count;
int pan_display;
};
struct pll_info {
int pll_max;
int pll_min;
int sclk, mclk, mclk_pm, xclk;
int ref_div;
int ref_clk;
}; };
typedef struct {
u16 unknown1;
u16 PCLK_min_freq;
u16 PCLK_max_freq;
u16 unknown2;
u16 ref_freq;
u16 ref_divider;
u16 unknown3;
u16 MCLK_pwd;
u16 MCLK_max_freq;
u16 XCLK_max_freq;
u16 SCLK_freq;
} __attribute__ ((packed)) PLL_BLOCK_MACH64;
struct pll_514 { struct pll_514 {
u8 m; u8 m;
u8 n; u8 n;
...@@ -36,16 +82,39 @@ struct pll_ct { ...@@ -36,16 +82,39 @@ struct pll_ct {
u8 pll_ref_div; u8 pll_ref_div;
u8 pll_gen_cntl; u8 pll_gen_cntl;
u8 mclk_fb_div; u8 mclk_fb_div;
u8 mclk_fb_mult; /* 2 ro 4 */
/* u8 sclk_fb_div;*/
u8 pll_vclk_cntl; u8 pll_vclk_cntl;
u8 vclk_post_div; u8 vclk_post_div;
u8 vclk_fb_div; u8 vclk_fb_div;
u8 pll_ext_cntl; u8 pll_ext_cntl;
/* u8 ext_vpll_cntl;
u8 spll_cntl2;*/
u32 dsp_config; /* Mach64 GTB DSP */ u32 dsp_config; /* Mach64 GTB DSP */
u32 dsp_on_off; /* Mach64 GTB DSP */ u32 dsp_on_off; /* Mach64 GTB DSP */
u32 dsp_loop_latency;
u32 fifo_size;
u32 xclkpagefaultdelay;
u32 xclkmaxrasdelay;
u8 xclk_ref_div;
u8 xclk_post_div;
u8 mclk_post_div_real; u8 mclk_post_div_real;
u8 xclk_post_div_real;
u8 vclk_post_div_real; u8 vclk_post_div_real;
u8 features;
#ifdef CONFIG_FB_ATY_GENERIC_LCD
u32 xres; /* use for LCD stretching/scaling */
#endif
}; };
/*
for pll_ct.features
*/
#define DONT_USE_SPLL 0x1
#define DONT_USE_XDLL 0x2
#define USE_CPUCLK 0x4
#define POWERDOWN_PLL 0x8
union aty_pll { union aty_pll {
struct pll_ct ct; struct pll_ct ct;
struct pll_514 ibm514; struct pll_514 ibm514;
...@@ -56,39 +125,65 @@ union aty_pll { ...@@ -56,39 +125,65 @@ union aty_pll {
* The hardware parameters for each card * The hardware parameters for each card
*/ */
struct aty_cursor {
u8 bits[8][64];
u8 mask[8][64];
u8 __iomem *ram;
};
struct atyfb_par { struct atyfb_par {
struct aty_cmap_regs __iomem *aty_cmap_regs; struct aty_cmap_regs __iomem *aty_cmap_regs;
struct { u8 red, green, blue; } palette[256];
const struct aty_dac_ops *dac_ops; const struct aty_dac_ops *dac_ops;
const struct aty_pll_ops *pll_ops; const struct aty_pll_ops *pll_ops;
struct aty_cursor *cursor;
void __iomem *ati_regbase; void __iomem *ati_regbase;
unsigned long clk_wr_offset; unsigned long clk_wr_offset; /* meaning overloaded, clock id by CT */
struct crtc crtc; struct crtc crtc;
union aty_pll pll; union aty_pll pll;
struct pll_info pll_limits;
u32 features; u32 features;
u32 ref_clk_per; u32 ref_clk_per;
u32 pll_per; u32 pll_per;
u32 mclk_per; u32 mclk_per;
u32 xclk_per;
u8 bus_type; u8 bus_type;
u8 ram_type; u8 ram_type;
u8 mem_refresh_rate; u8 mem_refresh_rate;
u8 blitter_may_be_busy; u16 pci_id;
u32 accel_flags; u32 accel_flags;
int blitter_may_be_busy;
int asleep;
int lock_blank;
unsigned long res_start;
unsigned long res_size;
#ifdef __sparc__ #ifdef __sparc__
struct pci_mmap_map *mmap_map; struct pci_mmap_map *mmap_map;
u8 mmaped; u8 mmaped;
#endif
int open; int open;
#ifdef CONFIG_FB_ATY_GENERIC_LCD
unsigned long bios_base_phys;
unsigned long bios_base;
unsigned long lcd_table;
u16 lcd_width;
u16 lcd_height;
u32 lcd_pixclock;
u16 lcd_refreshrate;
u16 lcd_htotal;
u16 lcd_hdisp;
u16 lcd_hsync_dly;
u16 lcd_hsync_len;
u16 lcd_vtotal;
u16 lcd_vdisp;
u16 lcd_vsync_len;
u16 lcd_right_margin;
u16 lcd_lower_margin;
u16 lcd_hblank_len;
u16 lcd_vblank_len;
#endif #endif
#ifdef CONFIG_PMAC_PBOOK unsigned long aux_start; /* auxiliary aperture */
struct fb_info *next; unsigned long aux_size;
unsigned char *save_framebuffer; struct aty_interrupt vblank;
unsigned long save_pll[64]; unsigned long irq_flags;
unsigned int irq;
spinlock_t int_lock;
#ifdef CONFIG_MTRR
int mtrr_aper;
int mtrr_reg;
#endif #endif
}; };
...@@ -101,7 +196,7 @@ struct atyfb_par { ...@@ -101,7 +196,7 @@ struct atyfb_par {
#define M64F_RESET_3D 0x00000001 #define M64F_RESET_3D 0x00000001
#define M64F_MAGIC_FIFO 0x00000002 #define M64F_MAGIC_FIFO 0x00000002
#define M64F_GTB_DSP 0x00000004 #define M64F_GTB_DSP 0x00000004
#define M64F_FIFO_24 0x00000008 #define M64F_FIFO_32 0x00000008
#define M64F_SDRAM_MAGIC_PLL 0x00000010 #define M64F_SDRAM_MAGIC_PLL 0x00000010
#define M64F_MAGIC_POSTDIV 0x00000020 #define M64F_MAGIC_POSTDIV 0x00000020
#define M64F_INTEGRATED 0x00000040 #define M64F_INTEGRATED 0x00000040
...@@ -116,9 +211,10 @@ struct atyfb_par { ...@@ -116,9 +211,10 @@ struct atyfb_par {
#define M64F_G3_PB_1_1 0x00008000 #define M64F_G3_PB_1_1 0x00008000
#define M64F_G3_PB_1024x768 0x00010000 #define M64F_G3_PB_1024x768 0x00010000
#define M64F_EXTRA_BRIGHT 0x00020000 #define M64F_EXTRA_BRIGHT 0x00020000
#define M64F_LT_SLEEP 0x00040000 #define M64F_LT_LCD_REGS 0x00040000
#define M64F_XL_DLL 0x00080000 #define M64F_XL_DLL 0x00080000
#define M64F_MFB_FORCE_4 0x00100000
#define M64F_HW_TRIPLE 0x00200000
/* /*
* Register access * Register access
...@@ -137,8 +233,7 @@ static inline u32 aty_ld_le32(int regindex, const struct atyfb_par *par) ...@@ -137,8 +233,7 @@ static inline u32 aty_ld_le32(int regindex, const struct atyfb_par *par)
#endif #endif
} }
static inline void aty_st_le32(int regindex, u32 val, static inline void aty_st_le32(int regindex, u32 val, const struct atyfb_par *par)
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)
...@@ -163,8 +258,7 @@ static inline u8 aty_ld_8(int regindex, const struct atyfb_par *par) ...@@ -163,8 +258,7 @@ static inline u8 aty_ld_8(int regindex, const struct atyfb_par *par)
#endif #endif
} }
static inline void aty_st_8(int regindex, u8 val, static inline void aty_st_8(int regindex, u8 val, const struct atyfb_par *par)
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)
...@@ -177,17 +271,10 @@ static inline void aty_st_8(int regindex, u8 val, ...@@ -177,17 +271,10 @@ static inline void aty_st_8(int regindex, u8 val,
#endif #endif
} }
static inline u8 aty_ld_pll(int offset, const struct atyfb_par *par) #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD)
{ extern void aty_st_lcd(int index, u32 val, const struct atyfb_par *par);
u8 res; extern u32 aty_ld_lcd(int index, const struct atyfb_par *par);
#endif
/* write addr byte */
aty_st_8(CLOCK_CNTL + 1, (offset << 2), par);
/* read the register value */
res = aty_ld_8(CLOCK_CNTL + 2, par);
return res;
}
/* /*
* DAC operations * DAC operations
...@@ -210,12 +297,11 @@ extern const struct aty_dac_ops aty_dac_ct; /* Integrated */ ...@@ -210,12 +297,11 @@ 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 * info, u32 vclk_per, int (*var_to_pll) (const struct fb_info * info, u32 vclk_per, u32 bpp, union aty_pll * pll);
u8 bpp, union aty_pll * pll); u32 (*pll_to_var) (const struct fb_info * info, const union aty_pll * pll);
u32(*pll_to_var) (const struct fb_info * info, void (*set_pll) (const struct fb_info * info, const union aty_pll * pll);
const union aty_pll * pll); void (*get_pll) (const struct fb_info *info, union aty_pll * pll);
void (*set_pll) (const struct fb_info * info, int (*init_pll) (const struct fb_info * info, union aty_pll * pll);
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 */
...@@ -227,20 +313,16 @@ extern const struct aty_pll_ops aty_pll_unsupported; /* unsupported */ ...@@ -227,20 +313,16 @@ 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 *info, extern void aty_set_pll_ct(const struct fb_info *info, const union aty_pll *pll);
const union aty_pll *pll); extern u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par);
extern void aty_calc_pll_ct(const struct fb_info *info,
struct pll_ct *pll);
/* /*
* Hardware cursor support * Hardware cursor support
*/ */
extern struct aty_cursor *aty_init_cursor(struct fb_info *info); extern int aty_init_cursor(struct fb_info *info);
extern int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor); extern int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor);
extern void aty_set_cursor_color(struct fb_info *info);
extern void aty_set_cursor_shape(struct fb_info *info);
/* /*
* Hardware acceleration * Hardware acceleration
...@@ -260,6 +342,5 @@ static inline void wait_for_idle(struct atyfb_par *par) ...@@ -260,6 +342,5 @@ static inline void wait_for_idle(struct atyfb_par *par)
} }
extern void aty_reset_engine(const struct atyfb_par *par); extern void aty_reset_engine(const struct atyfb_par *par);
extern void aty_init_engine(struct atyfb_par *par, extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info);
struct fb_info *info);
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -13,22 +13,41 @@ ...@@ -13,22 +13,41 @@
* Generic Mach64 routines * Generic Mach64 routines
*/ */
/* this is for DMA GUI engine! work in progress */
typedef struct {
u32 frame_buf_offset;
u32 system_mem_addr;
u32 command;
u32 reserved;
} BM_DESCRIPTOR_ENTRY;
#define LAST_DESCRIPTOR (1 << 31)
#define SYSTEM_TO_FRAME_BUFFER 0
static u32 rotation24bpp(u32 dx, u32 direction)
{
u32 rotation;
if (direction & DST_X_LEFT_TO_RIGHT) {
rotation = (dx / 4) % 6;
} else {
rotation = ((dx + 2) / 4) % 6;
}
return ((rotation << 8) | DST_24_ROTATION_ENABLE);
}
void aty_reset_engine(const struct atyfb_par *par) 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, par) & ~GUI_ENGINE_ENABLE, aty_ld_le32(GEN_TEST_CNTL, par) & ~GUI_ENGINE_ENABLE, par);
par);
/* enable engine */ /* enable engine */
aty_st_le32(GEN_TEST_CNTL, aty_st_le32(GEN_TEST_CNTL,
aty_ld_le32(GEN_TEST_CNTL, par) | GUI_ENGINE_ENABLE, aty_ld_le32(GEN_TEST_CNTL, par) | GUI_ENGINE_ENABLE, par);
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_st_le32(BUS_CNTL,
aty_ld_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_HOST_ERR_ACK | BUS_FIFO_ERR_ACK, par);
par) | BUS_HOST_ERR_ACK | BUS_FIFO_ERR_ACK,
par);
} }
static void reset_GTC_3D_engine(const struct atyfb_par *par) static void reset_GTC_3D_engine(const struct atyfb_par *par)
...@@ -51,7 +70,7 @@ void aty_init_engine(struct atyfb_par *par, struct fb_info *info) ...@@ -51,7 +70,7 @@ void aty_init_engine(struct atyfb_par *par, struct fb_info *info)
if (info->var.bits_per_pixel == 24) { if (info->var.bits_per_pixel == 24) {
/* In 24 bpp, the engine is in 8 bpp - this requires that all */ /* In 24 bpp, the engine is in 8 bpp - this requires that all */
/* horizontal coordinates and widths must be adjusted */ /* horizontal coordinates and widths must be adjusted */
pitch_value = pitch_value * 3; pitch_value *= 3;
} }
/* On GTC (RagePro), we need to reset the 3D engine before */ /* On GTC (RagePro), we need to reset the 3D engine before */
...@@ -174,9 +193,10 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) ...@@ -174,9 +193,10 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{ {
struct atyfb_par *par = (struct atyfb_par *) info->par; struct atyfb_par *par = (struct atyfb_par *) info->par;
u32 dy = area->dy, sy = area->sy, direction = DST_LAST_PEL; u32 dy = area->dy, sy = area->sy, direction = DST_LAST_PEL;
u32 sx = area->sx, dx = area->dx, width = area->width; u32 sx = area->sx, dx = area->dx, width = area->width, rotation = 0;
u32 pitch_value;
if (par->asleep)
return;
if (!area->width || !area->height) if (!area->width || !area->height)
return; return;
if (!par->accel_flags) { if (!par->accel_flags) {
...@@ -186,11 +206,9 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) ...@@ -186,11 +206,9 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
return; return;
} }
pitch_value = info->var.xres_virtual;
if (info->var.bits_per_pixel == 24) { if (info->var.bits_per_pixel == 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;
sx *= 3; sx *= 3;
dx *= 3; dx *= 3;
width *= 3; width *= 3;
...@@ -208,19 +226,25 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) ...@@ -208,19 +226,25 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
} else } else
direction |= DST_X_LEFT_TO_RIGHT; direction |= DST_X_LEFT_TO_RIGHT;
if (info->var.bits_per_pixel == 24) {
rotation = rotation24bpp(dx, direction);
}
wait_for_fifo(4, par); wait_for_fifo(4, par);
aty_st_le32(DP_SRC, FRGD_SRC_BLIT, par); aty_st_le32(DP_SRC, FRGD_SRC_BLIT, par);
aty_st_le32(SRC_Y_X, (sx << 16) | sy, par); aty_st_le32(SRC_Y_X, (sx << 16) | sy, par);
aty_st_le32(SRC_HEIGHT1_WIDTH1, (width << 16) | area->height, par); aty_st_le32(SRC_HEIGHT1_WIDTH1, (width << 16) | area->height, par);
aty_st_le32(DST_CNTL, direction, par); aty_st_le32(DST_CNTL, direction | rotation, par);
draw_rect(dx, dy, width, area->height, par); draw_rect(dx, dy, width, area->height, par);
} }
void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{ {
struct atyfb_par *par = (struct atyfb_par *) info->par; struct atyfb_par *par = (struct atyfb_par *) info->par;
u32 color = rect->color, dx = rect->dx, width = rect->width; u32 color = rect->color, dx = rect->dx, width = rect->width, rotation = 0;
if (par->asleep)
return;
if (!rect->width || !rect->height) if (!rect->width || !rect->height)
return; return;
if (!par->accel_flags) { if (!par->accel_flags) {
...@@ -238,6 +262,7 @@ void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) ...@@ -238,6 +262,7 @@ void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
/* horizontal coordinates and widths must be adjusted */ /* horizontal coordinates and widths must be adjusted */
dx *= 3; dx *= 3;
width *= 3; width *= 3;
rotation = rotation24bpp(dx, DST_X_LEFT_TO_RIGHT);
} }
wait_for_fifo(3, par); wait_for_fifo(3, par);
...@@ -247,15 +272,162 @@ void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) ...@@ -247,15 +272,162 @@ void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
par); par);
aty_st_le32(DST_CNTL, aty_st_le32(DST_CNTL,
DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM | DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM |
DST_X_LEFT_TO_RIGHT, par); DST_X_LEFT_TO_RIGHT | rotation, par);
draw_rect(dx, rect->dy, width, rect->height, par); draw_rect(dx, rect->dy, width, rect->height, par);
} }
void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) void atyfb_imageblit(struct fb_info *info, const struct fb_image *image)
{ {
struct atyfb_par *par = (struct atyfb_par *) info->par; struct atyfb_par *par = (struct atyfb_par *) info->par;
u32 src_bytes, dx = image->dx, dy = image->dy, width = image->width;
u32 pix_width_save, pix_width, host_cntl, rotation = 0, src, mix;
if (par->asleep)
return;
if (!image->width || !image->height)
return;
if (!par->accel_flags ||
(image->depth != 1 && info->var.bits_per_pixel != image->depth)) {
if (par->blitter_may_be_busy) if (par->blitter_may_be_busy)
wait_for_idle(par); wait_for_idle(par);
cfb_imageblit(info, image); cfb_imageblit(info, image);
return;
}
wait_for_idle(par);
pix_width = pix_width_save = aty_ld_le32(DP_PIX_WIDTH, par);
host_cntl = aty_ld_le32(HOST_CNTL, par) | HOST_BYTE_ALIGN;
switch (image->depth) {
case 1:
pix_width &= ~(BYTE_ORDER_MASK | HOST_MASK);
pix_width |= (BYTE_ORDER_MSB_TO_LSB | HOST_1BPP);
break;
case 4:
pix_width &= ~(BYTE_ORDER_MASK | HOST_MASK);
pix_width |= (BYTE_ORDER_MSB_TO_LSB | HOST_4BPP);
break;
case 8:
pix_width &= ~HOST_MASK;
pix_width |= HOST_8BPP;
break;
case 15:
pix_width &= ~HOST_MASK;
pix_width |= HOST_15BPP;
break;
case 16:
pix_width &= ~HOST_MASK;
pix_width |= HOST_16BPP;
break;
case 24:
pix_width &= ~HOST_MASK;
pix_width |= HOST_24BPP;
break;
case 32:
pix_width &= ~HOST_MASK;
pix_width |= HOST_32BPP;
break;
}
if (info->var.bits_per_pixel == 24) {
/* In 24 bpp, the engine is in 8 bpp - this requires that all */
/* horizontal coordinates and widths must be adjusted */
dx *= 3;
width *= 3;
rotation = rotation24bpp(dx, DST_X_LEFT_TO_RIGHT);
pix_width &= ~DST_MASK;
pix_width |= DST_8BPP;
/*
* since Rage 3D IIc we have DP_HOST_TRIPLE_EN bit
* this hwaccelerated triple has an issue with not aligned data
*/
if (M64_HAS(HW_TRIPLE) && image->width % 8 == 0)
pix_width |= DP_HOST_TRIPLE_EN;
}
if (image->depth == 1) {
u32 fg, bg;
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
fg = ((u32*)(info->pseudo_palette))[image->fg_color];
bg = ((u32*)(info->pseudo_palette))[image->bg_color];
} else {
fg = image->fg_color;
bg = image->bg_color;
}
wait_for_fifo(2, par);
aty_st_le32(DP_BKGD_CLR, bg, par);
aty_st_le32(DP_FRGD_CLR, fg, par);
src = MONO_SRC_HOST | FRGD_SRC_FRGD_CLR | BKGD_SRC_BKGD_CLR;
mix = FRGD_MIX_S | BKGD_MIX_S;
} else {
src = MONO_SRC_ONE | FRGD_SRC_HOST;
mix = FRGD_MIX_D_XOR_S | BKGD_MIX_D;
}
wait_for_fifo(6, par);
aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF, par);
aty_st_le32(DP_PIX_WIDTH, pix_width, par);
aty_st_le32(DP_MIX, mix, par);
aty_st_le32(DP_SRC, src, par);
aty_st_le32(HOST_CNTL, host_cntl, par);
aty_st_le32(DST_CNTL, DST_Y_TOP_TO_BOTTOM | DST_X_LEFT_TO_RIGHT | rotation, par);
draw_rect(dx, dy, width, image->height, par);
src_bytes = (((image->width * image->depth) + 7) / 8) * image->height;
/* manual triple each pixel */
if (info->var.bits_per_pixel == 24 && !(pix_width & DP_HOST_TRIPLE_EN)) {
int inbit, outbit, mult24, byte_id_in_dword, width;
u8 *pbitmapin = (u8*)image->data, *pbitmapout;
u32 hostdword;
for (width = image->width, inbit = 7, mult24 = 0; src_bytes; ) {
for (hostdword = 0, pbitmapout = (u8*)&hostdword, byte_id_in_dword = 0;
byte_id_in_dword < 4 && src_bytes;
byte_id_in_dword++, pbitmapout++) {
for (outbit = 7; outbit >= 0; outbit--) {
*pbitmapout |= (((*pbitmapin >> inbit) & 1) << outbit);
mult24++;
/* next bit */
if (mult24 == 3) {
mult24 = 0;
inbit--;
width--;
}
/* next byte */
if (inbit < 0 || width == 0) {
src_bytes--;
pbitmapin++;
inbit = 7;
if (width == 0) {
width = image->width;
outbit = 0;
}
}
}
}
wait_for_fifo(1, par);
aty_st_le32(HOST_DATA0, hostdword, par);
}
} else {
u32 *pbitmap, dwords = (src_bytes + 3) / 4;
for (pbitmap = (u32*)(image->data); dwords; dwords--, pbitmap++) {
wait_for_fifo(1, par);
aty_st_le32(HOST_DATA0, le32_to_cpup(pbitmap), par);
}
}
wait_for_idle(par);
/* restore pix_width */
wait_for_fifo(1, par);
aty_st_le32(DP_PIX_WIDTH, pix_width_save, par);
} }
This diff is collapsed.
/* /*
* ATI Mach64 CT/VT/GT/LT Cursor Support * ATI Mach64 CT/VT/GT/LT Cursor Support
*/ */
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/console.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/string.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -19,13 +18,49 @@ ...@@ -19,13 +18,49 @@
#include <video/mach64.h> #include <video/mach64.h>
#include "atyfb.h" #include "atyfb.h"
/*
* The hardware cursor definition requires 2 bits per pixel. The
* Cursor size reguardless of the visible cursor size is 64 pixels
* by 64 lines. The total memory required to define the cursor is
* 16 bytes / line for 64 lines or 1024 bytes of data. The data
* must be in a contigiuos format. The 2 bit cursor code values are
* as follows:
*
* 00 - pixel colour = CURSOR_CLR_0
* 01 - pixel colour = CURSOR_CLR_1
* 10 - pixel colour = transparent (current display pixel)
* 11 - pixel colour = 1's complement of current display pixel
*
* Cursor Offset 64 pixels Actual Displayed Area
* \_________________________/
* | | | |
* |<--------------->| | |
* | CURS_HORZ_OFFSET| | |
* | |_______| | 64 Lines
* | ^ | |
* | | | |
* | CURS_VERT_OFFSET| |
* | | | |
* |____________________|____| |
*
*
* The Screen position of the top left corner of the displayed
* cursor is specificed by CURS_HORZ_VERT_POSN. Care must be taken
* when the cursor hot spot is not the top left corner and the
* physical cursor position becomes negative. It will be be displayed
* if either the horizontal or vertical cursor position is negative
*
* If x becomes negative the cursor manager must adjust the CURS_HORZ_OFFSET
* to a larger number and saturate CUR_HORZ_POSN to zero.
*
* if Y becomes negative, CUR_VERT_OFFSET must be adjusted to a larger number,
* CUR_OFFSET must be adjusted to a point to the appropraite line in the cursor
* definitation and CUR_VERT_POSN must be saturated to zero.
*/
/* /*
* Hardware Cursor support. * Hardware Cursor support.
*/ */
static const u8 cursor_pixel_map[2] = { 0, 15 };
static const u8 cursor_color_map[2] = { 0, 0xff };
static const u8 cursor_bits_lookup[16] = { static const u8 cursor_bits_lookup[16] = {
0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54, 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
...@@ -36,90 +71,25 @@ static const u8 cursor_mask_lookup[16] = { ...@@ -36,90 +71,25 @@ static const u8 cursor_mask_lookup[16] = {
0xa8, 0x28, 0x88, 0x08, 0xa0, 0x20, 0x80, 0x00 0xa8, 0x28, 0x88, 0x08, 0xa0, 0x20, 0x80, 0x00
}; };
void aty_set_cursor_color(struct fb_info *info) int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
struct aty_cursor *c = par->cursor;
const u8 *pixel = cursor_pixel_map; /* ++Geert: Why?? */
const u8 *red = cursor_color_map;
const u8 *green = cursor_color_map;
const u8 *blue = cursor_color_map;
u32 fg_color, bg_color;
if (!c)
return;
#ifdef __sparc__
if (par->mmaped)
return;
#endif
fg_color = (u32) red[0] << 24;
fg_color |= (u32) green[0] << 16;
fg_color |= (u32) blue[0] << 8;
fg_color |= (u32) pixel[0];
bg_color = (u32) red[1] << 24;
bg_color |= (u32) green[1] << 16;
bg_color |= (u32) blue[1] << 8;
bg_color |= (u32) pixel[1];
wait_for_fifo(2, par);
aty_st_le32(CUR_CLR0, fg_color, par);
aty_st_le32(CUR_CLR1, bg_color, par);
}
void aty_set_cursor_shape(struct fb_info *info)
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
struct fb_cursor *cursor = &info->cursor;
struct aty_cursor *c = par->cursor;
u8 m, b;
u8 __iomem *ram;
int x, y;
if (!c)
return;
#ifdef __sparc__
if (par->mmaped)
return;
#endif
ram = c->ram;
for (y = 0; y < cursor->image.height; y++) {
for (x = 0; x < cursor->image.width >> 2; x++) {
m = c->mask[x][y];
b = c->bits[x][y];
fb_writeb(cursor_mask_lookup[m >> 4] |
cursor_bits_lookup[(b & m) >> 4], ram++);
fb_writeb(cursor_mask_lookup[m & 0x0f] |
cursor_bits_lookup[(b & m) & 0x0f],
ram++);
}
for (; x < 8; x++) {
fb_writeb(0xaa, ram++);
fb_writeb(0xaa, ram++);
}
}
fb_memset(ram, 0xaa, (64 - cursor->image.height) * 16);
}
static void aty_set_cursor(struct fb_info *info)
{ {
struct atyfb_par *par = (struct atyfb_par *) info->par; struct atyfb_par *par = (struct atyfb_par *) info->par;
struct fb_cursor *cursor = &info->cursor;
struct aty_cursor *c = par->cursor;
u16 xoff, yoff; u16 xoff, yoff;
int x, y; int x, y;
if (!c)
return;
#ifdef __sparc__ #ifdef __sparc__
if (par->mmaped) if (par->mmaped)
return; return -EPERM;
#endif #endif
if (par->asleep)
return -EPERM;
if (cursor->enable) { /* Hide cursor */
wait_for_fifo(1, par);
aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) & ~HWCURSOR_ENABLE, par);
/* set position */
if (cursor->set & FB_CUR_SETPOS) {
x = cursor->image.dx - cursor->hot.x - info->var.xoffset; x = cursor->image.dx - cursor->hot.x - info->var.xoffset;
if (x < 0) { if (x < 0) {
xoff = -x; xoff = -x;
...@@ -136,107 +106,118 @@ static void aty_set_cursor(struct fb_info *info) ...@@ -136,107 +106,118 @@ static void aty_set_cursor(struct fb_info *info)
yoff = 0; yoff = 0;
} }
/*
* In doublescan mode, the cursor location also needs to be
* doubled.
*/
if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
y<<=1;
wait_for_fifo(4, par); wait_for_fifo(4, par);
aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1), aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1), par);
par);
aty_st_le32(CUR_HORZ_VERT_OFF, aty_st_le32(CUR_HORZ_VERT_OFF,
((u32) (64 - cursor->image.height + yoff) << 16) | xoff, ((u32) (64 - cursor->image.height + yoff) << 16) | xoff,
par); par);
aty_st_le32(CUR_HORZ_VERT_POSN, ((u32) y << 16) | x, par); aty_st_le32(CUR_HORZ_VERT_POSN, ((u32) y << 16) | x, par);
aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
| HWCURSOR_ENABLE, par);
} else {
wait_for_fifo(1, par);
aty_st_le32(GEN_TEST_CNTL,
aty_ld_le32(GEN_TEST_CNTL,
par) & ~HWCURSOR_ENABLE, par);
} }
if (par->blitter_may_be_busy)
wait_for_idle(par);
}
int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) /* Set color map */
{ if (cursor->set & FB_CUR_SETCMAP) {
struct atyfb_par *par = (struct atyfb_par *) info->par; u32 fg_idx, bg_idx, fg, bg;
struct aty_cursor *c = par->cursor;
if (!c) fg_idx = cursor->image.fg_color;
return -1; bg_idx = cursor->image.bg_color;
#ifdef __sparc__ fg = (info->cmap.red[fg_idx] << 24) |
if (par->mmaped) (info->cmap.green[fg_idx] << 16) |
return 0; (info->cmap.blue[fg_idx] << 8) | 15;
#endif
bg = (info->cmap.red[bg_idx] << 24) |
(info->cmap.green[bg_idx] << 16) |
(info->cmap.blue[bg_idx] << 8);
wait_for_fifo(2, par);
aty_st_le32(CUR_CLR0, bg, par);
aty_st_le32(CUR_CLR1, fg, par);
}
aty_set_cursor(info); if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
cursor->image.dx = info->cursor.image.dx; u8 *src = (u8 *)cursor->image.data;
cursor->image.dy = info->cursor.image.dy; u8 *msk = (u8 *)cursor->mask;
u8 __iomem *dst = (u8 __iomem *)info->sprite.addr;
unsigned int width = (cursor->image.width + 7) >> 3;
unsigned int height = cursor->image.height;
unsigned int align = info->sprite.scan_align;
unsigned int i, j, offset;
u8 m, b;
// Clear cursor image with 1010101010...
fb_memset(dst, 0xaa, 1024);
offset = align - width*2;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
b = *src++;
m = *msk++;
switch (cursor->rop) {
case ROP_XOR:
// Upper 4 bits of mask data
fb_writeb(cursor_mask_lookup[m >> 4 ] |
cursor_bits_lookup[(b ^ m) >> 4], dst++);
// Lower 4 bits of mask
fb_writeb(cursor_mask_lookup[m & 0x0f ] |
cursor_bits_lookup[(b ^ m) & 0x0f], dst++);
break;
case ROP_COPY:
// Upper 4 bits of mask data
fb_writeb(cursor_mask_lookup[m >> 4 ] |
cursor_bits_lookup[(b & m) >> 4], dst++);
// Lower 4 bits of mask
fb_writeb(cursor_mask_lookup[m & 0x0f ] |
cursor_bits_lookup[(b & m) & 0x0f], dst++);
break;
}
}
dst += offset;
}
}
aty_set_cursor(info); if (cursor->enable) {
wait_for_fifo(1, par);
aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
| HWCURSOR_ENABLE, par);
}
return 0; return 0;
} }
struct aty_cursor *__init aty_init_cursor(struct fb_info *info) int __init aty_init_cursor(struct fb_info *info)
{ {
struct aty_cursor *cursor; unsigned long addr;
void __iomem *addr;
cursor = kmalloc(sizeof(struct aty_cursor), GFP_ATOMIC);
if (!cursor)
return NULL;
memset(cursor, 0, sizeof(*cursor));
info->fix.smem_len -= PAGE_SIZE; info->fix.smem_len -= PAGE_SIZE;
#ifdef __sparc__ #ifdef __sparc__
addr = (unsigned long) info->screen_base - 0x800000 + info->fix.smem_len; addr = (unsigned long) info->screen_base - 0x800000 + info->fix.smem_len;
cursor->ram = (u8 *) addr; info->sprite.addr = (u8 *) addr;
#else #else
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
addr = info->fix.smem_start - 0x800000 + info->fix.smem_len; addr = info->fix.smem_start - 0x800000 + info->fix.smem_len;
cursor->ram = (u8 *) ioremap(addr, 1024); info->sprite.addr = (u8 *) ioremap(addr, 1024);
#else #else
addr = info->screen_base + info->fix.smem_len; addr = (unsigned long) info->screen_base + info->fix.smem_len;
cursor->ram = addr; info->sprite.addr = (u8 *) addr;
#endif #endif
#endif #endif
if (!cursor->ram) { if (!info->sprite.addr)
kfree(cursor); return -ENXIO;
return NULL; info->sprite.size = PAGE_SIZE;
} info->sprite.scan_align = 16; /* Scratch pad 64 bytes wide */
return cursor; info->sprite.buf_align = 16; /* and 64 lines tall. */
} info->sprite.flags = FB_PIXMAP_IO;
int atyfb_set_font(struct fb_info *info, int width, int height) info->fbops->fb_cursor = atyfb_cursor;
{
struct atyfb_par *par = (struct atyfb_par *) info->par;
struct fb_cursor *cursor = &info->cursor;
struct aty_cursor *c = par->cursor;
int i, j;
if (c) {
if (!width || !height) {
width = 8;
height = 16;
}
cursor->hot.x = 0;
cursor->hot.y = 0;
cursor->image.width = width;
cursor->image.height = height;
memset(c->bits, 0xff, sizeof(c->bits));
memset(c->mask, 0, sizeof(c->mask));
for (i = 0, j = width; j >= 0; j -= 8, i++) { return 0;
c->mask[i][height - 2] =
(j >= 8) ? 0xff : (0xff << (8 - j));
c->mask[i][height - 1] =
(j >= 8) ? 0xff : (0xff << (8 - j));
}
aty_set_cursor_color(info);
aty_set_cursor_shape(info);
}
return 1;
} }
...@@ -121,7 +121,7 @@ static int aty_set_dac_514(const struct fb_info *info, ...@@ -121,7 +121,7 @@ static int aty_set_dac_514(const struct fb_info *info,
} }
static int aty_var_to_pll_514(const struct fb_info *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) u32 bpp, union aty_pll *pll)
{ {
/* /*
* FIXME: use real calculations instead of using fixed values from the old * FIXME: use real calculations instead of using fixed values from the old
...@@ -253,9 +253,9 @@ static int aty_set_dac_ATI68860_B(const struct fb_info *info, ...@@ -253,9 +253,9 @@ static int aty_set_dac_ATI68860_B(const struct fb_info *info,
temp = aty_ld_8(DAC_CNTL, par); temp = aty_ld_8(DAC_CNTL, par);
aty_st_8(DAC_CNTL, temp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, par); aty_st_8(DAC_CNTL, temp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, par);
if (info->fix.smem_len < MEM_SIZE_1M) if (info->fix.smem_len < ONE_MB)
mask = 0x04; mask = 0x04;
else if (info->fix.smem_len == MEM_SIZE_1M) else if (info->fix.smem_len == ONE_MB)
mask = 0x08; mask = 0x08;
else else
mask = 0x0C; mask = 0x0C;
...@@ -339,8 +339,8 @@ const struct aty_dac_ops aty_dac_att21c498 = { ...@@ -339,8 +339,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 *info, static int aty_var_to_pll_18818(const struct fb_info *info, u32 vclk_per,
u32 vclk_per, u8 bpp, union aty_pll *pll) u32 bpp, union aty_pll *pll)
{ {
u32 MHz100; /* in 0.01 MHz */ u32 MHz100; /* in 0.01 MHz */
u32 program_bits; u32 program_bits;
...@@ -495,8 +495,8 @@ const struct aty_pll_ops aty_pll_ati18818_1 = { ...@@ -495,8 +495,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 *info, static int aty_var_to_pll_1703(const struct fb_info *info, u32 vclk_per,
u32 vclk_per, u8 bpp, union aty_pll *pll) u32 bpp, union aty_pll *pll)
{ {
u32 mhz100; /* in 0.01 MHz */ u32 mhz100; /* in 0.01 MHz */
u32 program_bits; u32 program_bits;
...@@ -611,8 +611,8 @@ const struct aty_pll_ops aty_pll_stg1703 = { ...@@ -611,8 +611,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 *info, static int aty_var_to_pll_8398(const struct fb_info *info, u32 vclk_per,
u32 vclk_per, u8 bpp, union aty_pll *pll) u32 bpp, union aty_pll *pll)
{ {
u32 tempA, tempB, fOut, longMHz100, diff, preDiff; u32 tempA, tempB, fOut, longMHz100, diff, preDiff;
...@@ -736,7 +736,7 @@ const struct aty_pll_ops aty_pll_ch8398 = { ...@@ -736,7 +736,7 @@ const struct aty_pll_ops aty_pll_ch8398 = {
*/ */
static int aty_var_to_pll_408(const struct fb_info *info, u32 vclk_per, static int aty_var_to_pll_408(const struct fb_info *info, u32 vclk_per,
u8 bpp, union aty_pll *pll) u32 bpp, union aty_pll *pll)
{ {
u32 mhz100; /* in 0.01 MHz */ u32 mhz100; /* in 0.01 MHz */
u32 program_bits; u32 program_bits;
......
...@@ -148,15 +148,15 @@ static void reset_sdram(struct atyfb_par *par) ...@@ -148,15 +148,15 @@ static void reset_sdram(struct atyfb_par *par)
static void init_dll(struct atyfb_par *par) static void init_dll(struct atyfb_par *par)
{ {
// enable DLL // enable DLL
aty_st_pll(PLL_GEN_CNTL, aty_st_pll_ct(PLL_GEN_CNTL,
aty_ld_pll(PLL_GEN_CNTL, par) & 0x7f, aty_ld_pll_ct(PLL_GEN_CNTL, par) & 0x7f,
par); par);
// reset DLL // reset DLL
aty_st_pll(DLL_CNTL, 0x82, par); aty_st_pll_ct(DLL_CNTL, 0x82, par);
aty_st_pll(DLL_CNTL, 0xE2, par); aty_st_pll_ct(DLL_CNTL, 0xE2, par);
mdelay(5); mdelay(5);
aty_st_pll(DLL_CNTL, 0x82, par); aty_st_pll_ct(DLL_CNTL, 0x82, par);
mdelay(6); mdelay(6);
} }
...@@ -164,8 +164,8 @@ static void reset_clocks(struct atyfb_par *par, struct pll_ct *pll, ...@@ -164,8 +164,8 @@ static void reset_clocks(struct atyfb_par *par, struct pll_ct *pll,
int hsync_enb) int hsync_enb)
{ {
reset_gui(par); reset_gui(par);
aty_st_pll(MCLK_FB_DIV, pll->mclk_fb_div, par); aty_st_pll_ct(MCLK_FB_DIV, pll->mclk_fb_div, par);
aty_st_pll(SCLK_FB_DIV, pll->sclk_fb_div, par); aty_st_pll_ct(SCLK_FB_DIV, pll->sclk_fb_div, par);
mdelay(15); mdelay(15);
init_dll(par); init_dll(par);
...@@ -177,9 +177,9 @@ static void reset_clocks(struct atyfb_par *par, struct pll_ct *pll, ...@@ -177,9 +177,9 @@ static void reset_clocks(struct atyfb_par *par, struct pll_ct *pll,
aty_st_8(CRTC_GEN_CNTL+3, aty_st_8(CRTC_GEN_CNTL+3,
hsync_enb ? 0x00 : 0x04, par); hsync_enb ? 0x00 : 0x04, par);
aty_st_pll(SPLL_CNTL2, pll->spll_cntl2, par); aty_st_pll_ct(SPLL_CNTL2, pll->spll_cntl2, par);
aty_st_pll(PLL_GEN_CNTL, pll->pll_gen_cntl, par); aty_st_pll_ct(PLL_GEN_CNTL, pll->pll_gen_cntl, par);
aty_st_pll(PLL_VCLK_CNTL, pll->pll_vclk_cntl, par); aty_st_pll_ct(PLL_VCLK_CNTL, pll->pll_vclk_cntl, par);
} }
int atyfb_xl_init(struct fb_info *info) int atyfb_xl_init(struct fb_info *info)
...@@ -216,31 +216,31 @@ int atyfb_xl_init(struct fb_info *info) ...@@ -216,31 +216,31 @@ int atyfb_xl_init(struct fb_info *info)
if ((err = aty_pll_ct.var_to_pll(info, 39726, 8, &pll))) if ((err = aty_pll_ct.var_to_pll(info, 39726, 8, &pll)))
return err; return err;
aty_st_pll(LVDS_CNTL0, 0x00, par); aty_st_pll_ct(LVDS_CNTL0, 0x00, par);
aty_st_pll(DLL2_CNTL, card->dll2_cntl, par); aty_st_pll_ct(DLL2_CNTL, card->dll2_cntl, par);
aty_st_pll(V2PLL_CNTL, 0x10, par); aty_st_pll_ct(V2PLL_CNTL, 0x10, par);
aty_st_pll(MPLL_CNTL, MPLL_GAIN, par); aty_st_pll_ct(MPLL_CNTL, MPLL_GAIN, par);
aty_st_pll(VPLL_CNTL, VPLL_GAIN, par); aty_st_pll_ct(VPLL_CNTL, VPLL_GAIN, par);
aty_st_pll(PLL_VCLK_CNTL, 0x00, par); aty_st_pll_ct(PLL_VCLK_CNTL, 0x00, par);
aty_st_pll(VFC_CNTL, 0x1B, par); aty_st_pll_ct(VFC_CNTL, 0x1B, par);
aty_st_pll(PLL_REF_DIV, pll.ct.pll_ref_div, par); aty_st_pll_ct(PLL_REF_DIV, pll.ct.pll_ref_div, par);
aty_st_pll(PLL_EXT_CNTL, pll.ct.pll_ext_cntl, par); aty_st_pll_ct(PLL_EXT_CNTL, pll.ct.pll_ext_cntl, par);
aty_st_pll(SPLL_CNTL2, 0x03, par); aty_st_pll_ct(SPLL_CNTL2, 0x03, par);
aty_st_pll(PLL_GEN_CNTL, 0x44, par); aty_st_pll_ct(PLL_GEN_CNTL, 0x44, par);
reset_clocks(par, &pll.ct, 0); reset_clocks(par, &pll.ct, 0);
mdelay(10); mdelay(10);
aty_st_pll(VCLK_POST_DIV, 0x03, par); aty_st_pll_ct(VCLK_POST_DIV, 0x03, par);
aty_st_pll(VCLK0_FB_DIV, 0xDA, par); aty_st_pll_ct(VCLK0_FB_DIV, 0xDA, par);
aty_st_pll(VCLK_POST_DIV, 0x0F, par); aty_st_pll_ct(VCLK_POST_DIV, 0x0F, par);
aty_st_pll(VCLK1_FB_DIV, 0xF5, par); aty_st_pll_ct(VCLK1_FB_DIV, 0xF5, par);
aty_st_pll(VCLK_POST_DIV, 0x3F, par); aty_st_pll_ct(VCLK_POST_DIV, 0x3F, par);
aty_st_pll(PLL_EXT_CNTL, 0x40 | pll.ct.pll_ext_cntl, par); aty_st_pll_ct(PLL_EXT_CNTL, 0x40 | pll.ct.pll_ext_cntl, par);
aty_st_pll(VCLK2_FB_DIV, 0x00, par); aty_st_pll_ct(VCLK2_FB_DIV, 0x00, par);
aty_st_pll(VCLK_POST_DIV, 0xFF, par); aty_st_pll_ct(VCLK_POST_DIV, 0xFF, par);
aty_st_pll(PLL_EXT_CNTL, 0xC0 | pll.ct.pll_ext_cntl, par); aty_st_pll_ct(PLL_EXT_CNTL, 0xC0 | pll.ct.pll_ext_cntl, par);
aty_st_pll(VCLK3_FB_DIV, 0x00, par); aty_st_pll_ct(VCLK3_FB_DIV, 0x00, par);
aty_st_8(BUS_CNTL, 0x01, par); aty_st_8(BUS_CNTL, 0x01, par);
aty_st_le32(BUS_CNTL, card->bus_cntl | 0x08000000, par); aty_st_le32(BUS_CNTL, card->bus_cntl | 0x08000000, par);
...@@ -295,7 +295,7 @@ int atyfb_xl_init(struct fb_info *info) ...@@ -295,7 +295,7 @@ int atyfb_xl_init(struct fb_info *info)
aty_st_8(CRTC_GEN_CNTL+3, 0x04, par); aty_st_8(CRTC_GEN_CNTL+3, 0x04, par);
mdelay(10); mdelay(10);
aty_st_pll(PLL_YCLK_CNTL, 0x25, par); aty_st_pll_ct(PLL_YCLK_CNTL, 0x25, par);
aty_st_le16(CUSTOM_MACRO_CNTL, 0x0179, par); aty_st_le16(CUSTOM_MACRO_CNTL, 0x0179, par);
aty_st_le16(CUSTOM_MACRO_CNTL+2, 0x005E, par); aty_st_le16(CUSTOM_MACRO_CNTL+2, 0x005E, par);
...@@ -309,9 +309,9 @@ int atyfb_xl_init(struct fb_info *info) ...@@ -309,9 +309,9 @@ int atyfb_xl_init(struct fb_info *info)
aty_st_8(CONFIG_STAT0, 0xA0 | card->mem_type, par); aty_st_8(CONFIG_STAT0, 0xA0 | card->mem_type, par);
aty_st_pll(PLL_YCLK_CNTL, 0x01, par); aty_st_pll_ct(PLL_YCLK_CNTL, 0x01, par);
mdelay(15); mdelay(15);
aty_st_pll(PLL_YCLK_CNTL, card->pll_yclk_cntl, par); aty_st_pll_ct(PLL_YCLK_CNTL, card->pll_yclk_cntl, par);
mdelay(1); mdelay(1);
reset_clocks(par, &pll.ct, 0); reset_clocks(par, &pll.ct, 0);
......
This diff is collapsed.
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