diff options
Diffstat (limited to 'target/linux/ep93xx/patches-2.6.30/009-ep93xx-fb.patch')
-rw-r--r-- | target/linux/ep93xx/patches-2.6.30/009-ep93xx-fb.patch | 3565 |
1 files changed, 0 insertions, 3565 deletions
diff --git a/target/linux/ep93xx/patches-2.6.30/009-ep93xx-fb.patch b/target/linux/ep93xx/patches-2.6.30/009-ep93xx-fb.patch deleted file mode 100644 index d7816bd722..0000000000 --- a/target/linux/ep93xx/patches-2.6.30/009-ep93xx-fb.patch +++ /dev/null @@ -1,3565 +0,0 @@ ---- a/drivers/video/Kconfig -+++ b/drivers/video/Kconfig -@@ -255,6 +255,25 @@ config FB_CIRRUS - Say N unless you have such a graphics board or plan to get one - before you next recompile the kernel. - -+config FB_EP93XX -+ tristate "EP93xx frame buffer support" -+ depends on FB -+ select FB_CFB_FILLRECT -+ select FB_CFB_COPYAREA -+ select FB_CFB_IMAGEBLIT -+ help -+ This is the frame buffer device driver for the internal raster engine -+ on certain members of the EP93xx family. For VGA and LCD output. -+ -+config FB_EP93XX_MONO -+ tristate "EP93xx Mono frame buffer support" -+ depends on FB -+ select FB_CFB_FILLRECT -+ select FB_CFB_COPYAREA -+ help -+ This is the frame buffer device driver for the internal raster engine -+ on certain members of the EP93xx family. For LCD output. -+ - config FB_PM2 - tristate "Permedia2 support" - depends on FB && ((AMIGA && BROKEN) || PCI) ---- a/drivers/video/Makefile -+++ b/drivers/video/Makefile -@@ -95,6 +95,8 @@ obj-$(CONFIG_FB_ARMCLCD) += amba-clcd. - obj-$(CONFIG_FB_68328) += 68328fb.o - obj-$(CONFIG_FB_GBE) += gbefb.o - obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o -+obj-$(CONFIG_FB_EP93XX) += ep93xxfb.o -+obj-$(CONFIG_FB_EP93XX_MONO) += ep93xxfb_mono.o - obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o - obj-$(CONFIG_FB_PXA) += pxafb.o - obj-$(CONFIG_FB_W100) += w100fb.o ---- /dev/null -+++ b/drivers/video/ep93xxfb.c -@@ -0,0 +1,1628 @@ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/reboot.h> -+#include <linux/errno.h> -+#include <linux/string.h> -+#include <linux/mm.h> -+#include <linux/delay.h> -+#include <linux/fb.h> -+#include <linux/init.h> -+#include <linux/ioport.h> -+#include <linux/interrupt.h> -+#include <linux/dma-mapping.h> -+#include <asm/io.h> -+#include <asm/uaccess.h> -+#include "ep93xxfb.h" -+#include <mach/hardware.h> -+#include <linux/platform_device.h> -+ -+#include "console/fbcon.h" -+ -+ -+#if defined(CONFIG_MACH_EDB9312) || defined(CONFIG_MACH_EDB9315) || defined(CONFIG_MACH_EDB9307) || defined(CONFIG_MACH_EDB9301) || defined(CONFIG_MACH_EDB9302) -+#define CONFIG_EP93XX_SDCS3 -+#else -+#define CONFIG_EP93XX_SDCS0 -+#endif -+ -+//#define DEBUG 1 -+#ifdef DEBUG -+#define DPRINTK( fmt, arg... ) printk( fmt, ##arg ) -+#else -+#define DPRINTK( fmt, arg... ) -+#endif -+ -+#define FBDEV_NAME "ep93xxfb" -+ -+#define ep93xxfb_outl(value, reg) \ -+{ \ -+ outl(RASTER_SWLOCK_VALUE, RASTER_SWLOCK); \ -+ outl(value, reg); \ -+} -+ -+#define DEFAULT_OUT CRT_OUT -+#define DEFAULT_MODE 7 -+#define DEFAULT_BPP 24 -+ -+static DECLARE_WAIT_QUEUE_HEAD(ep93xxfb_wait_in); -+ -+static unsigned int pseudo_palette[256]; -+static unsigned long *cursor_data = NULL; -+static struct ep93xxfb_info epinfo; -+ -+static int vout = DEFAULT_OUT; -+static int vmode = DEFAULT_MODE; -+static int depth = DEFAULT_BPP; -+ -+ -+static int ep93xxfb_setcol(struct fb_info *info, int bpp); -+ -+ -+static struct ep93xxfb_videomodes ep93xxfb_vmods[] = { -+ { -+ "Philips-LB064V02-640x480x60", -+ 640, 24, 96, 40, 480, 10, 2, 33, 60, -+ CLK_INTERNAL, EDGE_FALLING, POL_LOW, POL_LOW, POL_LOW, -+ }, -+ { // 1 -+ "CRT-640x480-60", -+ 640, 24, 96, 40, 480, 11, 2, 32, 60, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_LOW, POL_LOW, -+ }, -+ { // 2 -+ "CRT-640x480-72", -+ 640, 40, 40, 144, 480, 8, 3, 30, 72, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_LOW, POL_LOW, -+ }, -+ { // 3 -+ "CRT-640x480-75", -+ 640, 16, 76, 120, 480, 1, 3, 16, 75, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_LOW, POL_LOW, -+ }, -+ { // 4 -+ "CRT-640x480-85", -+ 640, 56, 56, 80, 480, 1, 3, 25, 85, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_LOW, POL_LOW, -+ }, -+ { // 5 -+ "CTR-640x480-100", -+ 640, 32, 96, 96, 480, 8, 6, 36, 100, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_LOW, POL_LOW, -+ }, -+ { // 6 -+ "CRT-800x600-56", -+ 800, 24, 72, 128, 600, 1, 2, 22, 56, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_LOW, POL_LOW, -+ }, -+ { // 7 -+ "CRT-800x600-60", -+ 800, 40, 128, 88, 600, 1, 4, 23, 60, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_HIGH, POL_HIGH, -+ }, -+ { // 8 -+ "CRT-800x600-72", -+ 800, 56, 120, 64, 600, 37, 6, 23, 72, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_LOW, POL_LOW, -+ }, -+ { // 9 -+ "CRT-800x600-85", -+ 800, 64, 64, 160, 600, 16, 5, 36, 85, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_LOW, POL_LOW, -+ }, -+ { // 10 -+ "CRT-800x600-100", -+ 800, 64, 64, 160, 600, 4, 6, 30, 100, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_LOW, POL_LOW, -+ }, -+ { // 11 -+ "CRT-1024x768-60", -+ 1024, 8, 144, 168, 768, 3, 6, 29, 60, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_LOW, POL_LOW, -+ }, -+ { // 12 -+ "CRT-1024x768-70", -+ 1024, 24, 136, 144, 768, 3, 6, 29, 70, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_LOW, POL_LOW, -+ }, -+ { // 13 -+ "CRT-1024x768-75", -+ 1024, 16, 96, 176, 768, 1, 3, 28, 75, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_HIGH, POL_HIGH, -+ }, -+ { // 14 -+ "CRT-1024x768-85", -+ 1024, 48, 96, 208, 768, 1, 3, 36, 85, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_HIGH, POL_HIGH, -+ }, -+ { // 15 -+ "CRT-1280x720-60", -+ 1280, 48, 112, 248, 720, 1, 3, 38, 60, -+ CLK_INTERNAL, EDGE_RISING, POL_LOW, POL_HIGH, POL_HIGH, -+ } -+}; -+ -+static void philips_lb064v02_on(unsigned char value) -+{ -+ DPRINTK("philips_lb064v02_on \n"); -+ outl(inl(GPIO_PADDR) | 2, GPIO_PADDR); -+ outl(inl(GPIO_PADR) | 2, GPIO_PADR); -+} -+ -+static void philips_lb064v02_off(unsigned char value) -+{ -+ DPRINTK("philips_lb064v02_off \n"); -+ outl(inl(GPIO_PADR) & ~2, GPIO_PADR); -+} -+ -+static irqreturn_t ep93xxfb_irq_handler(int i, void *blah) -+{ -+ outl(0x00000000, BLOCKCTRL); -+ wake_up(&ep93xxfb_wait_in); -+ return IRQ_HANDLED; -+} -+ -+static void ep93xxfb_wait(void) -+{ -+ DECLARE_WAITQUEUE(wait, current); -+ add_wait_queue(&ep93xxfb_wait_in, &wait); -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ -+ while (inl(BLOCKCTRL) & 0x00000001){ -+ if(/*(pls_proba==1)&&*/(!in_atomic())) -+ schedule(); -+ } -+ -+ remove_wait_queue(&ep93xxfb_wait_in, &wait); -+ set_current_state(TASK_RUNNING); -+ -+} -+ -+void ep93xxfb_fillrect(struct fb_info *p, const struct fb_fillrect *fill) -+{ -+ unsigned long blkdestwidth,tmp; -+ -+ if (!fill->width || !fill->height || -+ (fill->dx >= p->var.xres) || -+ (fill->dy >= p->var.yres) || -+ ((fill->dx + fill->width - 1) >= p->var.xres) || -+ ((fill->dy + fill->height - 1) >= p->var.yres)) -+ return; -+ -+ tmp = (( fill->dx + fill->width ) * epinfo.bpp ); -+ blkdestwidth = tmp / 32; -+ if(blkdestwidth > 0 && (tmp % 32 == 0)) -+ blkdestwidth--; -+ blkdestwidth = blkdestwidth - (fill->dx * epinfo.bpp) / 32; -+ -+ outl(fill->color, BLOCKMASK); -+ outl( ((fill->dx * epinfo.bpp) & 0x1F) | -+ ((((fill->dx + fill->width - 1) * epinfo.bpp ) & 0x1F) << 16), -+ DESTPIXELSTRT); -+ outl( ((epinfo.xres * epinfo.bpp) / 32), DESTLINELENGTH); -+ outl( blkdestwidth, BLKDESTWIDTH ); -+ outl(fill->height - 1, BLKDESTHEIGHT); -+ outl((epinfo.fb_phys + (fill->dy * epinfo.xres * epinfo.bpp ) / 8 + -+ (fill->dx * epinfo.bpp ) / 8 ) -+ , BLKDSTSTRT); -+ outl( epinfo.pixformat | 0x0000000B, BLOCKCTRL); -+ ep93xxfb_wait(); -+ -+} -+ -+void ep93xxfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) -+{ -+ unsigned long startsx,stopsx,startdx,stopdx,startsy,startdy; -+ unsigned long blksrcwidth,blkdestwidth,tmp; -+ unsigned long val = 0; -+ -+ if( !area->width || !area->width || -+ (area->sx >= p->var.xres) || (area->sy >= p->var.yres) || -+ (area->dx >= p->var.xres) || (area->dy >= p->var.yres) || -+ ((area->dx + area->width - 1) >= p->var.xres) || -+ ((area->dy + area->height - 1) >= p->var.yres)) -+ return; -+ -+ if(area->sx == area->dx && area->sy == area->dy) -+ return; -+ -+ if ((area->dy == area->sy) && (area->dx > area->sx) && -+ (area->dx < (area->sx + area->width - 1))) { -+ startdx = area->dx + area->width - 1; -+ stopdx = area->dx; -+ startsx = area->sx + area->width - 1; -+ stopsx = area->sx; -+ val |= 0x000000A0; -+ } -+ else { -+ startdx = area->dx; -+ stopdx = area->dx + area->width - 1; -+ startsx = area->sx; -+ stopsx = area->sx + area->width - 1; -+ } -+ -+ if (area->dy <= area->sy) { -+ startdy = area->dy; -+ startsy = area->sy; -+ } -+ else { -+ startdy = area->dy + area->height -1; -+ startsy = area->sy + area->height -1; -+ val |= 0x00000140; -+ } -+ -+ tmp = (( area->sx + area->width ) * epinfo.bpp ); -+ blksrcwidth = tmp / 32; -+ if(blksrcwidth > 0 && (tmp % 32 == 0)) -+ blksrcwidth--; -+ blksrcwidth = blksrcwidth - (area->sx * epinfo.bpp) / 32; -+ -+ tmp = (( area->dx + area->width ) * epinfo.bpp ); -+ blkdestwidth = tmp / 32; -+ if(blkdestwidth > 0 && (tmp % 32 == 0)) -+ blkdestwidth--; -+ blkdestwidth = blkdestwidth - (area->dx * epinfo.bpp) / 32; -+ -+ outl( 0x00000000 , BLOCKCTRL); -+ -+ /*** src ***/ -+ outl((((startsx * epinfo.bpp) & 0x1F) | -+ (((stopsx * epinfo.bpp ) & 0x1F) << 16)) -+ , SRCPIXELSTRT); -+ outl((epinfo.fb_phys + (startsy * epinfo.xres * epinfo.bpp ) / 8 + -+ (startsx * epinfo.bpp ) / 8 ) -+ , BLKSRCSTRT); -+ outl(((epinfo.xres * epinfo.bpp) / 32), SRCLINELENGTH); -+ outl( blksrcwidth, BLKSRCWIDTH ); -+ -+ /*** dest ***/ -+ outl((((startdx * epinfo.bpp) & 0x1F) | -+ (((stopdx * epinfo.bpp ) & 0x1F) << 16)) -+ , DESTPIXELSTRT); -+ outl((epinfo.fb_phys + (startdy * epinfo.xres * epinfo.bpp ) / 8 + -+ (startdx * epinfo.bpp ) / 8 ) -+ , BLKDSTSTRT); -+ outl( ((epinfo.xres * epinfo.bpp) / 32), DESTLINELENGTH); -+ outl( blkdestwidth, BLKDESTWIDTH); -+ outl( area->height - 1 , BLKDESTHEIGHT); -+ outl( epinfo.pixformat | val | 0x00000003, BLOCKCTRL); -+ ep93xxfb_wait(); -+} -+ -+void ep93xxfb_imageblit(struct fb_info *p, const struct fb_image *image) -+{ -+// unsigned long blkdestwidth,tmp; -+// void * pucBlitBuf; -+ cfb_imageblit( p , image ); -+ return; -+/* -+ if ((image->dx >= p->var.xres) || -+ (image->dy >= p->var.yres) || -+ ((image->dx + image->width - 1) >= p->var.xres) || -+ ((image->dy + image->height - 1) >= p->var.yres)) -+ return; -+ if (epinfo.bpp != image->depth ) -+ return; -+ -+ tmp = (( image->dx + image->width ) * epinfo.bpp ); -+ blkdestwidth = tmp / 32; -+ if(blkdestwidth > 0 && (tmp % 32 == 0)) -+ blkdestwidth--; -+ blkdestwidth = blkdestwidth - (image->dx * epinfo.bpp) / 32; -+ -+ pucBlitBuf = kmalloc(1024*8,GFP_KERNEL); -+ copy_from_user(pucBlitBuf, image->data, 5000); -+ -+ outl( 0x00000000 , BLOCKCTRL); -+ -+ outl( 0x00000000, SRCPIXELSTRT); -+ outl( virt_to_phys(pucBlitBuf), BLKSRCSTRT); -+ outl( (image->width * epinfo.bpp) / 32 , SRCLINELENGTH); -+ outl(((image->width - 1) * epinfo.bpp) / 32, BLKSRCWIDTH ); -+ -+ outl(((image->dx * epinfo.bpp) & 0x1F) | -+ ((((image->dx + image->width - 1) * epinfo.bpp ) & 0x1F) << 16) -+ , DESTPIXELSTRT); -+ outl((epinfo.fb_phys + (image->dy * epinfo.xres * epinfo.bpp ) / 8 + -+ (image->dx * epinfo.bpp ) / 8 ) -+ , BLKDSTSTRT); -+ outl( ((epinfo.xres * epinfo.bpp) / 32), DESTLINELENGTH ); -+ outl( blkdestwidth, BLKDESTWIDTH ); -+ outl( image->height - 1 , BLKDESTHEIGHT); -+ outl(image->fg_color, BLOCKMASK); -+ outl(image->bg_color, BACKGROUND); -+ outl( epinfo.pixformat | 0x00000003, BLOCKCTRL ); -+ ep93xxfb_wait(); -+*/ -+} -+ -+ -+static unsigned long isqrt(unsigned long a) -+{ -+ unsigned long rem = 0; -+ unsigned long root = 0; -+ int i; -+ -+ for (i = 0; i < 16; i++) { -+ root <<= 1; -+ rem = ((rem << 2) + (a >> 30)); -+ a <<= 2; -+ root++; -+ if (root <= rem) { -+ rem -= root; -+ root++; -+ } -+ else -+ root--; -+ } -+ return root >> 1; -+} -+ -+int ep93xxfb_line(struct fb_info *info, struct ep93xx_line *line) -+{ -+ unsigned long value = 0; -+ long x, y, dx, dy, count, xinc, yinc, xval, yval, incr; -+ -+ if ((line->x1 > info->var.xres) || -+ (line->x2 > info->var.xres) || -+ (line->y1 > info->var.yres) || -+ (line->y2 > info->var.yres)) -+ return -EFAULT; -+ x = line->x1; -+ y = line->y1; -+ dx = line->x2 - line->x1; -+ dy = line->y2 - line->y1; -+ -+ if ( !dx || !dy ) -+ return -EFAULT; -+ -+ if ( dx < 0 && dy < 0 ) { -+ x = line->x2; -+ y = line->y2; -+ dx *= -1; -+ dy *= -1; -+ } -+ else if ( dx < 0 && dy > 0 ){ -+ dx *= -1; -+ value = 0x000000A0; -+ } -+ else if( dy < 0 && dx > 0 ){ -+ dy *= -1; -+ value = 0x00000140; -+ } -+ -+ if (line->flags & LINE_PRECISE) { -+ count = isqrt(((dy * dy) + (dx * dx)) * 4096); -+ xinc = (4095 * 64 * dx) / count; -+ yinc = (4095 * 64 * dy) / count; -+ xval = 2048; -+ yval = 2048; -+ count = 0; -+ while (dx || dy) { -+ incr = 0; -+ xval -= xinc; -+ if (xval <= 0) { -+ xval += 4096; -+ dx--; -+ incr = 1; -+ } -+ yval -= yinc; -+ if (yval <= 0) { -+ yval += 4096; -+ dy--; -+ incr = 1; -+ } -+ count += incr; -+ } -+ } -+ else { -+ if ( dx == dy ) { -+ xinc = 4095; -+ yinc = 4095; -+ count = dx; -+ -+ } -+ else if ( dx < dy ) { -+ xinc = ( dx * 4095 ) / dy; -+ yinc = 4095; -+ count = dy; -+ -+ } -+ else { -+ xinc = 4095; -+ yinc = ( dy * 4095 ) / dx; -+ count = dx; -+ } -+ } -+ -+ outl(0x08000800, LINEINIT); -+ if (line->flags & LINE_PATTERN) -+ outl(line->pattern, LINEPATTRN); -+ else -+ outl(0x000fffff, LINEPATTRN); -+ outl(epinfo.fb_phys + ((y * epinfo.xres * epinfo.bpp) / 8) + -+ ((x * epinfo.bpp ) / 8 ), BLKDSTSTRT); -+ -+ outl(((x * epinfo.bpp) & 0x1F) | -+ ((((x + dx - 1) * epinfo.bpp) & 0x1F ) << 16), -+ DESTPIXELSTRT); -+ outl((epinfo.xres * epinfo.bpp) / 32, DESTLINELENGTH); -+ outl(line->fgcolor, BLOCKMASK); -+ outl(line->bgcolor, BACKGROUND); -+ outl((yinc << 16) | xinc, LINEINC); -+ outl( count & 0xFFF, BLKDESTWIDTH); -+ outl( 0 , BLKDESTHEIGHT); -+ value |= (line->flags & LINE_BACKGROUND) ? 0x00004000 : 0; -+ outl(epinfo.pixformat | value | 0x00000013, BLOCKCTRL); -+ ep93xxfb_wait(); -+ return 0; -+} -+ -+int ioctl_cursor=0; -+ -+int ep93xxfb_cursor(struct fb_info *info, struct ep93xx_cursor *cursor) -+{ -+ unsigned long x,y,save; -+ -+ if((cursor->width ==0) || (cursor->height ==0) ) -+ { -+ struct fb_cursor *fbcon_cursor =(struct fb_cursor *)cursor; -+ struct fbcon_ops *ops = (struct fbcon_ops *)info->fbcon_par; -+ unsigned int scan_align = info->pixmap.scan_align - 1; -+ unsigned int buf_align = info->pixmap.buf_align - 1; -+ unsigned int i, size, dsize, s_pitch, d_pitch; -+ struct fb_image *image; -+ u8 *src, *dst; -+ -+ if(ioctl_cursor==1 ){ -+ DPRINTK("softcursor error return\n"); -+ return 0; -+ } -+ -+ -+ if (info->state != FBINFO_STATE_RUNNING) -+ return 0; -+ -+ s_pitch = (fbcon_cursor->image.width + 7) >> 3; -+ dsize = s_pitch * fbcon_cursor->image.height; -+ -+ if (dsize + sizeof(struct fb_image) != ops->cursor_size) { -+ if (ops->cursor_src != NULL) -+ kfree(ops->cursor_src); -+ ops->cursor_size = dsize + sizeof(struct fb_image); -+ -+ ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC); -+ if (!ops->cursor_src) { -+ ops->cursor_size = 0; -+ return -ENOMEM; -+ } -+ } -+ src = ops->cursor_src + sizeof(struct fb_image); -+ image = (struct fb_image *)ops->cursor_src; -+ *image = fbcon_cursor->image; -+ d_pitch = (s_pitch + scan_align) & ~scan_align; -+ -+ size = d_pitch * image->height + buf_align; -+ size &= ~buf_align; -+ dst = fb_get_buffer_offset(info, &info->pixmap, size); -+ -+ if (fbcon_cursor->enable) { -+ switch (fbcon_cursor->rop) { -+ case ROP_XOR: -+ for (i = 0; i < dsize; i++) -+ src[i] = image->data[i] ^ fbcon_cursor->mask[i]; -+ break; -+ case ROP_COPY: -+ default: -+ for (i = 0; i < dsize; i++) -+ src[i] = image->data[i] & fbcon_cursor->mask[i]; -+ break; -+ } -+ } else -+ memcpy(src, image->data, dsize); -+ -+ fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height); -+ image->data = dst; -+ info->fbops->fb_imageblit(info, image); -+ return 0; -+ -+ } -+ else{ -+ ioctl_cursor = 1; -+ -+ /*if (cursor->width > 16 || cursor->height > 16){ -+ DPRINTK("%s width %d or heright %d error\n",__FUNCTION__,cursor->width,cursor->height); -+ return -ENXIO; -+ }*/ -+ -+ if (cursor->flags & CURSOR_OFF) -+ outl(inl(CURSORXYLOC) & ~0x00008000, CURSORXYLOC); -+ -+ if (cursor->flags & CURSOR_SETSHAPE) { -+ copy_from_user(cursor_data, cursor->data, -+ cursor->width * cursor->height / 4); -+ save = inl(CURSORXYLOC); -+ outl(save & ~0x00008000, CURSORXYLOC); -+ -+ outl(virt_to_phys(cursor_data), CURSOR_ADR_START); -+ outl(virt_to_phys(cursor_data), CURSOR_ADR_RESET); -+ outl(((cursor->width - 1) & 0x30) << 4 | ((cursor->height - 1) << 2) | -+ ((cursor->width - 1) >> 4), CURSORSIZE); -+ outl(save, CURSORXYLOC); -+ -+ } -+ -+ if (cursor->flags & CURSOR_SETCOLOR) { -+ outl(cursor->color1, CURSORCOLOR1); -+ outl(cursor->color2, CURSORCOLOR2); -+ outl(cursor->blinkcolor1, CURSORBLINK1); -+ outl(cursor->blinkcolor2, CURSORBLINK2); -+ } -+ -+ if (cursor->flags & CURSOR_BLINK) { -+ if (cursor->blinkrate) -+ outl(0x00000100 | cursor->blinkrate, CURSORBLINK); -+ else -+ outl(0x0000000FF, CURSORBLINK); -+ } -+ -+ if (cursor->flags & CURSOR_MOVE) { -+ x = (inl(HACTIVESTRTSTOP) & 0x000007ff) - cursor->dx - 2; -+ y = (inl(VACTIVESTRTSTOP) & 0x000007ff) - cursor->dy; -+ outl((inl(CURSORXYLOC) & 0x8000) | (y << 16) | x, CURSORXYLOC); -+ } -+ -+ if(cursor->flags & CURSOR_ON) -+ outl(inl(CURSORXYLOC) | 0x00008000, CURSORXYLOC); -+ -+ return 0; -+ } -+} -+ -+ -+ -+static inline void -+ep93xxfb_palette_write(u_int regno, u_int red, u_int green, -+ u_int blue, u_int trans) -+{ -+ unsigned int cont, i, pal; -+ DPRINTK("ep93xxfb_palette_write - enter\n"); -+ pal = ((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8); -+ pseudo_palette[regno] = pal; -+ outl( pal, ( COLOR_LUT + ( regno << 2 ))); -+ cont = inl( LUTCONT ); -+ -+ if (( cont & LUTCONT_STAT && cont & LUTCONT_RAM1 ) || -+ ( !( cont & LUTCONT_STAT ) && !( cont&LUTCONT_RAM1 ))) { -+ for ( i = 0; i < 256; i++ ) { -+ outl( pseudo_palette[i], ( COLOR_LUT + ( i << 2 )) ); -+ } -+ outl( cont ^ LUTCONT_RAM1, LUTCONT ); -+ } -+} -+ -+int ep93xxfb_setcolreg(unsigned regno, unsigned red, unsigned green, -+ unsigned blue, unsigned transp, -+ struct fb_info *info) -+{ -+ -+#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) -+ -+ switch ( info->fix.visual ) -+ { -+ case FB_VISUAL_PSEUDOCOLOR: -+ ep93xxfb_palette_write(regno, red, green, blue, transp); -+ break; -+ case FB_VISUAL_TRUECOLOR: -+ if (regno >= 16) -+ return 1; -+ red = CNVT_TOHW(red, info->var.red.length); -+ green = CNVT_TOHW(green, info->var.green.length); -+ blue = CNVT_TOHW(blue, info->var.blue.length); -+ transp = CNVT_TOHW(transp, info->var.transp.length); -+ ((u32 *)(info->pseudo_palette))[regno] = -+ (red << info->var.red.offset) | -+ (green << info->var.green.offset) | -+ (blue << info->var.blue.offset) | -+ (transp << info->var.transp.offset); -+ break; -+ case FB_VISUAL_DIRECTCOLOR: -+ red = CNVT_TOHW(red, 8); -+ green = CNVT_TOHW(green, 8); -+ blue = CNVT_TOHW(blue, 8); -+ transp = CNVT_TOHW(transp, 8); -+ break; -+ } -+#undef CNVT_TOHW -+ return 0; -+} -+ -+static int ep93xx_pan_display(struct fb_var_screeninfo *var, -+ struct fb_info *info) -+{ -+ DPRINTK("ep93xx_pan_display - enter\n"); -+ -+ if (var->yoffset < 0 -+ || var->yoffset + var->yres > info->var.yres_virtual -+ || var->xoffset) -+ return -EINVAL; -+ -+ outl(epinfo.fb_phys + info->fix.line_length * var->yoffset -+ , VIDSCRNPAGE); -+ -+ info->var.xoffset = var->xoffset; -+ info->var.yoffset = var->yoffset; -+ -+ DPRINTK("ep93xx_pan_display - exit\n"); -+ return 0; -+} -+ -+ -+static int -+ep93xxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -+{ -+ struct fb_var_screeninfo tmp_var; -+ unsigned long pclk; -+ DPRINTK("ep93xxfb_check_var - enter\n"); -+ -+ if( vout != 0) { -+ printk(" ep93xxfb_check_var - vout != 0\n"); -+ return -EINVAL; -+ } -+ -+ memcpy (&tmp_var, var, sizeof (tmp_var)); -+ -+ if( (tmp_var.vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED ) { -+ printk(" ep93xxfb_check_var - unsupported video mode\n"); -+ return -EINVAL; -+ } -+ -+ if( ((tmp_var.xres * tmp_var.yres * tmp_var.bits_per_pixel) / 8) > -+ MAX_FBMEM_SIZE ) { -+ printk(" ep93xxfb_check_var - memory error \n"); -+ return -ENOMEM; -+ } -+ -+ if( ((tmp_var.xres_virtual * tmp_var.yres_virtual * tmp_var.bits_per_pixel) / 8) > -+ MAX_FBMEM_SIZE ) { -+ printk(" ep93xxfb_check_var - memory error \n"); -+ return -ENOMEM; -+ } -+ -+ pclk = 1000 * (1000000000 / tmp_var.pixclock); -+ -+ if( pclk > ep93xx_get_max_video_clk() ) { -+ printk(" ep93xxfb_check_var - pixel clock error %lu\n",pclk); -+ return -EINVAL; -+ } -+ -+ if (var->xres_virtual != var->xres) -+ var->xres_virtual = var->xres; -+ if (var->yres_virtual < var->yres) -+ var->yres_virtual = var->yres; -+ -+ if (var->xoffset < 0) -+ var->xoffset = 0; -+ if (var->yoffset < 0) -+ var->yoffset = 0; -+ -+ switch (tmp_var.bits_per_pixel) { -+ case 8: -+ break; -+ case 16: -+ break; -+ case 24: -+ break; -+ case 32: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ DPRINTK("ep93xxfb_check_var - exit\n"); -+ return 0; -+} -+ -+ -+static int ep93xxfb_set_par(struct fb_info *info) -+{ -+ struct fb_var_screeninfo tmp_var; -+ unsigned long attribs; -+ -+ DPRINTK("ep93xxfb_set_par - enter\n"); -+ -+ if( ep93xxfb_check_var(&info->var,info) < 0 ) -+ return -EINVAL; -+ -+ if( !ep93xxfb_setcol(info,info->var.bits_per_pixel) ) -+ return -EINVAL; -+ -+ -+ info->fix.line_length = (info->var.xres * info->var.bits_per_pixel) / 8; -+ -+ ep93xxfb_blank( 1 , info ); -+ -+ memcpy(&tmp_var,&info->var,sizeof(tmp_var)); -+ -+ epinfo.xres = tmp_var.xres; -+ epinfo.xsync = tmp_var.hsync_len; -+ epinfo.xfp = tmp_var.right_margin; -+ epinfo.xbp = tmp_var.left_margin; -+ epinfo.xtotal = epinfo.xres + epinfo.xsync + -+ epinfo.xfp + epinfo.xbp; -+ -+ epinfo.yres = tmp_var.yres; -+ epinfo.ysync = tmp_var.vsync_len; -+ epinfo.yfp = tmp_var.lower_margin; -+ epinfo.ybp = tmp_var.upper_margin; -+ epinfo.ytotal = epinfo.yres + epinfo.ysync + -+ epinfo.yfp + epinfo.ybp; -+ -+ epinfo.pixclock = tmp_var.pixclock ; -+ epinfo.refresh = 1000 * (1000000000 / tmp_var.pixclock) ; -+ -+ if( epinfo.refresh > ep93xx_get_max_video_clk()) -+ epinfo.refresh = ep93xx_get_max_video_clk(); -+ epinfo.bpp = tmp_var.bits_per_pixel; -+ -+ ep93xxfb_setclk(); -+ ep93xxfb_timing_signal_generation(); -+ -+ // set video memory parameters -+ outl(epinfo.fb_phys, VIDSCRNPAGE); -+ outl(epinfo.yres , SCRNLINES); -+ outl(((epinfo.xres * epinfo.bpp) / 32) - 1, LINELENGTH); -+ outl((epinfo.xres * epinfo.bpp) / 32, VLINESTEP); -+ -+ // set pixel mode -+ ep93xxfb_pixelmod(epinfo.bpp); -+ -+ attribs = 0; -+#ifdef CONFIG_EP93XX_SDCS0 -+ attribs |= 0 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS1 -+ attribs |= 1 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS2 -+ attribs |= 2 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS3 -+ attribs |= 3 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+ -+ attribs |= VIDEOATTRIBS_INVCLK; -+ if( tmp_var.sync & FB_SYNC_HOR_HIGH_ACT ) -+ attribs |= VIDEOATTRIBS_HSPOL; -+ if( tmp_var.sync & FB_SYNC_VERT_HIGH_ACT ) -+ attribs |= VIDEOATTRIBS_VCPOL; -+ -+ ep93xxfb_outl(attribs, VIDEOATTRIBS); -+ ep93xxfb_blank( 0 , info ); -+ -+ DPRINTK("ep93xxfb_set_par - exit\n"); -+ -+ return 0; -+} -+ -+ -+static int ep93xxfb_blank(int blank_mode,struct fb_info *info) -+{ -+ unsigned long attribs; -+ DPRINTK("ep93xxfb_blank - enter\n"); -+ attribs = inl(VIDEOATTRIBS); -+ -+#ifdef CONFIG_EP93XX_SDCS0 -+ attribs |= 0 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS1 -+ attribs |= 1 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS2 -+ attribs |= 2 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS3 -+ attribs |= 3 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+ -+ if (blank_mode) { -+ if (epinfo.off) -+ (epinfo.off)( 0 ); -+ -+ ep93xxfb_outl(attribs & ~(VIDEOATTRIBS_DATAEN | -+ VIDEOATTRIBS_SYNCEN | VIDEOATTRIBS_PCLKEN | -+ VIDEOATTRIBS_EN), VIDEOATTRIBS); -+ } -+ else { -+ if (epinfo.clk_src == CLK_INTERNAL) -+ attribs |= VIDEOATTRIBS_PCLKEN; -+ else -+ attribs &= ~VIDEOATTRIBS_PCLKEN; -+ -+ ep93xxfb_outl(attribs | VIDEOATTRIBS_DATAEN | -+ VIDEOATTRIBS_SYNCEN | VIDEOATTRIBS_EN, -+ VIDEOATTRIBS); -+ -+ if (epinfo.configure) -+ (epinfo.configure)( epinfo.automods ); -+ if (epinfo.on) -+ (epinfo.on)( 0 ); -+ } -+ return 0; -+} -+ -+static int ep93xxfb_mmap(struct fb_info *info,struct vm_area_struct *vma) -+{ -+ unsigned long off, start, len; -+ -+ DPRINTK("ep93xxfb_mmap - enter\n"); -+ -+ off = vma->vm_pgoff << PAGE_SHIFT; -+ start = info->fix.smem_start; -+ len = PAGE_ALIGN(start & ~PAGE_MASK) + info->fix.smem_len; -+ start &= PAGE_MASK; -+ if ((vma->vm_end - vma->vm_start + off) > len) -+ return -EINVAL; -+ -+ off += start; -+ vma->vm_pgoff = off >> PAGE_SHIFT; -+ -+ vma->vm_flags |= VM_IO; -+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); -+ -+ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, -+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) { -+ DPRINTK("ep93xxfb_mmap error\n"); -+ return -EAGAIN; -+ } -+ -+ DPRINTK("ep93xxfb_mmap - exit\n"); -+ return 0; -+} -+ -+static unsigned long ep93xx_get_pll_frequency(unsigned long pll) -+{ -+ unsigned long fb1, fb2, ipd, ps, freq; -+ -+ if (pll == 1) -+ pll = inl(EP93XX_SYSCON_CLOCK_SET1); -+ else if (pll == 2) -+ pll = inl(EP93XX_SYSCON_CLOCK_SET2); -+ else -+ return 0; -+ -+ ps = (pll & SYSCON_CLKSET1_PLL1_PS_MASK) >> SYSCON_CLKSET1_PLL1_PS_SHIFT; -+ fb1 = ((pll & SYSCON_CLKSET1_PLL1_X1FBD1_MASK) >> SYSCON_CLKSET1_PLL1_X1FBD1_SHIFT); -+ fb2 = ((pll & SYSCON_CLKSET1_PLL1_X2FBD2_MASK) >> SYSCON_CLKSET1_PLL1_X2FBD2_SHIFT); -+ ipd = ((pll & SYSCON_CLKSET1_PLL1_X2IPD_MASK) >> SYSCON_CLKSET1_PLL1_X2IPD_SHIFT); -+ -+ freq = (((0x00e10000 * (fb1+1)) / (ipd+1)) * (fb2+1)) >> ps; -+ return freq; -+} -+ -+static int ep93xx_get_max_video_clk() -+{ -+ unsigned long f,freq = 0; -+ -+ freq = 14745600 / 4; -+ f = ep93xx_get_pll_frequency(1) / 4; -+ if ( f > freq ) -+ freq = f; -+ f = ep93xx_get_pll_frequency(2) / 4; -+ if ( f > freq ) -+ freq = f; -+ -+ return freq; -+} -+ -+static int ep93xx_set_video_div(unsigned long freq) -+{ -+ unsigned long pdiv = 0, div = 0, psel = 0, esel = 0; -+ unsigned long err, f, i, j, k; -+ -+ err = -1; -+ -+ for (i = 0; i < 3; i++) { -+ if (i == 0) -+ f = 14745600 * 2; -+ else if (i == 1) -+ f = ep93xx_get_pll_frequency(1) * 2; -+ else -+ f = ep93xx_get_pll_frequency(2) * 2; -+ -+ for (j = 4; j <= 6; j++) { -+ k = f / (freq * j); -+ if (k < 2) -+ continue; -+ -+ if (abs(((f / (j * k))) - freq ) < err ) { -+ pdiv = j - 3; -+ div = k; -+ psel = (i == 2) ? 1 : 0; -+ esel = (i == 0) ? 0 : 1; -+ err = (f / (j * k)) - freq; -+ } -+ } -+ } -+ -+ if (err == -1) -+ return -1; -+ -+ SysconSetLocked(SYSCON_VIDDIV,SYSCON_VIDDIV_VENA | (esel ? SYSCON_VIDDIV_ESEL : 0) | -+ (psel ? SYSCON_VIDDIV_PSEL : 0) | -+ (pdiv << SYSCON_VIDDIV_PDIV_SHIFT) | -+ (div << SYSCON_VIDDIV_VDIV_SHIFT) -+ ); -+ -+ return freq + err; -+} -+ -+static void ep93xxfb_pixelmod(int bpp) -+{ -+ unsigned long tmpdata = 0; -+ -+ DPRINTK("ep93xxfb_pixelmod %dbpp -enter\n",bpp); -+ switch(bpp) { -+ case 8: -+ tmpdata = PIXELMODE_P_8BPP | -+ PIXELMODE_S_1PPCMAPPED | -+ PIXELMODE_C_LUT; -+ epinfo.pixformat = PIXEL_FORMAT_8; -+ break; -+ case 16: -+ tmpdata = PIXELMODE_P_16BPP | -+ PIXELMODE_S_1PPCMAPPED | -+ PIXELMODE_C_565; -+ epinfo.pixformat = PIXEL_FORMAT_16; -+ break; -+ case 24: -+ tmpdata = PIXELMODE_P_24BPP | -+ PIXELMODE_S_1PPC | -+ PIXELMODE_C_888; -+ epinfo.pixformat = PIXEL_FORMAT_24; -+ break; -+ case 32: -+ tmpdata = PIXELMODE_P_32BPP | -+ PIXELMODE_S_1PPC | -+ PIXELMODE_C_888; -+ epinfo.pixformat = PIXEL_FORMAT_32; -+ break; -+ default: -+ break; -+ } -+ outl(tmpdata,PIXELMODE); -+} -+ -+static void ep93xxfb_timing_signal_generation(void) -+{ -+ unsigned long vlinestotal,vsyncstart,vsyncstop, -+ vactivestart,vactivestop, -+ vblankstart,vblankstop, -+ vclkstart,vclkstop; -+ -+ unsigned long hclkstotal,hsyncstart,hsyncstop, -+ hactivestart,hactivestop, -+ hblankstart,hblankstop, -+ hclkstart,hclkstop; -+ -+ DPRINTK("ep93xxfb_timing_signal_generation - enter\n"); -+ -+ vlinestotal = epinfo.ytotal - 1; -+ vsyncstart = vlinestotal; -+ vsyncstop = vlinestotal - epinfo.ysync; -+ vblankstart = vlinestotal - epinfo.ysync - epinfo.ybp; -+ vblankstop = epinfo.yfp - 1; -+ vactivestart = vblankstart; -+ vactivestop = vblankstop; -+ vclkstart = vlinestotal; -+ vclkstop = vlinestotal + 1; -+ -+ hclkstotal = epinfo.xtotal - 1; -+ hsyncstart = hclkstotal; -+ hsyncstop = hclkstotal - epinfo.xsync; -+ hblankstart = hclkstotal - epinfo.xsync - epinfo.xbp; -+ hblankstop = epinfo.xfp - 1; -+ hactivestart = hblankstart; -+ hactivestop = hblankstop; -+ hclkstart = hclkstotal ; -+ hclkstop = hclkstotal ; -+ -+ ep93xxfb_outl(0, VIDEOATTRIBS); -+ -+ ep93xxfb_outl( vlinestotal , VLINESTOTAL ); -+ ep93xxfb_outl( vsyncstart + (vsyncstop << 16), VSYNCSTRTSTOP ); -+ ep93xxfb_outl( vactivestart + (vactivestop << 16), VACTIVESTRTSTOP ); -+ ep93xxfb_outl( vblankstart + (vblankstop << 16), VBLANKSTRTSTOP ); -+ ep93xxfb_outl( vclkstart + (vclkstop << 16), VCLKSTRTSTOP ); -+ -+ ep93xxfb_outl( hclkstotal , HCLKSTOTAL ); -+ ep93xxfb_outl( hsyncstart + (hsyncstop << 16), HSYNCSTRTSTOP ); -+ ep93xxfb_outl( hactivestart + (hactivestop << 16) , HACTIVESTRTSTOP ); -+ ep93xxfb_outl( hblankstart + (hblankstop << 16) , HBLANKSTRTSTOP ); -+ ep93xxfb_outl( hclkstart + (hclkstop << 16) , HCLKSTRTSTOP ); -+ -+ ep93xxfb_outl(0, LINECARRY); -+ -+} -+ -+static int ep93xxfb_setcol(struct fb_info *info, int bpp) -+{ -+ -+ DPRINTK("ep93xxfb_setcol %dbpp\n",bpp); -+ switch(bpp) { -+ case 8: -+ info->var.bits_per_pixel = 8; -+ info->var.red.length = 8; -+ info->var.green.length = 8; -+ info->var.blue.length = 8; -+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR; -+ break; -+ case 16: -+ info->var.bits_per_pixel = 16; -+ info->var.red.offset = 11; -+ info->var.red.length = 5; -+ info->var.green.offset = 5; -+ info->var.green.length = 6; -+ info->var.blue.offset = 0; -+ info->var.blue.length = 5; -+ info->fix.visual = FB_VISUAL_TRUECOLOR; -+ break; -+ case 24: -+ info->var.bits_per_pixel = 24; -+ info->var.red.length = 8; -+ info->var.blue.length = 8; -+ info->var.green.length = 8; -+ info->var.red.offset = 16; -+ info->var.green.offset = 8; -+ info->var.blue.offset = 0; -+ info->fix.visual = FB_VISUAL_TRUECOLOR; -+ break; -+ case 32: -+ info->var.bits_per_pixel = 32; -+ info->var.red.length = 8; -+ info->var.blue.length = 8; -+ info->var.green.length = 8; -+ info->var.transp.length = 0; -+ info->var.red.offset = 16; -+ info->var.green.offset = 8; -+ info->var.blue.offset = 0; -+ info->var.transp.offset = 0; -+ info->fix.visual = FB_VISUAL_TRUECOLOR; -+ break; -+ default: -+ return 0; -+ } -+ return 1; -+} -+ -+static int ep93xxfb_setclk() -+{ -+ unsigned long calc_clk,act_clk; -+ -+ if ( epinfo.clk_src == CLK_INTERNAL ) { -+ SysconSetLocked(EP93XX_SYSCON_DEVICE_CONFIG,inl(EP93XX_SYSCON_DEVICE_CONFIG) & ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE); -+ calc_clk = epinfo.refresh; -+ act_clk = ep93xx_set_video_div( calc_clk ); -+ if ( act_clk == -1 ) -+ return -ENODEV; -+ -+ epinfo.refresh = act_clk; -+ epinfo.pixclock = 1000000000 / (act_clk / 1000); -+ } -+ else { -+ SysconSetLocked(SYSCON_VIDDIV,0); -+ SysconSetLocked(EP93XX_SYSCON_DEVICE_CONFIG,inl(EP93XX_SYSCON_DEVICE_CONFIG) | EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE); -+ -+ } -+ -+ return 0; -+} -+ -+ -+static void ep93xxfb_get_par(struct fb_info *info) -+{ -+ -+ DPRINTK("ep93xxfb_get_par - enter\n"); -+ epinfo.configure = NULL; -+ epinfo.on = NULL; -+ epinfo.off = NULL; -+ -+ switch( vout ) { -+ case LCD_OUT: -+ epinfo.on = philips_lb064v02_on; -+ epinfo.off = philips_lb064v02_off; -+ -+ case CRT_OUT: -+ epinfo.xres = ep93xxfb_vmods[vmode].hres; -+ epinfo.xsync = ep93xxfb_vmods[vmode].hsync; -+ epinfo.xfp = ep93xxfb_vmods[vmode].hfp; -+ epinfo.xbp = ep93xxfb_vmods[vmode].hbp; -+ epinfo.xtotal = epinfo.xres + epinfo.xsync + -+ epinfo.xfp + epinfo.xbp; -+ -+ epinfo.yres = ep93xxfb_vmods[vmode].vres; -+ epinfo.ysync = ep93xxfb_vmods[vmode].vsync; -+ epinfo.yfp = ep93xxfb_vmods[vmode].vfp; -+ epinfo.ybp = ep93xxfb_vmods[vmode].vbp; -+ epinfo.ytotal = epinfo.yres + epinfo.ysync + -+ epinfo.yfp + epinfo.ybp; -+ -+ epinfo.refresh = ep93xxfb_vmods[vmode].refresh; -+ epinfo.refresh = epinfo.xtotal * epinfo.ytotal * epinfo.refresh; -+ epinfo.pixclock = 1000000000 / ( epinfo.refresh / 1000); -+ epinfo.bpp = depth; -+ -+ epinfo.clk_src = ep93xxfb_vmods[vmode].clk_src; -+ epinfo.clk_edge = ep93xxfb_vmods[vmode].clk_edge; -+ epinfo.pol_blank = ep93xxfb_vmods[vmode].pol_blank; -+ epinfo.pol_xsync = ep93xxfb_vmods[vmode].pol_hsync; -+ epinfo.pol_ysync = ep93xxfb_vmods[vmode].pol_vsync; -+ break; -+ -+ } -+} -+ -+static int ep93xxfb_alloc_videomem(void) -+{ -+ unsigned long adr,size,pgsize; -+ int order; -+ -+ DPRINTK("ep93xxfb_alloc_videomem - enter \n"); -+ -+ epinfo.fb_log = NULL; -+ epinfo.fb_size = PAGE_ALIGN( MAX_FBMEM_SIZE/*ep93xxfb_vmods[vmode].hres * ep93xxfb_vmods[vmode].vres * (depth / 8)*/ ); -+ order = get_order( epinfo.fb_size ); -+ epinfo.fb_log = (void*) __get_free_pages( GFP_KERNEL, order ); -+ -+ if (epinfo.fb_log) { -+ epinfo.fb_phys = __virt_to_phys((int) epinfo.fb_log ); -+ adr = (unsigned long)epinfo.fb_log; -+ size = epinfo.fb_size; -+ pgsize = 1 << order; -+ do { -+ adr += pgsize; -+ SetPageReserved(virt_to_page(adr)); -+ } while(size -= pgsize); -+ } -+ else{ -+ printk("%s memory fail \n",__FUNCTION__); -+ return -ENOMEM; -+ } -+ -+ memset(epinfo.fb_log,0x00,epinfo.fb_size); -+ DPRINTK(" fb_log_addres = 0x%x\n",epinfo.fb_log); -+ DPRINTK(" fb_phys_address = 0x%x\n",epinfo.fb_phys); -+ DPRINTK(" fb_size = %lu\n",epinfo.fb_size); -+ DPRINTK(" fb_page_order = %d\n",order); -+ DPRINTK("ep93xxfb_alloc_videomem - exit \n"); -+ return 0; -+} -+ -+static void ep93xxfb_release_videomem(void) -+{ -+ unsigned long adr,size,psize; -+ int order; -+ -+ DPRINTK("ep93xxfb_release_videomem - enter \n"); -+ -+ if (epinfo.fb_log) { -+ order = get_order(epinfo.fb_size); -+ adr = (unsigned long)epinfo.fb_log; -+ size = epinfo.fb_size; -+ psize = 1 << order ; -+ do { -+ adr += psize; -+ ClearPageReserved(virt_to_page(adr)); -+ } while(size -= psize); -+ free_pages((unsigned long)epinfo.fb_log, order ); -+ } -+ -+ -+ DPRINTK("ep93xxfb_release_videomem - exit \n"); -+} -+ -+static void ep93xxfb_setinfo(struct fb_info *info) -+{ -+ -+ info->pseudo_palette = pseudo_palette; -+ info->var.xres = epinfo.xres; -+ info->var.yres = epinfo.yres; -+ info->var.xres_virtual = epinfo.xres; -+ info->var.yres_virtual = epinfo.yres; -+ -+ ep93xxfb_setcol( info, depth ); -+ -+ info->var.activate = FB_ACTIVATE_NOW; -+ info->var.left_margin = epinfo.xbp; -+ info->var.right_margin = epinfo.xfp; -+ info->var.upper_margin = epinfo.ybp; -+ info->var.lower_margin = epinfo.yfp; -+ info->var.hsync_len = epinfo.xsync; -+ info->var.vsync_len = epinfo.ysync; -+ -+ if( epinfo.pol_xsync == POL_HIGH ) -+ info->var.sync |= FB_SYNC_HOR_HIGH_ACT; -+ if( epinfo.pol_ysync == POL_HIGH ) -+ info->var.sync |= FB_SYNC_VERT_HIGH_ACT; -+ -+ info->var.vmode = FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP; -+ info->fix.smem_start = epinfo.fb_phys; -+ info->fix.smem_len = epinfo.fb_size; -+ info->fix.type = FB_TYPE_PACKED_PIXELS; -+ info->fix.line_length = epinfo.xres * (epinfo.bpp / 8); -+ info->screen_base = epinfo.fb_log; -+ info->var.pixclock = epinfo.pixclock; -+ info->fix.ypanstep = 1; -+ info->fix.ywrapstep = 1; -+ -+} -+ -+static int ep93xxfb_config(struct fb_info *info) -+{ -+ unsigned long attribs; -+ -+ DPRINTK("ep93xxfb_config - enter\n"); -+ -+ ep93xxfb_get_par( info ); -+ if( ep93xxfb_alloc_videomem() != 0 ) { -+ printk("Unable to allocate video memory\n"); -+ return -ENOMEM; -+ } -+ -+ if( ep93xxfb_setclk() != 0 ) { -+ printk("Unable to set pixel clock\n"); -+ ep93xxfb_release_videomem(); -+ return -ENODEV; -+ } -+ -+ SysconSetLocked(EP93XX_SYSCON_DEVICE_CONFIG, inl(EP93XX_SYSCON_DEVICE_CONFIG) |EP93XX_SYSCON_DEVCFG_RasOnP3); -+ ep93xxfb_timing_signal_generation(); -+ -+ /* set video memory parameters */ -+ outl(epinfo.fb_phys, VIDSCRNPAGE); -+ outl(epinfo.yres , SCRNLINES); -+ outl(((epinfo.xres * epinfo.bpp) / 32) - 1, LINELENGTH); -+ outl((epinfo.xres * epinfo.bpp) / 32, VLINESTEP); -+ -+ -+ /* set pixel mode */ -+ ep93xxfb_pixelmod(depth); -+ -+ attribs = 0; -+ -+#ifdef CONFIG_EP93XX_SDCS0 -+ attribs |= 0 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS1 -+ attribs |= 1 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS2 -+ attribs |= 2 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS3 -+ attribs |= 3 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+ -+ if(epinfo.clk_edge == EDGE_RISING) -+ attribs |= VIDEOATTRIBS_INVCLK; -+ if(epinfo.pol_blank == POL_HIGH) -+ attribs |= VIDEOATTRIBS_BLKPOL; -+ if(epinfo.pol_xsync == POL_HIGH) -+ attribs |= VIDEOATTRIBS_HSPOL; -+ if(epinfo.pol_ysync == POL_HIGH) -+ attribs |= VIDEOATTRIBS_VCPOL; -+ -+ ep93xxfb_outl(attribs, VIDEOATTRIBS); -+ ep93xxfb_setinfo( info ); -+ -+ if(epinfo.configure) -+ (epinfo.configure)( epinfo.automods ); -+ -+ ep93xxfb_blank( 0 , info ); -+ -+ DPRINTK("ep93xxfb_config - exit\n"); -+ return 0; -+} -+ -+int ep93xxfb_ioctl(struct fb_info *info,unsigned int cmd, unsigned long arg) -+{ -+ struct fb_fillrect fill; -+ struct fb_copyarea cparea; -+ struct fb_image img; -+ struct ep93xx_line line; -+ struct ep93xx_cursor cursor; -+ -+ switch (cmd) { -+ case FBIO_EP93XX_CURSOR: -+ copy_from_user(&cursor, (void *)arg, sizeof(struct ep93xx_cursor)); -+ ep93xxfb_cursor(info,&cursor); -+ break; -+ case FBIO_EP93XX_LINE: -+ copy_from_user(&line, (void *)arg, sizeof(struct ep93xx_line)); -+ ep93xxfb_line(info,&line); -+ break; -+ case FBIO_EP93XX_FILL: -+ copy_from_user(&fill, (void *)arg, sizeof(struct fb_fillrect)); -+ ep93xxfb_fillrect(info,&fill); -+ break; -+ case FBIO_EP93XX_BLIT: -+ copy_from_user(&img, (void *)arg, sizeof(struct fb_image)); -+ ep93xxfb_imageblit(info, &img); -+ break; -+ case FBIO_EP93XX_COPY: -+ copy_from_user(&cparea, (void *)arg, sizeof(struct fb_copyarea)); -+ ep93xxfb_copyarea(info,&cparea); -+ break; -+ default: -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+ -+static struct fb_ops ep93xxfb_ops = { -+ .owner = THIS_MODULE, -+ .fb_setcolreg = ep93xxfb_setcolreg, -+ .fb_check_var = ep93xxfb_check_var, -+ .fb_set_par = ep93xxfb_set_par, -+ .fb_blank = ep93xxfb_blank, -+ .fb_pan_display = ep93xx_pan_display, -+ .fb_fillrect = ep93xxfb_fillrect, -+ .fb_copyarea = ep93xxfb_copyarea, -+ .fb_imageblit = cfb_imageblit, -+ .fb_cursor = ep93xxfb_cursor, -+ .fb_ioctl = ep93xxfb_ioctl, -+ .fb_mmap = ep93xxfb_mmap, -+}; -+ -+ -+static struct resource ep93xxfb_raster_resources = { -+ .start = EP93XX_RASTER_PHYS_BASE, -+ .end = EP93XX_RASTER_PHYS_BASE + 0x1ffff, -+ .flags = IORESOURCE_MEM, -+}; -+ -+ -+static int __init ep93xxfb_probe(struct platform_device *device) -+{ -+ struct fb_info *info = NULL; -+ struct resource *res = NULL; -+ int ret = 0; -+ int arb = 0; -+ -+ DPRINTK("ep93xxfb_probe - enter \n"); -+ -+ -+ if(!device) { -+ printk("error : to_platform_device\n"); -+ return -ENODEV; -+ } -+ res = platform_get_resource( device, IORESOURCE_MEM, 0); -+ if(!res) { -+ printk("error : platform_get_resource \n"); -+ return -ENODEV; -+ } -+ cursor_data = kmalloc( 64 * 64 * 2, GFP_KERNEL ); -+ memset( cursor_data, 0x00, 64 * 64 * 2 ); -+ if(!cursor_data) { -+ printk("Unable to allocate memory for hw_cursor\n"); -+ return -ENOMEM; -+ } -+ if (!request_mem_region(res->start,res->end - res->start + 1, FBDEV_NAME )) -+ return -EBUSY; -+ -+ info = framebuffer_alloc(sizeof(u32) * 256, &device->dev); -+ -+ if(!info) { -+ printk("Unable to allocate memory for frame buffer\n"); -+ return -ENOMEM; -+ } -+ -+ info->flags = FBINFO_DEFAULT; -+ strncpy(info->fix.id, FBDEV_NAME, sizeof(info->fix.id)); -+ info->fix.mmio_start = res->start; -+ info->fix.mmio_len = res->end - res->start + 1; -+ info->fbops = &ep93xxfb_ops; -+ info->pseudo_palette = info->par; -+ info->state = FBINFO_STATE_RUNNING; -+ -+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { -+ ret = -ENOMEM; -+ goto fbuff; -+ } -+ -+ if ((ret = ep93xxfb_config(info)) < 0) -+ goto clmap; -+ -+ if (register_framebuffer(info) < 0) { -+ printk(KERN_ERR "Unable to register ep93xxfb frame buffer\n"); -+ ret = -EINVAL; -+ goto clmap; -+ } -+ platform_set_drvdata(device, info); -+ printk(KERN_INFO "fb%d: EP93xx frame buffer at %dx%dx%dbpp\n", info->node, -+ info->var.xres, info->var.yres, info->var.bits_per_pixel); -+ -+ /*change the raster arb to the highest one--Bo*/ -+ arb = inl(EP93XX_SYSCON_BMAR); -+ arb = (arb & 0x3f8) | 0x01; -+ outl(arb,EP93XX_SYSCON_BMAR); -+ -+ DPRINTK("ep93xxfb_probe - exit \n"); -+ return 0; -+ -+clmap: -+ fb_dealloc_cmap(&info->cmap); -+ -+fbuff: -+ framebuffer_release(info); -+ return ret; -+} -+ -+static int ep93xxfb_remove(struct platform_device *device) -+{ -+ struct resource *res; -+ struct fb_info *info; -+ struct ep93xx_cursor cursor; -+ -+ DPRINTK("ep93xxfb_remove - enter \n"); -+ -+ info = platform_get_drvdata(device); -+ -+ ep93xxfb_release_videomem(); -+ -+ res = platform_get_resource( device, IORESOURCE_MEM, 0); -+ release_mem_region(res->start, res->end - res->start + 1); -+ -+ platform_set_drvdata(device, NULL); -+ unregister_framebuffer(info); -+ -+ fb_dealloc_cmap(&info->cmap); -+ framebuffer_release(info); -+ -+ cursor.flags = CURSOR_OFF; -+ ep93xxfb_cursor(info,&cursor); -+ if(cursor_data!=NULL) -+ kfree(cursor_data); -+ -+ ep93xxfb_blank( 1, info ); -+ -+ DPRINTK("ep93xxfb_remove - exit \n"); -+ return 0; -+} -+ -+static void ep93xxfb_platform_release(struct device *device) -+{ -+ DPRINTK("ep93xxfb_platform_release - enter\n"); -+} -+ -+static int ep93xxfb_check_param(void) -+{ -+ -+ switch(vout) { -+ case CRT_OUT: -+ if( vmode >=(sizeof(ep93xxfb_vmods)/sizeof(ep93xxfb_vmods[0]))){ -+ vmode = 1; -+ depth = DEFAULT_BPP; -+ return 0; -+ } -+ break; -+ case LCD_OUT: -+ if( vmode != 0 || depth != 16 ) { -+ vmode = 0; -+ depth = DEFAULT_BPP; -+ return 0; -+ } -+ break; -+ default: -+ vmode = DEFAULT_MODE; -+ depth = DEFAULT_BPP; -+ vout = DEFAULT_OUT; -+ return 0; -+ break; -+ } -+ -+ if(!((depth == 8) || (depth == 16) || (depth == 24) || (depth == 32))) -+ depth = DEFAULT_BPP; -+ -+ return 1; -+} -+ -+int __init ep93xxfb_setup(char *options) -+{ -+ char *opt; -+ -+ DPRINTK("ep93xxfb_setup - %s\n",options); -+ -+ if (!options || !*options) -+ return 0; -+ -+ while ((opt = strsep(&options, ",")) != NULL) { -+ if (!strncmp(opt, "vout=", 5)) -+ vout = simple_strtoul(opt + 5, NULL, 0); -+ else if (!strncmp(opt, "vmode=", 6)) -+ vmode = simple_strtoul(opt + 6, NULL, 0); -+ else if (!strncmp(opt, "depth=", 6)) -+ depth = simple_strtoul(opt + 6, NULL, 0); -+ } -+ ep93xxfb_check_param(); -+ return 0; -+} -+ -+ -+static struct platform_driver ep93xxfb_driver = { -+ .probe = ep93xxfb_probe, -+ .remove = ep93xxfb_remove, -+ .driver = { -+ .name = FBDEV_NAME, -+ }, -+}; -+ -+static struct platform_device ep93xxfb_device = { -+ .name = FBDEV_NAME, -+ .id = -1, -+ .dev = { -+ .release = ep93xxfb_platform_release, -+ }, -+ .num_resources = 1, -+ .resource = &ep93xxfb_raster_resources, -+}; -+ -+int __init ep93xxfb_init(void) -+{ -+ int ret = 0; -+ char *option = NULL; -+ -+ DPRINTK("ep93xxfb_init - enter\n"); -+ -+ if (fb_get_options("ep93xxfb", &option)) -+ return -ENODEV; -+ ep93xxfb_setup(option); -+ -+ -+ if( !ep93xxfb_check_param() ) { -+ printk("Unsupported format \n"); -+ return -1; -+ } -+ /*Add the Hardware accel irq */ -+ outl(0x00000000, BLOCKCTRL); -+ ret = request_irq(IRQ_EP93XX_GRAPHICS, ep93xxfb_irq_handler, IRQF_DISABLED,"graphics",NULL); -+ -+ if (ret != 0) { -+ printk("%s: can't get irq %i, err %d\n",__FUNCTION__, IRQ_EP93XX_GRAPHICS, ret); -+ return -EBUSY; -+ } -+ -+ /*-------------------------------*/ -+ ret = platform_driver_register(&ep93xxfb_driver); -+ -+ if (!ret) { -+ ret = platform_device_register(&ep93xxfb_device); -+ if (ret) -+ platform_driver_unregister(&ep93xxfb_driver); -+ } -+ -+ DPRINTK("ep93xxfb_init - exit\n"); -+ return ret; -+} -+ -+ -+ -+static void __exit ep93xxfb_exit(void) -+{ -+ DPRINTK("ep93xxfb_exit - enter\n"); -+ platform_driver_unregister(&ep93xxfb_driver); -+ platform_device_unregister(&ep93xxfb_device); -+ DPRINTK("ep93xxfb_exit - exit\n"); -+} -+ -+module_init(ep93xxfb_init); -+module_exit(ep93xxfb_exit); -+ -+ -+module_param( vmode, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); -+MODULE_PARM_DESC(vmode, "Specify the video mode number that should be used"); -+module_param( vout , int , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ); -+MODULE_PARM_DESC(vout ,"Specify video output (0 = CRT ,1 = LCD )"); -+module_param( depth , int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); -+MODULE_PARM_DESC(depth ,"Color depth (8,16,24,32)"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/drivers/video/ep93xxfb.h -@@ -0,0 +1,236 @@ -+#ifndef __EP93XXFB_H__ -+#define __EP93XXFB_H__ -+ -+ -+#define POL_HIGH 1 -+#define POL_LOW 0 -+#define EDGE_RISING 1 -+#define EDGE_FALLING 0 -+#define CLK_INTERNAL 1 -+#define CLK_EXTERNAL 0 -+ -+#define CRT_OUT 0 -+#define LCD_OUT 1 -+#define TV_OUT 2 -+ -+#define MAX_XRES 1280 -+#define MAX_YRES 1024 -+#define MAX_BPP 16 -+#define MAX_FBMEM_SIZE 3686400/*1920000*/ -+ -+#define MAX_XRES_CRT MAX_XRES -+#define MAX_YRES_CRT MAX_YRES -+#define MAX_XRES_SVIDEO 1024 -+#define MAX_YRES_SVIDEO 768 -+ -+#define PIXEL_FORMAT_SHIFT 17 -+#define PIXEL_FORMAT_4 ( 1 << PIXEL_FORMAT_SHIFT ) -+#define PIXEL_FORMAT_8 ( 2 << PIXEL_FORMAT_SHIFT ) -+#define PIXEL_FORMAT_16 ( 4 << PIXEL_FORMAT_SHIFT ) -+#define PIXEL_FORMAT_24 ( 6 << PIXEL_FORMAT_SHIFT ) -+#define PIXEL_FORMAT_32 ( 7 << PIXEL_FORMAT_SHIFT ) -+ -+ -+struct ep93xxfb_videomodes -+{ -+ const char *name; -+ -+ unsigned long hres; // Horizontal Valid -+ unsigned long hfp; // Horizontal Front Porch -+ unsigned long hsync; // Horizontal Sync Width -+ unsigned long hbp; // Horizontal Back Porch -+ -+ unsigned long vres; // Vertical Valid -+ unsigned long vfp; // Vertical Front Porch -+ unsigned long vsync; // Vertical Sync Width -+ unsigned long vbp; // Vertical Back Porch -+ -+ unsigned long refresh; // Vertical Sync Frequency -+ -+ unsigned long clk_src; -+ unsigned long clk_edge; -+ unsigned long pol_blank; -+ unsigned long pol_hsync; -+ unsigned long pol_vsync; -+}; -+ -+ -+struct ep93xxfb_info -+{ -+ -+ -+ dma_addr_t fb_phys; -+ void *fb_log; -+ unsigned long fb_size; -+ unsigned long fb_actsize; -+ -+ unsigned long xtotal; -+ unsigned long ytotal; -+ -+ unsigned int xres; -+ unsigned int xfp; -+ unsigned int xsync; -+ unsigned int xbp; -+ -+ unsigned int yres; -+ unsigned int yfp; -+ unsigned int ysync; -+ unsigned int ybp; -+ unsigned int bpp; -+ -+ unsigned long refresh; -+ unsigned long pixclock; -+ unsigned long pixformat; -+ -+ unsigned int clk_src; -+ unsigned int clk_edge; -+ unsigned int pol_blank; -+ unsigned int pol_xsync; -+ unsigned int pol_ysync; -+ -+ unsigned char automods; -+ -+ void (*configure)(unsigned char value); -+ void (*on)(unsigned char value); -+ void (*off)(unsigned char value); -+}; -+ -+static int ep93xxfb_setclk(void); -+static int ep93xx_get_max_video_clk(void); -+static void ep93xxfb_pixelmod(int bpp); -+static void ep93xxfb_timing_signal_generation(void); -+static int ep93xxfb_blank(int blank_mode,struct fb_info *info); -+ -+#define EE_DELAY_USEC 2 -+#define EE_READ_TIMEOUT 100 -+#define CX25871_DEV_ADDRESS 0x88 -+#define GPIOG_EEDAT 2 -+#define GPIOG_EECLK 1 -+#define CXMODES_COUNT 24 -+ -+struct cx25871_vmodes -+{ -+ -+ const char *name; -+ unsigned char automode; -+ unsigned int hres; -+ unsigned int vres; -+ unsigned int hclktotal; -+ unsigned int vclktotal; -+ unsigned int hblank; -+ unsigned int vblank; -+ unsigned long clkfrequency; -+ -+}; -+ -+ -+int write_reg(unsigned char ucRegAddr, unsigned char ucRegValue); -+void cx25871_on(unsigned char value); -+void cx25871_off(unsigned char value); -+void cx25871_config(unsigned char value); -+ -+static void philips_lb064v02_on(unsigned char value); -+static void philips_lb064v02_off(unsigned char value); -+ -+ -+#define FBIO_EP93XX_CURSOR 0x000046c1 -+#define FBIO_EP93XX_LINE 0x000046c2 -+#define FBIO_EP93XX_FILL 0x000046c3 -+#define FBIO_EP93XX_BLIT 0x000046c4 -+#define FBIO_EP93XX_COPY 0x000046c5 -+ -+ -+#define CURSOR_BLINK 0x00000001 -+#define CURSOR_MOVE 0x00000002 -+#define CURSOR_SETSHAPE 0x00000004 -+#define CURSOR_SETCOLOR 0x00000008 -+#define CURSOR_ON 0x00000010 -+#define CURSOR_OFF 0x00000020 -+ -+ -+/* -+* ioctl(fd, FBIO_EP93XX_CURSOR, ep93xx_cursor *) -+* -+* "data" points to an array of pixels that define the cursor; each row should -+* be a multiple of 32-bit values (i.e. 16 pixels). Each pixel is two bits, -+* where the values are: -+* -+* 00 => transparent 01 => invert 10 => color1 11 => color2 -+* -+* The data is arranged as follows (per word): -+* -+* bits: |31-30|29-28|27-26|25-24|23-22|21-20|19-18|17-16| -+* pixel: | 12 | 13 | 14 | 15 | 8 | 9 | 10 | 11 | -+* bits: |15-14|13-12|11-10| 9-8 | 7-6 | 5-4 | 3-2 | 1-0 | -+* pixel: | 4 | 5 | 6 | 7 | 0 | 1 | 2 | 3 | -+* -+* Regardless of the frame buffer color depth, "color1", "color2", -+* "blinkcolor1", and "blinkcolor2" are 24-bit colors since the cursor is -+* injected into the data stream right before the video DAC. -+* -+* When "blinkrate" is not zero, pixel value 10 will alternate between "color1" -+* and "blinkcolor1" (similar for pixel value 11 and "color2"/"blinkcolor2"). -+* -+* "blinkrate" ranges between 0 and 255. When 0, blinking is disabled. 255 is -+* the fastest blink rate and 1 is the slowest. -+* -+* Both "width" and "height" must be between 1 and 64; it is preferable to have -+* "width" a multiple of 16. -+*/ -+struct ep93xx_cursor { -+ unsigned long flags; -+ unsigned long dx; // Only used if CURSOR_MOVE is set -+ unsigned long dy; // Only used if CURSOR_MOVE is set -+ unsigned long width; // Only used if CURSOR_SETSHAPE is set -+ unsigned long height; // Only used if CURSOR_SETSHAPE is set -+ const char *data; // Only used if CURSOR_SETSHAPE is set -+ unsigned long blinkrate; // Only used if CURSOR_BLINK is set -+ unsigned long color1; // Only used if CURSOR_SETCOLOR is set -+ unsigned long color2; // Only used if CURSOR_SETCOLOR is set -+ unsigned long blinkcolor1; // Only used if CURSOR_SETCOLOR is set -+ unsigned long blinkcolor2; // Only used if CURSOR_SETCOLOR is set -+}; -+ -+ -+/* -+ * The bits in the flags field of ep93xx_line. -+*/ -+/* -+* ioctl(fd, FBIO_EP93XX_LINE, ep93xx_line *) -+* -+* The line starts at ("x1","y1") and ends at ("x2","y2"). This means that -+* when using a pattern, the two coordinates are not transitive (i.e. swapping -+* ("x1","y1") with ("x2","y2") will not necessarily draw the exact same line, -+* pattern-wise). -+* -+* "pattern" is a 2 to 16 bit pattern (since a 1 bit pattern isn't much of a -+* pattern). The lower 16 bits define the pattern (1 being foreground, 0 being -+* background or transparent), and bits 19-16 define the length of the pattern -+* (as pattern length - 1). So, for example, "0xf00ff" defines a 16 bit -+* with the first 8 pixels in the foreground color and the next 8 pixels in the -+* background color or transparent. -+* -+* LINE_PRECISE is used to apply angularly corrected patterns to line. It -+* should only be used when LINE_PATTERN is also set. The pattern will be -+* applied along the length of the line, instead of along the length of the -+* major axis. This may result in the loss of fine details in the pattern, and -+* will take more time to draw the line in most cases. -+*/ -+ -+#define LINE_PATTERN 0x00000001 -+#define LINE_PRECISE 0x00000002 -+#define LINE_BACKGROUND 0x00000004 -+ -+struct ep93xx_line { -+ unsigned long flags; -+ unsigned long x1; -+ unsigned long y1; -+ unsigned long x2; -+ unsigned long y2; -+ unsigned long fgcolor; -+ unsigned long bgcolor; // Only used if LINE_BACKGROUND is set -+ unsigned long pattern; // Only used if LINE_PATTERN is set -+}; -+ -+#endif /* __EP93XXFB_H__ */ -+ ---- /dev/null -+++ b/drivers/video/ep93xxfb_mono.c -@@ -0,0 +1,1281 @@ -+/* -+ * drivers/video/ep93xxfb_mono.c -- grayscale on mono LCD driver for -+ * Cirrus Logic EP93xx. -+ * -+ * Copyright (C) 2007 Cirrus Logic -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file COPYING in the main directory of this archive for -+ * more details. -+ * -+ * This driver works for the following two LCD: -+ * SHARP LM121VB1T01 - A dual scan 640x480 monochrome LCD. -+ * HOSIDEN HLM6323 - A single scan 320x240 monochrome LCD. -+ * -+ * And support two gray modes: -+ * 8 levels of gray - Actually is 7 levels of gray. Two of the levels -+ * have the same gray. -+ * 16 levels of gray - Extending the gray levels by switching the LUT -+ * for each frame. -+ * -+ * HW connection for SHARP LM121VB1T01: -+ * P12 <------> LCD_U0 -+ * P8 <------> LCD_U1 -+ * P4 <------> LCD_U2 -+ * P0 <------> LCD_U3 -+ * P14 <------> LCD_L0 -+ * P10 <------> LCD_L1 -+ * P6 <------> LCD_L2 -+ * P2 <------> LCD_L3 -+ * HW connection for HOSIDEN HLM6323: -+ * P12 <------> LCD_0 -+ * P8 <------> LCD_1 -+ * P4 <------> LCD_2 -+ * P0 <------> LCD_3 -+ * -+ */ -+ -+#include <linux/version.h> -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/reboot.h> -+#include <linux/errno.h> -+#include <linux/string.h> -+#include <linux/mm.h> -+#include <linux/delay.h> -+#include <linux/fb.h> -+#include <linux/init.h> -+#include <linux/ioport.h> -+#include <linux/interrupt.h> -+#include <linux/dma-mapping.h> -+#include <asm/io.h> -+#include <asm/uaccess.h> -+#include <mach/hardware.h> -+ -+ -+#include <linux/platform_device.h> -+ -+#define CONFIG_EP93XX_SDCS0 -+ -+#undef DEBUG -+#ifdef DEBUG -+#define DPRINTK( fmt, arg... ) printk( fmt, ##arg ) -+#else -+#define DPRINTK( fmt, arg... ) -+#endif -+ -+#define FBDEV_NAME "ep93xxfb" -+ -+#define ep93xxfb_lock_outl(value, reg) \ -+{ \ -+ outl(RASTER_SWLOCK_VALUE, RASTER_SWLOCK); \ -+ outl(value, reg); \ -+ DPRINTK(#reg"=0x%08x\n", (unsigned int)(value)); \ -+} -+ -+#define ep93xxfb_outl(value, reg) \ -+{ \ -+ outl(value, reg); \ -+ DPRINTK(#reg"=0x%08x\n", (unsigned int)(value)); \ -+} -+ -+static unsigned int pseudo_palette[256]; -+ -+struct ep93xxfb_mono_videomodes -+{ -+ const char *name; -+ -+ unsigned long hres; // Horizontal Valid -+ unsigned long vres; // Vertical Valid -+ unsigned int freq; -+ unsigned int dualscan; -+ unsigned int bpp; -+ unsigned int graylevel; -+ -+ void (*configure)(unsigned char value); -+ void (*on)(unsigned char value); -+ void (*off)(unsigned char value); -+}; -+ -+struct ep93xxfb_mono_info -+{ -+ dma_addr_t fb_phys; -+ void *fb_log; -+ unsigned long fb_size; -+ unsigned long fb_actsize; -+ -+ unsigned int xres; -+ unsigned int yres; -+ -+ unsigned int freq; -+ unsigned int dualscan; -+ unsigned int bpp; -+ unsigned int graylevel; -+ -+ void (*configure)(unsigned char value); -+ void (*on)(unsigned char value); -+ void (*off)(unsigned char value); -+}; -+ -+ -+void LM121VB1T01_configure(unsigned char value); -+void HOSIDEN_HLM6323_configure(unsigned char value); -+ -+static int vmode = 1; -+ -+static struct ep93xxfb_mono_info epinfo; -+static struct ep93xxfb_mono_videomodes ep93xxfb_vmods[] = -+{ -+ { -+ "SHARP-LM121VB1T01-8GRAY", -+ 640, 480, 100, -+ 1, //dual scan -+ 4, //4bpp -+ 8, //8-level grayscale -+ LM121VB1T01_configure, -+ NULL, -+ NULL, -+ }, -+ { -+ "SHARP-LM121VB1T01-16GRAY", -+ 640, 480, 120, -+ 1, //dual scan -+ 4, //4bpp -+ 16, //16-level grayscale -+ LM121VB1T01_configure, -+ NULL, -+ NULL, -+ }, -+ { -+ "HOSIDEN HLM6323", -+ 320, 240, 115, -+ 0, //single scan -+ 4, //4bpp -+ 8, //8-level grayscale -+ HOSIDEN_HLM6323_configure, -+ NULL, -+ NULL, -+ }, -+ { -+ "HOSIDEN HLM6323", -+ 320, 240, 115, -+ 0, //single scan -+ 4, //4bpp -+ 16, //16-level grayscale -+ HOSIDEN_HLM6323_configure, -+ NULL, -+ NULL, -+ }, -+}; -+ -+ -+#define EP93XX_GS_OFFSET(lut, frame, pixel) ( (lut) + ( (pixel) << 2) + ((frame) << 5 )) -+ -+static unsigned long DY_LUT[2][16]; -+ -+static unsigned long GSLUT[32] = -+{ -+ 0x00070000, 0x00070000, 0x00070000, 0x00070000, /*0%*/ -+ 0x00078241, 0x00074182, 0x00071428, 0x00072814, /*25%*/ -+ 0x00000412, 0x00000241, 0x00000124, 0x00000000, /*33%*/ -+ 0x0007aa55, 0x000755aa, 0x000755aa, 0x0007aa55, /*50%*/ -+ 0x00000bed, 0x00000dbe, 0x00000edb, 0x00000000, /*66%*/ -+ 0x00077dbe, 0x0007be7d, 0x0007ebd7, 0x0007d7eb, /*75%*/ -+ 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, /*100%*/ -+ 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, -+}; -+ -+static void ep93xxfb_8gray_palette_init(void) -+{ -+ unsigned int cont, i, n; -+ unsigned int frame, pixval, gslut; -+ cont = inl(LUTCONT); -+ for (i=0; i< 16; i++) -+ { -+ n = (i & 0xe) << 4; -+ outl( n, (COLOR_LUT+(i<<2)) ); -+ } -+ for (pixval=0; pixval < 8; pixval++) -+ { -+ for (frame=0; frame < 4; frame++) -+ { -+ gslut = GSLUT[pixval*4 + frame]; -+ outl(gslut,EP93XX_GS_OFFSET(GS_LUT, frame, pixval)); -+ } -+ } -+ outl( cont ^ LUTCONT_RAM1, LUTCONT ); -+} -+ -+static void ep93xxfb_16gray_palette_switch(int index) -+{ -+ unsigned int cont, i, n; -+ cont = inl(LUTCONT); -+ n = index & 0x1; -+ for (i=0; i< 16; i++) -+ { -+ outl( DY_LUT[n][i], (COLOR_LUT+(i<<2)) ); -+ } -+ outl( cont ^ LUTCONT_RAM1, LUTCONT ); -+} -+ -+static void ep93xxfb_16gray_palette_init(void) -+{ -+ int i; -+ unsigned int cont; -+ unsigned int frame, pixval, gslut; -+ int split_table[16][2] = -+ { -+ {0, 0 }, -+ {0, 2 }, -+ {1, 1 }, -+ {3, 0 }, -+ -+ {2, 2 }, -+ {4, 0 }, -+ {3, 2 }, -+ {4, 2 }, -+ -+ {3, 3 }, // {6, 0 }, -+ {3, 4 }, -+ {4, 4 }, -+ {6, 2 }, -+ -+ {5, 5 }, -+ {3, 6 }, -+ {4, 6 }, -+ {6, 6 }, -+ }; -+ -+ cont = inl(LUTCONT); -+ for (i=0; i< 16; i++) -+ { -+ DY_LUT[0][i]=split_table[i][0] << 5; -+ DY_LUT[1][i]=split_table[i][1] << 5; -+ -+ outl( DY_LUT[0][i], (COLOR_LUT+(i<<2)) ); -+ } -+ -+ for (pixval=0; pixval < 8; pixval++) -+ { -+ for (frame=0; frame < 4; frame++) -+ { -+ gslut = GSLUT[pixval*4 + frame]; -+ outl(gslut,EP93XX_GS_OFFSET(GS_LUT, frame, pixval)); -+ outl(gslut,EP93XX_GS_OFFSET(GS_LUT2, frame, pixval)); -+ outl(gslut,EP93XX_GS_OFFSET(GS_LUT3, frame, pixval)); -+ } -+ } -+ outl( cont ^ LUTCONT_RAM1, LUTCONT ); -+} -+ -+static int ep93xxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -+{ -+ struct fb_var_screeninfo tmp_var; -+ DPRINTK("ep93xxfb_check_var - enter\n"); -+ -+ memcpy (&tmp_var, var, sizeof (tmp_var)); -+ -+ if (var->xres_virtual != var->xres) -+ var->xres_virtual = var->xres; -+ if (var->yres_virtual < var->yres) -+ var->yres_virtual = var->yres; -+ -+ if (var->xoffset < 0) -+ var->xoffset = 0; -+ if (var->yoffset < 0) -+ var->yoffset = 0; -+ -+ switch (tmp_var.bits_per_pixel) -+ { -+ case 4: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ DPRINTK("ep93xxfb_check_var - exit\n"); -+ return 0; -+} -+ -+static int ep93xxfb_set_par(struct fb_info *info) -+{ -+ DPRINTK("ep93xxfb_set_par\n"); -+ switch (info->var.bits_per_pixel) { -+ case 4: -+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR; -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+ -+static int ep93xxfb_blank(int blank_mode,struct fb_info *info) -+{ -+ unsigned long attribs; -+ DPRINTK("ep93xxfb_blank - enter\n"); -+ attribs = inl(VIDEOATTRIBS); -+ -+ if (blank_mode) { -+ if (epinfo.off) -+ (epinfo.off)( 0 ); -+ -+ ep93xxfb_lock_outl(attribs & ~(VIDEOATTRIBS_DATAEN | -+ VIDEOATTRIBS_SYNCEN | VIDEOATTRIBS_PCLKEN | -+ VIDEOATTRIBS_EN), VIDEOATTRIBS); -+ } -+ else { -+ -+ if (epinfo.configure) -+ (epinfo.configure)( (unsigned char) epinfo.graylevel ); -+ if (epinfo.on) -+ (epinfo.on)( 0 ); -+ } -+ return 0; -+} -+ -+static void ep93xxfb_get_par(struct fb_info *info) -+{ -+ -+ DPRINTK("ep93xxfb_get_par - enter\n"); -+ -+ epinfo.configure = ep93xxfb_vmods[vmode].configure; -+ epinfo.on = ep93xxfb_vmods[vmode].on; -+ epinfo.off = ep93xxfb_vmods[vmode].off; -+ -+ epinfo.freq = ep93xxfb_vmods[vmode].freq; -+ epinfo.dualscan = ep93xxfb_vmods[vmode].dualscan; -+ epinfo.bpp = ep93xxfb_vmods[vmode].bpp; -+ epinfo.graylevel = ep93xxfb_vmods[vmode].graylevel; -+ -+ epinfo.xres = ep93xxfb_vmods[vmode].hres; -+ epinfo.yres = ep93xxfb_vmods[vmode].vres; -+ -+} -+ -+static int ep93xxfb_alloc_videomem(void) -+{ -+ unsigned long adr,size,pgsize; -+ int order; -+ -+ DPRINTK("ep93xxfb_alloc_videomem - enter \n"); -+ -+ epinfo.fb_log = NULL; -+ epinfo.fb_size = epinfo.xres*epinfo.yres*epinfo.bpp/8; -+ order = get_order( epinfo.fb_size ); -+ epinfo.fb_log = (void*) __get_free_pages( GFP_KERNEL, order ); -+ -+ if (epinfo.fb_log) { -+ epinfo.fb_phys = __virt_to_phys((int) epinfo.fb_log ); -+ adr = (unsigned long)epinfo.fb_log; -+ size = epinfo.fb_size; -+ pgsize = 1 << order; -+ do { -+ adr += pgsize; -+ SetPageReserved(virt_to_page(adr)); -+ } while(size -= pgsize); -+ } -+ else -+ return -ENOMEM; -+ -+ memset(epinfo.fb_log,0x00,epinfo.fb_size); -+ -+ DPRINTK(" fb_log_addres = 0x%x\n", (unsigned int)epinfo.fb_log); -+ DPRINTK(" fb_phys_address = 0x%x\n", (unsigned int)epinfo.fb_phys); -+ DPRINTK(" fb_size = %lu\n", (unsigned long)epinfo.fb_size); -+ DPRINTK(" fb_page_order = %d\n", (unsigned int)order); -+ DPRINTK("ep93xxfb_alloc_videomem - exit \n"); -+ return 0; -+} -+ -+static void ep93xxfb_release_videomem(void) -+{ -+ unsigned long adr,size,psize; -+ int order; -+ -+ DPRINTK("ep93xxfb_release_videomem - enter \n"); -+ if (epinfo.fb_log) { -+ order = get_order(epinfo.fb_size); -+ adr = (unsigned long)epinfo.fb_log; -+ size = epinfo.fb_size; -+ psize = 1 << order ; -+ do { -+ adr += psize; -+ ClearPageReserved(virt_to_page(adr)); -+ } while(size -= psize); -+ free_pages((unsigned long)epinfo.fb_log, order ); -+ } -+ DPRINTK("ep93xxfb_release_videomem - exit \n"); -+} -+ -+static void ep93xxfb_setinfo(struct fb_info *info) -+{ -+ -+ DPRINTK("ep93xxfb_setinfo - enter \n"); -+ info->pseudo_palette = pseudo_palette; -+ info->var.xres = epinfo.xres; -+ info->var.yres = epinfo.yres; -+ info->var.xres_virtual = epinfo.xres; -+ info->var.yres_virtual = epinfo.yres; -+ -+ info->var.bits_per_pixel = epinfo.bpp; -+ info->var.red.length = epinfo.bpp; -+ info->var.green.length = epinfo.bpp; -+ info->var.blue.length = epinfo.bpp; -+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR; -+ info->var.red.offset = 0; -+ info->var.green.offset =0; -+ info->var.blue.offset = 0; -+ -+ info->fix.smem_start = epinfo.fb_phys; -+ info->fix.smem_len = epinfo.fb_size; -+ info->fix.type = FB_TYPE_PACKED_PIXELS; -+ info->fix.line_length = (epinfo.xres * epinfo.bpp) / 8; -+ info->fix.accel = FB_ACCEL_NONE; -+ info->screen_base = epinfo.fb_log; -+ info->fix.ypanstep = 1; -+ info->fix.ywrapstep = 1; -+ -+ DPRINTK("ep93xxfb_setinfo - exit \n"); -+} -+ -+static int ep93xxfb_config(struct fb_info *info) -+{ -+ DPRINTK("ep93xxfb_config - enter\n"); -+ -+ ep93xxfb_get_par( info ); -+ if( ep93xxfb_alloc_videomem() != 0 ) { -+ printk("Unable to allocate video memory\n"); -+ return -ENOMEM; -+ } -+ -+ /* set video memory parameters */ -+ ep93xxfb_outl(epinfo.fb_phys, VIDSCRNPAGE); -+ if(epinfo.dualscan) -+ { -+ ep93xxfb_outl(epinfo.fb_phys + (epinfo.bpp*epinfo.xres*epinfo.yres/16) -+ , VIDSCRNHPG); -+ } -+ -+ DPRINTK(" fb_phys = 0x%x\n", inl(VIDSCRNPAGE) ); -+ DPRINTK(" fb_phys_hpg = 0x%x\n", inl(VIDSCRNHPG)); -+ -+ ep93xxfb_outl(epinfo.yres , SCRNLINES); -+ ep93xxfb_outl(((epinfo.xres * epinfo.bpp) / 32) - 1, LINELENGTH); -+ ep93xxfb_outl((epinfo.xres * epinfo.bpp) / 32, VLINESTEP); -+ -+ if(epinfo.configure) -+ (epinfo.configure)( (unsigned char) epinfo.graylevel ); -+ -+ ep93xxfb_setinfo( info ); -+ -+ -+ DPRINTK("ep93xxfb_config - exit\n"); -+ return 0; -+} -+ -+static unsigned long ep93xx_get_pll_frequency(unsigned long pll) -+{ -+ unsigned long fb1, fb2, ipd, ps, freq; -+ -+ if (pll == 1) -+ pll = inl(EP93XX_SYSCON_CLOCK_SET1); -+ else if (pll == 2) -+ pll = inl(EP93XX_SYSCON_CLOCK_SET2); -+ else -+ return 0; -+ -+ ps = (pll & SYSCON_CLKSET1_PLL1_PS_MASK) >> SYSCON_CLKSET1_PLL1_PS_SHIFT; -+ fb1 = ((pll & SYSCON_CLKSET1_PLL1_X1FBD1_MASK) >> SYSCON_CLKSET1_PLL1_X1FBD1_SHIFT); -+ fb2 = ((pll & SYSCON_CLKSET1_PLL1_X2FBD2_MASK) >> SYSCON_CLKSET1_PLL1_X2FBD2_SHIFT); -+ ipd = ((pll & SYSCON_CLKSET1_PLL1_X2IPD_MASK) >> SYSCON_CLKSET1_PLL1_X2IPD_SHIFT); -+ -+ freq = (((0x00e10000 * (fb1+1)) / (ipd+1)) * (fb2+1)) >> ps; -+ return freq; -+} -+ -+static int ep93xx_set_video_div(unsigned long freq) -+{ -+ unsigned long pdiv = 0, div = 0, psel = 0, esel = 0; -+ unsigned long err, f, i, j, k; -+ -+ err = -1; -+ -+ for (i = 0; i < 3; i++) { -+ if (i == 0) -+ f = 14745600 * 2; -+ else if (i == 1) -+ f = ep93xx_get_pll_frequency(1) * 2; -+ else -+ f = ep93xx_get_pll_frequency(2) * 2; -+ -+ for (j = 4; j <= 6; j++) { -+ k = f / (freq * j); -+ if (k < 2) -+ continue; -+ -+ if (abs(((f / (j * k))) - freq ) < err ) { -+ pdiv = j - 3; -+ div = k; -+ psel = (i == 2) ? 1 : 0; -+ esel = (i == 0) ? 0 : 1; -+ err = (f / (j * k)) - freq; -+ } -+ } -+ } -+ -+ if (err == -1) -+ return -1; -+ -+ f = SYSCON_VIDDIV_VENA | (esel ? SYSCON_VIDDIV_ESEL : 0) | -+ (psel ? SYSCON_VIDDIV_PSEL : 0) | -+ (pdiv << SYSCON_VIDDIV_PDIV_SHIFT) | -+ (div << SYSCON_VIDDIV_VDIV_SHIFT); -+ outl(0xaa, EP93XX_SYSCON_SWLOCK); -+ outl(f, SYSCON_VIDDIV); -+ -+ return freq + err; -+} -+ -+static int interrupt_hooked = 0; -+static int vs_counter = 0; -+ -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17) -+static irqreturn_t ep93xxfb_irq_handler(int i, void *blah) -+#else -+static irqreturn_t ep93xxfb_irq_handler(int i, void *blah, struct pt_regs *regs) -+#endif -+{ -+ -+ outl(RASTER_SWLOCK_VALUE, RASTER_SWLOCK); -+ outl( -+#ifdef CONFIG_EP93XX_SDCS0 -+ (0 << VIDEOATTRIBS_SDSEL_SHIFT) | -+#endif -+#ifdef CONFIG_EP93XX_SDCS1 -+ (1 << VIDEOATTRIBS_SDSEL_SHIFT) | -+#endif -+#ifdef CONFIG_EP93XX_SDCS2 -+ (2 << VIDEOATTRIBS_SDSEL_SHIFT) | -+#endif -+#ifdef CONFIG_EP93XX_SDCS3 -+ (3 << VIDEOATTRIBS_SDSEL_SHIFT) | -+#endif -+ VIDEOATTRIBS_VCPOL | VIDEOATTRIBS_HSPOL | -+ VIDEOATTRIBS_DATAEN | VIDEOATTRIBS_SYNCEN | VIDEOATTRIBS_INVCLK | -+ VIDEOATTRIBS_PCLKEN | VIDEOATTRIBS_EN | VIDEOATTRIBS_INTEN , -+ VIDEOATTRIBS ); -+ -+ ep93xxfb_16gray_palette_switch(vs_counter++); -+ -+ return IRQ_HANDLED; -+} -+ -+void LM121VB1T01_configure(unsigned char value) -+{ -+ -+ int n; -+ unsigned long attribs; -+ printk("LM121VB1T01_configure\n"); -+ -+ switch(value) -+ { -+ case 8: -+ ep93xxfb_8gray_palette_init(); -+ break; -+ case 16: -+ ep93xxfb_16gray_palette_init(); -+ break; -+ default: -+ return; -+ } -+ -+ SysconSetLocked(EP93XX_SYSCON_DEVICE_CONFIG, (inl(EP93XX_SYSCON_DEVICE_CONFIG) & ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE) | EP93XX_SYSCON_DEVCFG_RasOnP3); -+ -+ ep93xx_set_video_div(epinfo.freq*240*1280); -+ -+ ep93xxfb_lock_outl( 0x00000000 , VIDEOATTRIBS ); -+ -+ n = 240; -+ ep93xxfb_lock_outl( n + 3 , VLINESTOTAL ); -+ ep93xxfb_lock_outl( ((n)<<16) + n+1 , VSYNCSTRTSTOP ); -+ ep93xxfb_lock_outl( ((2)<<16) + n+2 , VACTIVESTRTSTOP ); -+ ep93xxfb_lock_outl( ((3)<<16) + n+3 , VBLANKSTRTSTOP ); -+ ep93xxfb_lock_outl( ((n+3)<<16) + n+3 , VCLKSTRTSTOP ); -+ -+ n = 1280; -+ ep93xxfb_lock_outl( n + 15 , HCLKSTOTAL ); -+ ep93xxfb_lock_outl( ((n+5)<<16) + n+ 14 , HSYNCSTRTSTOP ); -+ ep93xxfb_lock_outl( ((15)<<16) + n + 15 , HACTIVESTRTSTOP ); -+ ep93xxfb_lock_outl( ((n+15)<<16) + 15 , HBLANKSTRTSTOP ); -+ ep93xxfb_lock_outl( ((n)<<16) + n , HCLKSTRTSTOP ); -+ -+ ep93xxfb_lock_outl( 14 , LINECARRY ); -+ -+ attribs = 0; -+ -+#ifdef CONFIG_EP93XX_SDCS0 -+ attribs |= 0 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS1 -+ attribs |= 1 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS2 -+ attribs |= 2 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS3 -+ attribs |= 3 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+ -+ switch(value) -+ { -+ case 8: -+ ep93xxfb_lock_outl( PIXELMODE_DSCAN | -+ PIXELMODE_S_8PPC | PIXELMODE_P_4BPP | -+ PIXELMODE_C_GSLUT , PIXELMODE ); -+ -+ ep93xxfb_lock_outl( -+ attribs | VIDEOATTRIBS_VCPOL | VIDEOATTRIBS_HSPOL | -+ VIDEOATTRIBS_DATAEN | VIDEOATTRIBS_SYNCEN | VIDEOATTRIBS_INVCLK | -+ VIDEOATTRIBS_PCLKEN | VIDEOATTRIBS_EN , -+ VIDEOATTRIBS ); -+ break; -+ case 16: -+ if(!interrupt_hooked) -+ { -+ request_irq(IRQ_EP93XX_VSYNC, ep93xxfb_irq_handler, IRQF_DISABLED, "lut switch interrupt", NULL); -+ interrupt_hooked = 1; -+ } -+ ep93xxfb_lock_outl( PIXELMODE_DSCAN | -+ PIXELMODE_S_8PPC | PIXELMODE_P_4BPP | PIXELMODE_C_GSLUT, PIXELMODE ); -+ -+ ep93xxfb_lock_outl( -+ attribs | VIDEOATTRIBS_VCPOL | VIDEOATTRIBS_HSPOL | -+ VIDEOATTRIBS_DATAEN | VIDEOATTRIBS_SYNCEN | VIDEOATTRIBS_INVCLK | -+ VIDEOATTRIBS_PCLKEN | VIDEOATTRIBS_EN | VIDEOATTRIBS_INTEN, -+ VIDEOATTRIBS ); -+ break; -+ default: -+ return; -+ } -+ -+} -+ -+void HOSIDEN_HLM6323_configure(unsigned char value) -+{ -+ int n; -+ unsigned long attribs; -+ -+ printk("HOSIDEN_HLM6323_configure\n"); -+ -+ switch(value) -+ { -+ case 8: -+ ep93xxfb_8gray_palette_init(); -+ break; -+ case 16: -+ ep93xxfb_16gray_palette_init(); -+ break; -+ default: -+ return; -+ } -+ -+ SysconSetLocked(EP93XX_SYSCON_DEVICE_CONFIG, inl(EP93XX_SYSCON_DEVICE_CONFIG) |EP93XX_SYSCON_DEVCFG_RasOnP3); -+ -+ ep93xxfb_lock_outl( 0x00000000 , VIDEOATTRIBS ); -+ -+ ep93xx_set_video_div(epinfo.freq*320*240); -+ mdelay(10); -+ -+ n = 240; -+ ep93xxfb_lock_outl( n + 3 , VLINESTOTAL ); -+ ep93xxfb_lock_outl( ((n+1)<<16) + n +2 , VSYNCSTRTSTOP ); -+ ep93xxfb_lock_outl( ((3)<<16) + n +3 , VACTIVESTRTSTOP ); -+ ep93xxfb_lock_outl( ((3)<<16) + n +3 , VBLANKSTRTSTOP ); -+ ep93xxfb_lock_outl( ((n+3)<<16) + n +3, VCLKSTRTSTOP ); -+ -+ n = 320; -+ ep93xxfb_lock_outl( n + 3, HCLKSTOTAL ); -+ ep93xxfb_lock_outl( ((n+1)<<16) + n+2 , HSYNCSTRTSTOP ); -+ ep93xxfb_lock_outl( ((3)<<16) + n+3 , HACTIVESTRTSTOP ); -+ ep93xxfb_lock_outl( ((3)<<16) + n+3 , HBLANKSTRTSTOP ); -+ ep93xxfb_lock_outl( ((n+3)<<16) + n+3 , HCLKSTRTSTOP ); -+ -+ ep93xxfb_lock_outl( 3 , LINECARRY ); -+ -+ attribs = 0; -+ -+#ifdef CONFIG_EP93XX_SDCS0 -+ attribs |= 0 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS1 -+ attribs |= 1 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS2 -+ attribs |= 2 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+#ifdef CONFIG_EP93XX_SDCS3 -+ attribs |= 3 << VIDEOATTRIBS_SDSEL_SHIFT; -+#endif -+ -+ switch(value) -+ { -+ case 8: -+ ep93xxfb_lock_outl( -+ PIXELMODE_S_4PPC | PIXELMODE_P_4BPP | PIXELMODE_C_GSLUT, PIXELMODE ); -+ ep93xxfb_lock_outl( -+ attribs | VIDEOATTRIBS_VCPOL | VIDEOATTRIBS_HSPOL | -+ VIDEOATTRIBS_DATAEN | VIDEOATTRIBS_SYNCEN | VIDEOATTRIBS_INVCLK | -+ VIDEOATTRIBS_PCLKEN | VIDEOATTRIBS_EN , -+ VIDEOATTRIBS ); -+ break; -+ case 16: -+ ep93xxfb_lock_outl( -+ PIXELMODE_S_4PPC | PIXELMODE_P_4BPP | PIXELMODE_C_GSLUT, PIXELMODE ); -+ if(!interrupt_hooked) -+ { -+ request_irq(IRQ_EP93XX_VSYNC, ep93xxfb_irq_handler, IRQF_DISABLED, "lut switch interrupt", NULL); -+ interrupt_hooked = 1; -+ } -+ ep93xxfb_lock_outl( -+ attribs | VIDEOATTRIBS_VCPOL | VIDEOATTRIBS_HSPOL | -+ VIDEOATTRIBS_DATAEN | VIDEOATTRIBS_SYNCEN | VIDEOATTRIBS_INVCLK | -+ VIDEOATTRIBS_PCLKEN | VIDEOATTRIBS_EN | VIDEOATTRIBS_INTEN, -+ VIDEOATTRIBS ); -+ break; -+ default: -+ return; -+ } -+} -+ -+#define FB_WRITEL fb_writel -+#define FB_READL fb_readl -+#define LEFT_POS(bpp) (0) -+#define SHIFT_HIGH(val, bits) ((val) << (bits)) -+#define SHIFT_LOW(val, bits) ((val) >> (bits)) -+static inline void color_imageblit(const struct fb_image *image, -+ struct fb_info *p, u8 *dst1, -+ u32 start_index, -+ u32 pitch_index) -+{ -+ /* Draw the penguin */ -+ u32 *dst, *dst2; -+ u32 color = 0, val, shift; -+ int i, n, bpp = p->var.bits_per_pixel; -+ u32 null_bits = 32 - bpp; -+ u32 *palette = (u32 *) p->pseudo_palette; -+ const u8 *src = image->data; -+ -+ dst2 = (u32 *) dst1; -+ for (i = image->height; i--; ) { -+ n = image->width; -+ dst = (u32 *) dst1; -+ shift = 0; -+ val = 0; -+ -+ if (start_index) { -+ u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index)); -+ val = FB_READL(dst) & start_mask; -+ shift = start_index; -+ } -+ while (n--) { -+ if (p->fix.visual == FB_VISUAL_TRUECOLOR || -+ p->fix.visual == FB_VISUAL_DIRECTCOLOR ) -+ color = palette[*src]; -+ else -+ color = *src; -+ color <<= LEFT_POS(bpp); -+ val |= SHIFT_HIGH(color, shift); -+ if (shift >= null_bits) { -+ FB_WRITEL(val, dst++); -+ -+ val = (shift == null_bits) ? 0 : -+ SHIFT_LOW(color, 32 - shift); -+ } -+ shift += bpp; -+ shift &= (32 - 1); -+ src++; -+ } -+ if (shift) { -+ u32 end_mask = SHIFT_HIGH(~(u32)0, shift); -+ -+ FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); -+ } -+ dst1 += p->fix.line_length; -+ if (pitch_index) { -+ dst2 += p->fix.line_length; -+ dst1 = (u8 *)((long __force)dst2 & ~(sizeof(u32) - 1)); -+ -+ start_index += pitch_index; -+ start_index &= 32 - 1; -+ } -+ } -+} -+ -+static const int reversebit[]= -+{ -+ 7, 6, 5, 4, 3, 2, 1, 0, -+ 15,14,13,12,11,10, 9, 8, -+ 23,22,21,20,19,18,17,16, -+ 31,30,29,28,27,26,25,24, -+}; -+static inline void slow_imageblit(const struct fb_image *image, struct fb_info *p, -+ u8 *dst1, u32 fgcolor, -+ u32 bgcolor, -+ u32 start_index, -+ u32 pitch_index) -+{ -+ u32 shift, color = 0, bpp = p->var.bits_per_pixel; -+ u32 *dst, *dst2; -+ u32 val, pitch = p->fix.line_length; -+ u32 null_bits = 32 - bpp; -+ u32 spitch = (image->width+7)/8; -+ const u8 *src = image->data, *s; -+ u32 i, j, l; -+ -+ dst2 = (u32 *) dst1; -+ fgcolor <<= LEFT_POS(bpp); -+ bgcolor <<= LEFT_POS(bpp); -+ for (i = image->height; i--; ) { -+ shift = val = 0; -+ l = 8; -+ j = image->width; -+ dst = (u32 *) dst1; -+ s = src; -+ -+ /* write leading bits */ -+ if (start_index) { -+ u32 start_mask = ~(SHIFT_HIGH(~(u32)0,start_index)); -+ val = FB_READL(dst) & start_mask; -+ shift = start_index; -+ } -+ -+ while (j--) { -+ l--; -+ color = (*s & (1 << l)) ? fgcolor : bgcolor; -+ val |= SHIFT_HIGH(color, reversebit[shift]); -+ /* Did the bitshift spill bits to the next long? */ -+ if (shift >= null_bits) { -+ FB_WRITEL(val, dst++); -+ val = (shift == null_bits) ? 0 : -+ SHIFT_LOW(color, 32 - reversebit[shift]); -+ } -+ shift += bpp; -+ shift &= (32 - 1); -+ if (!l) { l = 8; s++; }; -+ } -+ -+ /* write trailing bits */ -+ if (shift) { -+ u32 end_mask = SHIFT_HIGH(~(u32)0, shift); -+ -+ FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); -+ } -+ -+ dst1 += pitch; -+ src += spitch; -+ if (pitch_index) { -+ dst2 += pitch; -+ dst1 = (u8 *)((long __force)dst2 & ~(sizeof(u32) - 1)); -+ start_index += pitch_index; -+ start_index &= 32 - 1; -+ } -+ -+ } -+} -+ -+static void ep93xx_imageblit(struct fb_info *p, const struct fb_image *image) -+{ -+ u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; -+ u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel; -+ u32 dx = image->dx, dy = image->dy; -+ u8 *dst1; -+ -+ if (p->state != FBINFO_STATE_RUNNING) -+ return; -+ -+ bitstart = (dy * p->fix.line_length * 8) + (dx * bpp); -+ start_index = bitstart & (32 - 1); -+ pitch_index = (p->fix.line_length & (bpl - 1)) * 8; -+ -+ bitstart /= 8; -+ bitstart &= ~(bpl - 1); -+ dst1 = p->screen_base + bitstart; -+ -+ if (p->fbops->fb_sync) -+ p->fbops->fb_sync(p); -+ -+ if (image->depth == 1) { -+ if (p->fix.visual == FB_VISUAL_TRUECOLOR || -+ p->fix.visual == FB_VISUAL_DIRECTCOLOR) { -+ fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color]; -+ bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color]; -+ } else { -+ fgcolor = image->fg_color; -+ bgcolor = image->bg_color; -+ } -+ slow_imageblit(image, p, dst1, fgcolor, bgcolor, -+ start_index, pitch_index); -+ } else -+ color_imageblit(image, p, dst1, start_index, pitch_index); -+} -+ -+ -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) -+ -+int ep93xxfb_ioctl(struct fb_info *info,unsigned int cmd, unsigned long arg) -+{ -+ return 0; -+} -+ -+static int ep93xxfb_mmap(struct fb_info *info,struct vm_area_struct *vma) -+{ -+ unsigned long off, start, len; -+ -+ DPRINTK("ep93xxfb_mmap - enter\n"); -+ -+ off = vma->vm_pgoff << PAGE_SHIFT; -+ start = info->fix.smem_start; -+ len = PAGE_ALIGN(start & ~PAGE_MASK) + info->fix.smem_len; -+ start &= PAGE_MASK; -+ if ((vma->vm_end - vma->vm_start + off) > len) -+ return -EINVAL; -+ -+ off += start; -+ vma->vm_pgoff = off >> PAGE_SHIFT; -+ -+ vma->vm_flags |= VM_IO; -+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); -+ -+ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, -+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) { -+ DPRINTK("ep93xxfb_mmap error\n"); -+ return -EAGAIN; -+ } -+ -+ DPRINTK("ep93xxfb_mmap - exit\n"); -+ return 0; -+} -+ -+ -+static struct fb_ops ep93xxfb_ops = { -+ .owner = THIS_MODULE, -+ .fb_check_var = ep93xxfb_check_var, -+ .fb_set_par = ep93xxfb_set_par, -+ .fb_blank = ep93xxfb_blank, -+ .fb_fillrect = cfb_fillrect, -+ .fb_copyarea = cfb_copyarea, -+ // .fb_imageblit = cfb_imageblit, -+ .fb_imageblit = ep93xx_imageblit, -+ .fb_ioctl = ep93xxfb_ioctl, -+ .fb_mmap = ep93xxfb_mmap, -+}; -+ -+ -+static struct resource ep93xxfb_raster_resources = { -+ .start = EP93XX_RASTER_PHYS_BASE, -+ .end = EP93XX_RASTER_PHYS_BASE + 0x1ffff, -+ .flags = IORESOURCE_MEM, -+}; -+ -+ -+static int __init ep93xxfb_probe(struct platform_device *device) -+{ -+ struct fb_info *info = NULL; -+ struct resource *res = NULL; -+ int ret = 0; -+ int arb = 0; -+ -+ DPRINTK("ep93xxfb_probe - enter \n"); -+ -+ if(!device) { -+ printk("error : to_platform_device\n"); -+ return -ENODEV; -+ } -+ res = platform_get_resource( device, IORESOURCE_MEM, 0); -+ if(!res) { -+ printk("error : platform_get_resource \n"); -+ return -ENODEV; -+ } -+ if (!request_mem_region(res->start,res->end - res->start + 1, FBDEV_NAME )) -+ return -EBUSY; -+ -+ info = framebuffer_alloc(sizeof(u32) * 256, &device->dev); -+ -+ if(!info) { -+ printk("Unable to allocate memory for frame buffer\n"); -+ return -ENOMEM; -+ } -+ -+ info->flags = FBINFO_DEFAULT; -+ strncpy(info->fix.id, FBDEV_NAME, sizeof(info->fix.id)); -+ info->fix.mmio_start = res->start; -+ info->fix.mmio_len = res->end - res->start + 1; -+ info->fbops = &ep93xxfb_ops; -+ info->pseudo_palette = info->par; -+ info->state = FBINFO_STATE_RUNNING; -+ -+ printk("mmio_start = 0x%08x\n", res->start); -+ printk("mmio_len = 0x%08x\n", res->end - res->start + 1); -+ -+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { -+ ret = -ENOMEM; -+ goto fbuff; -+ } -+ -+ if ((ret = ep93xxfb_config(info)) < 0) -+ goto clmap; -+ -+ if (register_framebuffer(info) < 0) { -+ printk(KERN_ERR "Unable to register ep93xxfb frame buffer\n"); -+ ret = -EINVAL; -+ goto clmap; -+ } -+ platform_set_drvdata(device, info); -+ printk(KERN_INFO "fb%d: EP93xx frame buffer at %dx%dx%dbpp\n", info->node, -+ info->var.xres, info->var.yres, info->var.bits_per_pixel); -+ -+ /*change the raster arb to the highest one--Bo*/ -+ arb = inl(EP93XX_SYSCON_BMAR); -+ arb = (arb & 0x3f8) | 0x01; -+ ep93xxfb_outl(arb,EP93XX_SYSCON_BMAR); -+ -+ DPRINTK("ep93xxfb_probe - exit \n"); -+ return 0; -+ -+clmap: -+ fb_dealloc_cmap(&info->cmap); -+ -+fbuff: -+ framebuffer_release(info); -+ return ret; -+} -+ -+static int ep93xxfb_remove(struct platform_device *device) -+{ -+ struct resource *res; -+ struct fb_info *info; -+ -+ DPRINTK("ep93xxfb_remove - enter \n"); -+ -+ info = platform_get_drvdata(device); -+ -+ ep93xxfb_release_videomem(); -+ -+ res = platform_get_resource( device, IORESOURCE_MEM, 0); -+ release_mem_region(res->start, res->end - res->start + 1); -+ -+ platform_set_drvdata(device, NULL); -+ unregister_framebuffer(info); -+ -+ fb_dealloc_cmap(&info->cmap); -+ framebuffer_release(info); -+ -+ ep93xxfb_blank( 1, info ); -+ -+ DPRINTK("ep93xxfb_remove - exit \n"); -+ return 0; -+} -+ -+static void ep93xxfb_platform_release(struct device *device) -+{ -+ DPRINTK("ep93xxfb_platform_release - enter\n"); -+} -+ -+ -+static struct platform_driver ep93xxfb_driver = { -+ .probe = ep93xxfb_probe, -+ .remove = ep93xxfb_remove, -+ .driver = { -+ .name = FBDEV_NAME, -+ }, -+}; -+ -+static struct platform_device ep93xxfb_device = { -+ .name = FBDEV_NAME, -+ .id = -1, -+ .dev = { -+ .release = ep93xxfb_platform_release, -+ }, -+ .num_resources = 1, -+ .resource = &ep93xxfb_raster_resources, -+}; -+ -+int __init ep93xxfb_init(void) -+{ -+ int ret = 0; -+ -+ DPRINTK("ep93xxfb_init - enter\n"); -+ -+ ret = platform_driver_register(&ep93xxfb_driver); -+ -+ if (!ret) { -+ ret = platform_device_register(&ep93xxfb_device); -+ if (ret) -+ platform_driver_unregister(&ep93xxfb_driver); -+ } -+ DPRINTK("ep93xxfb_init - exit\n"); -+ return ret; -+} -+ -+static void __exit ep93xxfb_exit(void) -+{ -+ DPRINTK("ep93xxfb_exit - enter\n"); -+ platform_driver_unregister(&ep93xxfb_driver); -+ platform_device_unregister(&ep93xxfb_device); -+ DPRINTK("ep93xxfb_exit - exit\n"); -+} -+ -+#else // LINUX_VERSION_CODE -+ -+ -+int ep93xxfb_setcolreg(unsigned regno, unsigned red, unsigned green, -+ unsigned blue, unsigned transp, -+ struct fb_info *info) -+{ -+ return 0; -+} -+static struct fb_ops ep93xxfb_ops = { -+ .owner = THIS_MODULE, -+ .fb_setcolreg = ep93xxfb_setcolreg, -+ .fb_check_var = ep93xxfb_check_var, -+ .fb_set_par = ep93xxfb_set_par, -+ .fb_blank = ep93xxfb_blank, -+ .fb_fillrect = cfb_fillrect, -+ .fb_copyarea = cfb_copyarea, -+ .fb_imageblit = ep93xx_imageblit, -+ .fb_cursor = soft_cursor, -+}; -+ -+static int __init ep93xxfb_probe(struct device *device) -+{ -+ struct platform_device *pdev = to_platform_device(device); -+ struct fb_info *info = NULL; -+ struct resource *res = NULL; -+ int ret = 0; -+ int arb = 0; -+ -+ DPRINTK("ep93xxfb_probe - enter \n"); -+ -+ -+ if(!device) { -+ printk("error : to_platform_device\n"); -+ return -ENODEV; -+ } -+ res = platform_get_resource( pdev, IORESOURCE_MEM, 0); -+ if(!res) { -+ printk("error : platform_get_resource \n"); -+ return -ENODEV; -+ } -+ if (!request_mem_region(res->start,res->end - res->start + 1, FBDEV_NAME )) -+ return -EBUSY; -+ -+ info = framebuffer_alloc(sizeof(u32) * 256, &pdev->dev); -+ -+ if(!info) { -+ printk("Unable to allocate memory for frame buffer\n"); -+ return -ENOMEM; -+ } -+ -+ info->flags = FBINFO_DEFAULT; -+ strncpy(info->fix.id, FBDEV_NAME, sizeof(info->fix.id)); -+ info->fix.mmio_start = res->start; -+ info->fix.mmio_len = res->end - res->start + 1; -+ info->fbops = &ep93xxfb_ops; -+ info->pseudo_palette = info->par; -+ info->state = FBINFO_STATE_RUNNING; -+ -+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { -+ ret = -ENOMEM; -+ goto fbuff; -+ } -+ -+ if ((ret = ep93xxfb_config(info)) < 0) -+ goto clmap; -+ -+ if (register_framebuffer(info) < 0) { -+ printk(KERN_ERR "Unable to register ep93xxfb frame buffer\n"); -+ ret = -EINVAL; -+ goto clmap; -+ } -+ dev_set_drvdata(device, info); -+ printk(KERN_INFO "fb%d: EP93xx frame buffer at %dx%dx%dbpp\n", info->node, -+ info->var.xres, info->var.yres, info->var.bits_per_pixel); -+ -+ /*change the raster arb to the highest one--Bo*/ -+ arb = inl(EP93XX_SYSCON_BMAR); -+ arb = (arb & 0x3f8) | 0x01; -+ ep93xxfb_outl(arb,EP93XX_SYSCON_BMAR); -+ -+ DPRINTK("ep93xxfb_probe - exit \n"); -+ return 0; -+ -+clmap: -+ fb_dealloc_cmap(&info->cmap); -+ -+fbuff: -+ framebuffer_release(info); -+ return ret; -+} -+ -+static int ep93xxfb_remove(struct device *device) -+{ -+ struct platform_device *pdev = to_platform_device(device); -+ struct resource *res; -+ struct fb_info *info; -+ -+ DPRINTK("ep93xxfb_remove - enter \n"); -+ -+ info = dev_get_drvdata(device); -+ -+ ep93xxfb_release_videomem(); -+ -+ res = platform_get_resource( pdev, IORESOURCE_MEM, 0); -+ release_mem_region(res->start, res->end - res->start + 1); -+ -+ dev_set_drvdata(device, NULL); -+ unregister_framebuffer(info); -+ -+ fb_dealloc_cmap(&info->cmap); -+ framebuffer_release(info); -+ -+ ep93xxfb_blank( 1, info ); -+ -+ DPRINTK("ep93xxfb_remove - exit \n"); -+ return 0; -+} -+static struct device_driver ep93xxfb_driver = { -+ .name = FBDEV_NAME, -+ .bus = &platform_bus_type, -+ .probe = ep93xxfb_probe, -+ .remove = ep93xxfb_remove, -+}; -+int __init ep93xxfb_init(void) -+{ -+ DPRINTK("ep93xxfb_init\n"); -+ return driver_register(&ep93xxfb_driver); -+} -+ -+static void __exit ep93xxfb_exit(void) -+{ -+ DPRINTK("ep93xxfb_exit\n"); -+ return driver_unregister(&ep93xxfb_driver); -+} -+ -+int __init ep93xxfb_setup(char *options) -+{ -+ DPRINTK("ep93xxfb_setup\n"); -+ return 0; -+} -+ -+#endif // LINUX_VERSION_CODE -+ -+ -+module_init(ep93xxfb_init); -+module_exit(ep93xxfb_exit); -+MODULE_AUTHOR("John Zheng <yujiang.zheng@cirrus.com>"); -+MODULE_LICENSE("GPL"); -+ ---- a/arch/arm/mach-ep93xx/include/mach/hardware.h -+++ b/arch/arm/mach-ep93xx/include/mach/hardware.h -@@ -7,6 +7,7 @@ - #include "ep93xx-regs.h" - - #define pcibios_assign_all_busses() 0 -+#include "regs_raster.h" - #include "regs_touch.h" - - #include "platform.h" ---- a/arch/arm/mach-ep93xx/include/mach/irqs.h -+++ b/arch/arm/mach-ep93xx/include/mach/irqs.h -@@ -34,7 +34,8 @@ - #define IRQ_EP93XX_UART3TX 28 - #define IRQ_EP93XX_KEY 29 - #define IRQ_EP93XX_TOUCH 30 --#define EP93XX_VIC1_VALID_IRQ_MASK 0x7ffffffc -+#define IRQ_EP93XX_GRAPHICS 31 -+#define EP93XX_VIC1_VALID_IRQ_MASK 0xfffffffc - - #define IRQ_EP93XX_EXT0 32 - #define IRQ_EP93XX_EXT1 33 ---- /dev/null -+++ b/arch/arm/mach-ep93xx/include/mach/regs_raster.h -@@ -0,0 +1,347 @@ -+/*============================================================================= -+ * -+ * FILE: regs_raster.h -+ * -+ * DESCRIPTION: ep93xx Raster Engine Register Definition -+ * -+ * Copyright Cirrus Logic, 2001-2003 -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ *============================================================================= -+ */ -+#ifndef _REGS_RASTER_H_ -+#define _REGS_RASTER_H_ -+ -+//----------------------------------------------------------------------------- -+// VLINESTOTAL Register Definitions -+//----------------------------------------------------------------------------- -+#define VLINESTOTAL_MASK 0x000007ff -+ -+//----------------------------------------------------------------------------- -+// VSYNCSTRTSTOP Register Definitions -+//----------------------------------------------------------------------------- -+#define VSYNCSTRTSTOP_STRT_MASK 0x07ff0000 -+#define VSYNCSTRTSTOP_STRT_SHIFT 0 -+#define VSYNCSTRTSTOP_STOP_MASK 0x000007ff -+#define VSYNCSTRTSTOP_STOP_SHIFT 16 -+ -+//----------------------------------------------------------------------------- -+// VACTIVESTRTSTOP Register Definitions -+//----------------------------------------------------------------------------- -+#define VACTIVESTRTSTOP_STRT_MASK 0x07ff0000 -+#define VACTIVESTRTSTOP_STRT_SHIFT 0 -+#define VACTIVESTRTSTOP_STOP_MASK 0x000007ff -+#define VACTIVESTRTSTOP_STOP_SHIFT 16 -+ -+//----------------------------------------------------------------------------- -+// VCLKSTRTSTOP Register Definitions -+//----------------------------------------------------------------------------- -+#define VCLKSTRTSTOP_STRT_MASK 0x07ff0000 -+#define VCLKSTRTSTOP_STRT_SHIFT 0 -+#define VCLKSTRTSTOP_STOP_MASK 0x000007ff -+#define VCLKSTRTSTOP_STOP_SHIFT 16 -+ -+//----------------------------------------------------------------------------- -+// VBLANKSTRTSTOP Register Definitions -+//----------------------------------------------------------------------------- -+#define VBLANKSTRTSTOP_STRT_MASK 0x07ff0000 -+#define VBLANKSTRTSTOP_STRT_SHIFT 0 -+#define VBLANKSTRTSTOP_STOP_MASK 0x000007ff -+#define VBLANKSTRTSTOP_STOP_SHIFT 16 -+ -+//----------------------------------------------------------------------------- -+// HSYNCSTRTSTOP Register Definitions -+//----------------------------------------------------------------------------- -+#define HSYNCSTRTSTOP_STRT_MASK 0x07ff0000 -+#define HSYNCSTRTSTOP_STRT_SHIFT 0 -+#define HSYNCSTRTSTOP_STOP_MASK 0x000007ff -+#define HSYNCSTRTSTOP_STOP_SHIFT 16 -+ -+//----------------------------------------------------------------------------- -+// HACTIVESTRTSTOP Register Definitions -+//----------------------------------------------------------------------------- -+#define HACTIVESTRTSTOP_STRT_MASK 0x07ff0000 -+#define HACTIVESTRTSTOP_STRT_SHIFT 0 -+#define HACTIVESTRTSTOP_STOP_MASK 0x000007ff -+#define HACTIVESTRTSTOP_STOP_SHIFT 16 -+ -+//----------------------------------------------------------------------------- -+// HCLKSTRTSTOP Register Definitions -+//----------------------------------------------------------------------------- -+#define HCLKSTRTSTOP_STRT_MASK 0x07ff0000 -+#define HCLKSTRTSTOP_STRT_SHIFT 0 -+#define HCLKSTRTSTOP_STOP_MASK 0x000007ff -+#define HCLKSTRTSTOP_STOP_SHIFT 16 -+ -+//----------------------------------------------------------------------------- -+// BRIGHTNESS Register Definitions -+//----------------------------------------------------------------------------- -+#define BRIGHTNESS_MASK 0x0000ffff -+#define BRIGHTNESS_CNT_MASK 0x000000ff -+#define BRIGHTNESS_CNT_SHIFT 0 -+#define BRIGHTNESS_CMP_MASK 0x0000ff00 -+#define BRIGHTNESS_CMP_SHIFT 8 -+ -+//----------------------------------------------------------------------------- -+// VIDEOATTRIBS Register Definitions -+//----------------------------------------------------------------------------- -+#define VIDEOATTRIBS_MASK 0x001fffff -+#define VIDEOATTRIBS_EN 0x00000001 -+#define VIDEOATTRIBS_PCLKEN 0x00000002 -+#define VIDEOATTRIBS_SYNCEN 0x00000004 -+#define VIDEOATTRIBS_DATAEN 0x00000008 -+#define VIDEOATTRIBS_CSYNC 0x00000010 -+#define VIDEOATTRIBS_VCPOL 0x00000020 -+#define VIDEOATTRIBS_HSPOL 0x00000040 -+#define VIDEOATTRIBS_BLKPOL 0x00000080 -+#define VIDEOATTRIBS_INVCLK 0x00000100 -+#define VIDEOATTRIBS_ACEN 0x00000200 -+#define VIDEOATTRIBS_LCDEN 0x00000400 -+#define VIDEOATTRIBS_CCIREN 0x00001000 -+#define VIDEOATTRIBS_PIFEN 0x00002000 -+#define VIDEOATTRIBS_INTEN 0x00004000 -+#define VIDEOATTRIBS_INT 0x00008000 -+#define VIDEOATTRIBS_INTRLC 0x00010000 -+#define VIDEOATTRIBS_EQUSER 0x00020000 -+#define VIDEOATTRIBS_DHORZ 0x00040000 -+#define VIDEOATTRIBS_DVERT 0x00080000 -+#define VIDEOATTRIBS_BKPXD 0x00100000 -+ -+#define VIDEOATTRIBS_SDSEL_MASK 0x00600000 -+#define VIDEOATTRIBS_SDSEL_SHIFT 21 -+ -+//----------------------------------------------------------------------------- -+// HBLANKSTRTSTOP Register Definitions -+//----------------------------------------------------------------------------- -+#define HBLANKSTRTSTOP_STRT_MASK 0x07ff0000 -+#define HBLANKSTRTSTOP_STRT_SHIFT 0 -+#define HBLANKSTRTSTOP_STOP_MASK 0x000007ff -+#define HBLANKSTRTSTOP_STOP_SHIFT 16 -+ -+//----------------------------------------------------------------------------- -+// LINECARRY Register Definitions -+//----------------------------------------------------------------------------- -+#define LINECARRY_LCARY_MASK 0x000007ff -+#define LINECARRY_LCARY_SHIFT 0 -+ -+//----------------------------------------------------------------------------- -+// BLINKRATE Register Definitons -+//----------------------------------------------------------------------------- -+#define BLINKRATE_MASK 0x000000ff -+ -+//----------------------------------------------------------------------------- -+// BLINKMASK Register Definitons -+//----------------------------------------------------------------------------- -+#define BLINKMASK_MASK 0x00ffffff -+ -+//----------------------------------------------------------------------------- -+// VIDSCRNPAGE Register Definitons -+//----------------------------------------------------------------------------- -+#define VIDSCRNPAGE_PAGE_MASK 0x0ffffffc -+ -+//----------------------------------------------------------------------------- -+// VIDSCRNHPG Register Definitons -+//----------------------------------------------------------------------------- -+#define VIDSCRNHPG_MASK 0x0ffffffc -+ -+//----------------------------------------------------------------------------- -+// SCRNLINES Register Definitons -+//----------------------------------------------------------------------------- -+#define SCRNLINES_MASK 0x000007ff -+ -+//----------------------------------------------------------------------------- -+// LINELENGTH Register Definitons -+//----------------------------------------------------------------------------- -+#define LINELENGTH_MASK 0x000007ff -+ -+//----------------------------------------------------------------------------- -+// VLINESTEP Register Definitons -+//----------------------------------------------------------------------------- -+#define VLINESTEP_MASK 0x00000fff -+ -+//----------------------------------------------------------------------------- -+// RASTER_SWLOCK Register Definitons -+//----------------------------------------------------------------------------- -+#define RASTER_SWLOCK_MASK_WR 0xff -+#define RASTER_SWLOCK_MASK_R 0x1 -+#define RASTER_SWLOCK_VALUE 0xaa -+ -+//----------------------------------------------------------------------------- -+// LUTCONT Register Definitions -+//----------------------------------------------------------------------------- -+#define LUTCONT_MASK 0x00000003 -+#define LUTCONT_SWTCH 0x00000001 -+#define LUTCONT_STAT 0x00000002 -+#define LUTCONT_RAM0 0 -+#define LUTCONT_RAM1 1 -+ -+//----------------------------------------------------------------------------- -+// CURSORBLINK1 Register Definitions -+//----------------------------------------------------------------------------- -+#define CURSORBLINK1_MASK 0x00ffffff -+//----------------------------------------------------------------------------- -+// CURSORBLINK2 Register Definitions -+//----------------------------------------------------------------------------- -+#define CURSORBLINK2_MASK 0x00ffffff -+ -+//----------------------------------------------------------------------------- -+// CURSORBLINK Register Definitions -+//----------------------------------------------------------------------------- -+#define CURSORBLINK_MASK 0x000001ff -+#define CURSORBLINK_RATE_MASK 0x000000ff -+#define CURSORBLINK_RATE_SHIFT 0 -+#define CURSORBLINK_EN 0x00000100 -+ -+//----------------------------------------------------------------------------- -+// BLINKPATRN Register Definitions -+//----------------------------------------------------------------------------- -+#define BLINKPATRN_MASK 0x00ffffff -+ -+//----------------------------------------------------------------------------- -+// PATRNMASK Register Definitions -+//----------------------------------------------------------------------------- -+#define PATRNMASK_MASK 0x00ffffff -+ -+//----------------------------------------------------------------------------- -+// BG_OFFSET Register Definitions -+//----------------------------------------------------------------------------- -+#define BG_OFFSET_MASK 0x00ffffff -+ -+//----------------------------------------------------------------------------- -+// PIXELMODE Register Definitions -+//----------------------------------------------------------------------------- -+#define PIXELMODE_P_MASK 0x00000007 -+#define PIXELMODE_P_MUX_DISABLE 0x00000000 -+#define PIXELMODE_P_4BPP 0x00000001 -+#define PIXELMODE_P_8BPP 0x00000002 -+#define PIXELMODE_P_16BPP 0x00000004 -+#define PIXELMODE_P_24BPP 0x00000006 -+#define PIXELMODE_P_32BPP 0x00000007 -+ -+#define PIXELMODE_S_MASK 0x00000038 -+#define PIXELMODE_S_1PPC 0x00000000 -+#define PIXELMODE_S_1PPCMAPPED 0x00000008 -+#define PIXELMODE_S_2PPC 0x00000010 -+#define PIXELMODE_S_4PPC 0x00000018 -+#define PIXELMODE_S_8PPC 0x00000020 -+#define PIXELMODE_S_223PPC 0x00000028 -+#define PIXELMODE_S_DS223PPC 0x00000030 -+#define PIXELMODE_S_UNDEF 0x00000038 -+ -+#define PIXELMODE_M_MASK 0x000003c0 -+#define PIXELMODE_M_NOBLINK 0x00000000 -+#define PIXELMODE_M_ANDBLINK 0x00000040 -+#define PIXELMODE_M_ORBLINK 0x00000080 -+#define PIXELMODE_M_XORBLINK 0x000000c0 -+#define PIXELMODE_M_BGBLINK 0x00000100 -+#define PIXELMODE_M_OFFSINGBLINK 0x00000140 -+#define PIXELMODE_M_OFF888BLINK 0x00000180 -+#define PIXELMODE_M_DIMBLINK 0x00000300 -+#define PIXELMODE_M_BRTBLINK 0x00000340 -+#define PIXELMODE_M_DIM888BLINK 0x00000380 -+#define PIXELMODE_M_BRT888BLINK 0x000003c0 -+ -+#define PIXELMODE_C_MASK 0x00003c00 -+#define PIXELMODE_C_LUT 0x00000000 -+#define PIXELMODE_C_888 0x00001000 -+#define PIXELMODE_C_565 0x00001400 -+#define PIXELMODE_C_555 0x00001800 -+#define PIXELMODE_C_GSLUT 0x00002000 -+ -+#define PIXELMODE_DSCAN 0x00004000 -+#define PIXELMODE_TRBSW 0x00008000 -+ -+//----------------------------------------------------------------------------- -+//PARLLIFOUT Register Defintions -+//----------------------------------------------------------------------------- -+#define PARLLIFOUT_DAT_MASK 0x0000000f -+#define PARLLIFOUT_DAT_SHIFT 0 -+#define PARLLIFOUT_RD 0x00000010 -+ -+//----------------------------------------------------------------------------- -+//PARLLIFIN Register Defintions -+//----------------------------------------------------------------------------- -+#define PARLLIFIN_DAT_MASK 0x0000000f -+#define PARLLIFIN_DAT_SHIFT 0 -+#define PARLLIFIN_CNT_MASK 0x000f0000 -+#define PARLLIFIN_CNT_SHIFT 16 -+#define PARLLIFIN_ESTRT_MASK 0x00f00000 -+#define PARLLIFIN_ESTRT_SHIFT 20 -+ -+//----------------------------------------------------------------------------- -+// CURSORADRSTART Register Defintions -+//----------------------------------------------------------------------------- -+#define CURSOR_ADR_START_MASK 0xfffffffc -+ -+//----------------------------------------------------------------------------- -+// CURSORADRSTART Register Defintions -+//----------------------------------------------------------------------------- -+#define CURSOR_ADR_RESET_MASK 0xfffffffc -+ -+//----------------------------------------------------------------------------- -+// CURSORCOLOR1 Register Definitions -+//----------------------------------------------------------------------------- -+#define CURSORCOLOR1_MASK 0x00ffffff -+//----------------------------------------------------------------------------- -+// CURSORCOLOR2 Register Definitions -+//----------------------------------------------------------------------------- -+#define CURSORCOLOR2_MASK 0x00ffffff -+ -+//----------------------------------------------------------------------------- -+// CURSORXYLOC Register Definitions -+//----------------------------------------------------------------------------- -+#define CURSORXYLOC_MASK 0x07ff87ff -+#define CURSORXYLOC_XLOC_MASK 0x000007ff -+#define CURSORXYLOC_XLOC_SHIFT 0 -+#define CURSORXYLOC_CEN 0x00008000 -+#define CURSORXYLOC_YLOC_MASK 0x07ff0000 -+#define CURSORXYLOC_YLOC_SHIFT 16 -+ -+//----------------------------------------------------------------------------- -+// CURSOR_DSCAN_LH_YLOC Register Definitions -+//----------------------------------------------------------------------------- -+#define CURSOR_DSCAN_LH_YLOC_MASK 0x000087ff -+ -+#define CURSOR_DSCAN_LH_YLOC_YLOC_MASK 0x000007ff -+#define CURSOR_DSCAN_LH_YLOC_YLOC_SHIFT 0 -+#define CURSOR_DSCAN_LH_YLOC_CLHEN 0x00008000 -+ -+//----------------------------------------------------------------------------- -+// CURSORSIZE Register Definitions -+//----------------------------------------------------------------------------- -+#define CURSORSIZE_MASK 0x0000ffff -+ -+#define CURSORSIZE_CWID_MASK 0x00000003 -+#define CURSORSIZE_CWID_SHIFT 0 -+#define CURSORSIZE_CWID_1_WORD 0 -+#define CURSORSIZE_CWID_2_WORD 1 -+#define CURSORSIZE_CWID_3_WORD 2 -+#define CURSORSIZE_CWID_4_WORD 3 -+ -+#define CURSORSIZE_CLINS_MASK 0x000000fc -+#define CURSORSIZE_CLINS_SHIFT 2 -+ -+#define CURSORSIZE_CSTEP_MASK 0x00000300 -+#define CURSORSIZE_CSTEP_SHIFT 8 -+#define CURSORSIZE_CSTEP_1_WORD 0 -+#define CURSORSIZE_CSTEP_2_WORD 1 -+#define CURSORSIZE_CSTEP_3_WORD 2 -+#define CURSORSIZE_CSTEP_4_WORD 3 -+ -+#define CURSORSIZE_DLNS_MASK 0x0000fc00 -+#define CURSORSIZE_DLNS_SHIFT 10 -+ -+#endif /* _REGS_RASTER_H_ */ |