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 #include <linux/slab.h>
21 #if defined(CONFIG_OF)
22 #include <linux/of_platform.h>
24 #include "mb862xxfb.h"
25 #include "mb862xx_reg.h"
26 #include "mb862xxfb_accel.h"
28 static void mb862xxfb_write_fifo(u32 count
, u32
*data
, struct fb_info
*info
)
30 struct mb862xxfb_par
*par
= info
->par
;
34 while (total
< count
) {
36 outreg(geo
, GDC_GEO_REG_INPUT_FIFO
, data
[total
]);
40 free
= (u32
) inreg(draw
, GDC_REG_FIFO_COUNT
);
45 static void mb86290fb_copyarea(struct fb_info
*info
,
46 const struct fb_copyarea
*area
)
50 cmd
[0] = (GDC_TYPE_SETREGISTER
<< 24) | (1 << 16) | GDC_REG_MODE_BITMAP
;
51 /* Set raster operation */
52 cmd
[1] = (2 << 7) | (GDC_ROP_COPY
<< 9);
53 cmd
[2] = GDC_TYPE_BLTCOPYP
<< 24;
55 if (area
->sx
>= area
->dx
&& area
->sy
>= area
->dy
)
56 cmd
[2] |= GDC_CMD_BLTCOPY_TOP_LEFT
<< 16;
57 else if (area
->sx
>= area
->dx
&& area
->sy
<= area
->dy
)
58 cmd
[2] |= GDC_CMD_BLTCOPY_BOTTOM_LEFT
<< 16;
59 else if (area
->sx
<= area
->dx
&& area
->sy
>= area
->dy
)
60 cmd
[2] |= GDC_CMD_BLTCOPY_TOP_RIGHT
<< 16;
62 cmd
[2] |= GDC_CMD_BLTCOPY_BOTTOM_RIGHT
<< 16;
64 cmd
[3] = (area
->sy
<< 16) | area
->sx
;
65 cmd
[4] = (area
->dy
<< 16) | area
->dx
;
66 cmd
[5] = (area
->height
<< 16) | area
->width
;
67 mb862xxfb_write_fifo(6, cmd
, info
);
71 * Fill in the cmd array /GDC FIFO commands/ to draw a 1bit image.
72 * Make sure cmd has enough room!
74 static void mb86290fb_imageblit1(u32
*cmd
, u16 step
, u16 dx
, u16 dy
,
75 u16 width
, u16 height
, u32 fgcolor
,
76 u32 bgcolor
, const struct fb_image
*image
,
80 unsigned const char *line
;
83 /* set colors and raster operation regs */
84 cmd
[0] = (GDC_TYPE_SETREGISTER
<< 24) | (1 << 16) | GDC_REG_MODE_BITMAP
;
85 /* Set raster operation */
86 cmd
[1] = (2 << 7) | (GDC_ROP_COPY
<< 9);
88 (GDC_TYPE_SETCOLORREGISTER
<< 24) | (GDC_CMD_BODY_FORE_COLOR
<< 16);
91 (GDC_TYPE_SETCOLORREGISTER
<< 24) | (GDC_CMD_BODY_BACK_COLOR
<< 16);
96 bytes
= (image
->width
+ 7) >> 3;
99 cmd
[6] = (GDC_TYPE_DRAWBITMAPP
<< 24) |
100 (GDC_CMD_BITMAP
<< 16) | (2 + (step
* height
));
101 cmd
[7] = (dy
<< 16) | dx
;
102 cmd
[8] = (height
<< 16) | width
;
105 memcpy(&cmd
[9 + i
* step
], line
, step
<< 2);
106 #ifdef __LITTLE_ENDIAN
109 for (k
= 0; k
< step
; k
++)
110 cmd
[9 + i
* step
+ k
] =
111 cpu_to_be32(cmd
[9 + i
* step
+ k
]);
120 * Fill in the cmd array /GDC FIFO commands/ to draw a 8bit image.
121 * Make sure cmd has enough room!
123 static void mb86290fb_imageblit8(u32
*cmd
, u16 step
, u16 dx
, u16 dy
,
124 u16 width
, u16 height
, u32 fgcolor
,
125 u32 bgcolor
, const struct fb_image
*image
,
126 struct fb_info
*info
)
129 unsigned const char *line
, *ptr
;
132 cmd
[0] = (GDC_TYPE_DRAWBITMAPP
<< 24) |
133 (GDC_CMD_BLT_DRAW
<< 16) | (2 + (height
* step
));
134 cmd
[1] = (dy
<< 16) | dx
;
135 cmd
[2] = (height
<< 16) | width
;
138 line
= ptr
= image
->data
;
139 bytes
= image
->width
;
143 for (j
= 0; j
< step
; j
++) {
144 cmd
[3 + i
* step
+ j
] =
145 (((u32
*) (info
->pseudo_palette
))[*ptr
]) & 0xffff;
147 cmd
[3 + i
* step
+ j
] |=
149 pseudo_palette
))[*ptr
]) & 0xffff) << 16;
159 * Fill in the cmd array /GDC FIFO commands/ to draw a 16bit image.
160 * Make sure cmd has enough room!
162 static void mb86290fb_imageblit16(u32
*cmd
, u16 step
, u16 dx
, u16 dy
,
163 u16 width
, u16 height
, u32 fgcolor
,
164 u32 bgcolor
, const struct fb_image
*image
,
165 struct fb_info
*info
)
168 unsigned const char *line
;
173 bytes
= image
->width
<< 1;
175 cmd
[0] = (GDC_TYPE_DRAWBITMAPP
<< 24) |
176 (GDC_CMD_BLT_DRAW
<< 16) | (2 + step
* height
);
177 cmd
[1] = (dy
<< 16) | dx
;
178 cmd
[2] = (height
<< 16) | width
;
181 memcpy(&cmd
[3 + i
* step
], line
, step
);
187 static void mb86290fb_imageblit(struct fb_info
*info
,
188 const struct fb_image
*image
)
192 void (*cmdfn
) (u32
*, u16
, u16
, u16
, u16
, u16
, u32
, u32
,
193 const struct fb_image
*, struct fb_info
*) = NULL
;
195 u32 fgcolor
= 0, bgcolor
= 0;
198 u16 width
= image
->width
, height
= image
->height
;
199 u16 dx
= image
->dx
, dy
= image
->dy
;
200 int x2
, y2
, vxres
, vyres
;
202 mdr
= (GDC_ROP_COPY
<< 9);
203 x2
= image
->dx
+ image
->width
;
204 y2
= image
->dy
+ image
->height
;
205 vxres
= info
->var
.xres_virtual
;
206 vyres
= info
->var
.yres_virtual
;
212 switch (image
->depth
) {
214 step
= (width
+ 31) >> 5;
215 cmdlen
= 9 + height
* step
;
216 cmdfn
= mb86290fb_imageblit1
;
217 if (info
->fix
.visual
== FB_VISUAL_TRUECOLOR
||
218 info
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
) {
220 ((u32
*) (info
->pseudo_palette
))[image
->fg_color
];
222 ((u32
*) (info
->pseudo_palette
))[image
->bg_color
];
224 fgcolor
= image
->fg_color
;
225 bgcolor
= image
->bg_color
;
231 step
= (width
+ 1) >> 1;
232 cmdlen
= 3 + height
* step
;
233 cmdfn
= mb86290fb_imageblit8
;
237 step
= (width
+ 1) >> 1;
238 cmdlen
= 3 + height
* step
;
239 cmdfn
= mb86290fb_imageblit16
;
243 cfb_imageblit(info
, image
);
247 cmd
= kmalloc(cmdlen
* 4, GFP_DMA
);
249 return cfb_imageblit(info
, image
);
250 cmdfn(cmd
, step
, dx
, dy
, width
, height
, fgcolor
, bgcolor
, image
, info
);
251 mb862xxfb_write_fifo(cmdlen
, cmd
, info
);
255 static void mb86290fb_fillrect(struct fb_info
*info
,
256 const struct fb_fillrect
*rect
)
259 u32 x2
, y2
, vxres
, vyres
, height
, width
, fg
;
262 vxres
= info
->var
.xres_virtual
;
263 vyres
= info
->var
.yres_virtual
;
265 if (!rect
->width
|| !rect
->height
|| rect
->dx
> vxres
269 /* We could use hardware clipping but on many cards you get around
270 * hardware clipping by writing to framebuffer directly. */
271 x2
= rect
->dx
+ rect
->width
;
272 y2
= rect
->dy
+ rect
->height
;
275 width
= x2
- rect
->dx
;
276 height
= y2
- rect
->dy
;
277 if (info
->fix
.visual
== FB_VISUAL_TRUECOLOR
||
278 info
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
)
279 fg
= ((u32
*) (info
->pseudo_palette
))[rect
->color
];
286 /* Set raster operation */
287 cmd
[1] = (2 << 7) | (GDC_ROP_XOR
<< 9);
291 /* Set raster operation */
292 cmd
[1] = (2 << 7) | (GDC_ROP_COPY
<< 9);
297 cmd
[0] = (GDC_TYPE_SETREGISTER
<< 24) | (1 << 16) | GDC_REG_MODE_BITMAP
;
298 /* cmd[1] set earlier */
300 (GDC_TYPE_SETCOLORREGISTER
<< 24) | (GDC_CMD_BODY_FORE_COLOR
<< 16);
302 cmd
[4] = (GDC_TYPE_DRAWRECTP
<< 24) | (GDC_CMD_BLT_FILL
<< 16);
303 cmd
[5] = (rect
->dy
<< 16) | (rect
->dx
);
304 cmd
[6] = (height
<< 16) | width
;
306 mb862xxfb_write_fifo(7, cmd
, info
);
309 void mb862xxfb_init_accel(struct fb_info
*info
, int xres
)
311 struct mb862xxfb_par
*par
= info
->par
;
313 if (info
->var
.bits_per_pixel
== 32) {
314 info
->fbops
->fb_fillrect
= cfb_fillrect
;
315 info
->fbops
->fb_copyarea
= cfb_copyarea
;
316 info
->fbops
->fb_imageblit
= cfb_imageblit
;
318 outreg(disp
, GC_L0EM
, 3);
319 info
->fbops
->fb_fillrect
= mb86290fb_fillrect
;
320 info
->fbops
->fb_copyarea
= mb86290fb_copyarea
;
321 info
->fbops
->fb_imageblit
= mb86290fb_imageblit
;
323 outreg(draw
, GDC_REG_DRAW_BASE
, 0);
324 outreg(draw
, GDC_REG_MODE_MISC
, 0x8000);
325 outreg(draw
, GDC_REG_X_RESOLUTION
, xres
);
328 FBINFO_HWACCEL_COPYAREA
| FBINFO_HWACCEL_FILLRECT
|
329 FBINFO_HWACCEL_IMAGEBLIT
;
330 info
->fix
.accel
= 0xff; /*FIXME: add right define */
332 EXPORT_SYMBOL(mb862xxfb_init_accel
);