From b1ee26bab14886350ba12a5c10cbc0696ac679bf Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 15 Oct 2008 22:03:46 -0700 Subject: radeonfb: accelerate imageblit and other improvements Implement support for HW color expansion of 1bpp images, along with some improvements to the FIFO handling and other accel operations. The offset fixup code is now unnecessary as the fbcon core will call our set_par upon switch back from KD_GRAPHICS before anything else happens. I removed it as it would slow down accel operations. The fifo wait has been improved to avoid hitting the HW register as often, and the various accel ops are now performing better caching of register values. Overall, this improve accel performances. The imageblit acceleration does result in a small overall regression in performances on some machines (on the order of 5% on some x86), probably becaus the SW path provides a better bus utilisation, but I decided to ingnore that as the performances is still very good, and on the other hand, some machines such as some sparc64 get a 3 fold performance improvement. Signed-off-by: Benjamin Herrenschmidt Acked-by: David S. Miller Cc: Krzysztof Halasa Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/aty/radeon_base.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'drivers/video/aty/radeon_base.c') diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index d0f1a7fc2c9d..9a5821c65ebf 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -852,7 +852,6 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var, if (rinfo->asleep) return 0; - radeon_fifo_wait(2); OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel / 8) & ~7); return 0; @@ -882,7 +881,6 @@ static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd, if (rc) return rc; - radeon_fifo_wait(2); if (value & 0x01) { tmp = INREG(LVDS_GEN_CNTL); @@ -940,7 +938,7 @@ int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch) if (rinfo->lock_blank) return 0; - radeon_engine_idle(); + radeon_engine_idle(rinfo); val = INREG(CRTC_EXT_CNTL); val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | @@ -1048,7 +1046,7 @@ static int radeonfb_blank (int blank, struct fb_info *info) if (rinfo->asleep) return 0; - + return radeon_screen_blank(rinfo, blank, 0); } @@ -1074,8 +1072,6 @@ static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green, pindex = regno; if (!rinfo->asleep) { - radeon_fifo_wait(9); - if (rinfo->bpp == 16) { pindex = regno * 8; @@ -1244,8 +1240,6 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg { int i; - radeon_fifo_wait(20); - /* Workaround from XFree */ if (rinfo->is_mobility) { /* A temporal workaround for the occational blanking on certain laptop @@ -1341,7 +1335,7 @@ static void radeon_lvds_timer_func(unsigned long data) { struct radeonfb_info *rinfo = (struct radeonfb_info *)data; - radeon_engine_idle(); + radeon_engine_idle(rinfo); OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl); } @@ -1359,10 +1353,11 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode, if (nomodeset) return; + radeon_engine_idle(rinfo); + if (!regs_only) radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0); - radeon_fifo_wait(31); for (i=0; i<10; i++) OUTREG(common_regs[i].reg, common_regs[i].val); @@ -1390,7 +1385,6 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode, radeon_write_pll_regs(rinfo, mode); if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) { - radeon_fifo_wait(10); OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp); OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp); OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid); @@ -1405,7 +1399,6 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode, if (!regs_only) radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0); - radeon_fifo_wait(2); OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl); return; @@ -1556,7 +1549,7 @@ static int radeonfb_set_par(struct fb_info *info) /* We always want engine to be idle on a mode switch, even * if we won't actually change the mode */ - radeon_engine_idle(); + radeon_engine_idle(rinfo); hSyncStart = mode->xres + mode->right_margin; hSyncEnd = hSyncStart + mode->hsync_len; @@ -1851,7 +1844,6 @@ static int radeonfb_set_par(struct fb_info *info) return 0; } - static struct fb_ops radeonfb_ops = { .owner = THIS_MODULE, .fb_check_var = radeonfb_check_var, @@ -1875,6 +1867,7 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) info->par = rinfo; info->pseudo_palette = rinfo->pseudo_palette; info->flags = FBINFO_DEFAULT + | FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_XPAN @@ -2006,7 +1999,6 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo) u32 tom = INREG(NB_TOM); tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); - radeon_fifo_wait(6); OUTREG(MC_FB_LOCATION, tom); OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); -- cgit v1.2.3