All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pete Popov <pete_popov@yahoo.com>
To: linux-fbdev-devel@lists.sourceforge.net
Cc: pete_popov@yahoo.com
Subject: PATCH
Date: 21 Feb 2004 16:44:37 -0800	[thread overview]
Message-ID: <1077410677.9577.4.camel@localhost.localdomain> (raw)


This is a 2.4 patch for the SMI 501 chip. I don't know if anyone is
interested in applying it and/or using it, but I thought I'd send it.
The driver has been tested on the AMD Mirage platform. The I2C portion
of the driver has been sent to the I2C maintainer. 

Pete

diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/Config.in linux-2.4-dev/drivers/video/Config.in
--- linux-2.4-orig/drivers/video/Config.in	2004-01-13 21:51:28.000000000 -0800
+++ linux-2.4-dev/drivers/video/Config.in	2004-02-21 16:19:24.000000000 -0800
@@ -159,6 +159,7 @@
 	    bool '    SIS 300 series support' CONFIG_FB_SIS_300
 	    bool '    SIS 315/330 series support' CONFIG_FB_SIS_315
 	 fi
+	 bool '  SiliconMotion 501 Driver' CONFIG_FB_SMI501
 	 tristate '  NeoMagic display support (EXPERIMENTAL)' CONFIG_FB_NEOMAGIC
 	 tristate '  3Dfx Banshee/Voodoo3 display support (EXPERIMENTAL)' CONFIG_FB_3DFX
 	 tristate '  3Dfx Voodoo Graphics (sst1) support (EXPERIMENTAL)' CONFIG_FB_VOODOO1
diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/fbmem.c linux-2.4-dev/drivers/video/fbmem.c
--- linux-2.4-orig/drivers/video/fbmem.c	2004-01-13 21:51:28.000000000 -0800
+++ linux-2.4-dev/drivers/video/fbmem.c	2004-02-21 16:19:24.000000000 -0800
@@ -145,6 +145,8 @@
 extern int sstfb_setup(char*);
 extern int it8181fb_init(void);
 extern int it8181fb_setup(char*);
