diff options
Diffstat (limited to 'drivers/video/fbdev/aty')
-rw-r--r-- | drivers/video/fbdev/aty/atyfb.h | 12 | ||||
-rw-r--r-- | drivers/video/fbdev/aty/atyfb_base.c | 36 | ||||
-rw-r--r-- | drivers/video/fbdev/aty/mach64_accel.c | 32 |
3 files changed, 43 insertions, 37 deletions
diff --git a/drivers/video/fbdev/aty/atyfb.h b/drivers/video/fbdev/aty/atyfb.h index d09bab3bf224..e5a347c58180 100644 --- a/drivers/video/fbdev/aty/atyfb.h +++ b/drivers/video/fbdev/aty/atyfb.h @@ -147,6 +147,7 @@ struct atyfb_par { u16 pci_id; u32 accel_flags; int blitter_may_be_busy; + unsigned fifo_space; int asleep; int lock_blank; unsigned long res_start; @@ -346,10 +347,13 @@ extern int aty_init_cursor(struct fb_info *info); * Hardware acceleration */ -static inline void wait_for_fifo(u16 entries, const struct atyfb_par *par) +static inline void wait_for_fifo(u16 entries, struct atyfb_par *par) { - while ((aty_ld_le32(FIFO_STAT, par) & 0xffff) > - ((u32) (0x8000 >> entries))); + unsigned fifo_space = par->fifo_space; + while (entries > fifo_space) { + fifo_space = 16 - fls(aty_ld_le32(FIFO_STAT, par) & 0xffff); + } + par->fifo_space = fifo_space - entries; } static inline void wait_for_idle(struct atyfb_par *par) @@ -359,7 +363,7 @@ static inline void wait_for_idle(struct atyfb_par *par) par->blitter_may_be_busy = 0; } -extern void aty_reset_engine(const struct atyfb_par *par); +extern void aty_reset_engine(struct atyfb_par *par); extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info); void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index 05111e90f168..b6fe103df145 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -1480,24 +1480,28 @@ static int atyfb_set_par(struct fb_info *info) base = 0x2000; printk("debug atyfb: Mach64 non-shadow register values:"); for (i = 0; i < 256; i = i+4) { - if (i % 16 == 0) - printk("\ndebug atyfb: 0x%04X: ", base + i); - printk(" %08X", aty_ld_le32(i, par)); + if (i % 16 == 0) { + pr_cont("\n"); + printk("debug atyfb: 0x%04X: ", base + i); + } + pr_cont(" %08X", aty_ld_le32(i, par)); } - printk("\n\n"); + pr_cont("\n\n"); #ifdef CONFIG_FB_ATY_CT /* PLL registers */ base = 0x00; printk("debug atyfb: Mach64 PLL register values:"); for (i = 0; i < 64; i++) { - if (i % 16 == 0) - printk("\ndebug atyfb: 0x%02X: ", base + i); + if (i % 16 == 0) { + pr_cont("\n"); + printk("debug atyfb: 0x%02X: ", base + i); + } if (i % 4 == 0) - printk(" "); - printk("%02X", aty_ld_pll_ct(i, par)); + pr_cont(" "); + pr_cont("%02X", aty_ld_pll_ct(i, par)); } - printk("\n\n"); + pr_cont("\n\n"); #endif /* CONFIG_FB_ATY_CT */ #ifdef CONFIG_FB_ATY_GENERIC_LCD @@ -1509,19 +1513,19 @@ static int atyfb_set_par(struct fb_info *info) for (i = 0; i <= POWER_MANAGEMENT; i++) { if (i == EXT_VERT_STRETCH) continue; - printk("\ndebug atyfb: 0x%04X: ", + pr_cont("\ndebug atyfb: 0x%04X: ", lt_lcd_regs[i]); - printk(" %08X", aty_ld_lcd(i, par)); + pr_cont(" %08X", aty_ld_lcd(i, par)); } } else { for (i = 0; i < 64; i++) { if (i % 4 == 0) - printk("\ndebug atyfb: 0x%02X: ", + pr_cont("\ndebug atyfb: 0x%02X: ", base + i); - printk(" %08X", aty_ld_lcd(i, par)); + pr_cont(" %08X", aty_ld_lcd(i, par)); } } - printk("\n\n"); + pr_cont("\n\n"); } #endif /* CONFIG_FB_ATY_GENERIC_LCD */ } @@ -2597,8 +2601,8 @@ static int aty_init(struct fb_info *info) aty_ld_le32(DSP_ON_OFF, par), aty_ld_le32(CLOCK_CNTL, par)); for (i = 0; i < 40; i++) - printk(" %02x", aty_ld_pll_ct(i, par)); - printk("\n"); + pr_cont(" %02x", aty_ld_pll_ct(i, par)); + pr_cont("\n"); } #endif if (par->pll_ops->init_pll) diff --git a/drivers/video/fbdev/aty/mach64_accel.c b/drivers/video/fbdev/aty/mach64_accel.c index 2541a0e0de76..e4b2c89baee2 100644 --- a/drivers/video/fbdev/aty/mach64_accel.c +++ b/drivers/video/fbdev/aty/mach64_accel.c @@ -37,7 +37,7 @@ static u32 rotation24bpp(u32 dx, u32 direction) return ((rotation << 8) | DST_24_ROTATION_ENABLE); } -void aty_reset_engine(const struct atyfb_par *par) +void aty_reset_engine(struct atyfb_par *par) { /* reset engine */ aty_st_le32(GEN_TEST_CNTL, @@ -50,6 +50,8 @@ void aty_reset_engine(const struct atyfb_par *par) /* HOST errors */ aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_HOST_ERR_ACK | BUS_FIFO_ERR_ACK, par); + + par->fifo_space = 0; } static void reset_GTC_3D_engine(const struct atyfb_par *par) @@ -127,7 +129,7 @@ void aty_init_engine(struct atyfb_par *par, struct fb_info *info) /* set host attributes */ wait_for_fifo(13, par); - aty_st_le32(HOST_CNTL, 0, par); + aty_st_le32(HOST_CNTL, HOST_BYTE_ALIGN, par); /* set pattern attributes */ aty_st_le32(PAT_REG0, 0, par); @@ -233,7 +235,8 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) rotation = rotation24bpp(dx, direction); } - wait_for_fifo(4, par); + wait_for_fifo(5, par); + aty_st_le32(DP_PIX_WIDTH, par->crtc.dp_pix_width, par); aty_st_le32(DP_SRC, FRGD_SRC_BLIT, par); aty_st_le32(SRC_Y_X, (sx << 16) | sy, par); aty_st_le32(SRC_HEIGHT1_WIDTH1, (width << 16) | area->height, par); @@ -269,7 +272,8 @@ void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) rotation = rotation24bpp(dx, DST_X_LEFT_TO_RIGHT); } - wait_for_fifo(3, par); + wait_for_fifo(4, par); + aty_st_le32(DP_PIX_WIDTH, par->crtc.dp_pix_width, par); aty_st_le32(DP_FRGD_CLR, color, par); aty_st_le32(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE, @@ -284,7 +288,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) { 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; + u32 pix_width, rotation = 0, src, mix; if (par->asleep) return; @@ -296,8 +300,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) return; } - pix_width = pix_width_save = aty_ld_le32(DP_PIX_WIDTH, par); - host_cntl = aty_ld_le32(HOST_CNTL, par) | HOST_BYTE_ALIGN; + pix_width = par->crtc.dp_pix_width; switch (image->depth) { case 1: @@ -345,7 +348,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) * 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) + if (image->depth == 1 && M64_HAS(HW_TRIPLE) && image->width % 8 == 0) pix_width |= DP_HOST_TRIPLE_EN; } @@ -370,19 +373,18 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) mix = FRGD_MIX_D_XOR_S | BKGD_MIX_D; } - wait_for_fifo(6, par); - aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF, par); + wait_for_fifo(5, 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(HOST_CNTL, HOST_BYTE_ALIGN, 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)) { + if (image->depth == 1 && 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; @@ -415,7 +417,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) } } wait_for_fifo(1, par); - aty_st_le32(HOST_DATA0, hostdword, par); + aty_st_le32(HOST_DATA0, le32_to_cpu(hostdword), par); } } else { u32 *pbitmap, dwords = (src_bytes + 3) / 4; @@ -424,8 +426,4 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) aty_st_le32(HOST_DATA0, get_unaligned_le32(pbitmap), par); } } - - /* restore pix_width */ - wait_for_fifo(1, par); - aty_st_le32(DP_PIX_WIDTH, pix_width_save, par); } |