Commit 5b1d28d6 authored by Florian Tobias Schandinat's avatar Florian Tobias Schandinat Committed by James Toy

v2: - fix copyarea with overlapping areas

    - add raster operation code conversion and checking
Signed-off-by: default avatarFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: Scott Fang <ScottFang@viatech.com.cn>
Cc: Joseph Chan <JosephChan@via.com.tw>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 1ea5fe32
......@@ -25,13 +25,40 @@ static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height,
u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
u32 fg_color, u32 bg_color, u8 fill_rop)
{
u32 tmp, i;
u32 ge_cmd = 0, tmp, i;
if (!op || op > 3) {
printk(KERN_WARNING "hw_bitblt_1: Invalid operation: %d\n", op);
return -EINVAL;
}
if (op != VIA_BITBLT_FILL && !src_mem && src_addr == dst_addr) {
if (src_x < dst_x) {
ge_cmd |= 0x00008000;
src_x += width - 1;
dst_x += width - 1;
}
if (src_y < dst_y) {
ge_cmd |= 0x00004000;
src_y += height - 1;
dst_y += height - 1;
}
}
if (op == VIA_BITBLT_FILL) {
switch (fill_rop) {
case 0x00: /* blackness */
case 0x5A: /* pattern inversion */
case 0xF0: /* pattern copy */
case 0xFF: /* whiteness */
break;
default:
printk(KERN_WARNING "hw_bitblt_1: Invalid fill rop: "
"%u\n", fill_rop);
return -EINVAL;
}
}
switch (dst_bpp) {
case 8:
tmp = 0x00000000;
......@@ -113,19 +140,18 @@ static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height,
tmp = (tmp >> 3) | (dst_pitch << (16 - 3));
writel(tmp, engine + 0x38);
tmp = 0;
if (op == VIA_BITBLT_FILL)
tmp |= fill_rop << 24 | 0x00002000 | 0x00000001;
ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001;
else {
tmp = 0xCC000000; /* ROP=SRCCOPY */
ge_cmd |= 0xCC000000; /* ROP=SRCCOPY */
if (src_mem)
tmp |= 0x00000040;
ge_cmd |= 0x00000040;
if (op == VIA_BITBLT_MONO)
tmp |= 0x00000002 | 0x00000100 | 0x00020000;
ge_cmd |= 0x00000002 | 0x00000100 | 0x00020000;
else
tmp |= 0x00000001;
ge_cmd |= 0x00000001;
}
writel(tmp, engine);
writel(ge_cmd, engine);
if (op == VIA_BITBLT_FILL || !src_mem)
return 0;
......@@ -144,13 +170,40 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
u32 fg_color, u32 bg_color, u8 fill_rop)
{
u32 tmp, i;
u32 ge_cmd = 0, tmp, i;
if (!op || op > 3) {
printk(KERN_WARNING "hw_bitblt_2: Invalid operation: %d\n", op);
return -EINVAL;
}
if (op != VIA_BITBLT_FILL && !src_mem && src_addr == dst_addr) {
if (src_x < dst_x) {
ge_cmd |= 0x00008000;
src_x += width - 1;
dst_x += width - 1;
}
if (src_y < dst_y) {
ge_cmd |= 0x00004000;
src_y += height - 1;
dst_y += height - 1;
}
}
if (op == VIA_BITBLT_FILL) {
switch (fill_rop) {
case 0x00: /* blackness */
case 0x5A: /* pattern inversion */
case 0xF0: /* pattern copy */
case 0xFF: /* whiteness */
break;
default:
printk(KERN_WARNING "hw_bitblt_2: Invalid fill rop: "
"%u\n", fill_rop);
return -EINVAL;
}
}
switch (dst_bpp) {
case 8:
tmp = 0x00000000;
......@@ -230,19 +283,18 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
if (op == VIA_BITBLT_MONO)
writel(bg_color, engine + 0x50);
tmp = 0;
if (op == VIA_BITBLT_FILL)
tmp |= fill_rop << 24 | 0x00002000 | 0x00000001;
ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001;
else {
tmp = 0xCC000000; /* ROP=SRCCOPY */
ge_cmd |= 0xCC000000; /* ROP=SRCCOPY */
if (src_mem)
tmp |= 0x00000040;
ge_cmd |= 0x00000040;
if (op == VIA_BITBLT_MONO)
tmp |= 0x00000002 | 0x00000100 | 0x00020000;
ge_cmd |= 0x00000002 | 0x00000100 | 0x00020000;
else
tmp |= 0x00000001;
ge_cmd |= 0x00000001;
}
writel(tmp, engine);
writel(ge_cmd, engine);
if (op == VIA_BITBLT_FILL || !src_mem)
return 0;
......
......@@ -768,6 +768,7 @@ static void viafb_fillrect(struct fb_info *info,
{
struct viafb_par *viapar = info->par;
u32 fg_color;
u8 rop;
if (!viapar->shared->hw_bitblt) {
cfb_fillrect(info, rect);
......@@ -782,11 +783,16 @@ static void viafb_fillrect(struct fb_info *info,
else
fg_color = rect->color;
if (rect->rop == ROP_XOR)
rop = 0x5A;
else
rop = 0xF0;
DEBUG_MSG(KERN_DEBUG "viafb 2D engine: fillrect\n");
if (viapar->shared->hw_bitblt(viapar->io_virt, VIA_BITBLT_FILL,
rect->width, rect->height, info->var.bits_per_pixel,
viapar->vram_addr, info->fix.line_length, rect->dx, rect->dy,
NULL, 0, 0, 0, 0, fg_color, 0, rect->rop))
NULL, 0, 0, 0, 0, fg_color, 0, rop))
cfb_fillrect(info, rect);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment