[PATCH] au1100fb.c ported from 2.4 to 2.6

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

works in 16bpp, anyone with a system that works in 8bbp can give me a
hand to test this mode?

-- 
Christian <c.pellegrin@xxxxxxxxxxx>
Index: drivers/video/Kconfig
===================================================================
RCS file: /home/cvs/linux/drivers/video/Kconfig,v
retrieving revision 1.31
diff -u -r1.31 Kconfig
--- drivers/video/Kconfig	24 Nov 2004 09:03:40 -0000	1.31
+++ drivers/video/Kconfig	12 Jan 2005 09:05:16 -0000
@@ -973,7 +973,7 @@
 
 config FB_AU1100
 	bool "Au1100 LCD Driver"
-	depends on FB && EXPERIMENTAL && PCI && MIPS && MIPS_PB1100=y
+	depends on FB && EXPERIMENTAL && MIPS && SOC_AU1X00
 
 config FB_SBUS
 	bool "SBUS and UPA framebuffers"
Index: drivers/video/Makefile
===================================================================
RCS file: /home/cvs/linux/drivers/video/Makefile,v
retrieving revision 1.85
diff -u -r1.85 Makefile
--- drivers/video/Makefile	15 Nov 2004 11:49:34 -0000	1.85
+++ drivers/video/Makefile	12 Jan 2005 09:05:21 -0000
@@ -94,7 +94,7 @@
 obj-$(CONFIG_FB_PMAGB_B)	  += pmagb-b-fb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_MAXINE)		  += maxinefb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_TX3912)		  += tx3912fb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
-obj-$(CONFIG_FB_AU1100)		  += au1100fb.o fbgen.o
+obj-$(CONFIG_FB_AU1100)		  += au1100fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 
 
 # Platform or fallback drivers go here
Index: drivers/video/au1100fb.c
===================================================================
RCS file: /home/cvs/linux/drivers/video/au1100fb.c,v
retrieving revision 1.3
diff -u -r1.3 au1100fb.c
--- drivers/video/au1100fb.c	26 Oct 2004 02:23:08 -0000	1.3
+++ drivers/video/au1100fb.c	12 Jan 2005 09:05:26 -0000
@@ -2,16 +2,28 @@
  * BRIEF MODULE DESCRIPTION
  *	Au1100 LCD Driver.
  *
+ * Adapted by <c.pellegrin@xxxxxxxxxxx> for kernel 2.6
+ *
+ *  TODO:
+ *  8bpp support ASA I get hardware for testing
+ *
+ * based on code:
+ ****** 2.4 au1100fb.c
  * Copyright 2002 MontaVista Software
  * Author: MontaVista Software, Inc.
  *		ppopov@xxxxxxxxxx or source@xxxxxxxxxx
  *
  * Copyright 2002 Alchemy Semiconductor
  * Author: Alchemy Semiconductor
+ ****** 2.6 vesafb.c
+ * framebuffer driver for VBE 2.0 compliant graphic boards
+ *
+ * switching to graphics mode happens at boot time (while
+ * running in real mode, see arch/i386/boot/video.S).
+ *
+ * (c) 1998 Gerd Knorr <kraxel@xxxxxxxxxxxxxxxxxxxxx>
  *
- * Based on:
- * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
- *  Created 28 Dec 1997 by Geert Uytterhoeven
+ ******
  *
  *  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
@@ -43,37 +55,18 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
+#include <linux/ioport.h>
 #include <linux/init.h>
-#include <linux/pci.h>
 
-#include <asm/au1000.h>
-#include <asm/pb1100.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-pb1x00/pb1100.h>
 #include "au1100fb.h"
 
-#include <video/fbcon.h>
-#include <video/fbcon-mfb.h>
-#include <video/fbcon-cfb2.h>
-#include <video/fbcon-cfb4.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-
-/* 
- * Sanity check. If this is a new Au1100 based board, search for
- * the PB1100 ifdefs to make sure you modify the code accordingly.
- */
-#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_HYDROGEN3)
-#else
-error Unknown Au1100 board
-#endif
-
-#define CMAPSIZE 16
 
-static int my_lcd_index; /* default is zero */
-struct known_lcd_panels *p_lcd;
-AU1100_LCD *p_lcd_reg = (AU1100_LCD *)AU1100_LCD_ADDR;
+/* --------------------------------------------------------------------- */
 
 struct au1100fb_info {
-	struct fb_info_gen gen;
+	struct fb_info gen;
 	unsigned long fb_virt_start;
 	unsigned long fb_size;
 	unsigned long fb_phys;
@@ -88,192 +81,53 @@
 };
 
 
-struct au1100fb_par {
-        struct fb_var_screeninfo var;
-	
-	int line_length;  // in bytes
-	int cmap_len;     // color-map length
-};
-
+/* --------------------------------------------------------------------- */
 
-static struct au1100fb_info fb_info;
-static struct au1100fb_par current_par;
-static struct display disp;
-
-int au1100fb_init(void);
-void au1100fb_setup(char *options, int *ints);
-static int au1100fb_mmap(struct fb_info *fb, struct file *file, 
-		struct vm_area_struct *vma);
-static int au1100_blank(int blank_mode, struct fb_info_gen *info);
-static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-			  u_long arg, int con, struct fb_info *info);
+static int my_lcd_index; /* default is zero */
+struct known_lcd_panels *p_lcd;
+AU1100_LCD *p_lcd_reg = (AU1100_LCD *)AU1100_LCD_ADDR;
+static int             depth;
+static int nohwcursor;
 
-void au1100_nocursor(struct display *p, int mode, int xx, int yy){};
+static struct au1100fb_info *my_fb_info; /* the info for the current driver */
 
-static struct fb_ops au1100fb_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:       au1100fb_ioctl,
-	fb_mmap:        au1100fb_mmap,
+static struct fb_var_screeninfo au1100fb_defined __initdata = {
+	.activate	= FB_ACTIVATE_NOW,
+	.height		= -1,
+	.width		= -1,
+	.right_margin	= 32,
+	.upper_margin	= 16,
+	.lower_margin	= 4,
+	.vsync_len	= 4,
+	.vmode		= FB_VMODE_NONINTERLACED,
 };
 
-static void au1100_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 struct fb_fix_screeninfo au1100fb_fix __initdata = {
+	.id	= "AU1100 FB",
+	.type	= FB_TYPE_PACKED_PIXELS,
+	.accel	= FB_ACCEL_NONE,
+};
 
-}
+/* --------------------------------------------------------------------- */
 
