diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2007-07-17 07:05:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-17 13:23:13 -0400 |
commit | a58d67ce7d648f3a2512d6d044b5eab0c6f71253 (patch) | |
tree | c8f5d53350aaad18038c8e8329d882b31aeb7373 /drivers/video/pm3fb.c | |
parent | 08a498de79727d63a011f2583e9aba4d3083c3a0 (diff) |
pm3fb: fillrect acceleration
This is a port of accelerated fillrect function from the 2.4 kernel driver.
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Antonino Daplas <adaplas@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/pm3fb.c')
-rw-r--r-- | drivers/video/pm3fb.c | 241 |
1 files changed, 238 insertions, 3 deletions
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c index b52e883f0a52..a9b841c6f356 100644 --- a/drivers/video/pm3fb.c +++ b/drivers/video/pm3fb.c | |||
@@ -77,7 +77,7 @@ static struct fb_fix_screeninfo pm3fb_fix __devinitdata = { | |||
77 | .xpanstep = 1, | 77 | .xpanstep = 1, |
78 | .ypanstep = 1, | 78 | .ypanstep = 1, |
79 | .ywrapstep = 0, | 79 | .ywrapstep = 0, |
80 | .accel = FB_ACCEL_NONE, | 80 | .accel = FB_ACCEL_3DLABS_PERMEDIA3, |
81 | }; | 81 | }; |
82 | 82 | ||
83 | /* | 83 | /* |
@@ -185,6 +185,238 @@ static inline int pm3fb_shift_bpp(unsigned bpp, int v) | |||
185 | return 0; | 185 | return 0; |
186 | } | 186 | } |
187 | 187 | ||
188 | /* acceleration */ | ||
189 | static int pm3fb_sync(struct fb_info *info) | ||
190 | { | ||
191 | struct pm3_par *par = info->par; | ||
192 | |||
193 | PM3_WAIT(par, 2); | ||
194 | PM3_WRITE_REG(par, PM3FilterMode, PM3FilterModeSync); | ||
195 | PM3_WRITE_REG(par, PM3Sync, 0); | ||
196 | mb(); | ||
197 | do { | ||
198 | while ((PM3_READ_REG(par, PM3OutFIFOWords)) == 0); | ||
199 | rmb(); | ||
200 | } while ((PM3_READ_REG(par, PM3OutputFifo)) != PM3Sync_Tag); | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static void pm3fb_init_engine(struct fb_info *info) | ||
206 | { | ||
207 | struct pm3_par *par = info->par; | ||
208 | const u32 width = (info->var.xres_virtual + 7) & ~7; | ||
209 | |||
210 | PM3_WAIT(par, 50); | ||
211 | PM3_WRITE_REG(par, PM3FilterMode, PM3FilterModeSync); | ||
212 | PM3_WRITE_REG(par, PM3StatisticMode, 0x0); | ||
213 | PM3_WRITE_REG(par, PM3DeltaMode, 0x0); | ||
214 | PM3_WRITE_REG(par, PM3RasterizerMode, 0x0); | ||
215 | PM3_WRITE_REG(par, PM3ScissorMode, 0x0); | ||
216 | PM3_WRITE_REG(par, PM3LineStippleMode, 0x0); | ||
217 | PM3_WRITE_REG(par, PM3AreaStippleMode, 0x0); | ||
218 | PM3_WRITE_REG(par, PM3GIDMode, 0x0); | ||
219 | PM3_WRITE_REG(par, PM3DepthMode, 0x0); | ||
220 | PM3_WRITE_REG(par, PM3StencilMode, 0x0); | ||
221 | PM3_WRITE_REG(par, PM3StencilData, 0x0); | ||
222 | PM3_WRITE_REG(par, PM3ColorDDAMode, 0x0); | ||
223 | PM3_WRITE_REG(par, PM3TextureCoordMode, 0x0); | ||
224 | PM3_WRITE_REG(par, PM3TextureIndexMode0, 0x0); | ||
225 | PM3_WRITE_REG(par, PM3TextureIndexMode1, 0x0); | ||
226 | PM3_WRITE_REG(par, PM3TextureReadMode, 0x0); | ||
227 | PM3_WRITE_REG(par, PM3LUTMode, 0x0); | ||
228 | PM3_WRITE_REG(par, PM3TextureFilterMode, 0x0); | ||
229 | PM3_WRITE_REG(par, PM3TextureCompositeMode, 0x0); | ||
230 | PM3_WRITE_REG(par, PM3TextureApplicationMode, 0x0); | ||
231 | PM3_WRITE_REG(par, PM3TextureCompositeColorMode1, 0x0); | ||
232 | PM3_WRITE_REG(par, PM3TextureCompositeAlphaMode1, 0x0); | ||
233 | PM3_WRITE_REG(par, PM3TextureCompositeColorMode0, 0x0); | ||
234 | PM3_WRITE_REG(par, PM3TextureCompositeAlphaMode0, 0x0); | ||
235 | PM3_WRITE_REG(par, PM3FogMode, 0x0); | ||
236 | PM3_WRITE_REG(par, PM3ChromaTestMode, 0x0); | ||
237 | PM3_WRITE_REG(par, PM3AlphaTestMode, 0x0); | ||
238 | PM3_WRITE_REG(par, PM3AntialiasMode, 0x0); | ||
239 | PM3_WRITE_REG(par, PM3YUVMode, 0x0); | ||
240 | PM3_WRITE_REG(par, PM3AlphaBlendColorMode, 0x0); | ||
241 | PM3_WRITE_REG(par, PM3AlphaBlendAlphaMode, 0x0); | ||
242 | PM3_WRITE_REG(par, PM3DitherMode, 0x0); | ||
243 | PM3_WRITE_REG(par, PM3LogicalOpMode, 0x0); | ||
244 | PM3_WRITE_REG(par, PM3RouterMode, 0x0); | ||
245 | PM3_WRITE_REG(par, PM3Window, 0x0); | ||
246 | |||
247 | PM3_WRITE_REG(par, PM3Config2D, 0x0); | ||
248 | |||
249 | PM3_WRITE_REG(par, PM3SpanColorMask, 0xffffffff); | ||
250 | |||
251 | PM3_WRITE_REG(par, PM3XBias, 0x0); | ||
252 | PM3_WRITE_REG(par, PM3YBias, 0x0); | ||
253 | PM3_WRITE_REG(par, PM3DeltaControl, 0x0); | ||
254 | |||
255 | PM3_WRITE_REG(par, PM3BitMaskPattern, 0xffffffff); | ||
256 | |||
257 | PM3_WRITE_REG(par, PM3FBDestReadEnables, | ||
258 | PM3FBDestReadEnables_E(0xff) | | ||
259 | PM3FBDestReadEnables_R(0xff) | | ||
260 | PM3FBDestReadEnables_ReferenceAlpha(0xff)); | ||
261 | PM3_WRITE_REG(par, PM3FBDestReadBufferAddr0, 0x0); | ||
262 | PM3_WRITE_REG(par, PM3FBDestReadBufferOffset0, 0x0); | ||
263 | PM3_WRITE_REG(par, PM3FBDestReadBufferWidth0, | ||
264 | PM3FBDestReadBufferWidth_Width(width)); | ||
265 | |||
266 | PM3_WRITE_REG(par, PM3FBDestReadMode, | ||
267 | PM3FBDestReadMode_ReadEnable | | ||
268 | PM3FBDestReadMode_Enable0); | ||
269 | PM3_WRITE_REG(par, PM3FBSourceReadBufferAddr, 0x0); | ||
270 | PM3_WRITE_REG(par, PM3FBSourceReadBufferOffset, 0x0); | ||
271 | PM3_WRITE_REG(par, PM3FBSourceReadBufferWidth, | ||
272 | PM3FBSourceReadBufferWidth_Width(width)); | ||
273 | PM3_WRITE_REG(par, PM3FBSourceReadMode, | ||
274 | PM3FBSourceReadMode_Blocking | | ||
275 | PM3FBSourceReadMode_ReadEnable); | ||
276 | |||
277 | PM3_WAIT(par, 2); | ||
278 | { | ||
279 | unsigned long rm = 1; | ||
280 | switch (info->var.bits_per_pixel) { | ||
281 | case 8: | ||
282 | PM3_WRITE_REG(par, PM3PixelSize, | ||
283 | PM3PixelSize_GLOBAL_8BIT); | ||
284 | break; | ||
285 | case 16: | ||
286 | PM3_WRITE_REG(par, PM3PixelSize, | ||
287 | PM3PixelSize_GLOBAL_16BIT); | ||
288 | break; | ||
289 | case 32: | ||
290 | PM3_WRITE_REG(par, PM3PixelSize, | ||
291 | PM3PixelSize_GLOBAL_32BIT); | ||
292 | break; | ||
293 | default: | ||
294 | DPRINTK(1, "Unsupported depth %d\n", | ||
295 | info->var.bits_per_pixel); | ||
296 | break; | ||
297 | } | ||
298 | PM3_WRITE_REG(par, PM3RasterizerMode, rm); | ||
299 | } | ||
300 | |||
301 | PM3_WAIT(par, 20); | ||
302 | PM3_WRITE_REG(par, PM3FBSoftwareWriteMask, 0xffffffff); | ||
303 | PM3_WRITE_REG(par, PM3FBHardwareWriteMask, 0xffffffff); | ||
304 | PM3_WRITE_REG(par, PM3FBWriteMode, | ||
305 | PM3FBWriteMode_WriteEnable | | ||
306 | PM3FBWriteMode_OpaqueSpan | | ||
307 | PM3FBWriteMode_Enable0); | ||
308 | PM3_WRITE_REG(par, PM3FBWriteBufferAddr0, 0x0); | ||
309 | PM3_WRITE_REG(par, PM3FBWriteBufferOffset0, 0x0); | ||
310 | PM3_WRITE_REG(par, PM3FBWriteBufferWidth0, | ||
311 | PM3FBWriteBufferWidth_Width(width)); | ||
312 | |||
313 | PM3_WRITE_REG(par, PM3SizeOfFramebuffer, 0x0); | ||
314 | { | ||
315 | /* size in lines of FB */ | ||
316 | unsigned long sofb = info->screen_size / | ||
317 | info->fix.line_length; | ||
318 | if (sofb > 4095) | ||
319 | PM3_WRITE_REG(par, PM3SizeOfFramebuffer, 4095); | ||
320 | else | ||
321 | PM3_WRITE_REG(par, PM3SizeOfFramebuffer, sofb); | ||
322 | |||
323 | switch (info->var.bits_per_pixel) { | ||
324 | case 8: | ||
325 | PM3_WRITE_REG(par, PM3DitherMode, | ||
326 | (1 << 10) | (2 << 3)); | ||
327 | break; | ||
328 | case 16: | ||
329 | PM3_WRITE_REG(par, PM3DitherMode, | ||
330 | (1 << 10) | (1 << 3)); | ||
331 | break; | ||
332 | case 32: | ||
333 | PM3_WRITE_REG(par, PM3DitherMode, | ||
334 | (1 << 10) | (0 << 3)); | ||
335 | break; | ||
336 | default: | ||
337 | DPRINTK(1, "Unsupported depth %d\n", | ||
338 | info->current_par->depth); | ||
339 | break; | ||
340 | } | ||
341 | } | ||
342 | |||
343 | PM3_WRITE_REG(par, PM3dXDom, 0x0); | ||
344 | PM3_WRITE_REG(par, PM3dXSub, 0x0); | ||
345 | PM3_WRITE_REG(par, PM3dY, (1 << 16)); | ||
346 | PM3_WRITE_REG(par, PM3StartXDom, 0x0); | ||
347 | PM3_WRITE_REG(par, PM3StartXSub, 0x0); | ||
348 | PM3_WRITE_REG(par, PM3StartY, 0x0); | ||
349 | PM3_WRITE_REG(par, PM3Count, 0x0); | ||
350 | |||
351 | /* Disable LocalBuffer. better safe than sorry */ | ||
352 | PM3_WRITE_REG(par, PM3LBDestReadMode, 0x0); | ||
353 | PM3_WRITE_REG(par, PM3LBDestReadEnables, 0x0); | ||
354 | PM3_WRITE_REG(par, PM3LBSourceReadMode, 0x0); | ||
355 | PM3_WRITE_REG(par, PM3LBWriteMode, 0x0); | ||
356 | |||
357 | pm3fb_sync(info); | ||
358 | } | ||
359 | |||
360 | static void pm3fb_fillrect (struct fb_info *info, | ||
361 | const struct fb_fillrect *region) | ||
362 | { | ||
363 | struct pm3_par *par = info->par; | ||
364 | struct fb_fillrect modded; | ||
365 | int vxres, vyres; | ||
366 | u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ? | ||
367 | ((u32*)info->pseudo_palette)[region->color] : region->color; | ||
368 | |||
369 | if (info->state != FBINFO_STATE_RUNNING) | ||
370 | return; | ||
371 | if ((info->flags & FBINFO_HWACCEL_DISABLED) || | ||
372 | region->rop != ROP_COPY ) { | ||
373 | cfb_fillrect(info, region); | ||
374 | return; | ||
375 | } | ||
376 | |||
377 | vxres = info->var.xres_virtual; | ||
378 | vyres = info->var.yres_virtual; | ||
379 | |||
380 | memcpy(&modded, region, sizeof(struct fb_fillrect)); | ||
381 | |||
382 | if(!modded.width || !modded.height || | ||
383 | modded.dx >= vxres || modded.dy >= vyres) | ||
384 | return; | ||
385 | |||
386 | if(modded.dx + modded.width > vxres) | ||
387 | modded.width = vxres - modded.dx; | ||
388 | if(modded.dy + modded.height > vyres) | ||
389 | modded.height = vyres - modded.dy; | ||
390 | |||
391 | if(info->var.bits_per_pixel == 8) | ||
392 | color |= color << 8; | ||
393 | if(info->var.bits_per_pixel <= 16) | ||
394 | color |= color << 16; | ||
395 | |||
396 | PM3_WAIT(par, 4); | ||
397 | |||
398 | PM3_WRITE_REG(par, PM3Config2D, | ||
399 | PM3Config2D_UseConstantSource | | ||
400 | PM3Config2D_ForegroundROPEnable | | ||
401 | (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */ | ||
402 | PM3Config2D_FBWriteEnable); | ||
403 | |||
404 | PM3_WRITE_REG(par, PM3ForegroundColor, color); | ||
405 | |||
406 | PM3_WRITE_REG(par, PM3RectanglePosition, | ||
407 | (PM3RectanglePosition_XOffset(modded.dx)) | | ||
408 | (PM3RectanglePosition_YOffset(modded.dy))); | ||
409 | |||
410 | PM3_WRITE_REG(par, PM3Render2D, | ||
411 | PM3Render2D_XPositive | | ||
412 | PM3Render2D_YPositive | | ||
413 | PM3Render2D_Operation_Normal | | ||
414 | PM3Render2D_SpanOperation | | ||
415 | (PM3Render2D_Width(modded.width)) | | ||
416 | (PM3Render2D_Height(modded.height))); | ||
417 | } | ||
418 | /* end of acceleration functions */ | ||
419 | |||
188 | /* write the mode to registers */ | 420 | /* write the mode to registers */ |
189 | static void pm3fb_write_mode(struct fb_info *info) | 421 | static void pm3fb_write_mode(struct fb_info *info) |
190 | { | 422 | { |
@@ -528,6 +760,7 @@ static int pm3fb_set_par(struct fb_info *info) | |||
528 | pm3fb_clear_colormap(par, 0, 0, 0); | 760 | pm3fb_clear_colormap(par, 0, 0, 0); |
529 | PM3_WRITE_DAC_REG(par, PM3RD_CursorMode, | 761 | PM3_WRITE_DAC_REG(par, PM3RD_CursorMode, |
530 | PM3RD_CursorMode_CURSOR_DISABLE); | 762 | PM3RD_CursorMode_CURSOR_DISABLE); |
763 | pm3fb_init_engine(info); | ||
531 | pm3fb_write_mode(info); | 764 | pm3fb_write_mode(info); |
532 | return 0; | 765 | return 0; |
533 | } | 766 | } |
@@ -675,10 +908,11 @@ static struct fb_ops pm3fb_ops = { | |||
675 | .fb_set_par = pm3fb_set_par, | 908 | .fb_set_par = pm3fb_set_par, |
676 | .fb_setcolreg = pm3fb_setcolreg, | 909 | .fb_setcolreg = pm3fb_setcolreg, |
677 | .fb_pan_display = pm3fb_pan_display, | 910 | .fb_pan_display = pm3fb_pan_display, |
678 | .fb_fillrect = cfb_fillrect, | 911 | .fb_fillrect = pm3fb_fillrect, |
679 | .fb_copyarea = cfb_copyarea, | 912 | .fb_copyarea = cfb_copyarea, |
680 | .fb_imageblit = cfb_imageblit, | 913 | .fb_imageblit = cfb_imageblit, |
681 | .fb_blank = pm3fb_blank, | 914 | .fb_blank = pm3fb_blank, |
915 | .fb_sync = pm3fb_sync, | ||
682 | }; | 916 | }; |
683 | 917 | ||
684 | /* ------------------------------------------------------------------------- */ | 918 | /* ------------------------------------------------------------------------- */ |
@@ -847,7 +1081,8 @@ static int __devinit pm3fb_probe(struct pci_dev *dev, | |||
847 | 1081 | ||
848 | info->fix = pm3fb_fix; | 1082 | info->fix = pm3fb_fix; |
849 | info->pseudo_palette = par->palette; | 1083 | info->pseudo_palette = par->palette; |
850 | info->flags = FBINFO_DEFAULT;/* | FBINFO_HWACCEL_YPAN;*/ | 1084 | info->flags = FBINFO_DEFAULT | |
1085 | FBINFO_HWACCEL_FILLRECT;/* | FBINFO_HWACCEL_YPAN;*/ | ||
851 | 1086 | ||
852 | /* | 1087 | /* |
853 | * This should give a reasonable default video mode. The following is | 1088 | * This should give a reasonable default video mode. The following is |