* [PATCH] au1100fb.c ported from 2.4 to 2.6
@ 2005-01-12 9:50 Christian
2005-02-02 9:05 ` Ulrich Eckhardt
2005-02-08 14:14 ` Ulrich Eckhardt
0 siblings, 2 replies; 5+ messages in thread
From: Christian @ 2005-01-12 9:50 UTC (permalink / raw)
To: linux-mips
[-- Attachment #1.1: Type: text/plain, Size: 149 bytes --]
Hi,
works in 16bpp, anyone with a system that works in 8bbp can give me a
hand to test this mode?
--
Christian <c.pellegrin@exadron.com>
[-- Attachment #1.2: fb1 --]
[-- Type: text/x-patch, Size: 28517 bytes --]
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@exadron.com> 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@mvista.com or source@mvista.com
*
* 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@goldbach.in-berlin.de>
*
- * 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@mvista.com>");
-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 #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] au1100fb.c ported from 2.4 to 2.6
2005-01-12 9:50 [PATCH] au1100fb.c ported from 2.4 to 2.6 Christian
@ 2005-02-02 9:05 ` Ulrich Eckhardt
2005-02-04 9:56 ` Christian
2005-02-08 14:14 ` Ulrich Eckhardt
1 sibling, 1 reply; 5+ messages in thread
From: Ulrich Eckhardt @ 2005-02-02 9:05 UTC (permalink / raw)
To: linux-mips; +Cc: Christian
Christian wrote:
> works in 16bpp, anyone with a system that works in 8bbp can give me a
> hand to test this mode?
I have a system that has a 4bpp monochrome display and the driver doesn't
work. After initializing, it turns on the display[1] but I fail to get any
content onto it. I extended the array with the display characteristics
according to an existing driver, but to no avail.
I'm pretty lost there, since I have zero prior experience with framebuffers or
video drivers, so I'd appreciate any hint that might get me towards debugging
this.
Uli
[1] p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] au1100fb.c ported from 2.4 to 2.6
2005-02-02 9:05 ` Ulrich Eckhardt
@ 2005-02-04 9:56 ` Christian
2005-02-04 13:18 ` Ulrich Eckhardt
0 siblings, 1 reply; 5+ messages in thread
From: Christian @ 2005-02-04 9:56 UTC (permalink / raw)
To: Ulrich Eckhardt; +Cc: linux-mips
[-- Attachment #1: Type: text/plain, Size: 1135 bytes --]
On Wed, 2005-02-02 at 10:05 +0100, Ulrich Eckhardt wrote:
> I have a system that has a 4bpp monochrome display and the driver doesn't
> work. After initializing, it turns on the display[1] but I fail to get any
> content onto it. I extended the array with the display characteristics
> according to an existing driver, but to no avail.
>
> I'm pretty lost there, since I have zero prior experience with framebuffers or
> video drivers, so I'd appreciate any hint that might get me towards debugging
> this.
Hi,
you actually have to do the following modification modifications.
First you have to modify the function au1100fb_setcolreg, add the switch
case for 4bpp. Look in the Alchemy manual for the format of the palette
in the 4 bpp case. Then look for my comment "TODO: 8bbp", put a switch
and for pseudocolor like visual ... I think this is not even necessary.
More important is that you change the monitor type. If you want I can
send you privately a patch this weekend, but I just cannot assure it
works, you have to test it and eventually contribute.
--
Christian <c.pellegrin@exadron.com>
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] au1100fb.c ported from 2.4 to 2.6
2005-02-04 9:56 ` Christian
@ 2005-02-04 13:18 ` Ulrich Eckhardt
0 siblings, 0 replies; 5+ messages in thread
From: Ulrich Eckhardt @ 2005-02-04 13:18 UTC (permalink / raw)
To: linux-mips
Christian wrote:
> First you have to modify the function au1100fb_setcolreg, add the switch
> case for 4bpp. Look in the Alchemy manual for the format of the palette
> in the 4 bpp case. Then look for my comment "TODO: 8bbp", put a switch
> and for pseudocolor like visual ... I think this is not even necessary.
Thanks, will look.
> More important is that you change the monitor type.
Yep, finding working parameters without real knowledge of what the registers
mean was the hardest part, but I have it working now.
> If you want I can
> send you privately a patch this weekend, but I just cannot assure it
> works, you have to test it and eventually contribute.
I'd appreciate that, thank you.
Currently I'm facing a different problem though, look at this code and the
bitmap it generates (4bpp):
unsigned long* fb = my_fb_info->fb_virt_start;
fb[0] = 0x0000000f; // *.......
fb[40] = 0x000000f0; // .*......
fb[80] = 0x000000ff; // **......
fb[120] = 0xf0000f00; // ..*....*
fb[160] = 0xff000f0f; // *.*...**
fb[200] = 0xfff00ff0; // .**..***
fb[240] = 0xffff0fff; // ***.****
To me, expecting the LSB to be part of the leftmost pixel is not really
surprising, but functions like cfb_fillrect() (or rather bitfill32() etc)
expect the order to be the other way around. I'm afraid that other
framebuffer functions also expect that, but I haven't gotten far enough to
test those. I only tested cfb_fillrect() and, seeing it fail, started looking
for answers... any idea?
I stumbled across another .. err .. 'feature': take a look at the appended
patch, in particular the handling of the mask for the first long, am I
dreaming or is this in fact handled wrongly in the current FB code? I'm a bit
confused, because the same mistake is made in pretty much every FB driver I
looked at.
Thanks
Uli
---
Index: cfbcopyarea.c
===================================================================
RCS file: /home/cvs/linux/drivers/video/cfbcopyarea.c,v
retrieving revision 1.10
diff -u -w -r1.10 cfbcopyarea.c
--- cfbcopyarea.c 12 Oct 2004 01:45:47 -0000 1.10
+++ cfbcopyarea.c 4 Feb 2005 13:11:16 -0000
@@ -70,7 +70,7 @@
} else {
// Multiple destination words
// Leading bits
- if (first) {
+ if (first != ~0UL) {
FB_WRITEL((FB_READL(src) & first) |
(FB_READL(dst) & ~first), dst);
@@ -223,7 +223,7 @@
} else {
// Multiple destination words
// Leading bits
- if (first) {
+ if (first != ~0UL) {
FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) & ~first), dst);
dst--;
src--;
Index: cfbfillrect.c
===================================================================
RCS file: /home/cvs/linux/drivers/video/cfbfillrect.c,v
retrieving revision 1.8
diff -u -w -r1.8 cfbfillrect.c
--- cfbfillrect.c 12 Oct 2004 01:45:47 -0000 1.8
+++ cfbfillrect.c 4 Feb 2005 13:11:16 -0000
@@ -142,7 +142,7 @@
} else {
// Multiple destination words
// Leading bits
- if (first) {
+ if (first != ~0UL) {
FB_WRITEL(comp(val, FB_READL(dst), first), dst);
dst++;
n -= BITS_PER_LONG-dst_idx;
@@ -166,7 +166,7 @@
// Trailing bits
if (last)
- FB_WRITEL(comp(val, FB_READL(dst), first), dst);
+ FB_WRITEL(comp(val, FB_READL(dst), last), dst);
}
}
@@ -197,7 +197,7 @@
} else {
// Multiple destination words
// Leading bits
- if (first) {
+ if (first != ~0UL) {
FB_WRITEL(comp(pat, FB_READL(dst), first), dst);
dst++;
pat = pat << left | pat >> right;
@@ -224,7 +224,7 @@
// Trailing bits
if (last)
- FB_WRITEL(comp(pat, FB_READL(dst), first), dst);
+ FB_WRITEL(comp(pat, FB_READL(dst), last), dst);
}
}
@@ -252,7 +252,7 @@
} else {
// Multiple destination words
// Leading bits
- if (first) {
+ if (first != ~0UL) {
dat = FB_READL(dst);
FB_WRITEL(comp(dat ^ val, dat, first), dst);
dst++;
@@ -287,7 +287,7 @@
// Trailing bits
if (last) {
dat = FB_READL(dst);
- FB_WRITEL(comp(dat ^ val, dat, first), dst);
+ FB_WRITEL(comp(dat ^ val, dat, last), dst);
}
}
}
@@ -320,7 +320,7 @@
} else {
// Multiple destination words
// Leading bits
- if (first) {
+ if (first != ~0UL) {
dat = FB_READL(dst);
FB_WRITEL(comp(dat ^ pat, dat, first), dst);
dst++;
@@ -354,7 +354,7 @@
// Trailing bits
if (last) {
dat = FB_READL(dst);
- FB_WRITEL(comp(dat ^ pat, dat, first), dst);
+ FB_WRITEL(comp(dat ^ pat, dat, last), dst);
}
}
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] au1100fb.c ported from 2.4 to 2.6
2005-01-12 9:50 [PATCH] au1100fb.c ported from 2.4 to 2.6 Christian
2005-02-02 9:05 ` Ulrich Eckhardt
@ 2005-02-08 14:14 ` Ulrich Eckhardt
1 sibling, 0 replies; 5+ messages in thread
From: Ulrich Eckhardt @ 2005-02-08 14:14 UTC (permalink / raw)
To: linux-mips; +Cc: Christian
[-- Attachment #1: Type: text/plain, Size: 710 bytes --]
Another two suggestions:
- you hard-coded the used display in au1100fb.{h,c} with #ifdef CONFIG_WWPC.
There is another option already used in arch/mips/au1000/common/setup.c, and
that is to append the necessary lines to the kernel commandline if no
conflicting arguments are present.
- I have removed the comments that say to which field a constant belongs and
instead converted au1100fb.h to use new-style initialisers which is just
easier to not get wrong. I also added parameters for my display and replaced
the #define for uint32. The new file is attached as whole, I didn't know
against what to diff it...
Could you merge the file and resend the patch? I hope it will get committed
then.
Uli
[-- Attachment #2: au1100fb.h --]
[-- Type: text/x-chdr, Size: 9587 bytes --]
/*
* BRIEF MODULE DESCRIPTION
* Hardware definitions for the Au1100 LCD controller
*
* Copyright 2002 MontaVista Software
* Copyright 2002 Alchemy Semiconductor
* Author: Alchemy Semiconductor, MontaVista Software
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _AU1100LCD_H
#define _AU1100LCD_H
/********************************************************************/
typedef volatile struct
{
u32 lcd_control;
u32 lcd_intstatus;
u32 lcd_intenable;
u32 lcd_horztiming;
u32 lcd_verttiming;
u32 lcd_clkcontrol;
u32 lcd_dmaaddr0;
u32 lcd_dmaaddr1;
u32 lcd_words;
u32 lcd_pwmdiv;
u32 lcd_pwmhi;
u32 reserved[(0x0400-0x002C)/4];
u32 lcd_pallettebase[256];
} AU1100_LCD;
/********************************************************************/
#define AU1100_LCD_ADDR 0xB5000000
/*
* Register bit definitions
*/
/* lcd_control */
#define LCD_CONTROL_SBB_1 (0<<21)
#define LCD_CONTROL_SBB_2 (1<<21)
#define LCD_CONTROL_SBB_3 (2<<21)
#define LCD_CONTROL_SBB_4 (3<<21)
#define LCD_CONTROL_SBPPF (7<<18)
#define LCD_CONTROL_SBPPF_655 (0<<18)
#define LCD_CONTROL_SBPPF_565 (1<<18)
#define LCD_CONTROL_SBPPF_556 (2<<18)
#define LCD_CONTROL_SBPPF_1555 (3<<18)
#define LCD_CONTROL_SBPPF_5551 (4<<18)
#define LCD_CONTROL_WP (1<<17)
#define LCD_CONTROL_WD (1<<16)
#define LCD_CONTROL_C (1<<15)
#define LCD_CONTROL_SM (3<<13)
#define LCD_CONTROL_SM_0 (0<<13)
#define LCD_CONTROL_SM_90 (1<<13)
#define LCD_CONTROL_SM_180 (2<<13)
#define LCD_CONTROL_SM_270 (3<<13)
#define LCD_CONTROL_DB (1<<12)
#define LCD_CONTROL_CCO (1<<11)
#define LCD_CONTROL_DP (1<<10)
#define LCD_CONTROL_PO (3<<8)
#define LCD_CONTROL_PO_00 (0<<8)
#define LCD_CONTROL_PO_01 (1<<8)
#define LCD_CONTROL_PO_10 (2<<8)
#define LCD_CONTROL_PO_11 (3<<8)
#define LCD_CONTROL_MPI (1<<7)
#define LCD_CONTROL_PT (1<<6)
#define LCD_CONTROL_PC (1<<5)
#define LCD_CONTROL_BPP (7<<1)
#define LCD_CONTROL_BPP_1 (0<<1)
#define LCD_CONTROL_BPP_2 (1<<1)
#define LCD_CONTROL_BPP_4 (2<<1)
#define LCD_CONTROL_BPP_8 (3<<1)
#define LCD_CONTROL_BPP_12 (4<<1)
#define LCD_CONTROL_BPP_16 (5<<1)
#define LCD_CONTROL_GO (1<<0)
/* lcd_intstatus, lcd_intenable */
#define LCD_INT_SD (1<<7)
#define LCD_INT_OF (1<<6)
#define LCD_INT_UF (1<<5)
#define LCD_INT_SA (1<<3)
#define LCD_INT_SS (1<<2)
#define LCD_INT_S1 (1<<1)
#define LCD_INT_S0 (1<<0)
/* lcd_horztiming */
#define LCD_HORZTIMING_HN2 (255<<24)
#define LCD_HORZTIMING_HN2_N(N) (((N)-1)<<24)
#define LCD_HORZTIMING_HN1 (255<<16)
#define LCD_HORZTIMING_HN1_N(N) (((N)-1)<<16)
#define LCD_HORZTIMING_HPW (63<<10)
#define LCD_HORZTIMING_HPW_N(N) (((N)-1)<<10)
#define LCD_HORZTIMING_PPL (1023<<0)
#define LCD_HORZTIMING_PPL_N(N) (((N)-1)<<0)
/* lcd_verttiming */
#define LCD_VERTTIMING_VN2 (255<<24)
#define LCD_VERTTIMING_VN2_N(N) (((N)-1)<<24)
#define LCD_VERTTIMING_VN1 (255<<16)
#define LCD_VERTTIMING_VN1_N(N) (((N)-1)<<16)
#define LCD_VERTTIMING_VPW (63<<10)
#define LCD_VERTTIMING_VPW_N(N) (((N)-1)<<10)
#define LCD_VERTTIMING_LPP (1023<<0)
#define LCD_VERTTIMING_LPP_N(N) (((N)-1)<<0)
/* lcd_clkcontrol */
#define LCD_CLKCONTROL_IB (1<<18)
#define LCD_CLKCONTROL_IC (1<<17)
#define LCD_CLKCONTROL_IH (1<<16)
#define LCD_CLKCONTROL_IV (1<<15)
#define LCD_CLKCONTROL_BF (31<<10)
#define LCD_CLKCONTROL_BF_N(N) (((N)-1)<<10)
#define LCD_CLKCONTROL_PCD (1023<<0)
#define LCD_CLKCONTROL_PCD_N(N) ((N)<<0)
/* lcd_pwmdiv */
#define LCD_PWMDIV_EN (1<<12)
#define LCD_PWMDIV_PWMDIV (2047<<0)
#define LCD_PWMDIV_PWMDIV_N(N) (((N)-1)<<0)
/* lcd_pwmhi */
#define LCD_PWMHI_PWMHI1 (2047<<12)
#define LCD_PWMHI_PWMHI1_N(N) ((N)<<12)
#define LCD_PWMHI_PWMHI0 (2047<<0)
#define LCD_PWMHI_PWMHI0_N(N) ((N)<<0)
/* lcd_pallettebase - MONOCHROME */
#define LCD_PALLETTE_MONO_MI (15<<0)
#define LCD_PALLETTE_MONO_MI_N(N) ((N)<<0)
/* lcd_pallettebase - COLOR */
#define LCD_PALLETTE_COLOR_BI (15<<8)
#define LCD_PALLETTE_COLOR_BI_N(N) ((N)<<8)
#define LCD_PALLETTE_COLOR_GI (15<<4)
#define LCD_PALLETTE_COLOR_GI_N(N) ((N)<<4)
#define LCD_PALLETTE_COLOR_RI (15<<0)
#define LCD_PALLETTE_COLOR_RI_N(N) ((N)<<0)
/* lcd_palletebase - COLOR TFT PALLETIZED */
#define LCD_PALLETTE_TFT_DC (65535<<0)
#define LCD_PALLETTE_TFT_DC_N(N) ((N)<<0)
/********************************************************************/
struct known_lcd_panels
{
uint32 xres;
uint32 yres;
uint32 bpp;
unsigned char panel_name[256];
uint32 mode_control;
uint32 mode_horztiming;
uint32 mode_verttiming;
uint32 mode_clkcontrol;
uint32 mode_pwmdiv;
uint32 mode_pwmhi;
uint32 mode_toyclksrc;
uint32 mode_backlight;
};
#if defined(__BIG_ENDIAN)
# define LCD_DEFAULT_PIX_FORMAT LCD_CONTROL_PO_11
#else
# define LCD_DEFAULT_PIX_FORMAT LCD_CONTROL_PO_00
#endif
/*
* The fb driver assumes that AUX PLL is at 48MHz. That can
* cover up to 800x600 resolution; if you need higher resolution,
* you should modify the driver as needed, not just this structure.
*/
struct known_lcd_panels panels[] =
{
#ifdef CONFIG_WWPC
{ /* just the standard LCD */
.xres = 240,
.yres = 320,
.bpp = 16,
.panel_name = "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
{ /* Pb1100 LCDA: Sharp 320x240 TFT panel */
.xres = 320,
.yres = 240,
.bpp = 16,
.panel_name = "Sharp_320x240_16",
.mode_control =
( LCD_CONTROL_SBPPF_565
| LCD_CONTROL_C
| LCD_CONTROL_SM_0
| LCD_DEFAULT_PIX_FORMAT
| LCD_CONTROL_PT
| LCD_CONTROL_PC
| LCD_CONTROL_BPP_16 ),
.mode_horztiming =
( LCD_HORZTIMING_HN2_N(8)
| LCD_HORZTIMING_HN1_N(60)
| LCD_HORZTIMING_HPW_N(12)
| LCD_HORZTIMING_PPL_N(320) ),
.mode_verttiming =
( LCD_VERTTIMING_VN2_N(5)
| LCD_VERTTIMING_VN1_N(17)
| LCD_VERTTIMING_VPW_N(1)
| LCD_VERTTIMING_LPP_N(240) ),
.mode_clkcontrol = LCD_CLKCONTROL_PCD_N(1),
.mode_pwmdiv = 0,
.mode_pwmhi = 0,
.mode_toyclksrc =
((1<<7) | (1<<6) | (1<<5)),
.mode_backlight = 6
},
{ /* Hitachi SP14Q005 and possibly others */
.xres = 320,
.yres = 240,
.bpp = 4,
.panel_name = "Hitachi_SP14Qxxx",
.mode_control =
( LCD_CONTROL_C
| LCD_CONTROL_BPP_4 ),
.mode_horztiming =
( LCD_HORZTIMING_HN2_N(1)
| LCD_HORZTIMING_HN1_N(1)
| LCD_HORZTIMING_HPW_N(1)
| LCD_HORZTIMING_PPL_N(320) ),
.mode_verttiming =
( LCD_VERTTIMING_VN2_N(1)
| LCD_VERTTIMING_VN1_N(1)
| LCD_VERTTIMING_VPW_N(1)
| LCD_VERTTIMING_LPP_N(240) ),
.mode_clkcontrol = LCD_CLKCONTROL_PCD_N(4),
.mode_pwmdiv = 0,
.mode_pwmhi = 0,
.mode_toyclksrc =
((1<<27) | (1<<26) | (1<<25) | (1<<7) | (1<<6) | (1<<5)),
.mode_backlight = 6
},
{ /* Pb1100 LCDC 640x480 TFT panel */
.xres = 640,
.yres = 480,
.bpp = 16,
.panel_name = "Generic_640x480_16",
.mode_control = 0x004806a | LCD_DEFAULT_PIX_FORMAT,
.mode_horztiming = 0x3434d67f,
.mode_verttiming = 0x0e0e39df,
.mode_clkcontrol = LCD_CLKCONTROL_PCD_N(1),
.mode_pwmdiv = 0,
.mode_pwmhi = 0,
.mode_toyclksrc =
((1<<7) | (1<<6) | (0<<5)),
.mode_backlight = 7
},
{ /* Pb1100 LCDB 640x480 PrimeView TFT panel */
.xres = 640,
.yres = 480,
.bpp = 16,
.panel_name = "PrimeView_640x480_16",
.mode_control = 0x0004886a | LCD_DEFAULT_PIX_FORMAT,
.mode_horztiming = 0x0e4bfe7f,
.mode_verttiming = 0x210805df,
.mode_clkcontrol = 0x00038001,
.mode_pwmdiv = 0,
.mode_pwmhi = 0,
.mode_toyclksrc =
((1<<7) | (1<<6) | (0<<5)),
.mode_backlight = 7
},
{ /* Pb1100 800x600x16bpp NEON CRT */
.xres = 800,
.yres = 600,
.bpp = 16,
.panel_name = "NEON_800x600_16",
.mode_control = 0x0004886A | LCD_DEFAULT_PIX_FORMAT,
.mode_horztiming = 0x005AFF1F,
.mode_verttiming = 0x16000E57,
.mode_clkcontrol = 0x00020000,
.mode_pwmdiv = 0,
.mode_pwmhi = 0,
.mode_toyclksrc =
((1<<7) | (1<<6) | (0<<5)),
.mode_backlight = 7
},
{ /* Pb1100 640x480x16bpp NEON CRT */
.xres = 640,
.yres = 480,
.bpp = 16,
.panel_name = "NEON_640x480_16",
.mode_control = 0x0004886A | LCD_DEFAULT_PIX_FORMAT,
.mode_horztiming = 0x0052E27F,
.mode_verttiming = 0x18000DDF,
.mode_clkcontrol = 0x00020000,
.mode_pwmdiv = 0,
.mode_pwmhi = 0,
.mode_toyclksrc =
((1<<7) | (1<<6) | (0<<5)),
.mode_backlight = 7
},
#endif
};
#endif /* _AU1100LCD_H */
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2005-02-08 14:12 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-01-12 9:50 [PATCH] au1100fb.c ported from 2.4 to 2.6 Christian
2005-02-02 9:05 ` Ulrich Eckhardt
2005-02-04 9:56 ` Christian
2005-02-04 13:18 ` Ulrich Eckhardt
2005-02-08 14:14 ` Ulrich Eckhardt
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.