-static int au1100_encode_fix(struct fb_fix_screeninfo *fix, 
-		const void *_par, struct fb_info_gen *_info)
+static int au1100fb_pan_display(struct fb_var_screeninfo *var,
+                              struct fb_info *info)
 {
-        struct au1100fb_info *info = (struct au1100fb_info *) _info;
-        struct au1100fb_par *par = (struct au1100fb_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)
+static int au1100fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			    unsigned blue, unsigned transp,
+			    struct fb_info *info)
 {
-	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 au1100_decode_var(const struct fb_var_screeninfo *var, 
-		void *_par, struct fb_info_gen *_info)
-{
-
-	struct au1100fb_par *par = (struct au1100fb_par *)_par;
-
 	/*
-	 * Don't allow setting any of these yet: xres and yres don't
-	 * make sense for LCD panels.
+	 *  Set a single color register. The values supplied are
+	 *  already rounded down to the hardware's capabilities
+	 *  (according to the entries in the `var' structure). Return
+	 *  != 0 for invalid regno.
 	 */
-	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 au1100fb_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 au1100_encode_var(struct fb_var_screeninfo *var, 
-		const void *par, struct fb_info_gen *_info)
-{
-
-	*var = ((struct au1100fb_par *)par)->var;
-	return 0;
-}
-
-static void 
-au1100_get_par(void *_par, struct fb_info_gen *_info)
-{
-	*(struct au1100fb_par *)_par = current_par;
-}
-
-static void au1100_set_par(const void *par, struct fb_info_gen *info)
-{
-	/* nothing to do: we don't change any settings */
-}
-
-static int au1100_getcolreg(unsigned regno, unsigned *red, unsigned *green,
-			 unsigned *blue, unsigned *transp,
-			 struct fb_info *info)
-{
-
-	struct au1100fb_info* i = (struct au1100fb_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 au1100_setcolreg(unsigned regno, unsigned red, unsigned green,
-			 unsigned blue, unsigned transp,
-			 struct fb_info *info)
-{
 	struct au1100fb_info* i = (struct au1100fb_info *)info;
-	u32 rgbcol;
 
 	if (regno > 255)
 		return 1;
@@ -307,75 +161,6 @@
 	return 0;
 }
 
-
-static int  au1100_blank(int blank_mode, struct fb_info_gen *_info)
-{
-
-	switch (blank_mode) {
-	case VESA_NO_BLANKING:
-		/* turn on panel */
-		//printk("turn on panel\n");
-#ifdef CONFIG_MIPS_PB1100
-		p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
-		au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight, 
-			PB1100_G_CONTROL);
-#endif
-#ifdef CONFIG_MIPS_HYDROGEN3
-		/*  Turn controller & power supply on,  GPIO213 */
-		au_writel(0x20002000, 0xB1700008);
-		au_writel(0x00040000, 0xB1900108);
-		au_writel(0x01000100, 0xB1700008);
-#endif
-		au_sync();
-		break;
-
-	case VESA_VSYNC_SUSPEND:
-	case VESA_HSYNC_SUSPEND:
-	case VESA_POWERDOWN:
-		/* turn off panel */
-		//printk("turn off panel\n");
-#ifdef CONFIG_MIPS_PB1100
-		au_writew(au_readw(PB1100_G_CONTROL) & ~p_lcd->mode_backlight, 
-			PB1100_G_CONTROL);
-		p_lcd_reg->lcd_control &= ~LCD_CONTROL_GO;
-#endif
-		au_sync();
-		break;
-	default: 
-		break;
-
-	}
-	return 0;
-}
-
-static void au1100_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;
-		if (fb_info.nohwcursor)
-			fbcon_cfb8.cursor = au1100_nocursor;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB16
-	case 16:
-		disp->dispsw = &fbcon_cfb16;
-		disp->dispsw_data = fb_info.fbcon_cmap16;
-		if (fb_info.nohwcursor)
-			fbcon_cfb16.cursor = au1100_nocursor;
-		break;
-#endif
-	default:
-		disp->dispsw = &fbcon_dummy;
-		disp->dispsw_data = NULL;
-		break;
-	}
-}
-
 static int
 au1100fb_mmap(struct fb_info *_fb,
 	     struct file *file,
@@ -389,8 +174,8 @@
 		return -EINVAL;
 	}
     
-	start = fb_info.fb_phys & PAGE_MASK;
-	len = PAGE_ALIGN((start & ~PAGE_MASK) + fb_info.fb_size);
+	start = my_fb_info->fb_phys & PAGE_MASK;
+	len = PAGE_ALIGN((start & ~PAGE_MASK) + my_fb_info->fb_size);
 
 	off = vma->vm_pgoff << PAGE_SHIFT;
 
@@ -408,7 +193,7 @@
 	/* 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,
+	if (io_remap_page_range(vma, vma->vm_start, off,
 				vma->vm_end - vma->vm_start,
 				vma->vm_page_prot)) {
 		return -EAGAIN;
@@ -418,33 +203,68 @@
 	return 0;
 }
 
-int au1100_pan_display(const struct fb_var_screeninfo *var,
-		       struct fb_info_gen *info)
-{
-	return 0;
-}
+static struct fb_ops au1100fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_setcolreg	= au1100fb_setcolreg,
+	.fb_pan_display	= au1100fb_pan_display,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
+	.fb_mmap        = au1100fb_mmap,
+};
 
-static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-			  u_long arg, int con, struct fb_info *info)
+void au1100fb_setup(char *options)
 {
-	/* nothing to do yet */
-	return -EINVAL;
-}
+	char* this_opt;
+#ifndef CONFIG_WWPC
+	int i;
+	int num_panels = sizeof(panels)/sizeof(struct known_lcd_panels);
+#endif
 
-static struct fbgen_hwswitch au1100_switch = {
-	au1100_detect, 
-	au1100_encode_fix, 
-	au1100_decode_var, 
-	au1100_encode_var, 
-	au1100_get_par, 
-	au1100_set_par, 
-	au1100_getcolreg, 
-	au1100_setcolreg, 
-	au1100_pan_display, 
-	au1100_blank, 
-	au1100_set_disp
-};
+    
+	if (!options || !*options)
+		return;
+
+	while ((this_opt = strsep(&options, ",")) != NULL) {
+		if (!strncmp(this_opt, "panel:", 6)) {
+#ifdef CONFIG_WWPC
+		  /* we have just one fixed LCD */
+		  my_lcd_index = 0;
+#else
+#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100)
+		  /* Read Pb1100 Switch S10 ? */
+			if (!strncmp(this_opt+6, "s10", 3))
+			{
+				int panel;
+				panel = *(volatile int *)0xAE000008; /* BCSR SWITCHES */
+				panel >>= 8;
+				panel &= 0x0F;
+				if (panel >= num_panels) panel = 0;
+				my_lcd_index = panel;
+			}
+			else
+#endif
+			/* Get the panel name, everything else if fixed */
+			for (i=0; i<num_panels; i++) {
+				if (!strncmp(this_opt+6, panels[i].panel_name, 
+							strlen(this_opt))) {
+					my_lcd_index = i;
+					break;
+				}
+			}
+#endif /* CONFIG_WWPC */
+		}
+		else if (!strncmp(this_opt, "nohwcursor", 10)) {
+			printk("nohwcursor\n");
+			nohwcursor = 1;
+		}
+	} 
 
+	printk("au1100fb: Panel %d %s\n", my_lcd_index,
+		panels[my_lcd_index].panel_name);
+	p_lcd = &panels[my_lcd_index];
+}
 
 int au1100_setmode(void) 
 {
@@ -478,7 +298,7 @@
 	p_lcd_reg->lcd_verttiming = p_lcd->mode_verttiming;
 	p_lcd_reg->lcd_clkcontrol = p_lcd->mode_clkcontrol;
 	p_lcd_reg->lcd_words = words - 1;
-	p_lcd_reg->lcd_dmaaddr0 = fb_info.fb_phys;
+	p_lcd_reg->lcd_dmaaddr0 = my_fb_info->fb_phys;
 
 	/* turn on panel */
 #ifdef CONFIG_MIPS_PB1100
@@ -491,23 +311,49 @@
 	au_writel(0x00040000, 0xB1900108);
 	au_writel(0x01000100, 0xB1700008);
 #endif
+#ifdef CONFIG_WWPC
+	au_writel(0x000221A1, 0xB190002C);
+
+	au_writel(0x40228000, 0xB1900108);
+	au_writel(0x001D0000, 0xB190010C);
+	au_writel(0x403F8000, 0xB1900100);
+
+	/* TODO: move in the right place */
+
+	au_writel(0x00000001, 0xB1700014);
+	au_writel(0x0000060F, 0xB1700000);
+	au_writel(0x060F0400, 0xB1700008);
+
+	/* turn on LCD */
+	{
+	  unsigned long t;
+
+	  t = au_readl(0xB1900108); 
+	  t |= (1 << 20);
+	  au_writel(t, 0xB1900108);
+	  udelay(1000);
+          t |= (1 << 19);
+          au_writel(t, 0xB1900108);
+	  printk("LCD ON: 0xB1900108 is %08lx\n", t);
+	}
+
+#endif
 
 	p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
 
 	return 0;
 }
 
