aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/w100fb.c
diff options
context:
space:
mode:
authorAlberto Mardegan <mardy@users.sourceforge.net>2006-03-31 05:31:46 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-31 15:19:00 -0500
commit9b0e1c5dd2941aec566047e10a5cc929ca7f7d4f (patch)
tree5d21dda4ee4b36f3f2247558190e12087a58070d /drivers/video/w100fb.c
parent1a37d5f51020b9967d4b4094f6d627d0873a6469 (diff)
[PATCH] w100fb: Add acceleration support to ATI Imageon
Add acceleration support in w100fb.c (i.e. ATI Imageons) for the copyarea and fillrect operations. Signed-off-by: Alberto Mardegan <mardy@users.sourceforge.net> Signed-off-by: Antonino Daplas <adaplas@pol.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/video/w100fb.c')
-rw-r--r--drivers/video/w100fb.c162
1 files changed, 158 insertions, 4 deletions
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index f6e24ee85f07..5fc86ea20692 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -4,8 +4,9 @@
4 * Frame Buffer Device for ATI Imageon w100 (Wallaby) 4 * Frame Buffer Device for ATI Imageon w100 (Wallaby)
5 * 5 *
6 * Copyright (C) 2002, ATI Corp. 6 * Copyright (C) 2002, ATI Corp.
7 * Copyright (C) 2004-2005 Richard Purdie 7 * Copyright (C) 2004-2006 Richard Purdie
8 * Copyright (c) 2005 Ian Molton 8 * Copyright (c) 2005 Ian Molton
9 * Copyright (c) 2006 Alberto Mardegan
9 * 10 *
10 * Rewritten for 2.6 by Richard Purdie <rpurdie@rpsys.net> 11 * Rewritten for 2.6 by Richard Purdie <rpurdie@rpsys.net>
11 * 12 *
@@ -14,6 +15,9 @@
14 * 15 *
15 * w32xx support by Ian Molton 16 * w32xx support by Ian Molton
16 * 17 *
18 * Hardware acceleration support by Alberto Mardegan
19 * <mardy@users.sourceforge.net>
20 *
17 * This program is free software; you can redistribute it and/or modify 21 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as 22 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation. 23 * published by the Free Software Foundation.
@@ -47,6 +51,7 @@ static void w100_set_dispregs(struct w100fb_par*);
47static void w100_update_enable(void); 51static void w100_update_enable(void);
48static void w100_update_disable(void); 52static void w100_update_disable(void);
49static void calc_hsync(struct w100fb_par *par); 53static void calc_hsync(struct w100fb_par *par);
54static void w100_init_graphic_engine(struct w100fb_par *par);
50struct w100_pll_info *w100_get_xtal_table(unsigned int freq); 55struct w100_pll_info *w100_get_xtal_table(unsigned int freq);
51 56
52/* Pseudo palette size */ 57/* Pseudo palette size */
@@ -248,6 +253,152 @@ static int w100fb_blank(int blank_mode, struct fb_info *info)
248} 253}
249 254
250 255
256static void w100_fifo_wait(int entries)
257{
258 union rbbm_status_u status;
259 int i;
260
261 for (i = 0; i < 2000000; i++) {
262 status.val = readl(remapped_regs + mmRBBM_STATUS);
263 if (status.f.cmdfifo_avail >= entries)
264 return;
265 udelay(1);
266 }
267 printk(KERN_ERR "w100fb: FIFO Timeout!\n");
268}
269
270
271static int w100fb_sync(struct fb_info *info)
272{
273 union rbbm_status_u status;
274 int i;
275
276 for (i = 0; i < 2000000; i++) {
277 status.val = readl(remapped_regs + mmRBBM_STATUS);
278 if (!status.f.gui_active)
279 return 0;
280 udelay(1);
281 }
282 printk(KERN_ERR "w100fb: Graphic engine timeout!\n");
283 return -EBUSY;
284}
285
286
287static void w100_init_graphic_engine(struct w100fb_par *par)
288{
289 union dp_gui_master_cntl_u gmc;
290 union dp_mix_u dp_mix;
291 union dp_datatype_u dp_datatype;
292 union dp_cntl_u dp_cntl;
293
294 w100_fifo_wait(4);
295 writel(W100_FB_BASE, remapped_regs + mmDST_OFFSET);
296 writel(par->xres, remapped_regs + mmDST_PITCH);
297 writel(W100_FB_BASE, remapped_regs + mmSRC_OFFSET);
298 writel(par->xres, remapped_regs + mmSRC_PITCH);
299
300 w100_fifo_wait(3);
301 writel(0, remapped_regs + mmSC_TOP_LEFT);
302 writel((par->yres << 16) | par->xres, remapped_regs + mmSC_BOTTOM_RIGHT);
303 writel(0x1fff1fff, remapped_regs + mmSRC_SC_BOTTOM_RIGHT);
304
305 w100_fifo_wait(4);
306 dp_cntl.val = 0;
307 dp_cntl.f.dst_x_dir = 1;
308 dp_cntl.f.dst_y_dir = 1;
309 dp_cntl.f.src_x_dir = 1;
310 dp_cntl.f.src_y_dir = 1;
311 dp_cntl.f.dst_major_x = 1;
312 dp_cntl.f.src_major_x = 1;
313 writel(dp_cntl.val, remapped_regs + mmDP_CNTL);
314
315 gmc.val = 0;
316 gmc.f.gmc_src_pitch_offset_cntl = 1;
317 gmc.f.gmc_dst_pitch_offset_cntl = 1;
318 gmc.f.gmc_src_clipping = 1;
319 gmc.f.gmc_dst_clipping = 1;
320 gmc.f.gmc_brush_datatype = GMC_BRUSH_NONE;
321 gmc.f.gmc_dst_datatype = 3; /* from DstType_16Bpp_444 */
322 gmc.f.gmc_src_datatype = SRC_DATATYPE_EQU_DST;
323 gmc.f.gmc_byte_pix_order = 1;
324 gmc.f.gmc_default_sel = 0;
325 gmc.f.gmc_rop3 = ROP3_SRCCOPY;
326 gmc.f.gmc_dp_src_source = DP_SRC_MEM_RECTANGULAR;
327 gmc.f.gmc_clr_cmp_fcn_dis = 1;
328 gmc.f.gmc_wr_msk_dis = 1;
329 gmc.f.gmc_dp_op = DP_OP_ROP;
330 writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL);
331
332 dp_datatype.val = dp_mix.val = 0;
333 dp_datatype.f.dp_dst_datatype = gmc.f.gmc_dst_datatype;
334 dp_datatype.f.dp_brush_datatype = gmc.f.gmc_brush_datatype;
335 dp_datatype.f.dp_src2_type = 0;
336 dp_datatype.f.dp_src2_datatype = gmc.f.gmc_src_datatype;
337 dp_datatype.f.dp_src_datatype = gmc.f.gmc_src_datatype;
338 dp_datatype.f.dp_byte_pix_order = gmc.f.gmc_byte_pix_order;
339 writel(dp_datatype.val, remapped_regs + mmDP_DATATYPE);
340
341 dp_mix.f.dp_src_source = gmc.f.gmc_dp_src_source;
342 dp_mix.f.dp_src2_source = 1;
343 dp_mix.f.dp_rop3 = gmc.f.gmc_rop3;
344 dp_mix.f.dp_op = gmc.f.gmc_dp_op;
345 writel(dp_mix.val, remapped_regs + mmDP_MIX);
346}
347
348
349static void w100fb_fillrect(struct fb_info *info,
350 const struct fb_fillrect *rect)
351{
352 union dp_gui_master_cntl_u gmc;
353
354 if (info->state != FBINFO_STATE_RUNNING)
355 return;
356 if (info->flags & FBINFO_HWACCEL_DISABLED) {
357 cfb_fillrect(info, rect);
358 return;
359 }
360
361 gmc.val = readl(remapped_regs + mmDP_GUI_MASTER_CNTL);
362 gmc.f.gmc_rop3 = ROP3_PATCOPY;
363 gmc.f.gmc_brush_datatype = GMC_BRUSH_SOLID_COLOR;
364 w100_fifo_wait(2);
365 writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL);
366 writel(rect->color, remapped_regs + mmDP_BRUSH_FRGD_CLR);
367
368 w100_fifo_wait(2);
369 writel((rect->dy << 16) | (rect->dx & 0xffff), remapped_regs + mmDST_Y_X);
370 writel((rect->width << 16) | (rect->height & 0xffff),
371 remapped_regs + mmDST_WIDTH_HEIGHT);
372}
373
374
375static void w100fb_copyarea(struct fb_info *info,
376 const struct fb_copyarea *area)
377{
378 u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
379 u32 h = area->height, w = area->width;
380 union dp_gui_master_cntl_u gmc;
381
382 if (info->state != FBINFO_STATE_RUNNING)
383 return;
384 if (info->flags & FBINFO_HWACCEL_DISABLED) {
385 cfb_copyarea(info, area);
386 return;
387 }
388
389 gmc.val = readl(remapped_regs + mmDP_GUI_MASTER_CNTL);
390 gmc.f.gmc_rop3 = ROP3_SRCCOPY;
391 gmc.f.gmc_brush_datatype = GMC_BRUSH_NONE;
392 w100_fifo_wait(1);
393 writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL);
394
395 w100_fifo_wait(3);
396 writel((sy << 16) | (sx & 0xffff), remapped_regs + mmSRC_Y_X);
397 writel((dy << 16) | (dx & 0xffff), remapped_regs + mmDST_Y_X);
398 writel((w << 16) | (h & 0xffff), remapped_regs + mmDST_WIDTH_HEIGHT);
399}
400
401
251/* 402/*
252 * Change the resolution by calling the appropriate hardware functions 403 * Change the resolution by calling the appropriate hardware functions
253 */ 404 */
@@ -265,6 +416,7 @@ static void w100fb_activate_var(struct w100fb_par *par)
265 w100_init_lcd(par); 416 w100_init_lcd(par);
266 w100_set_dispregs(par); 417 w100_set_dispregs(par);
267 w100_update_enable(); 418 w100_update_enable();
419 w100_init_graphic_engine(par);
268 420
269 calc_hsync(par); 421 calc_hsync(par);
270 422
@@ -394,9 +546,10 @@ static struct fb_ops w100fb_ops = {
394 .fb_set_par = w100fb_set_par, 546 .fb_set_par = w100fb_set_par,
395 .fb_setcolreg = w100fb_setcolreg, 547 .fb_setcolreg = w100fb_setcolreg,
396 .fb_blank = w100fb_blank, 548 .fb_blank = w100fb_blank,
397 .fb_fillrect = cfb_fillrect, 549 .fb_fillrect = w100fb_fillrect,
398 .fb_copyarea = cfb_copyarea, 550 .fb_copyarea = w100fb_copyarea,
399 .fb_imageblit = cfb_imageblit, 551 .fb_imageblit = cfb_imageblit,
552 .fb_sync = w100fb_sync,
400}; 553};
401 554
402#ifdef CONFIG_PM 555#ifdef CONFIG_PM
@@ -543,7 +696,8 @@ int __init w100fb_probe(struct platform_device *pdev)
543 } 696 }
544 697
545 info->fbops = &w100fb_ops; 698 info->fbops = &w100fb_ops;
546 info->flags = FBINFO_DEFAULT; 699 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
700 FBINFO_HWACCEL_FILLRECT;
547 info->node = -1; 701 info->node = -1;
548 info->screen_base = remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE); 702 info->screen_base = remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE);
549 info->screen_size = REMAPPED_FB_LEN; 703 info->screen_size = REMAPPED_FB_LEN;