mirror of https://github.com/hak5/openwrt.git
3566 lines
106 KiB
Diff
3566 lines
106 KiB
Diff
--- 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_ */
|