Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 164863
b: refs/heads/master
c: c3e2567
h: refs/heads/master
i:
  164861: fcfa268
  164859: a3d6f7b
  164855: 7f5b4f0
  164847: 38eb695
  164831: efe95cb
  164799: f66e715
  164735: 2dac260
  164607: 3b7227b
  164351: 32bac53
  163839: 820908f
v: v3
  • Loading branch information
Florian Tobias Schandinat authored and Linus Torvalds committed Sep 23, 2009
1 parent beb0f5a commit 2e05ccb
Show file tree
Hide file tree
Showing 5 changed files with 386 additions and 220 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c4df5489e40e55f2962b9e8100ebc0d4d1374415
refs/heads/master: c3e25673843153ea75fda79a47cf12f10a25ca37
363 changes: 312 additions & 51 deletions trunk/drivers/video/via/accel.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,316 @@
*/
#include "global.h"

void viafb_init_accel(void)
static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height,
u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
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 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;
break;
case 16:
tmp = 0x00000100;
break;
case 32:
tmp = 0x00000300;
break;
default:
printk(KERN_WARNING "hw_bitblt_1: Unsupported bpp %d\n",
dst_bpp);
return -EINVAL;
}
writel(tmp, engine + 0x04);

if (op != VIA_BITBLT_FILL) {
if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000)
|| src_y & 0xFFFFF000) {
printk(KERN_WARNING "hw_bitblt_1: Unsupported source "
"x/y %d %d\n", src_x, src_y);
return -EINVAL;
}
tmp = src_x | (src_y << 16);
writel(tmp, engine + 0x08);
}

if (dst_x & 0xFFFFF000 || dst_y & 0xFFFFF000) {
printk(KERN_WARNING "hw_bitblt_1: Unsupported destination x/y "
"%d %d\n", dst_x, dst_y);
return -EINVAL;
}
tmp = dst_x | (dst_y << 16);
writel(tmp, engine + 0x0C);

if ((width - 1) & 0xFFFFF000 || (height - 1) & 0xFFFFF000) {
printk(KERN_WARNING "hw_bitblt_1: Unsupported width/height "
"%d %d\n", width, height);
return -EINVAL;
}
tmp = (width - 1) | ((height - 1) << 16);
writel(tmp, engine + 0x10);

if (op != VIA_BITBLT_COLOR)
writel(fg_color, engine + 0x18);

if (op == VIA_BITBLT_MONO)
writel(bg_color, engine + 0x1C);

if (op != VIA_BITBLT_FILL) {
tmp = src_mem ? 0 : src_addr;
if (dst_addr & 0xE0000007) {
printk(KERN_WARNING "hw_bitblt_1: Unsupported source "
"address %X\n", tmp);
return -EINVAL;
}
tmp >>= 3;
writel(tmp, engine + 0x30);
}

if (dst_addr & 0xE0000007) {
printk(KERN_WARNING "hw_bitblt_1: Unsupported destination "
"address %X\n", dst_addr);
return -EINVAL;
}
tmp = dst_addr >> 3;
writel(tmp, engine + 0x34);

if (op == VIA_BITBLT_FILL)
tmp = 0;
else
tmp = src_pitch;
if (tmp & 0xFFFFC007 || dst_pitch & 0xFFFFC007) {
printk(KERN_WARNING "hw_bitblt_1: Unsupported pitch %X %X\n",
tmp, dst_pitch);
return -EINVAL;
}
tmp = (tmp >> 3) | (dst_pitch << (16 - 3));
writel(tmp, engine + 0x38);

if (op == VIA_BITBLT_FILL)
ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001;
else {
ge_cmd |= 0xCC000000; /* ROP=SRCCOPY */
if (src_mem)
ge_cmd |= 0x00000040;
if (op == VIA_BITBLT_MONO)
ge_cmd |= 0x00000002 | 0x00000100 | 0x00020000;
else
ge_cmd |= 0x00000001;
}
writel(ge_cmd, engine);

if (op == VIA_BITBLT_FILL || !src_mem)
return 0;

tmp = (width * height * (op == VIA_BITBLT_MONO ? 1 : (dst_bpp >> 3)) +
3) >> 2;

for (i = 0; i < tmp; i++)
writel(src_mem[i], engine + VIA_MMIO_BLTBASE);

return 0;
}

static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
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 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;
break;
case 16:
tmp = 0x00000100;
break;
case 32:
tmp = 0x00000300;
break;
default:
printk(KERN_WARNING "hw_bitblt_2: Unsupported bpp %d\n",
dst_bpp);
return -EINVAL;
}
writel(tmp, engine + 0x04);

if (op == VIA_BITBLT_FILL)
tmp = 0;
else
tmp = src_pitch;
if (tmp & 0xFFFFC007 || dst_pitch & 0xFFFFC007) {
printk(KERN_WARNING "hw_bitblt_2: Unsupported pitch %X %X\n",
tmp, dst_pitch);
return -EINVAL;
}
tmp = (tmp >> 3) | (dst_pitch << (16 - 3));
writel(tmp, engine + 0x08);

if ((width - 1) & 0xFFFFF000 || (height - 1) & 0xFFFFF000) {
printk(KERN_WARNING "hw_bitblt_2: Unsupported width/height "
"%d %d\n", width, height);
return -EINVAL;
}
tmp = (width - 1) | ((height - 1) << 16);
writel(tmp, engine + 0x0C);

if (dst_x & 0xFFFFF000 || dst_y & 0xFFFFF000) {
printk(KERN_WARNING "hw_bitblt_2: Unsupported destination x/y "
"%d %d\n", dst_x, dst_y);
return -EINVAL;
}
tmp = dst_x | (dst_y << 16);
writel(tmp, engine + 0x10);