-
-int __init au1100fb_init(void)
+static int __init au1100fb_probe(struct device *device)
 {
-	uint32 sys_clksrc;
+	struct platform_device *dev = to_platform_device(device);
+	struct fb_info *info;
+	int err;
 	unsigned long page;
+	unsigned int size_vmode;
+	uint32 sys_clksrc;
 
-	/*
-	* Get the panel information/display mode and update the registry
-	*/
-	p_lcd = &panels[my_lcd_index];
-
+	/* verify LCD rotation */
 	switch (p_lcd->mode_control & LCD_CONTROL_SM)
 	{
 		case LCD_CONTROL_SM_0:
@@ -526,6 +372,17 @@
 			break;
 	}
 
+	/* alloc info struct */
+	info = framebuffer_alloc(sizeof(struct au1100fb_info), &dev->dev);
+	if (!info) {
+		printk("Cannot allocate FB\n");
+		return -ENOMEM;
+	}
+	my_fb_info = (struct au1100fb_info *) info;
+	info->pseudo_palette = info->par;
+	info->par = NULL;
+	my_fb_info->nohwcursor = nohwcursor;
+
 	/*
 	 * Panel dimensions x bpp must be divisible by 32
 	 */
@@ -534,143 +391,225 @@
 	if (((p_lcd->xres * p_lcd->bpp) % 32) != 0) 
 		printk("HORZ %% 32\n");
 
-	/*
-	 * Allocate LCD framebuffer from system memory
-	 */
-	fb_info.fb_size = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 8;
-	
-	current_par.var.xres = p_lcd->xres;
-	current_par.var.xres_virtual = p_lcd->xres;
-	current_par.var.yres = p_lcd->yres;
-	current_par.var.yres_virtual = p_lcd->yres;
-	current_par.var.bits_per_pixel = p_lcd->bpp;
-
-	/* FIX!!! only works for 8/16 bpp */
-	current_par.line_length = p_lcd->xres * p_lcd->bpp / 8; /* in bytes */
-	fb_info.fb_virt_start = (unsigned long )
+	/* determine start address of the FB */
+	my_fb_info->fb_size = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 8;
+	my_fb_info->fb_virt_start = (unsigned long )
 		__get_free_pages(GFP_ATOMIC | GFP_DMA, 
-				get_order(fb_info.fb_size + 0x1000));
-	if (!fb_info.fb_virt_start) {
+				 get_order(my_fb_info->fb_size + 0x1000));
+	if (!my_fb_info->fb_virt_start) {
 		printk("Unable to allocate fb memory\n");
 		return -ENOMEM;
 	}
-	fb_info.fb_phys = virt_to_bus((void *)fb_info.fb_virt_start);
-
+	info->screen_base = my_fb_info->fb_virt_start;
+	my_fb_info->fb_phys = virt_to_bus((void *)my_fb_info->fb_virt_start);
+	au1100fb_fix.smem_start = my_fb_info->fb_virt_start;
 	/*
 	 * Set page reserved so that mmap will work. This is necessary
 	 * since we'll be remapping normal memory.
 	 */
-	for (page = fb_info.fb_virt_start;
-	     page < PAGE_ALIGN(fb_info.fb_virt_start + fb_info.fb_size); 
+	for (page = my_fb_info->fb_virt_start;
+	     page < PAGE_ALIGN(my_fb_info->fb_virt_start + my_fb_info->fb_size); 
 	     page += PAGE_SIZE) {
 		SetPageReserved(virt_to_page(page));
 	}
 
-	memset((void *)fb_info.fb_virt_start, 0, fb_info.fb_size);
+	/* setup bpp */
+	au1100fb_defined.bits_per_pixel = p_lcd->bpp;
+	if (15 == au1100fb_defined.bits_per_pixel)
+		au1100fb_defined.bits_per_pixel = 16;
+	au1100fb_fix.visual   = (au1100fb_defined.bits_per_pixel == 8) ?
+		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+
+	/* setup geometry */
+	au1100fb_defined.xres = p_lcd->xres;
+	au1100fb_defined.yres = p_lcd->yres;
+	au1100fb_fix.line_length = p_lcd->xres * p_lcd->bpp / 8;
+
+	/*   size_vmode -- that is the amount of memory needed for the
+	 *                 used video mode, i.e. the minimum amount of
+	 *                 memory we need. */
+	size_vmode = au1100fb_defined.yres * au1100fb_fix.line_length;
+
+	au1100fb_fix.smem_len = my_fb_info->fb_size;
+
+	printk(KERN_INFO "au1100fb: framebuffer at 0x%lx, mapped to 0x%p\n",
+	       au1100fb_fix.smem_start, info->screen_base);
+	printk(KERN_INFO "au1100fb: mode is %dx%dx%d, linelength=%d\n",
+	       au1100fb_defined.xres, au1100fb_defined.yres, au1100fb_defined.bits_per_pixel, au1100fb_fix.line_length);
+
+	au1100fb_defined.xres_virtual = au1100fb_defined.xres;
+	au1100fb_defined.yres_virtual = au1100fb_fix.smem_len / au1100fb_fix.line_length;
+
+	/* some dummy values for timing to make fbset happy */
+	au1100fb_defined.pixclock     = 10000000 / au1100fb_defined.xres * 1000 / au1100fb_defined.yres;
+	au1100fb_defined.left_margin  = (au1100fb_defined.xres / 8) & 0xf8;
+	au1100fb_defined.hsync_len    = (au1100fb_defined.xres / 8) & 0xf8;
+	
+	/* TODO, 8bpp */
+	au1100fb_defined.red.offset    = 11;
+	au1100fb_defined.red.length    = 5;
+	au1100fb_defined.green.offset  = 5;
+	au1100fb_defined.green.length  = 6;
+	au1100fb_defined.blue.offset   = 0;
+	au1100fb_defined.blue.length   = 5;
+	au1100fb_defined.transp.offset = 0;
+	au1100fb_defined.transp.length = 0;
+
+#if 0
+	/* test pattern */
+#define BLOCK 16
+	{
+		int x,y,xx,yy,i;
+		unsigned short c;
+		unsigned short *p = (unsigned short *) my_fb_info->fb_virt_start;
+		int mx = p_lcd->xres / BLOCK;
+		int my = p_lcd->yres / BLOCK;;
+		i = 0;
+		for(x=0; x<mx; x++) 
+			for(y=0; y<my; y++) {
+				switch (i%3) {
+				case 0:
+					c = (0x1f <<  au1100fb_defined.red.offset);
+					break;
+				case 1:
+					c = (0x3f <<  au1100fb_defined.green.offset);
+					break;
+				case 2:
+					c = (0x1f <<  au1100fb_defined.blue.offset);
+					break;
+				default:
+					c = 0;
+					break;
+				}
+				for(xx = x*BLOCK ; xx < (x+1)*BLOCK; xx++) 
+					for(yy = y*BLOCK ; yy < (y+1)*BLOCK; yy++) 
+						p[xx+yy*p_lcd->xres] = c;
+				i++;
+			}
+	}
+#undef BLOCK
+#else
+	memset((void *)my_fb_info->fb_virt_start, 0, my_fb_info->fb_size);
+#endif
+
+	screen_info.rsvd_size = 0;
+	screen_info.red_size = au1100fb_defined.red.length;
+	screen_info.green_size = au1100fb_defined.green.length;
+	screen_info.blue_size = au1100fb_defined.blue.length;
+	screen_info.rsvd_pos = 0;
+	screen_info.red_pos = au1100fb_defined.red.offset;
+	screen_info.green_pos = au1100fb_defined.green.offset;
+	screen_info.blue_pos = au1100fb_defined.blue.offset;
+	screen_info.lfb_base = my_fb_info->fb_virt_start;
+	screen_info.lfb_width = au1100fb_defined.xres;
+	screen_info.lfb_height = au1100fb_defined.yres;
+	screen_info.lfb_depth = au1100fb_defined.bits_per_pixel;
+	screen_info.lfb_linelength = au1100fb_fix.line_length;
+	screen_info.lfb_size = my_fb_info->fb_size;
+
+	if (au1100fb_defined.bits_per_pixel <= 8) {
+		depth = au1100fb_defined.green.length;
+		au1100fb_defined.red.length =
+		au1100fb_defined.green.length =
+		au1100fb_defined.blue.length =
+		au1100fb_defined.bits_per_pixel;
+	}
+
+	printk(KERN_INFO "au1100fb: %s: "
+	       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
+	       (au1100fb_defined.bits_per_pixel > 8) ?
+	       "Truecolor" : "Pseudocolor",
+	       screen_info.rsvd_size,
+	       screen_info.red_size,
+	       screen_info.green_size,
+	       screen_info.blue_size,
+	       screen_info.rsvd_pos,
+	       screen_info.red_pos,
+	       screen_info.green_pos,
+	       screen_info.blue_pos);
+
+	info->fbops = &au1100fb_ops;
+	info->var = au1100fb_defined;
+	info->fix = au1100fb_fix;
+	info->flags = FBINFO_FLAG_DEFAULT;
+
+	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+		err = -ENXIO;
+		goto err;
+	}
+	if (register_framebuffer(info)<0) {
+		err = -EINVAL;
+		fb_dealloc_cmap(&info->cmap);
+		goto err;
+	}
+	printk(KERN_INFO "fb%d: %s frame buffer device\n",
+	       info->node, info->fix.id);
 
 	/* set freqctrl now to allow more time to stabilize */
 	/* zero-out out LCD bits */
+#ifdef CONFIG_WWPC
+	{
+	  unsigned long t;
+
+	  t = au_readl(SYS_FREQCTRL1) & ~(0x3ff); 
+	  printk("before SYS_FREQCTRL1 is %08lx\n", t);
+	  t |= (1 << 1) | (9 << 2);
+	  au_writel(t, SYS_FREQCTRL1);
+	  printk("after SYS_FREQCTRL1 is %08lx\n", t);
+	}
+	sys_clksrc = au_readl(SYS_CLKSRC) & ~( (1<<9) | (1<<8) | (1<<7) | (1<<6) | (1<<5) ); 
+	sys_clksrc |= (1<<9) | (1<<7);
+	au_writel(sys_clksrc, SYS_CLKSRC);
+#else
 	sys_clksrc = au_readl(SYS_CLKSRC) & ~0x000003e0; 
 	sys_clksrc |= p_lcd->mode_toyclksrc;
 	au_writel(sys_clksrc, SYS_CLKSRC);
+#endif
 
-	/* FIXME add check to make sure auxpll is what is expected! */
+	/* setup LCD */
 	au1100_setmode();
 
-	fb_info.gen.parsize = sizeof(struct au1100fb_par);
-	fb_info.gen.fbhw = &au1100_switch;
-
-	strcpy(fb_info.gen.info.modename, "Au1100 LCD");
-	fb_info.gen.info.changevar = NULL;
-	fb_info.gen.info.node = -1;
-
-	fb_info.gen.info.fbops = &au1100fb_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)
-		return -EINVAL;
-	printk(KERN_INFO "fb%d: %s frame buffer device\n", 
-			GET_FB_IDX(fb_info.gen.info.node), 
-			fb_info.gen.info.modename);
-
 	return 0;
+err:
+	framebuffer_release(info);
+	return err;
 }
 
+static struct device_driver au1100fb_driver = {
+	.name	= "au1100fb",
+	.bus	= &platform_bus_type,
+	.probe	= au1100fb_probe,
+};
 
-void au1100fb_cleanup(struct fb_info *info)
-{
-	unregister_framebuffer(info);
-}
-
+static struct platform_device au1100fb_device = {
+	.name	= "au1100fb",
+};
 
-void au1100fb_setup(char *options, int *ints)
+int __init au1100fb_init(void)
 {
-	char* this_opt;
-	int i;
-	int num_panels = sizeof(panels)/sizeof(struct known_lcd_panels);
-
-    
-	if (!options || !*options)
-		return;
-
-	for(this_opt=strtok(options, ","); this_opt;
-	    this_opt=strtok(NULL, ",")) {
-		if (!strncmp(this_opt, "panel:", 6)) {
-#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100)
-			/* Read Pb1100 Switch S10 ? */
-			if (!strncmp(this_opt+6, "s10", 3))
-			{
-				int panel;
-				panel = *(volatile int *)0xAE000008; /* BCSR SWITCHES */
-				panel >>= 8;
-				panel &= 0x0F;
-				if (panel >= num_panels) panel = 0;
-				my_lcd_index = panel;
-			}
-			else
-#endif
-			/* Get the panel name, everything else if fixed */
-			for (i=0; i<num_panels; i++) {
-				if (!strncmp(this_opt+6, panels[i].panel_name, 
-							strlen(this_opt))) {
-					my_lcd_index = i;
-					break;
-				}
-			}
-		}
-		else if (!strncmp(this_opt, "nohwcursor", 10)) {
-			printk("nohwcursor\n");
-			fb_info.nohwcursor = 1;
-		}
-	} 
-
-	printk("au1100fb: Panel %d %s\n", my_lcd_index,
-		panels[my_lcd_index].panel_name);
-}
-
+	int ret;
+	char *option = NULL;
 