+extern int smi501fb_init(void);
+extern int smi501fb_setup(char*);
 
 static struct {
 	const char *name;
@@ -254,6 +256,9 @@
 #ifdef CONFIG_FB_VESA
 	{ "vesa", vesafb_init, vesafb_setup },
 #endif 
+#ifdef CONFIG_FB_SMI501
+	{ "smi501fb", smi501fb_init, smi501fb_setup },
+#endif
 
 	/*
 	 * Chipset specific drivers that don't use resource management (yet)
diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/Makefile linux-2.4-dev/drivers/video/Makefile
--- linux-2.4-orig/drivers/video/Makefile	2004-01-13 21:51:28.000000000 -0800
+++ linux-2.4-dev/drivers/video/Makefile	2004-02-21 16:19:24.000000000 -0800
@@ -88,6 +88,7 @@
 obj-$(CONFIG_FB_TX3912)           += tx3912fb.o
 obj-$(CONFIG_FB_AU1100)		  += au1100fb.o fbgen.o
 obj-$(CONFIG_FB_IT8181)		  += it8181fb.o fbgen.o
+obj-$(CONFIG_FB_SMI501)           += smi501fb.o fbgen.o
 
 subdir-$(CONFIG_STI_CONSOLE)      += sti
 ifeq ($(CONFIG_STI_CONSOLE),y)
diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/smi501fb.c linux-2.4-dev/drivers/video/smi501fb.c
--- linux-2.4-orig/drivers/video/smi501fb.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4-dev/drivers/video/smi501fb.c	2004-02-21 16:29:07.000000000 -0800
@@ -0,0 +1,801 @@
+/***************************************************************************
+        smifb.c  -  Silicon Motion, Inc. LynxEM+ frame buffer device
+                             -------------------
+    begin                : Thu Aug 9 2001
+    copyright            : (C) 2001 by Szu-Tao Huang
+    email                : johuang@siliconmotion.com
+    
+    Updated to SM501 by Eric.Devolder@amd.com and dan@embeddededge.com
+    for the AMD Mirage Portable Tablet.  20 Oct 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+
+static char *SMIRegs;		// point to virtual Memory Map IO starting address
+static char *SMILFB;		// point to virtual video memory starting address
+static struct smifb_info fb_info;
+static struct smifb_par current_par;	// used to record hardware information
+static struct display disp;
+
+#include "smi501fb.h"
+
+static int initdone = 0;
+
+static int
+smifb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+              u_long arg, int con, struct fb_info *info)
+{
+	unsigned char	bcmd, status;
+	unsigned int	bval;
+	struct	smireg_op	sreg;
+	int	retval;
+
+	retval = 0;
+	if (cmd == 1) {
+		/* Send command to battery charger.
+		*/
+		bcmd = (unsigned char)arg;
+
+		/* 0x22 is the slave address.
+		*/
+		smi_mmiowb(0x22, I2C_SLAVE_ADDRESS);
+		wmb();
+		smi_mmiowb(bcmd, I2C_DATA);
+		wmb();
+		smi_mmiowb(0, I2C_BYTE_COUNT);	/* byte count - 1 */
+		wmb();
+		smi_mmiowb(0x05, I2C_CONTROL);	/* enable, 100kHz, start */
+		wmb();
+		do {
+			status = smi_mmiorb(I2C_STATUS_RESET);
+			wmb();
+		} while (status == 0);
+		smi_mmiowb(0x00, I2C_CONTROL);	/* enable, 100kHz, stop */
+		if (status & 0x40)
+			smi_mmiowb(0x00, I2C_STATUS_RESET);
+	}
+	else if (cmd == 2) {
+		/* Read results of command.
+		*/
+		smi_mmiowb(0x23, I2C_SLAVE_ADDRESS);
+		wmb();
+		smi_mmiowb(1, I2C_BYTE_COUNT);	/* byte count - 1 */
+		wmb();
+		smi_mmiowb(0x05, I2C_CONTROL);	/* enable, 100kHz, start */
+		wmb();
+		do {
+			status = smi_mmiorb(I2C_STATUS_RESET);
+			wmb();
+		} while (status == 0);
+		bval = smi_mmiorl(I2C_DATA);
+		wmb();
+		smi_mmiowb(0x00, I2C_CONTROL);	/* enable, 100kHz, stop */
+		wmb();
+		if (copy_to_user((char *)arg, &bval, 4))
+			retval = -EFAULT;
+		if (status & 0x40)
+			smi_mmiowb(0x00, I2C_STATUS_RESET);
+	}
+	else if (cmd == 3) {	/* Debug test */
+		bval = smi_mmiorl(GPIO_DATA_HI);
+		bval ^= 0x0000c000;
+		smi_mmiowl(bval, GPIO_DATA_HI);
+
+	}
+	else if (cmd == 4) {	/* Register operation */
+		if (copy_from_user(&sreg, (void *)arg, sizeof(struct smireg_op))) {
+			return -EFAULT;
+		}
+
+		/* Just 32-bit access for now.
+		*/
+		if (sreg.sr_op == SMI_LOAD_REG) {
+			sreg.sr_val = smi_mmiorl(sreg.sr_reg);
+		}
+		else if (sreg.sr_op == SMI_STORE_REG) {
+			smi_mmiowl(sreg.sr_val, sreg.sr_reg);
+		}
+		else if (sreg.sr_op == SMI_AND_REG) {
+			bval = smi_mmiorl(sreg.sr_reg);
+			smi_mmiowl((bval & sreg.sr_val), sreg.sr_reg);
+			sreg.sr_val = bval;
+		}
+		else if (sreg.sr_op == SMI_OR_REG) {
+			bval = smi_mmiorl(sreg.sr_reg);
+			smi_mmiowl((bval | sreg.sr_val), sreg.sr_reg);
+			sreg.sr_val = bval;
+		}
+		else {
+			retval = -EINVAL;
+		}
+		if (copy_to_user((void *)arg, &sreg, sizeof(struct smireg_op))) {
+			retval = -EFAULT;
+		}
+	}
+	else {
+		retval = -EINVAL;
+	}
+
+	return retval;
+}
+
+static int
+smifb_mmap(struct fb_info *_fb,
+         struct file *file,
+         struct vm_area_struct *vma)
+{
+	unsigned int len;
+	unsigned long start=0, off;
+	struct smifb_info *fb = (struct smifb_info *)_fb;
+
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
+		return -EINVAL;
+	}
+
+	start = fb->fb_phys & PAGE_MASK;
+	len = PAGE_ALIGN((start & ~PAGE_MASK) + fb->fb_size);
+
+	off = vma->vm_pgoff << PAGE_SHIFT;
+
+	if ((vma->vm_end - vma->vm_start + off) > len) {
+		return -EINVAL;
+	}
+	off += start;
+	vma->vm_pgoff = off >> PAGE_SHIFT;
+
+	pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
+	pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED;
+
+	/* This is an IO map - tell maydump to skip this VMA */
+	vma->vm_flags |= VM_IO;
+
+	if (io_remap_page_range(vma->vm_start, off,
+                vma->vm_end - vma->vm_start,
+                vma->vm_page_prot)) {
+		return -EAGAIN;
+	}
+
+	fb->mmaped = 1;
+	return 0;
+}
+
+static struct fb_ops smifb_ops = {
+	owner:			THIS_MODULE,
+	fb_get_fix:		fbgen_get_fix,
+	fb_get_var:		fbgen_get_var,
+	fb_set_var:		fbgen_set_var,
+	fb_get_cmap:		fbgen_get_cmap,
+	fb_set_cmap:		fbgen_set_cmap,
+	fb_pan_display:		fbgen_pan_display,
+	fb_ioctl:		smifb_ioctl,
+	fb_mmap:		smifb_mmap,
+};
+
+static void smi_nocursor(struct display *p, int mode, int xx, int yy){};
+
+static void
+smi_detect (void)
+{
+	/*
+	 *  This function should detect the current video mode settings
+	 *  and store it as the default video mode
+	 */
+
+	/*
+	 * Yeh, well, we're not going to change any settings so we're
+	 * always stuck with the default ...
+	 */
+}
+
+static int
+smi_encode_fix(struct fb_fix_screeninfo *fix,
+        const void *_par, struct fb_info_gen *_info)
+{
+	struct smifb_info *info = (struct smifb_info *) _info;
+	struct smifb_par *par = (struct smifb_par *) _par;
+	struct fb_var_screeninfo *var = &par->var;
+
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+
+	fix->smem_start = info->fb_phys;
+	fix->smem_len = info->fb_size;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->type_aux = 0;
+	fix->visual = (var->bits_per_pixel == 8) ?
+            FB_VISUAL_PSEUDOCOLOR   : FB_VISUAL_TRUECOLOR;
+	fix->ywrapstep = 0;
+	fix->xpanstep = 1;
+	fix->ypanstep = 1;
+	fix->line_length = current_par.line_length;
+	return 0;
+}
+
+static void
+set_color_bitfields(struct fb_var_screeninfo *var)
+{
+	switch (var->bits_per_pixel) {
+	case 8:
+		var->red.offset = 0;
+		var->red.length = 8;
+		var->green.offset = 0;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		break;
+	case 16:    /* RGB 565 */
+		var->red.offset = 11;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 6;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		break;
+	}
+
+	var->red.msb_right = 0;
+	var->green.msb_right = 0;
+	var->blue.msb_right = 0;
+	var->transp.msb_right = 0;
+}
+
+static int
+smi_decode_var(const struct fb_var_screeninfo *var,
+        void *_par, struct fb_info_gen *_info)
+{
+
+	struct smifb_par *par = (struct smifb_par *)_par;
+
+	/*
+	 * Don't allow setting any of these yet: xres and yres don't
+	 * make sense for LCD panels.
+	 */
+/*
+	if (var->xres != p_lcd->xres || var->yres != p_lcd->yres ||
+			var->xres != p_lcd->xres || var->yres != p_lcd->yres) {
+		return -EINVAL;
+	}
+	if(var->bits_per_pixel != p_lcd->bpp) {
+		return -EINVAL;
+	} */
+
+	memset(par, 0, sizeof(struct smifb_par));
+	par->var = *var;
+
+	/* FIXME */
+	switch (var->bits_per_pixel) {
+	case 8:
+		par->var.bits_per_pixel = 8;
+		break;
+	case 16:
+		par->var.bits_per_pixel = 16;
+		break;
+	default:
+		printk("color depth %d bpp not supported\n",
+						var->bits_per_pixel);
+		return -EINVAL;
+
+	}
+	set_color_bitfields(&par->var);
+	par->cmap_len = (par->var.bits_per_pixel == 8) ? 256 : 16;
+	return 0;
+}
+
+static int
+smi_encode_var(struct fb_var_screeninfo *var,
+        const void *par, struct fb_info_gen *_info)
+{
+	*var = ((struct smifb_par *)par)->var;
+	return 0;
+}
+
+static void
+smi_get_par(void *_par, struct fb_info_gen *_info)
+{
+	*(struct smifb_par *)_par = current_par;
+}
+
+static void
+smi_set_par(const void *par, struct fb_info_gen *info)
+{
+	/* nothing to do: we don't change any settings */
+}
+
+static int
+smi_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+             unsigned *blue, unsigned *transp,
+             struct fb_info *info)
+{
+	struct smifb_info* i = (struct smifb_info*)info;
+
+	if (regno > 255)
+		return 1;
+
+	*red    = i->palette[regno].red;
+	*green  = i->palette[regno].green;
+	*blue   = i->palette[regno].blue;
+	*transp = 0;
+
+	return 0;
+}
+
+static int
+smi_setcolreg(unsigned regno, unsigned red, unsigned green,
+	unsigned blue, unsigned transp,
+	struct fb_info *info)
+{
+	struct smifb_info* i = (struct smifb_info *)info;
+
+	if (regno > 255)
+		return 1;
+
+	i->palette[regno].red    = red;
+	i->palette[regno].green  = green;
+	i->palette[regno].blue   = blue;
+
+	switch(current_par.var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		red >>= 10;
+		green >>= 10;
+		blue >>= 10;
+			// FIX!!! fill palette
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		i->fbcon_cmap16[regno] =
+		    ((red & 0xf800) >> 0) |
+		    ((green & 0xfc00) >> 5) |
+		    ((blue & 0xf800) >> 11);
+		break;
+#endif
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int
+smi_blank(int blank_mode, struct fb_info_gen *_info)
+{
+	switch (blank_mode) {
+	case VESA_NO_BLANKING:
+		/* turn on panel */
+		break;
+	case VESA_VSYNC_SUSPEND:
+	case VESA_HSYNC_SUSPEND:
+	case VESA_POWERDOWN:
+		/* turn off panel */
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static void
+smi_set_disp(const void *unused, struct display *disp,
+             struct fb_info_gen *info)
+{
+	disp->screen_base = (char *)fb_info.fb_virt_start;
+
+	switch (disp->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		disp->dispsw = &fbcon_cfb8;
+		//fbcon_cfb8.cursor = smi_nocursor;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		disp->dispsw = &fbcon_cfb16;
+		disp->dispsw_data = fb_info.fbcon_cmap16;
+		//fbcon_cfb16.cursor = smi_nocursor;
+		break;
+#endif
+	default:
+		disp->dispsw = &fbcon_dummy;
+		disp->dispsw_data = NULL;
+		break;
+    }
+}
+
+static int
+smi_pan_display(const struct fb_var_screeninfo *var,
+               struct fb_info_gen *info)
+{
+	return 0;
+}
+
+static struct fbgen_hwswitch smi_switch = {
+	detect:		smi_detect,
+	encode_fix:	smi_encode_fix,
+	decode_var:	smi_decode_var,
+	encode_var:	smi_encode_var,
+	get_par:	smi_get_par,
+	set_par:	smi_set_par,
+	getcolreg:	smi_getcolreg,
+	setcolreg:	smi_setcolreg,
+	pan_display:	smi_pan_display,
+	blank:		smi_blank,
+	set_disp:	smi_set_disp
+};
+
+/* GPIO functions to set/clear bits and direction for the bit-bang
+ * I2C algorithm.  Someday, these will need to be protected with
+ * spinlocks/irq.  Right now, I2C is the only one to modify GPIOs.
+ */
+void
+smi501_set_gpio_hi_data(unsigned int val)
+{
+	unsigned int reg;
+
+	reg = smi_mmiorl(GPIO_DATA_HI);
+	wmb();
+	reg |= val;
+	smi_mmiowl(reg, GPIO_DATA_HI);
+	wmb();
+}
+
+void
+smi501_clr_gpio_hi_data(unsigned int val)
+{
+	unsigned int new;
+
+	new = smi_mmiorl(GPIO_DATA_HI);
+	wmb();
+	new &= ~val;
+	smi_mmiowl(new, GPIO_DATA_HI);
+	wmb();
+}
+
+unsigned int
+smi501_get_gpio_hi_data(unsigned int mask)
+{
+	unsigned int new;
+
+	new = smi_mmiorl(GPIO_DATA_HI);
+	wmb();
+
+	return (new & mask);
+}
+
+void
+smi501_set_gpio_hi_direction(unsigned int mask, unsigned int val)
+{
+	unsigned int new;
+
+	new = smi_mmiorl(GPIO_DATA_DIR_HI);
+	wmb();
+	new &= ~mask;
+	new |= val;
+	smi_mmiowl(new, GPIO_DATA_DIR_HI);
+	wmb();
+}
+
+
+/* This function still needs lots of work to generically support
+ * different output devices (CRT or LCD) and resolutions.
+ * Currently hard-coded for Mirage 1024x768 LCD panel.
+ */
+static void
+smi_setmode(struct smifb_info *sfb,struct smifb_par *hw)
+{
+	uint	reg;
+
+	if (initdone)
+		return;
+
+	initdone = 1;
+
+	/* Just blast in some control values based upon the chip
+	 * documentation.  We use the internal memory, I don't know
+	 * how to determine the amount available yet.
+	 */
+	smi_mmiowl(0x07F127C2, DRAM_CTRL);
+	smi_mmiowl(0x02000020, PANEL_HWC_ADDRESS);
+	smi_mmiowl(0x007FF800, PANEL_HWC_ADDRESS);
+	smi_mmiowl(0x00021827, POWER_MODE1_GATE);
+	smi_mmiowl(0x011A0A09, POWER_MODE1_CLOCK);
+	smi_mmiowl(0x00000001, POWER_MODE_CTRL);
+	smi_mmiowl(0x80000000, PANEL_FB_ADDRESS);
+	smi_mmiowl(0x08000800, PANEL_FB_WIDTH);
+	smi_mmiowl(0x04000000, PANEL_WINDOW_WIDTH);
+	smi_mmiowl(0x03000000, PANEL_WINDOW_HEIGHT);
+	smi_mmiowl(0x00000000, PANEL_PLANE_TL);
+	smi_mmiowl(0x02FF03FF, PANEL_PLANE_BR);
+	smi_mmiowl(0x05D003FF, PANEL_HORIZONTAL_TOTAL);
+	smi_mmiowl(0x00C80424, PANEL_HORIZONTAL_SYNC);
+	smi_mmiowl(0x032502FF, PANEL_VERTICAL_TOTAL);
+	smi_mmiowl(0x00060302, PANEL_VERTICAL_SYNC);
+	smi_mmiowl(0x00013905, PANEL_DISPLAY_CTRL);
+	smi_mmiowl(0x01013105, PANEL_DISPLAY_CTRL);
+	waitforvsync();
+	smi_mmiowl(0x03013905, PANEL_DISPLAY_CTRL);
+	waitforvsync();
+	smi_mmiowl(0x07013905, PANEL_DISPLAY_CTRL);
+	waitforvsync();
+	smi_mmiowl(0x0F013905, PANEL_DISPLAY_CTRL);
+	smi_mmiowl(0x0002187F, POWER_MODE1_GATE);
+	smi_mmiowl(0x01011801, POWER_MODE1_CLOCK);
+	smi_mmiowl(0x00000001, POWER_MODE_CTRL);
+
+	smi_mmiowl(0x80000000, PANEL_FB_ADDRESS);
+	smi_mmiowl(0x00000000, PANEL_PAN_CTRL);
+	smi_mmiowl(0x00000000, PANEL_COLOR_KEY);
+
+	/* Enable I2C in GPIO.
+	*/
+#if 0
+	reg = smi_mmiorl(GPIO_HI_CTRL);
+	wmb();
+	reg |= 0x0000c000;		/* Enable bits 46, 47 */
+	smi_mmiowl(reg, GPIO_HI_CTRL);
+	wmb();
+	smi_mmiowb(0x00, I2C_CONTROL);	/* enable, 100kHz, stop */
+	wmb();
+	smi_mmiowb(0x00, I2C_STATUS_RESET);
+#else
+	/* Enable GPIO pins and make them inputs.
+	*/
+	reg = smi_mmiorl(GPIO_DATA_DIR_HI);
+	wmb();
+	reg &= ~0x0000c000;		/* Enable bits 46, 47 */
+	smi_mmiowl(reg, GPIO_DATA_DIR_HI);
+	reg = smi_mmiorl(GPIO_HI_CTRL);
+	wmb();
+	reg &= ~0x0000c000;		/* Enable bits 46, 47 */
+	smi_mmiowl(reg, GPIO_HI_CTRL);
+	wmb();
+	reg = smi_mmiorl(GPIO_DATA_HI);
+	wmb();
+	reg |= 0x0000c000;		/* Let 'em float */
+	smi_mmiowl(reg, GPIO_DATA_HI);
+#endif
+
+	/* Enable 8-bit ZV Port.
+	*/
+	reg = smi_mmiorl(GPIO_LO_CTRL);
+	wmb();
+	reg |= 0x00ff0000;		/* Enable bits 16-23 */
+	smi_mmiowl(reg, GPIO_LO_CTRL);
+	wmb();
+}
+
+/* Set up the zv port to be displayed on the screen.  Currently
+ * coded to expect CCIR 656, YUV 4:2:2 cosited from the PNX1302.
+ */
+static void
+set_videoport(int loc_x, int loc_y, int size_x, int size_y)
+{
+	int nbytes;
+	int top, left, bot, right;
+
+	/* Initialize registers, most power up undefined.
+	*/
+	smi_mmiowl(0x0014008a, ZV_CAPTURE_CLIP);
+	smi_mmiowl(((size_y << 16) | size_x), ZV_CAPTURE_SIZE);
+
+	/* Magic buffer addresses.  Just ensure they don't
+	 * collide with something else in memory.
+	 */
+	smi_mmiowl(0x00200000, ZV_CAPTURE_BUF0);
+	smi_mmiowl(0x00400000, ZV_CAPTURE_BUF1);
+	smi_mmiowl(0x00000000, ZV_CAPTURE_OFFSET);
+	smi_mmiowl(0x00000004, ZV_FIFO_CTRL);
+
+#if 0
+	smi_mmiowl(0x00016007, VIDEO_DISPLAY_CTRL);
+#else
+	smi_mmiowl(0x00010005, VIDEO_DISPLAY_CTRL);
+#endif
+	smi_mmiowl(0x00400000, VIDEO_DISPLAY_FB0);
+	smi_mmiowl(0x00400000, VIDEO_DISPLAY_FB1);
+	smi_mmiowl(((size_x * 2) << 16), VIDEO_DISPLAY_FBWIDTH);
+	nbytes = (size_x * 2) * size_y;
+	nbytes += 127;
+	nbytes &= ~127;
+	smi_mmiowl(0x00400000 + nbytes, VIDEO_DISPLAY_FB0LAST);
+	smi_mmiowl(0x00400000 + nbytes, VIDEO_DISPLAY_FB1LAST);
+
+
+	top = loc_y;
+	left = loc_x;
+	smi_mmiowl(((top << 16) | left), VIDEO_DISPLAY_TL);
+
+	/* Use max ntsc.
+	*/
+	bot = top + size_y;
+	right = left + size_x;
+	smi_mmiowl(((bot << 16) | right), VIDEO_DISPLAY_BR);
+
+	smi_mmiowl(0x00000000, VIDEO_SCALE);
+	smi_mmiowl(0x00000000, VIDEO_INITIAL_SCALE);
+
+	smi_mmiowl(0x00ededed, VIDEO_YUV_CONSTANTS);
+
+	smi_mmiowl(0x17010000, VIDEO_ALPHA_CTRL);
+
+	/* Enable
+	*/
+#if 0
+	smi_mmiowl(0x00000211, ZV_CAPTURE_CTRL);
+#endif
+
+}
+
+/*
+ * Unmap in the memory mapped IO registers
+ *
+ */
+
+static void __devinit
+smi_unmap_mmio(struct smifb_info *sfb)
+{
+	if (sfb && SMIRegs) {
+		iounmap(SMIRegs);
+		SMIRegs = NULL;
+	}
+}
+
+
+/*
+ * Unmap in the screen memory
+ *
+ */
+static void __devinit
+smi_unmap_smem(struct smifb_info *sfb)
+{
+	if (sfb && sfb->fb_virt_start) {
+		iounmap(sfb->fb_virt_start);
+		sfb->fb_virt_start = NULL;
+	}
+}
+
+void
+smi501fb_setup (char *options, int *ints)
+{
+	return;
+}
+
+int __init smi501fb_init(void)
+{
+	struct smifb_info *sfb;
+	char name[16];
+	int err;
+
+	struct pci_dev *pdev = NULL;
+	int i = 0;
+
+	/* Find and enable Voyager
+	 * Rev. AA is 0x501, Rev. B is 0x510.
+	 */
+	pdev = pci_find_device(0x126f,0x510, pdev);
+	if (pdev == NULL)
+		pdev = pci_find_device(0x126f,0x501, pdev);
+	if (pdev == NULL)
+		return -ENODEV;
+	
+	/* Enable the chip.
+	*/
+	err = pci_enable_device(pdev);
+	if (err)
+		return err;
+	current_par.chipID = 0x510;
+
+	err = -ENOMEM;
+	sprintf(name, "smifb");
+	sfb = &fb_info;
+	memset(sfb, 0, sizeof(struct smifb_info));
+	memset(&disp, 0, sizeof(struct display));
+
+	sfb->currcon = -1;
+	sfb->dev = pdev;
+
+
+	/* Set up MMIO space.
+	*/
+	sfb->mmio_phys = pci_resource_start(pdev,1);
+	sfb->mmio_size = 0x00200000;
+	sfb->mmio_virt_start = ioremap(sfb->mmio_phys, sfb->mmio_size);
+	SMIRegs = sfb->mmio_virt_start;
+
+	/* Set up framebuffer.  It's a 64M space, various amount of
+	 * internal memory.  I don't know how to determine the real
+	 * amount of memory (yet).
+	 */
+	sfb->fb_phys = pci_resource_start(pdev,0);
+	sfb->fb_size = 0x00800000;
+	sfb->fb_virt_start = ioremap(sfb->fb_phys, sfb->fb_size);
+	SMILFB = sfb->fb_virt_start;
+
+	 memset((void *)fb_info.fb_virt_start, 0, fb_info.fb_size);
+
+	current_par.var.xres =
+   	current_par.var.xres_virtual = 1024; //sfb->fb.var.xres;
+	current_par.var.yres =
+	current_par.var.yres_virtual = 768; //sfb->fb.var.yres;
+	current_par.var.bits_per_pixel = 16; //sfb->fb.var.bits_per_pixel;
+	current_par.line_length = (current_par.var.bits_per_pixel * current_par.var.xres) / 8;
+
+	smi_setmode(sfb, &current_par);
+
+	fb_info.gen.parsize = sizeof(struct smifb_par);
+	fb_info.gen.fbhw = &smi_switch;
+
+	strcpy(fb_info.gen.info.modename, "SMI Voyager");
+	fb_info.gen.info.changevar = NULL;
+	fb_info.gen.info.node = -1;
+
+	fb_info.gen.info.fbops = &smifb_ops;
+	fb_info.gen.info.disp = &disp;
+	fb_info.gen.info.switch_con = &fbgen_switch;
+	fb_info.gen.info.updatevar = &fbgen_update_var;
+	fb_info.gen.info.blank = &fbgen_blank;
+	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
+
+	/* This should give a reasonable default video mode
+	*/
+	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
+	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
+	fbgen_set_disp(-1, &fb_info.gen);
+	fbgen_install_cmap(0, &fb_info.gen);
+
+	if (register_framebuffer(&fb_info.gen.info) < 0)
+		goto failed;
+
+#if 0
+	/* This is for videoport testing.  The Mirage uses an 8-bit
+	 * video port, which is now known to not work properly
+	 * on the SMI501 part.
+	 */
+	set_videoport(150, 150, 768, 576);
+#endif
+
+	MOD_INC_USE_COUNT;
+	printk("Silicon Motion Inc. VOYAGER Init complete.\n");
+
+	return 0;
+
+failed:
+	smi_unmap_smem(sfb);
+	smi_unmap_mmio(sfb);
+
+	return err;
+}
diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/smi501fb.h linux-2.4-dev/drivers/video/smi501fb.h
--- linux-2.4-orig/drivers/video/smi501fb.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4-dev/drivers/video/smi501fb.h	2004-02-21 16:19:24.000000000 -0800
@@ -0,0 +1,171 @@
+/***************************************************************************
+			smifb.h  -  SiliconMotion LynxEM+ frame buffer device
+                             -------------------
+    begin                : Thu Aug 9 2001
+    copyright            : (C) 2001 by Szu-Tao Huang
+    email                : johuang@siliconmotion.com
+    
+    Updated to SM501 by Eric.Devolder@amd.com and dan@embeddededge.com
+    for the AMD Mirage Portable Tablet.  20 Oct 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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+#include <linux/config.h>
+
+#define smi_mmiowb(dat,reg)	writeb(dat, (unsigned int)(SMIRegs + reg))
+#define smi_mmioww(dat,reg)	writew(dat, (unsigned int)(SMIRegs + reg))
+#define smi_mmiowl(dat,reg)	writel(dat, (unsigned int)(SMIRegs + reg))
+
+#define smi_mmiorb(reg)	        readb(SMIRegs + reg)
+#define smi_mmiorw(reg)	        readw(SMIRegs + reg)
+#define smi_mmiorl(reg)	        readl(SMIRegs + reg)
+
+#define NR_PALETTE      256
+
+/* Address space offsets for various control/status registers.
+*/
+#define MISC_CTRL			0x000004
+#define GPIO_LO_CTRL			0x000008
+#define GPIO_HI_CTRL			0x00000c
+#define DRAM_CTRL			0x000010
+#define CURRENT_POWER_GATE		0x000038
+#define CURRENT_POWER_CLOCK		0x00003C
+#define POWER_MODE1_GATE                0x000048
+#define POWER_MODE1_CLOCK               0x00004C
+#define POWER_MODE_CTRL			0x000054
+
+#define GPIO_DATA_LO			0x010000
+#define GPIO_DATA_HI			0x010004
+#define GPIO_DATA_DIR_LO		0x010008
+#define GPIO_DATA_DIR_HI		0x01000c
+#define I2C_BYTE_COUNT			0x010040
+#define I2C_CONTROL			0x010041
+#define I2C_STATUS_RESET		0x010042
+#define I2C_SLAVE_ADDRESS		0x010043
+#define I2C_DATA			0x010044
+
+#define DE_COLOR_COMPARE		0x100020
+#define DE_COLOR_COMPARE_MASK		0x100024
+#define DE_MASKS			0x100028
+#define DE_WRAP				0x10004C
+
+#define PANEL_DISPLAY_CTRL              0x080000
+#define PANEL_PAN_CTRL                  0x080004
+#define PANEL_COLOR_KEY                 0x080008
+#define PANEL_FB_ADDRESS                0x08000C
+#define PANEL_FB_WIDTH                  0x080010
+#define PANEL_WINDOW_WIDTH              0x080014
+#define PANEL_WINDOW_HEIGHT             0x080018
+#define PANEL_PLANE_TL                  0x08001C
+#define PANEL_PLANE_BR                  0x080020
+#define PANEL_HORIZONTAL_TOTAL          0x080024
+#define PANEL_HORIZONTAL_SYNC           0x080028
+#define PANEL_VERTICAL_TOTAL            0x08002C
+#define PANEL_VERTICAL_SYNC             0x080030
+#define PANEL_CURRENT_LINE              0x080034
+#define VIDEO_DISPLAY_CTRL		0x080040
+#define VIDEO_DISPLAY_FB0		0x080044
+#define VIDEO_DISPLAY_FBWIDTH		0x080048
+#define VIDEO_DISPLAY_FB0LAST		0x08004C
+#define VIDEO_DISPLAY_TL		0x080050
+#define VIDEO_DISPLAY_BR		0x080054
+#define VIDEO_SCALE			0x080058
+#define VIDEO_INITIAL_SCALE		0x08005C
+#define VIDEO_YUV_CONSTANTS		0x080060
+#define VIDEO_DISPLAY_FB1		0x080064
+#define VIDEO_DISPLAY_FB1LAST		0x080068
+#define VIDEO_ALPHA_CTRL		0x080080
+#define PANEL_HWC_ADDRESS		0x0800F0
+#define CRT_DISPLAY_CTRL		0x080200
+
+#define ZV_CAPTURE_CTRL			0x090000
+#define ZV_CAPTURE_CLIP			0x090004
+#define ZV_CAPTURE_SIZE			0x090008
+#define ZV_CAPTURE_BUF0			0x09000c
+#define ZV_CAPTURE_BUF1			0x090010
+#define ZV_CAPTURE_OFFSET		0x090014
+#define ZV_FIFO_CTRL			0x090018
+
+#define waitforvsync() udelay(100); udelay(100); udelay(100); udelay(100);
+
+/*
+ * Minimum X and Y resolutions
+ */
+#define MIN_XRES	640
+#define MIN_YRES	480
+
+/*
+* Private structure
+*/
+struct smifb_info
+{
+        /*
+        * The following is a pointer to be passed into the
+        * functions below.  The modules outside the main
+        * smifb.c driver have no knowledge as to what
+        * is within this structure.
+        */
+        struct fb_info_gen          gen;
+        struct display_switch   *dispsw;
+        struct pci_dev	        *dev;
+        signed int              currcon;
+
+        struct {
+                u8 red, green, blue;
+        } palette[NR_PALETTE];
+
+        u_int                   palette_size;
+
+		int mmaped;
+		u32 mmio_phys;
+		u32 mmio_size;
+		char *mmio_virt_start;
+
+		u32 fb_phys;
+		u32 fb_size;
+		char *fb_virt_start;
+
+#if defined(FBCON_HAS_CFB16)
+		u16 fbcon_cmap16[16];
+#endif
+
+		/* smi_alloc_fb_info has struct display + 16*sizeof(u32)
+		*/
+		u32 yyy[16];
+};
+
+struct smifb_par
+{
+	struct fb_var_screeninfo var;
+	int line_length;	/* in bytes */
+	int cmap_len;		/* color-map length */
+
+	/*
+	 * Hardware
+	 */
+	u16		chipID;
+
+	u_int	width;
+	u_int	height;
+	u_int	hz;
+};
+
+/* User access to registers for debug and development.
+*/
+struct smireg_op {
+	uint	sr_op;
+	uint	sr_reg;
+	uint	sr_val;
+};
+
+#define SMI_LOAD_REG	1
+#define SMI_STORE_REG	2
+#define SMI_AND_REG	3
+#define SMI_OR_REG	4





-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click

             reply	other threads:[~2004-02-22  0:50 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-02-22  0:44 Pete Popov [this message]
2004-02-22 16:08 ` PATCH Kronos
2004-02-22 19:03   ` PATCH Pete Popov
  -- strict thread matches above, loose matches on Subject: below --
2024-06-18 16:19 Patch Solegaiter
2024-06-18 16:40 ` Patch bluez.test.bot
2020-06-23 23:14 Patch Joe Slater
     [not found] <06c7632e-9e21-7428-bfa3-4ec122f637fd@synopsys.com>
2016-12-27 16:41 ` Patch Joao Pinto
2016-12-27 16:42 ` Patch Joao Pinto
2013-11-22 16:35 Patch Arthur Schwalbenberg
2013-11-22 17:36 ` Patch Levente Kurusa
2013-11-25  8:58   ` Patch Daniel Vetter
2013-11-25  8:58     ` Patch Daniel Vetter
2013-01-23 22:12 Patch for ip setting on bridge interface and vlan Kevin Yung
2013-01-23 22:51 ` Patch Kevin Yung
2010-05-04 16:48 patch Kristoffer Ericson
2009-01-29 10:11 PATCH gabriele.paoloni
2004-10-11  0:01 PATCH Pete Popov
2004-10-11  0:32 ` PATCH Maciej W. Rozycki
2004-10-11  0:47   ` PATCH Pete Popov
2004-10-11  7:55   ` PATCH Pete Popov
2004-10-11 10:32     ` PATCH Christoph Hellwig
2004-10-11 17:07       ` PATCH Pete Popov
2004-10-11 13:53     ` PATCH Atsushi Nemoto
2004-10-11 16:33       ` PATCH Pete Popov
2004-10-11 18:04         ` PATCH Pete Popov
2004-10-10 23:43 PATCH Pete Popov
2004-10-10 17:17 PATCH Pete Popov
2004-10-10 18:01 ` PATCH Geert Uytterhoeven
2004-10-10 19:11   ` PATCH Maciej W. Rozycki
2004-10-10 22:50     ` PATCH Pete Popov
2004-10-11  0:25       ` PATCH Maciej W. Rozycki
2004-10-11  0:39         ` PATCH Pete Popov
2004-10-10 19:33   ` PATCH Matt Porter
2004-10-10 22:52     ` PATCH Pete Popov
2004-10-10 23:41     ` PATCH Pete Popov
2004-10-10  7:17 PATCH Pete Popov
2004-10-10  5:31 PATCH Pete Popov
2004-02-28 22:06 Patch Tommy McCabe
2003-12-01  5:58 patch Diyab
2003-12-01 14:36 ` patch Stephen Smalley
2003-11-03 22:45 Patch Frank Borich
2003-11-03 23:00 ` Patch Patrick Mansfield
     [not found] <OE58jbP3SIGYF2rEF6f00001796@hotmail.com>
2003-02-10 16:09 ` Patch Aman
2003-02-10 17:24   ` Patch Matt Porter
2002-12-25 17:36 Patch Mailhebuau Christophe
     [not found] ` <1040837764.2777.8.camel-SH3sQJamR4OeZLLa646FqQ@public.gmane.org>
2002-12-25 19:10   ` Patch Gregory Gulik
2002-12-26  5:12   ` Patch Theodore Morse
2002-12-14  4:52 PATCH Pete Popov
2002-12-17 22:29 ` PATCH Greg Lindahl
2002-12-17 22:40   ` PATCH Pete Popov
2002-12-17 23:24     ` PATCH Alan Cox
2002-12-17 22:51       ` PATCH Pete Popov
2002-12-17 22:59         ` PATCH Greg Lindahl
2002-12-20 20:43 ` PATCH James Simmons
2002-12-20 20:59   ` PATCH Pete Popov
2002-12-21 20:39     ` PATCH James Simmons
2002-12-14  4:50 PATCH Pete Popov
2002-11-18 23:07 patch deepak
2002-11-18 23:20 ` patch Rik van Riel
2002-11-19  7:33   ` patch Duncan Sands
2002-08-26  0:35 patch Russell Coker
2002-08-26 17:15 ` patch Stephen Smalley
2002-08-26 17:37 ` patch Stephen Smalley
2002-07-15 22:29 PATCH Pete Popov
2002-07-16 15:07 ` PATCH Ralf Baechle
2002-07-16 15:15   ` PATCH Pete Popov
2002-07-16 17:43     ` PATCH Joe George
2002-07-16 18:00       ` PATCH Pete Popov
2002-07-17  0:29         ` PATCH Vivien Chappelier
2002-05-22 15:04 patch Wilson G. Hein
2002-05-22 17:44 ` patch Riley Williams
2002-05-23 11:33 ` patch Wilbert Knol
2002-05-23 16:01   ` patch Richard Adams
2002-05-24 14:14   ` patch Tomi Manninen
2001-08-14 15:32 patch Ryan Senior
2001-08-15 12:55 ` patch Stephen Smalley
2001-07-17 12:54 Patch Cemil Degirmenci
1999-05-20 11:54 Patch nicolas.boussekeyt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1077410677.9577.4.camel@localhost.localdomain \
    --to=pete_popov@yahoo.com \
    --cc=linux-fbdev-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.