aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2007-07-17 07:05:46 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-17 13:23:13 -0400
commita58d67ce7d648f3a2512d6d044b5eab0c6f71253 (patch)
treec8f5d53350aaad18038c8e8329d882b31aeb7373 /drivers
parent08a498de79727d63a011f2583e9aba4d3083c3a0 (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')
-rw-r--r--drivers/video/pm3fb.c241
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 */
189static 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
205static 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
360static 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 */
189static void pm3fb_write_mode(struct fb_info *info) 421static 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