+	/* ignore error return of fb_get_options */
+	fb_get_options("au1100fb", &option);
+	au1100fb_setup(option);
+	ret = driver_register(&au1100fb_driver);
+
+	if (!ret) {
+		ret = platform_device_register(&au1100fb_device);
+		if (ret)
+			driver_unregister(&au1100fb_driver);
+	}
+	return ret;
+}
+module_init(au1100fb_init);
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
 
-#ifdef MODULE
 MODULE_LICENSE("GPL");
-int init_module(void)
-{
-	return au1100fb_init();
-}
-
-void cleanup_module(void)
-{
-	au1100fb_cleanup(void);
-}
-
-MODULE_AUTHOR("Pete Popov <ppopov@xxxxxxxxxx>");
-MODULE_DESCRIPTION("Au1100 LCD framebuffer device driver");
-#endif /* MODULE */
Index: drivers/video/au1100fb.h
===================================================================
RCS file: /home/cvs/linux/drivers/video/au1100fb.h,v
retrieving revision 1.1
diff -u -r1.1 au1100fb.h
--- drivers/video/au1100fb.h	14 Jul 2002 21:33:34 -0000	1.1
+++ drivers/video/au1100fb.h	12 Jan 2005 09:05:31 -0000
@@ -191,6 +191,39 @@
  */
 struct known_lcd_panels panels[] =
 {
+#ifdef CONFIG_WWPC
+	{ 			/* just the standard LCD */
+		240, /* xres */
+		320, /* yres */
+		16,  /* bpp  */
+
+		"WWPC LCD",
+
+		/* mode_control */
+		0x0006806A,
+
+		/* mode_horztiming */
+		0x0A1010EF,
+
+		/* mode_verttiming */
+		0x0301013F,
+
+		/* mode_clkcontrol */
+		0x00018001,
+
+		/* mode_pwmdiv */
+		0,
+
+		/* mode_pwmhi */
+		0,
+
+		/* mode_toyclksrc */
+		0,		/* not used */
+
+		/* mode_backlight */
+		0		/* not used */
+	}
+#else
 	{ /* 0: Pb1100 LCDA: Sharp 320x240 TFT panel */
 		320, /* xres */
 		240, /* yres */
@@ -377,5 +410,6 @@
 		/* mode_backlight */
 		7
 	},
+#endif
 };
 #endif /* _AU1100LCD_H */

Attachment: signature.asc
Description: This is a digitally signed message part


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux