2 * drivers/mb862xx/mb862xxfb_accel.c
4 * Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver acceleration support
6 * (C) 2007 Alexander Shishkin <virtuoso@slind.org>
7 * (C) 2009 Valentin Sitdikov <valentin.sitdikov@siemens.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
16 #include <linux/delay.h>
17 #include <linux/init.h>
18 #include <linux/interrupt.h>
19 #include <linux/pci.h>
20 #if defined(CONFIG_OF)
21 #include <linux/of_platform.h>
23 #include "mb862xxfb.h"
24 #include "mb862xx_reg.h"
25 #include "mb862xxfb_accel.h"
27 static void mb862xxfb_write_fifo(u32 count
, u32
*data
, struct fb_info
*info
)
29 struct mb862xxfb_par
*par
= info
->par
;
33 while (total
< count
) {
35 outreg(geo
, GDC_GEO_REG_INPUT_FIFO
, data
[total
]);
39 free
= (u32
) inreg(draw
, GDC_REG_FIFO_COUNT
);
44 static void mb86290fb_copyarea(struct fb_info
*info
,
45 const struct fb_copyarea
*area
)
49 cmd
[0] = (GDC_TYPE_SETREGISTER
<< 24) | (1 << 16) | GDC_REG_MODE_BITMAP
;
50 /* Set raster operation */
51 cmd
[1] = (2 << 7) | (GDC_ROP_COPY
<< 9);
52 cmd
[2] = GDC_TYPE_BLTCOPYP
<< 24;
54 if (area
->sx
>= area
->dx
&& area
->sy
>= area
->dy
)
55 cmd
[2] |= GDC_CMD_BLTCOPY_TOP_LEFT
<< 16;
56 else if (area
->sx
>= area
->dx
&& area
->sy
<= area
->dy
)
57 cmd
[2] |= GDC_CMD_BLTCOPY_BOTTOM_LEFT
<< 16;
58 else if (area
->sx
<= area
->dx
&& area
->sy
>= area
->dy
)
59 cmd
[2] |= GDC_CMD_BLTCOPY_TOP_RIGHT
<< 16;
61 cmd
[2] |= GDC_CMD_BLTCOPY_BOTTOM_RIGHT
<< 16;
63 cmd
[3] = (area
->sy
<< 16) | area
->sx
;
64 cmd
[4] = (area
->dy
<< 16) | area
->dx
;
65 cmd
[5] = (area
->height
<< 16) | area
->width
;
66 mb862xxfb_write_fifo(6, cmd
, info
);
70 * Fill in the cmd array /GDC FIFO commands/ to draw a 1bit image.
71 * Make sure cmd has enough room!
73 static void mb86290fb_imageblit1(u32
*cmd
, u16 step
, u16 dx
, u16 dy
,
74 u16 width
, u16 height
, u32 fgcolor
,
75 u32 bgcolor
, const struct fb_image
*image
,
79 unsigned const char *line
;
82 /* set colors and raster operation regs */
83 cmd
[0] = (GDC_TYPE_SETREGISTER
<< 24) | (1 << 16) | GDC_REG_MODE_BITMAP
;
84 /* Set raster operation */
85 cmd
[1] = (2 << 7) | (GDC_ROP_COPY
<< 9);
87 (GDC_TYPE_SETCOLORREGISTER
<< 24) | (GDC_CMD_BODY_FORE_COLOR
<< 16);
90 (GDC_TYPE_SETCOLORREGISTER
<< 24) | (GDC_CMD_BODY_BACK_COLOR
<< 16);
95 bytes
= (image
->width
+ 7) >> 3;
98 cmd
[6] = (GDC_TYPE_DRAWBITMAPP
<< 24) |
99 (GDC_CMD_BITMAP
<< 16) | (2 + (step
* height
));
100 cmd
[7] = (dy
<< 16) | dx
;
101 cmd
[8] = (height
<< 16) | width
;
104 memcpy(&cmd
[9 + i
* step
], line
, step
<< 2);
105 #ifdef __LITTLE_ENDIAN
108 for (k
= 0; k
< step
; k
++)
109 cmd
[9 + i
* step
+ k
] =
110 cpu_to_be32(cmd
[9 + i
* step
+ k
]);
119 * Fill in the cmd array /GDC FIFO commands/ to draw a 8bit image.
120 * Make sure cmd has enough room!
122 static void mb86290fb_imageblit8(u32
*cmd
, u16 step
, u16 dx
, u16 dy
,
123 u16 width
, u16 height
, u32 fgcolor
,
124 u32 bgcolor
, const struct fb_image
*image
,
125 struct fb_info
*info
)
128 unsigned const char *line
, *ptr
;
131 cmd
[0] = (GDC_TYPE_DRAWBITMAPP
<< 24) |
132 (GDC_CMD_BLT_DRAW
<< 16) | (2 + (height
* step
));
133 cmd
[1] = (dy
<< 16) | dx
;
134 cmd
[2] = (height
<< 16) | width
;
137 line
= ptr
= image
->data
;
138 bytes
= image
->width
;
142 for (j
= 0; j
< step
; j
++) {
143 cmd
[3 + i
* step
+ j
] =
144 (((u32
*) (info
->pseudo_palette
))[*ptr
]) & 0xffff;
146 cmd
[3 + i
* step
+ j
] |=
148 pseudo_palette
))[*ptr
]) & 0xffff) << 16;
158 * Fill in the cmd array /GDC FIFO commands/ to draw a 16bit image.
159 * Make sure cmd has enough room!
161 static void mb86290fb_imageblit16(u32
*cmd
, u16 step
, u16 dx
, u16 dy
,
162 u16 width
, u16 height
, u32 fgcolor
,
163 u32 bgcolor
, const struct fb_image
*image
,
164 struct fb_info
*info
)
167 unsigned const char *line
;
172 bytes
= image
->width
<< 1;
174 cmd
[0] = (GDC_TYPE_DRAWBITMAPP
<< 24) |
175 (GDC_CMD_BLT_DRAW
<< 16) | (2 + step
* height
);
176 cmd
[1] = (dy
<< 16) | dx
;
177 cmd
[2] = (height
<< 16) | width
;
180 memcpy(&cmd
[3 + i
* step
], line
, step
);
186 static void mb86290fb_imageblit(struct fb_info
*info
,
187 const struct fb_image
*image
)
191 void (*cmdfn
) (u32
*, u16
, u16
, u16
, u16
, u16
, u32
, u32
,
192 const struct fb_image
*, struct fb_info
*) = NULL
;
194 u32 fgcolor
= 0, bgcolor
= 0;
197 u16 width
= image
->width
, height
= image
->height
;
198 u16 dx
= image
->dx
, dy
= image
->dy
;
199 int x2
, y2
, vxres
, vyres
;
201 mdr
= (GDC_ROP_COPY
<< 9);
202 x2
= image
->dx
+ image
->width
;
203 y2
= image
->dy
+ image
->height
;
204 vxres
= info
->var
.xres_virtual
;
205 vyres
= info
->var
.yres_virtual
;
211 switch (image
->depth
) {
213 step
= (width
+ 31) >> 5;
214 cmdlen
= 9 + height
* step
;
215 cmdfn
= mb86290fb_imageblit1
;
216 if (info
->fix
.visual
== FB_VISUAL_TRUECOLOR
||
217 info
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
) {
219 ((u32
*) (info
->pseudo_palette
))[image
->fg_color
];
221 ((u32
*) (info
->pseudo_palette
))[image
->bg_color
];
223 fgcolor
= image
->fg_color
;
224 bgcolor
= image
->bg_color
;
230 step
= (width
+ 1) >> 1;
231 cmdlen
= 3 + height
* step
;
232 cmdfn
= mb86290fb_imageblit8
;
236 step
= (width
+ 1) >> 1;
237 cmdlen
= 3 + height
* step
;
238 cmdfn
= mb86290fb_imageblit16
;
242 cfb_imageblit(info
, image
);
246 cmd
= kmalloc(cmdlen
* 4, GFP_DMA
);
248 return cfb_imageblit(info
, image
);
249 cmdfn(cmd
, step
, dx
, dy
, width
, height
, fgcolor
, bgcolor
, image
, info
);
250 mb862xxfb_write_fifo(cmdlen
, cmd
, info
);
254 static void mb86290fb_fillrect(struct fb_info
*info
,
255 const struct fb_fillrect
*rect
)
258 u32 x2
, y2
, vxres
, vyres
, height
, width
, fg
;
261 vxres
= info
->var
.xres_virtual
;
262 vyres
= info
->var
.yres_virtual
;
264 if (!rect
->width
|| !rect
->height
|| rect
->dx
> vxres
268 /* We could use hardware clipping but on many cards you get around
269 * hardware clipping by writing to framebuffer directly. */
270 x2
= rect
->dx
+ rect
->width
;
271 y2
= rect
->dy
+ rect
->height
;
274 width
= x2
- rect
->dx
;
275 height
= y2
- rect
->dy
;
276 if (info
->fix
.visual
== FB_VISUAL_TRUECOLOR
||
277 info
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
)
278 fg
= ((u32
*) (info
->pseudo_palette
))[rect
->color
];
285 /* Set raster operation */
286 cmd
[1] = (2 << 7) | (GDC_ROP_XOR
<< 9);
290 /* Set raster operation */
291 cmd
[1] = (2 << 7) | (GDC_ROP_COPY
<< 9);
296 cmd
[0] = (GDC_TYPE_SETREGISTER
<< 24) | (1 << 16) | GDC_REG_MODE_BITMAP
;
297 /* cmd[1] set earlier */
299 (GDC_TYPE_SETCOLORREGISTER
<< 24) | (GDC_CMD_BODY_FORE_COLOR
<< 16);
301 cmd
[4] = (GDC_TYPE_DRAWRECTP
<< 24) | (GDC_CMD_BLT_FILL
<< 16);
302 cmd
[5] = (rect
->dy
<< 16) | (rect
->dx
);
303 cmd
[6] = (height
<< 16) | width
;
305 mb862xxfb_write_fifo(7, cmd
, info
);
308 void mb862xxfb_init_accel(struct fb_info
*info
, int xres
)
310 struct mb862xxfb_par
*par
= info
->par
;
312 if (info
->var
.bits_per_pixel
== 32) {
313 info
->fbops
->fb_fillrect
= cfb_fillrect
;
314 info
->fbops
->fb_copyarea
= cfb_copyarea
;
315 info
->fbops
->fb_imageblit
= cfb_imageblit
;
317 outreg(disp
, GC_L0EM
, 3);
318 info
->fbops
->fb_fillrect
= mb86290fb_fillrect
;
319 info
->fbops
->fb_copyarea
= mb86290fb_copyarea
;
320 info
->fbops
->fb_imageblit
= mb86290fb_imageblit
;
322 outreg(draw
, GDC_REG_DRAW_BASE
, 0);
323 outreg(draw
, GDC_REG_MODE_MISC
, 0x8000);
324 outreg(draw
, GDC_REG_X_RESOLUTION
, xres
);
327 FBINFO_HWACCEL_COPYAREA
| FBINFO_HWACCEL_FILLRECT
|
328 FBINFO_HWACCEL_IMAGEBLIT
;
329 info
->fix
.accel
= 0xff; /*FIXME: add right define */
331 EXPORT_SYMBOL(mb862xxfb_init_accel
);