diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-10-16 01:03:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-16 14:21:44 -0400 |
commit | b1ee26bab14886350ba12a5c10cbc0696ac679bf (patch) | |
tree | 18fff332492d5a989dde01864cfb3c524976209d /drivers/video/aty/radeon_base.c | |
parent | a6c0c37db654444dfce91cd75ad8a56bb15a0d25 (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.c | 22 |
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 | |||
1855 | static struct fb_ops radeonfb_ops = { | 1847 | static 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); |