12ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov/* 22ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * drivers/mb862xx/mb862xxfb_accel.c 32ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * 42ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver acceleration support 52ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * 62ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * (C) 2007 Alexander Shishkin <virtuoso@slind.org> 7da258016293f5e82b36db67ac3db3931a4fbbc4dAlexander Shishkin * (C) 2009 Valentin Sitdikov <v.sitdikov@gmail.com> 82ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * (C) 2009 Siemens AG 92ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * 102ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * This program is free software; you can redistribute it and/or modify 112ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * it under the terms of the GNU General Public License version 2 as 122ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * published by the Free Software Foundation. 132ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * 142ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov */ 152ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov#include <linux/fb.h> 162ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov#include <linux/delay.h> 172ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov#include <linux/init.h> 182ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov#include <linux/interrupt.h> 19a71dc148c2674bbb5988ea924702137993b3305aRandy Dunlap#include <linux/module.h> 202ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov#include <linux/pci.h> 215a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 222ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov#if defined(CONFIG_OF) 232ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov#include <linux/of_platform.h> 242ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov#endif 252ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov#include "mb862xxfb.h" 262ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov#include "mb862xx_reg.h" 272ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov#include "mb862xxfb_accel.h" 282ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 292ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikovstatic void mb862xxfb_write_fifo(u32 count, u32 *data, struct fb_info *info) 302ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov{ 312ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov struct mb862xxfb_par *par = info->par; 322ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov static u32 free; 332ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 342ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u32 total = 0; 352ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov while (total < count) { 362ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov if (free) { 372ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov outreg(geo, GDC_GEO_REG_INPUT_FIFO, data[total]); 382ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov total++; 392ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov free--; 402ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov } else { 412ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov free = (u32) inreg(draw, GDC_REG_FIFO_COUNT); 422ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov } 432ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov } 442ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov} 452ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 462ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikovstatic void mb86290fb_copyarea(struct fb_info *info, 472ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov const struct fb_copyarea *area) 482ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov{ 492ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov __u32 cmd[6]; 502ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 512ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[0] = (GDC_TYPE_SETREGISTER << 24) | (1 << 16) | GDC_REG_MODE_BITMAP; 522ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov /* Set raster operation */ 532ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[1] = (2 << 7) | (GDC_ROP_COPY << 9); 542ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[2] = GDC_TYPE_BLTCOPYP << 24; 552ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 562ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov if (area->sx >= area->dx && area->sy >= area->dy) 572ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[2] |= GDC_CMD_BLTCOPY_TOP_LEFT << 16; 582ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov else if (area->sx >= area->dx && area->sy <= area->dy) 592ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[2] |= GDC_CMD_BLTCOPY_BOTTOM_LEFT << 16; 602ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov else if (area->sx <= area->dx && area->sy >= area->dy) 612ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[2] |= GDC_CMD_BLTCOPY_TOP_RIGHT << 16; 622ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov else 632ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[2] |= GDC_CMD_BLTCOPY_BOTTOM_RIGHT << 16; 642ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 652ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[3] = (area->sy << 16) | area->sx; 662ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[4] = (area->dy << 16) | area->dx; 672ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[5] = (area->height << 16) | area->width; 682ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov mb862xxfb_write_fifo(6, cmd, info); 692ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov} 702ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 712ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov/* 722ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * Fill in the cmd array /GDC FIFO commands/ to draw a 1bit image. 732ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * Make sure cmd has enough room! 742ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov */ 752ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikovstatic void mb86290fb_imageblit1(u32 *cmd, u16 step, u16 dx, u16 dy, 762ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u16 width, u16 height, u32 fgcolor, 772ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u32 bgcolor, const struct fb_image *image, 782ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov struct fb_info *info) 792ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov{ 802ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov int i; 812ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov unsigned const char *line; 822ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u16 bytes; 832ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 842ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov /* set colors and raster operation regs */ 852ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[0] = (GDC_TYPE_SETREGISTER << 24) | (1 << 16) | GDC_REG_MODE_BITMAP; 862ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov /* Set raster operation */ 872ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[1] = (2 << 7) | (GDC_ROP_COPY << 9); 882ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[2] = 892ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov (GDC_TYPE_SETCOLORREGISTER << 24) | (GDC_CMD_BODY_FORE_COLOR << 16); 902ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[3] = fgcolor; 912ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[4] = 922ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov (GDC_TYPE_SETCOLORREGISTER << 24) | (GDC_CMD_BODY_BACK_COLOR << 16); 932ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[5] = bgcolor; 942ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 952ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov i = 0; 962ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov line = image->data; 972ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov bytes = (image->width + 7) >> 3; 982ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 992ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov /* and the image */ 1002ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[6] = (GDC_TYPE_DRAWBITMAPP << 24) | 1012ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov (GDC_CMD_BITMAP << 16) | (2 + (step * height)); 1022ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[7] = (dy << 16) | dx; 1032ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[8] = (height << 16) | width; 1042ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 1052ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov while (i < height) { 1062ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov memcpy(&cmd[9 + i * step], line, step << 2); 1072ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov#ifdef __LITTLE_ENDIAN 1082ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov { 1092ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov int k = 0; 1102ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov for (k = 0; k < step; k++) 1112ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[9 + i * step + k] = 1122ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cpu_to_be32(cmd[9 + i * step + k]); 1132ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov } 1142ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov#endif 1152ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov line += bytes; 1162ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov i++; 1172ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov } 1182ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov} 1192ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 1202ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov/* 1212ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * Fill in the cmd array /GDC FIFO commands/ to draw a 8bit image. 1222ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * Make sure cmd has enough room! 1232ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov */ 1242ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikovstatic void mb86290fb_imageblit8(u32 *cmd, u16 step, u16 dx, u16 dy, 1252ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u16 width, u16 height, u32 fgcolor, 1262ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u32 bgcolor, const struct fb_image *image, 1272ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov struct fb_info *info) 1282ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov{ 1292ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov int i, j; 1302ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov unsigned const char *line, *ptr; 1312ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u16 bytes; 1322ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 1332ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[0] = (GDC_TYPE_DRAWBITMAPP << 24) | 1342ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov (GDC_CMD_BLT_DRAW << 16) | (2 + (height * step)); 1352ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[1] = (dy << 16) | dx; 1362ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[2] = (height << 16) | width; 1372ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 1382ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov i = 0; 1392ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov line = ptr = image->data; 1402ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov bytes = image->width; 1412ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 1422ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov while (i < height) { 1432ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov ptr = line; 1442ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov for (j = 0; j < step; j++) { 1452ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[3 + i * step + j] = 1462ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov (((u32 *) (info->pseudo_palette))[*ptr]) & 0xffff; 1472ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov ptr++; 1482ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[3 + i * step + j] |= 1492ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov ((((u32 *) (info-> 1502ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov pseudo_palette))[*ptr]) & 0xffff) << 16; 1512ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov ptr++; 1522ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov } 1532ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 1542ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov line += bytes; 1552ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov i++; 1562ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov } 1572ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov} 1582ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 1592ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov/* 1602ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * Fill in the cmd array /GDC FIFO commands/ to draw a 16bit image. 1612ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * Make sure cmd has enough room! 1622ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov */ 1632ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikovstatic void mb86290fb_imageblit16(u32 *cmd, u16 step, u16 dx, u16 dy, 1642ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u16 width, u16 height, u32 fgcolor, 1652ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u32 bgcolor, const struct fb_image *image, 1662ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov struct fb_info *info) 1672ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov{ 1682ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov int i; 1692ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov unsigned const char *line; 1702ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u16 bytes; 1712ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 1722ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov i = 0; 1732ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov line = image->data; 1742ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov bytes = image->width << 1; 1752ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 1762ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[0] = (GDC_TYPE_DRAWBITMAPP << 24) | 1772ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov (GDC_CMD_BLT_DRAW << 16) | (2 + step * height); 1782ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[1] = (dy << 16) | dx; 1792ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[2] = (height << 16) | width; 1802ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 1812ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov while (i < height) { 1822ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov memcpy(&cmd[3 + i * step], line, step); 1832ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov line += bytes; 1842ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov i++; 1852ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov } 1862ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov} 1872ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 1882ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikovstatic void mb86290fb_imageblit(struct fb_info *info, 1892ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov const struct fb_image *image) 1902ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov{ 1912ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov int mdr; 1922ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u32 *cmd = NULL; 1932ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov void (*cmdfn) (u32 *, u16, u16, u16, u16, u16, u32, u32, 1942ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov const struct fb_image *, struct fb_info *) = NULL; 1952ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u32 cmdlen; 1962ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u32 fgcolor = 0, bgcolor = 0; 1972ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u16 step; 1982ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 1992ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u16 width = image->width, height = image->height; 2002ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u16 dx = image->dx, dy = image->dy; 2012ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov int x2, y2, vxres, vyres; 2022ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2032ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov mdr = (GDC_ROP_COPY << 9); 2042ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov x2 = image->dx + image->width; 2052ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov y2 = image->dy + image->height; 2062ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov vxres = info->var.xres_virtual; 2072ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov vyres = info->var.yres_virtual; 2082ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov x2 = min(x2, vxres); 2092ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov y2 = min(y2, vyres); 2102ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov width = x2 - dx; 2112ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov height = y2 - dy; 2122ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2132ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov switch (image->depth) { 2142ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov case 1: 2152ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov step = (width + 31) >> 5; 2162ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmdlen = 9 + height * step; 2172ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmdfn = mb86290fb_imageblit1; 2182ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov if (info->fix.visual == FB_VISUAL_TRUECOLOR || 2192ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov info->fix.visual == FB_VISUAL_DIRECTCOLOR) { 2202ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov fgcolor = 2212ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov ((u32 *) (info->pseudo_palette))[image->fg_color]; 2222ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov bgcolor = 2232ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov ((u32 *) (info->pseudo_palette))[image->bg_color]; 2242ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov } else { 2252ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov fgcolor = image->fg_color; 2262ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov bgcolor = image->bg_color; 2272ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov } 2282ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2292ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov break; 2302ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2312ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov case 8: 2322ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov step = (width + 1) >> 1; 2332ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmdlen = 3 + height * step; 2342ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmdfn = mb86290fb_imageblit8; 2352ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov break; 2362ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2372ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov case 16: 2382ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov step = (width + 1) >> 1; 2392ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmdlen = 3 + height * step; 2402ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmdfn = mb86290fb_imageblit16; 2412ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov break; 2422ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2432ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov default: 2442ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cfb_imageblit(info, image); 2452ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov return; 2462ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov } 2472ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2482ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd = kmalloc(cmdlen * 4, GFP_DMA); 2492ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov if (!cmd) 2502ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov return cfb_imageblit(info, image); 2512ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmdfn(cmd, step, dx, dy, width, height, fgcolor, bgcolor, image, info); 2522ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov mb862xxfb_write_fifo(cmdlen, cmd, info); 2532ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov kfree(cmd); 2542ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov} 2552ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2562ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikovstatic void mb86290fb_fillrect(struct fb_info *info, 2572ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov const struct fb_fillrect *rect) 2582ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov{ 2592ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2602ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u32 x2, y2, vxres, vyres, height, width, fg; 2612ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov u32 cmd[7]; 2622ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2632ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov vxres = info->var.xres_virtual; 2642ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov vyres = info->var.yres_virtual; 2652ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2662ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov if (!rect->width || !rect->height || rect->dx > vxres 2672ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov || rect->dy > vyres) 2682ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov return; 2692ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2702ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov /* We could use hardware clipping but on many cards you get around 2712ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov * hardware clipping by writing to framebuffer directly. */ 2722ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov x2 = rect->dx + rect->width; 2732ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov y2 = rect->dy + rect->height; 2742ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov x2 = min(x2, vxres); 2752ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov y2 = min(y2, vyres); 2762ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov width = x2 - rect->dx; 2772ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov height = y2 - rect->dy; 2782ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov if (info->fix.visual == FB_VISUAL_TRUECOLOR || 2792ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov info->fix.visual == FB_VISUAL_DIRECTCOLOR) 2802ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov fg = ((u32 *) (info->pseudo_palette))[rect->color]; 2812ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov else 2822ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov fg = rect->color; 2832ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2842ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov switch (rect->rop) { 2852ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2862ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov case ROP_XOR: 2872ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov /* Set raster operation */ 2882ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[1] = (2 << 7) | (GDC_ROP_XOR << 9); 2892ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov break; 2902ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2912ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov case ROP_COPY: 2922ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov /* Set raster operation */ 2932ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[1] = (2 << 7) | (GDC_ROP_COPY << 9); 2942ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov break; 2952ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2962ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov } 2972ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 2982ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[0] = (GDC_TYPE_SETREGISTER << 24) | (1 << 16) | GDC_REG_MODE_BITMAP; 2992ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov /* cmd[1] set earlier */ 3002ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[2] = 3012ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov (GDC_TYPE_SETCOLORREGISTER << 24) | (GDC_CMD_BODY_FORE_COLOR << 16); 3022ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[3] = fg; 3032ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[4] = (GDC_TYPE_DRAWRECTP << 24) | (GDC_CMD_BLT_FILL << 16); 3042ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[5] = (rect->dy << 16) | (rect->dx); 3052ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov cmd[6] = (height << 16) | width; 3062ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 3072ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov mb862xxfb_write_fifo(7, cmd, info); 3082ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov} 3092ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 3102ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikovvoid mb862xxfb_init_accel(struct fb_info *info, int xres) 3112ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov{ 3122ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov struct mb862xxfb_par *par = info->par; 3132ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 3142ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov if (info->var.bits_per_pixel == 32) { 3152ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov info->fbops->fb_fillrect = cfb_fillrect; 3162ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov info->fbops->fb_copyarea = cfb_copyarea; 3172ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov info->fbops->fb_imageblit = cfb_imageblit; 3182ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov } else { 3192ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov outreg(disp, GC_L0EM, 3); 3202ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov info->fbops->fb_fillrect = mb86290fb_fillrect; 3212ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov info->fbops->fb_copyarea = mb86290fb_copyarea; 3222ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov info->fbops->fb_imageblit = mb86290fb_imageblit; 3232ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov } 3242ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov outreg(draw, GDC_REG_DRAW_BASE, 0); 3252ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov outreg(draw, GDC_REG_MODE_MISC, 0x8000); 3262ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov outreg(draw, GDC_REG_X_RESOLUTION, xres); 3272ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov 3282ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov info->flags |= 3292ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | 3302ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov FBINFO_HWACCEL_IMAGEBLIT; 3312ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov info->fix.accel = 0xff; /*FIXME: add right define */ 3322ec509b96cce5e6d19ee43fdd818eab78e76328dValentin Sitdikov} 3332ec509b96cce5e6d19ee43fdd818eab78e76328dValentin SitdikovEXPORT_SYMBOL(mb862xxfb_init_accel); 334a71dc148c2674bbb5988ea924702137993b3305aRandy Dunlap 335a71dc148c2674bbb5988ea924702137993b3305aRandy DunlapMODULE_LICENSE("GPL v2"); 336