Skip to content

Commit

Permalink
tgafb accelerated code
Browse files Browse the repository at this point in the history
Add accelerated panning and accelerated color and mono image drawing.
Please apply.

Signed-off-by: James Simmons <jsimmons@infradead.org>
Acked-by: Maciej W. Rozycki <macro@linux-mips.org>  (tested, too!)
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
James Simmons authored and Linus Torvalds committed May 8, 2007
1 parent 86c6f7d commit 28b230e
Showing 1 changed file with 113 additions and 44 deletions.
157 changes: 113 additions & 44 deletions drivers/video/tgafb.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ static void tgafb_init_fix(struct fb_info *);
static void tgafb_imageblit(struct fb_info *, const struct fb_image *);
static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *);
static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *);
static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);

static int __devinit tgafb_register(struct device *dev);
static void __devexit tgafb_unregister(struct device *dev);
Expand All @@ -81,6 +82,7 @@ static struct fb_ops tgafb_ops = {
.fb_set_par = tgafb_set_par,
.fb_setcolreg = tgafb_setcolreg,
.fb_blank = tgafb_blank,
.fb_pan_display = tgafb_pan_display,
.fb_fillrect = tgafb_fillrect,
.fb_copyarea = tgafb_copyarea,
.fb_imageblit = tgafb_imageblit,
Expand Down Expand Up @@ -319,21 +321,7 @@ tgafb_set_par(struct fb_info *info)
BT485_WRITE(par, 0x00, BT485_ADDR_PAL_WRITE);
TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);

#ifdef CONFIG_HW_CONSOLE
for (i = 0; i < 16; i++) {
int j = color_table[i];

TGA_WRITE_REG(par, default_red[j]|(BT485_DATA_PAL<<8),
TGA_RAMDAC_REG);
TGA_WRITE_REG(par, default_grn[j]|(BT485_DATA_PAL<<8),
TGA_RAMDAC_REG);
TGA_WRITE_REG(par, default_blu[j]|(BT485_DATA_PAL<<8),
TGA_RAMDAC_REG);
}
for (i = 0; i < 240 * 3; i += 4) {
#else
for (i = 0; i < 256 * 3; i += 4) {
#endif
TGA_WRITE_REG(par, 0x55 | (BT485_DATA_PAL << 8),
TGA_RAMDAC_REG);
TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8),
Expand All @@ -358,18 +346,7 @@ tgafb_set_par(struct fb_info *info)
BT459_LOAD_ADDR(par, 0x0000);
TGA_WRITE_REG(par, BT459_PALETTE << 2, TGA_RAMDAC_SETUP_REG);

#ifdef CONFIG_HW_CONSOLE
for (i = 0; i < 16; i++) {
int j = color_table[i];

TGA_WRITE_REG(par, default_red[j], TGA_RAMDAC_REG);
TGA_WRITE_REG(par, default_grn[j], TGA_RAMDAC_REG);
TGA_WRITE_REG(par, default_blu[j], TGA_RAMDAC_REG);
}
for (i = 0; i < 240 * 3; i += 4) {
#else
for (i = 0; i < 256 * 3; i += 4) {
#endif
TGA_WRITE_REG(par, 0x55, TGA_RAMDAC_REG);
TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
Expand Down Expand Up @@ -646,16 +623,8 @@ tgafb_blank(int blank, struct fb_info *info)
* Acceleration.
*/

/**
* tgafb_imageblit - REQUIRED function. Can use generic routines if
* non acclerated hardware and packed pixel based.
* Copies a image from system memory to the screen.
*
* @info: frame buffer structure that represents a single frame buffer
* @image: structure defining the image.
*/
static void
tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct tga_par *par = (struct tga_par *) info->par;
u32 fgcolor, bgcolor, dx, dy, width, height, vxres, vyres, pixelmask;
Expand All @@ -665,6 +634,17 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
void __iomem *regs_base;
void __iomem *fb_base;

is8bpp = info->var.bits_per_pixel == 8;

/* For copies that aren't pixel expansion, there's little we
can do better than the generic code. */
/* ??? There is a DMA write mode; I wonder if that could be
made to pull the data from the image buffer... */
if (image->depth > 1) {
cfb_imageblit(info, image);
return;
}

dx = image->dx;
dy = image->dy;
width = image->width;
Expand All @@ -682,18 +662,8 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
if (dy + height > vyres)
height = vyres - dy;

/* For copies that aren't pixel expansion, there's little we
can do better than the generic code. */
/* ??? There is a DMA write mode; I wonder if that could be
made to pull the data from the image buffer... */
if (image->depth > 1) {
cfb_imageblit(info, image);
return;
}

regs_base = par->tga_regs_base;
fb_base = par->tga_fb_base;
is8bpp = info->var.bits_per_pixel == 8;

/* Expand the color values to fill 32-bits. */
/* ??? Would be nice to notice colour changes elsewhere, so
Expand Down Expand Up @@ -871,6 +841,85 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
regs_base + TGA_MODE_REG);
}

static void
tgafb_clut_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct tga_par *par = (struct tga_par *) info->par;
u32 color, dx, dy, width, height, vxres, vyres;
u32 *palette = ((u32 *)info->pseudo_palette);
unsigned long pos, line_length, i, j;
const unsigned char *data;
void *regs_base, *fb_base;

dx = image->dx;
dy = image->dy;
width = image->width;
height = image->height;
vxres = info->var.xres_virtual;
vyres = info->var.yres_virtual;
line_length = info->fix.line_length;

/* Crop the image to the screen. */
if (dx > vxres || dy > vyres)
return;
if (dx + width > vxres)
width = vxres - dx;
if (dy + height > vyres)
height = vyres - dy;

regs_base = par->tga_regs_base;
fb_base = par->tga_fb_base;

pos = dy * line_length + (dx * 4);
data = image->data;

/* Now copy the image, color_expanding via the palette. */
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
color = palette[*data++];
__raw_writel(color, fb_base + pos + j*4);
}
pos += line_length;
}
}

/**
* tgafb_imageblit - REQUIRED function. Can use generic routines if
* non acclerated hardware and packed pixel based.
* Copies a image from system memory to the screen.
*
* @info: frame buffer structure that represents a single frame buffer
* @image: structure defining the image.
*/
static void
tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
{
unsigned int is8bpp = info->var.bits_per_pixel == 8;

/* If a mono image, regardless of FB depth, go do it. */
if (image->depth == 1) {
tgafb_mono_imageblit(info, image);
return;
}

/* For copies that aren't pixel expansion, there's little we
can do better than the generic code. */
/* ??? There is a DMA write mode; I wonder if that could be
made to pull the data from the image buffer... */
if (image->depth == info->var.bits_per_pixel) {
cfb_imageblit(info, image);
return;
}

/* If 24-plane FB and the image is 8-plane with CLUT, we can do it. */
if (!is8bpp && image->depth == 8) {
tgafb_clut_imageblit(info, image);
return;
}

/* Silently return... */
}

/**
* tgafb_fillrect - REQUIRED function. Can use generic routines if
* non acclerated hardware and packed pixel based.
Expand Down Expand Up @@ -1480,6 +1529,26 @@ tgafb_init_fix(struct fb_info *info)
info->fix.ywrapstep = 0;

info->fix.accel = FB_ACCEL_DEC_TGA;

/*
* These are needed by fb_set_logo_truepalette(), so we
* set them here for 24-plane cards.
*/
if (tga_type != TGA_TYPE_8PLANE) {
info->var.red.length = 8;
info->var.green.length = 8;
info->var.blue.length = 8;
info->var.red.offset = 16;
info->var.green.offset = 8;
info->var.blue.offset = 0;
}
}

static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
{
/* We just use this to catch switches out of graphics mode. */
tgafb_set_par(info); /* A bit of overkill for BASE_ADDR reset. */
return 0;
}

static int __devinit
Expand Down

0 comments on commit 28b230e

Please sign in to comment.