aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/aty/radeon_base.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-16 01:03:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-16 14:21:44 -0400
commitb1ee26bab14886350ba12a5c10cbc0696ac679bf (patch)
tree18fff332492d5a989dde01864cfb3c524976209d /drivers/video/aty/radeon_base.c
parenta6c0c37db654444dfce91cd75ad8a56bb15a0d25 (diff)
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 <benh@kernel.crashing.org> Acked-by: David S. Miller <davem@davemloft.net> Cc: Krzysztof Halasa <khc@pm.waw.pl> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/aty/radeon_base.c')
-rw-r--r--drivers/video/aty/radeon_base.c22
1 files changed, 7 insertions, 15 deletions
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,
852 if (rinfo->asleep) 852 if (rinfo->asleep)
853 return 0; 853 return 0;
854 854
855 radeon_fifo_wait(2);
856 OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset) 855 OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
857 * var->bits_per_pixel / 8) & ~7); 856 * var->bits_per_pixel / 8) & ~7);
858 return 0; 857 return 0;
@@ -882,7 +881,6 @@ static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd,
882 if (rc) 881 if (rc)
883 return rc; 882 return rc;
884 883
885 radeon_fifo_wait(2);
886 if (value & 0x01) { 884 if (value & 0x01) {
887 tmp = INREG(LVDS_GEN_CNTL); 885 tmp = INREG(LVDS_GEN_CNTL);
888 886
@@ -940,7 +938,7 @@ int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch)
940 if (rinfo->lock_blank) 938 if (rinfo->lock_blank)
941 return 0; 939 return 0;
942 940
943 radeon_engine_idle(); 941 radeon_engine_idle(rinfo);
944 942
945 val = INREG(CRTC_EXT_CNTL); 943 val = INREG(CRTC_EXT_CNTL);
946 val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | 944 val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
@@ -1048,7 +1046,7 @@ static int radeonfb_blank (int blank, struct fb_info *info)
1048 1046
1049 if (rinfo->asleep) 1047 if (rinfo->asleep)
1050 return 0; 1048 return 0;
1051 1049
1052 return radeon_screen_blank(rinfo, blank, 0); 1050 return radeon_screen_blank(rinfo, blank, 0);
1053} 1051}
1054 1052
@@ -1074,8 +1072,6 @@ static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
1074 pindex = regno; 1072 pindex = regno;
1075 1073
1076 if (!rinfo->asleep) { 1074 if (!rinfo->asleep) {
1077 radeon_fifo_wait(9);
1078
1079 if (rinfo->bpp == 16) { 1075 if (rinfo->bpp == 16) {
1080 pindex = regno * 8; 1076 pindex = regno * 8;
1081 1077
@@ -1244,8 +1240,6 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
1244{ 1240{
1245 int i; 1241 int i;
1246 1242
1247 radeon_fifo_wait(20);
1248
1249 /* Workaround from XFree */ 1243 /* Workaround from XFree */
1250 if (rinfo->is_mobility) { 1244 if (rinfo->is_mobility) {
1251 /* A temporal workaround for the occational blanking on certain laptop 1245 /* A temporal workaround for the occational blanking on certain laptop
@@ -1341,7 +1335,7 @@ static void radeon_lvds_timer_func(unsigned long data)
1341{ 1335{
1342 struct radeonfb_info *rinfo = (struct radeonfb_info *)data; 1336 struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
1343 1337
1344 radeon_engine_idle(); 1338 radeon_engine_idle(rinfo);
1345 1339
1346 OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl); 1340 OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl);
1347} 1341}
@@ -1359,10 +1353,11 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
1359 if (nomodeset) 1353 if (nomodeset)
1360 return; 1354 return;
1361 1355
1356 radeon_engine_idle(rinfo);
1357
1362 if (!regs_only) 1358 if (!regs_only)
1363 radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0); 1359 radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0);
1364 1360
1365 radeon_fifo_wait(31);
1366 for (i=0; i<10; i++) 1361 for (i=0; i<10; i++)
1367 OUTREG(common_regs[i].reg, common_regs[i].val); 1362 OUTREG(common_regs[i].reg, common_regs[i].val);
1368 1363
@@ -1390,7 +1385,6 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
1390 radeon_write_pll_regs(rinfo, mode); 1385 radeon_write_pll_regs(rinfo, mode);
1391 1386
1392 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) { 1387 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
1393 radeon_fifo_wait(10);
1394 OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp); 1388 OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
1395 OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp); 1389 OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
1396 OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid); 1390 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,
1405 if (!regs_only) 1399 if (!regs_only)
1406 radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0); 1400 radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0);
1407 1401
1408 radeon_fifo_wait(2);
1409 OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl); 1402 OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
1410 1403
1411 return; 1404 return;
@@ -1556,7 +1549,7 @@ static int radeonfb_set_par(struct fb_info *info)
1556 /* We always want engine to be idle on a mode switch, even 1549 /* We always want engine to be idle on a mode switch, even
1557 * if we won't actually change the mode 1550 * if we won't actually change the mode
1558 */ 1551 */
1559 radeon_engine_idle(); 1552 radeon_engine_idle(rinfo);
1560 1553
1561 hSyncStart = mode->xres + mode->right_margin; 1554 hSyncStart = mode->xres + mode->right_margin;
1562 hSyncEnd = hSyncStart + mode->hsync_len; 1555 hSyncEnd = hSyncStart + mode->hsync_len;
@@ -1851,7 +1844,6 @@ static int radeonfb_set_par(struct fb_info *info)
1851 return 0; 1844 return 0;
1852} 1845}
1853 1846
1854
1855static struct fb_ops radeonfb_ops = { 1847static struct fb_ops radeonfb_ops = {
1856 .owner = THIS_MODULE, 1848 .owner = THIS_MODULE,
1857 .fb_check_var = radeonfb_check_var, 1849 .fb_check_var = radeonfb_check_var,
@@ -1875,6 +1867,7 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
1875 info->par = rinfo; 1867 info->par = rinfo;
1876 info->pseudo_palette = rinfo->pseudo_palette; 1868 info->pseudo_palette = rinfo->pseudo_palette;
1877 info->flags = FBINFO_DEFAULT 1869 info->flags = FBINFO_DEFAULT
1870 | FBINFO_HWACCEL_IMAGEBLIT
1878 | FBINFO_HWACCEL_COPYAREA 1871 | FBINFO_HWACCEL_COPYAREA
1879 | FBINFO_HWACCEL_FILLRECT 1872 | FBINFO_HWACCEL_FILLRECT
1880 | FBINFO_HWACCEL_XPAN 1873 | FBINFO_HWACCEL_XPAN
@@ -2006,7 +1999,6 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
2006 u32 tom = INREG(NB_TOM); 1999 u32 tom = INREG(NB_TOM);
2007 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); 2000 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
2008 2001
2009 radeon_fifo_wait(6);
2010 OUTREG(MC_FB_LOCATION, tom); 2002 OUTREG(MC_FB_LOCATION, tom);
2011 OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); 2003 OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
2012 OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); 2004 OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);