if (dst_addr & 0xE0000007) {
printk(KERN_WARNING "hw_bitblt_2: Unsupported destination "
"address %X\n", dst_addr);
return -EINVAL;
}
tmp = dst_addr >> 3;
writel(tmp, engine + 0x14);

if (op != VIA_BITBLT_FILL) {
if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000)
|| src_y & 0xFFFFF000) {
printk(KERN_WARNING "hw_bitblt_2: Unsupported source "
"x/y %d %d\n", src_x, src_y);
return -EINVAL;
}
tmp = src_x | (src_y << 16);
writel(tmp, engine + 0x18);

tmp = src_mem ? 0 : src_addr;
if (dst_addr & 0xE0000007) {
printk(KERN_WARNING "hw_bitblt_2: Unsupported source "
"address %X\n", tmp);
return -EINVAL;
}
tmp >>= 3;
writel(tmp, engine + 0x1C);
}

if (op != VIA_BITBLT_COLOR)
writel(fg_color, engine + 0x4C);

if (op == VIA_BITBLT_MONO)
writel(bg_color, engine + 0x50);

if (op == VIA_BITBLT_FILL)
ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001;
else {
ge_cmd |= 0xCC000000; /* ROP=SRCCOPY */
if (src_mem)
ge_cmd |= 0x00000040;
if (op == VIA_BITBLT_MONO)
ge_cmd |= 0x00000002 | 0x00000100 | 0x00020000;
else
ge_cmd |= 0x00000001;
}
writel(ge_cmd, engine);

if (op == VIA_BITBLT_FILL || !src_mem)
return 0;

tmp = (width * height * (op == VIA_BITBLT_MONO ? 1 : (dst_bpp >> 3)) +
3) >> 2;

for (i = 0; i < tmp; i++)
writel(src_mem[i], engine + VIA_MMIO_BLTBASE);

return 0;
}

void viafb_init_accel(struct viafb_shared *shared)
{
switch (shared->chip_info.gfx_chip_name) {
case UNICHROME_CLE266:
case UNICHROME_K400:
case UNICHROME_K800:
case UNICHROME_PM800:
case UNICHROME_CN700:
case UNICHROME_CX700:
case UNICHROME_CN750:
case UNICHROME_K8M890:
case UNICHROME_P4M890:
case UNICHROME_P4M900:
shared->hw_bitblt = hw_bitblt_1;
break;
case UNICHROME_VX800:
shared->hw_bitblt = hw_bitblt_2;
break;
default:
shared->hw_bitblt = NULL;
}

viaparinfo->fbmem_free -= CURSOR_SIZE;
viaparinfo->cursor_start = viaparinfo->fbmem_free;
viaparinfo->fbmem_used += CURSOR_SIZE;
Expand All @@ -30,30 +338,14 @@ void viafb_init_accel(void)
viaparinfo->fbmem_free -= (CURSOR_SIZE + VQ_SIZE);
viaparinfo->VQ_start = viaparinfo->fbmem_free;
viaparinfo->VQ_end = viaparinfo->VQ_start + VQ_SIZE - 1;
viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE); }
viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE);
}

void viafb_init_2d_engine(void)
{
u32 dwVQStartAddr, dwVQEndAddr, linesize;
u32 dwVQStartAddr, dwVQEndAddr;
u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;

/* init 2D engine regs to reset 2D engine */
writel(0x0, viaparinfo->io_virt + VIA_REG_GEMODE);
writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
writel(0x0, viaparinfo->io_virt + VIA_REG_DSTPOS);
writel(0x0, viaparinfo->io_virt + VIA_REG_DIMENSION);
writel(0x0, viaparinfo->io_virt + VIA_REG_PATADDR);
writel(0x0, viaparinfo->io_virt + VIA_REG_FGCOLOR);
writel(0x0, viaparinfo->io_virt + VIA_REG_BGCOLOR);
writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPTL);
writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPBR);
writel(0x0, viaparinfo->io_virt + VIA_REG_OFFSET);
writel(0x0, viaparinfo->io_virt + VIA_REG_KEYCONTROL);
writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE);
writel(0x0, viaparinfo->io_virt + VIA_REG_PITCH);
writel(0x0, viaparinfo->io_virt + VIA_REG_MONOPAT1);

/* Init AGP and VQ regs */
switch (viaparinfo->chip_info->gfx_chip_name) {
case UNICHROME_K8M890:
Expand Down Expand Up @@ -190,37 +482,6 @@ void viafb_init_2d_engine(void)
break;
}
}

viafb_set_2d_color_depth(viafbinfo->var.bits_per_pixel);

writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE);

linesize = viafbinfo->var.xres * viafbinfo->var.bits_per_pixel >> 3;
writel(VIA_PITCH_ENABLE | (linesize >> 3) | ((linesize >> 3) << 16),
viaparinfo->io_virt + VIA_REG_PITCH);
}

void viafb_set_2d_color_depth(int bpp)
{
u32 dwGEMode;

dwGEMode = readl(viaparinfo->io_virt + 0x04) & 0xFFFFFCFF;

switch (bpp) {
case 16:
dwGEMode |= VIA_GEM_16bpp;
break;
case 32:
dwGEMode |= VIA_GEM_32bpp;
break;
default:
dwGEMode |= VIA_GEM_8bpp;
break;
}

/* Set BPP and Pitch */
writel(dwGEMode, viaparinfo->io_virt + VIA_REG_GEMODE);
}

void viafb_hw_cursor_init(void)
Expand Down
Loading

0 comments on commit 2e05ccb

Please sign in to comment.