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 <v.sitdikov@gmail.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/module.h>
20 #include <linux/pci.h>
21 #include <linux/slab.h>
22 #if defined(CONFIG_OF)
23 #include <linux/of_platform.h>
25 #include "mb862xxfb.h"
26 #include "mb862xx_reg.h"
27 #include "mb862xxfb_accel.h"
29 static void mb862xxfb_write_fifo(u32 count
, u32
*data
, struct fb_info
*info
)
31 struct mb862xxfb_par
*par
= info
->par
;
35 while (total
< count
) {
37 outreg(geo
, GDC_GEO_REG_INPUT_FIFO
, data
[total
]);
41 free
= (u32
) inreg(draw
, GDC_REG_FIFO_COUNT
);
46 static void mb86290fb_copyarea(struct fb_info
*info
,
47 const struct fb_copyarea
*area
)
51 cmd
[0] = (GDC_TYPE_SETREGISTER
<< 24) | (1 << 16) | GDC_REG_MODE_BITMAP
;
52 /* Set raster operation */
53 cmd
[1] = (2 << 7) | (GDC_ROP_COPY
<< 9);
54 cmd
[2] = GDC_TYPE_BLTCOPYP
<< 24;
56 if (area
->sx
>= area
->dx
&& area
->sy
>= area
->dy
)
57 cmd
[2] |= GDC_CMD_BLTCOPY_TOP_LEFT
<< 16;
58 else if (area
->sx
>= area
->dx
&& area
->sy
<= area
->dy
)
59 cmd
[2] |= GDC_CMD_BLTCOPY_BOTTOM_LEFT
<< 16;
60 else if (area
->sx
<= area
->dx
&& area
->sy
>= area
->dy
)
61 cmd
[2] |= GDC_CMD_BLTCOPY_TOP_RIGHT
<< 16;
63 cmd
[2] |= GDC_CMD_BLTCOPY_BOTTOM_RIGHT
<< 16;
65 cmd
[3] = (area
->sy
<< 16) | area
->sx
;
66 cmd
[4] = (area
->dy
<< 16) | area
->dx
;
67 cmd
[5] = (area
->height
<< 16) | area
->width
;
68 mb862xxfb_write_fifo(6, cmd
, info
);
72 * Fill in the cmd array /GDC FIFO commands/ to draw a 1bit image.
73 * Make sure cmd has enough room!
75 static void mb86290fb_imageblit1(u32
*cmd
, u16 step
, u16 dx
, u16 dy
,
76 u16 width
, u16 height
, u32 fgcolor
,
77 u32 bgcolor
, const struct fb_image
*image
,
81 unsigned const char *line
;
84 /* set colors and raster operation regs */
85 cmd
[0] = (GDC_TYPE_SETREGISTER
<< 24) | (1 << 16) | GDC_REG_MODE_BITMAP
;
86 /* Set raster operation */
87 cmd
[1] = (2 << 7) | (GDC_ROP_COPY
<< 9);
89 (GDC_TYPE_SETCOLORREGISTER
<< 24) | (GDC_CMD_BODY_FORE_COLOR
<< 16);
92 (GDC_TYPE_SETCOLORREGISTER
<< 24) | (GDC_CMD_BODY_BACK_COLOR
<< 16);
97 bytes
= (image
->width
+ 7) >> 3;
100 cmd
[6] = (GDC_TYPE_DRAWBITMAPP
<< 24) |
101 (GDC_CMD_BITMAP
<< 16) | (2 + (step
* height
));
102 cmd
[7] = (dy
<< 16) | dx
;
103 cmd
[8] = (height
<< 16) | width
;
106 memcpy(&cmd
[9 + i
* step
], line
, step
<< 2);
107 #ifdef __LITTLE_ENDIAN
110 for (k
= 0; k
< step
; k
++)
111 cmd
[9 + i
* step
+ k
] =
112 cpu_to_be32(cmd
[9 + i
* step
+ k
]);
121 * Fill in the cmd array /GDC FIFO commands/ to draw a 8bit image.
122 * Make sure cmd has enough room!
124 static void mb86290fb_imageblit8(u32
*cmd
, u16 step
, u16 dx
, u16 dy
,
125 u16 width
, u16 height
, u32 fgcolor
,
126 u32 bgcolor
, const struct fb_image
*image
,
127 struct fb_info
*info
)
130 unsigned const char *line
, *ptr
;
133 cmd
[0] = (GDC_TYPE_DRAWBITMAPP
<< 24) |
134 (GDC_CMD_BLT_DRAW
<< 16) | (2 + (height
* step
));
135 cmd
[1] = (dy
<< 16) | dx
;
136 cmd
[2] = (height
<< 16) | width
;
139 line
= ptr
= image
->data
;
140 bytes
= image
->width
;
144 for (j
= 0; j
< step
; j
++) {
145 cmd
[3 + i
* step
+ j
] =
146 (((u32
*) (info
->pseudo_palette
))[*ptr
]) & 0xffff;
148 cmd
[3 + i
* step
+ j
] |=
150 pseudo_palette
))[*ptr
]) & 0xffff) << 16;
160 * Fill in the cmd array /GDC FIFO commands/ to draw a 16bit image.
161 * Make sure cmd has enough room!
163 static void mb86290fb_imageblit16(u32
*cmd
, u16 step
, u16 dx
, u16 dy
,
164 u16 width
, u16 height
, u32 fgcolor
,
165 u32 bgcolor
, const struct fb_image
*image
,
166 struct fb_info
*info
)
169 unsigned const char *line
;
174 bytes
= image
->width
<< 1;
176 cmd
[0] = (GDC_TYPE_DRAWBITMAPP
<< 24) |
177 (GDC_CMD_BLT_DRAW
<< 16) | (2 + step
* height
);
178 cmd
[1] = (dy
<< 16) | dx
;
179 cmd
[2] = (height
<< 16) | width
;
182 memcpy(&cmd
[3 + i
* step
], line
, step
);
188 static void mb86290fb_imageblit(struct fb_info
*info
,
189 const struct fb_image
*image
)
193 void (*cmdfn
) (u32
*, u16
, u16
, u16
, u16
, u16
, u32
, u32
,
194 const struct fb_image
*, struct fb_info
*) = NULL
;
196 u32 fgcolor
= 0, bgcolor
= 0;
199 u16 width
= image
->width
, height
= image
->height
;
200 u16 dx
= image
->dx
, dy
= image
->dy
;
201 int x2
, y2
, vxres
, vyres
;
203 mdr
= (GDC_ROP_COPY
<< 9);
204 x2
= image
->dx
+ image
->width
;
205 y2
= image
->dy
+ image
->height
;
206 vxres
= info
->var
.xres_virtual
;
207 vyres
= info
->var
.yres_virtual
;
213 switch (image
->depth
) {
215 step
= (width
+ 31) >> 5;
216 cmdlen
= 9 + height
* step
;
217 cmdfn
= mb86290fb_imageblit1
;
218 if (info
->fix
.visual
== FB_VISUAL_TRUECOLOR
||
219 info
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
) {
221 ((u32
*) (info
->pseudo_palette
))[image
->fg_color
];
223 ((u32
*) (info
->pseudo_palette
))[image
->bg_color
];
225 fgcolor
= image
->fg_color
;
226 bgcolor
= image
->bg_color
;
232 step
= (width
+ 1) >> 1;
233 cmdlen
= 3 + height
* step
;
234 cmdfn
= mb86290fb_imageblit8
;
238 step
= (width
+ 1) >> 1;
239 cmdlen
= 3 + height
* step
;
240 cmdfn
= mb86290fb_imageblit16
;
244 cfb_imageblit(info
, image
);
248 cmd
= kmalloc(cmdlen
* 4, GFP_DMA
);
250 return cfb_imageblit(info
, image
);
251 cmdfn(cmd
, step
, dx
, dy
, width
, height
, fgcolor
, bgcolor
, image
, info
);
252 mb862xxfb_write_fifo(cmdlen
, cmd
, info
);
256 static void mb86290fb_fillrect(struct fb_info
*info
,
257 const struct fb_fillrect
*rect
)
260 u32 x2
, y2
, vxres
, vyres
, height
, width
, fg
;
263 vxres
= info
->var
.xres_virtual
;
264 vyres
= info
->var
.yres_virtual
;
266 if (!rect
->width
|| !rect
->height
|| rect
->dx
> vxres
270 /* We could use hardware clipping but on many cards you get around
271 * hardware clipping by writing to framebuffer directly. */
272 x2
= rect
->dx
+ rect
->width
;
273 y2
= rect
->dy
+ rect
->height
;
276 width
= x2
- rect
->dx
;
277 height
= y2
- rect
->dy
;
278 if (info
->fix
.visual
== FB_VISUAL_TRUECOLOR
||
279 info
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
)
280 fg
= ((u32
*) (info
->pseudo_palette
))[rect
->color
];
287 /* Set raster operation */
288 cmd
[1] = (2 << 7) | (GDC_ROP_XOR
<< 9);
292 /* Set raster operation */
293 cmd
[1] = (2 << 7) | (GDC_ROP_COPY
<< 9);
298 cmd
[0] = (GDC_TYPE_SETREGISTER
<< 24) | (1 << 16) | GDC_REG_MODE_BITMAP
;
299 /* cmd[1] set earlier */
301 (GDC_TYPE_SETCOLORREGISTER
<< 24) | (GDC_CMD_BODY_FORE_COLOR
<< 16);
303 cmd
[4] = (GDC_TYPE_DRAWRECTP
<< 24) | (GDC_CMD_BLT_FILL
<< 16);
304 cmd
[5] = (rect
->dy
<< 16) | (rect
->dx
);
305 cmd
[6] = (height
<< 16) | width
;
307 mb862xxfb_write_fifo(7, cmd
, info
);
310 void mb862xxfb_init_accel(struct fb_info
*info
, int xres
)
312 struct mb862xxfb_par
*par
= info
->par
;
314 if (info
->var
.bits_per_pixel
== 32) {
315 info
->fbops
->fb_fillrect
= cfb_fillrect
;
316 info
->fbops
->fb_copyarea
= cfb_copyarea
;
317 info
->fbops
->fb_imageblit
= cfb_imageblit
;
319 outreg(disp
, GC_L0EM
, 3);
320 info
->fbops
->fb_fillrect
= mb86290fb_fillrect
;
321 info
->fbops
->fb_copyarea
= mb86290fb_copyarea
;
322 info
->fbops
->fb_imageblit
= mb86290fb_imageblit
;
324 outreg(draw
, GDC_REG_DRAW_BASE
, 0);
325 outreg(draw
, GDC_REG_MODE_MISC
, 0x8000);
326 outreg(draw
, GDC_REG_X_RESOLUTION
, xres
);
329 FBINFO_HWACCEL_COPYAREA
| FBINFO_HWACCEL_FILLRECT
|
330 FBINFO_HWACCEL_IMAGEBLIT
;
331 info
->fix
.accel
= 0xff; /*FIXME: add right define */
333 EXPORT_SYMBOL(mb862xxfb_init_accel
);
335 MODULE_LICENSE("GPL v2");