Re: [Linux-fbdev-devel] [PATCH] atmel_lcdfb: AT91/AT32 LCD Controller framebuffer driver
Hi Nicolas, > + info->fix.line_length = info->var.xres_virtual * > (info->var.bits_per_pixel / 8); line_length will always be 0 for bits_per_pixel < 8. Jan - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[Linux-fbdev-devel] [PATCH] atmel_lcdfb: AT91/AT32 LCD Controller framebuffer driver
From: Nicolas Ferre <[EMAIL PROTECTED]> Adds a framebuffer driver to ATMEL AT91SAM9x and AT32 aka AVR32 platforms. Those chips share quite the same IP and this code is suitable for both architectures. Signed-off-by: Nicolas Ferre <[EMAIL PROTECTED]> --- This second patch is rebuild following Antonio A. Daplas comments. Thank you Tony. The header file resides in an arch neutral directory. AT91 platform informations are directly submitted trough the at91 maintainer. drivers/video/Kconfig | 16 drivers/video/Makefile |1 drivers/video/atmel_lcdfb.c | 752 ++ include/video/atmel_lcdc.h | 196 4 files changed, 965 insertions(+) Index: b/include/video/atmel_lcdc.h === --- /dev/null +++ b/include/video/atmel_lcdc.h @@ -0,0 +1,196 @@ +/* + * Header file for AT91/AT32 LCD Controller + * + * Data structure and register user interface + * + * Copyright (C) 2007 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __ATMEL_LCDC_H__ +#define __ATMEL_LCDC_H__ + + /* LCD Controller info data structure */ +struct atmel_lcdfb_info { + spinlock_t lock; + struct fb_info *info; + void __iomem*mmio; + unsigned long irq_base; + + unsigned intguard_time; + struct platform_device *pdev; + struct clk *bus_clk; + struct clk *lcdc_clk; + unsigned intdefault_bpp; + unsigned intdefault_lcdcon2; + unsigned intdefault_dmacon; + void (*atmel_lcdfb_power_control)(int on); + struct fb_monspecs *default_monspecs; + u32 pseudo_palette[16]; +}; + +#define ATMEL_LCDC_DMABADDR1 0x00 +#define ATMEL_LCDC_DMABADDR2 0x04 +#define ATMEL_LCDC_DMAFRMPT1 0x08 +#define ATMEL_LCDC_DMAFRMPT2 0x0c +#define ATMEL_LCDC_DMAFRMADD1 0x10 +#define ATMEL_LCDC_DMAFRMADD2 0x14 + +#define ATMEL_LCDC_DMAFRMCFG 0x18 +#defineATMEL_LCDC_FRSIZE (0x7f << 0) +#defineATMEL_LCDC_BLENGTH_OFFSET 24 +#defineATMEL_LCDC_BLENGTH (0x7f << ATMEL_LCDC_BLENGTH_OFFSET) + +#define ATMEL_LCDC_DMACON 0x1c +#defineATMEL_LCDC_DMAEN(0x1 << 0) +#defineATMEL_LCDC_DMARST (0x1 << 1) +#defineATMEL_LCDC_DMABUSY (0x1 << 2) +#defineATMEL_LCDC_DMAUPDT (0x1 << 3) +#defineATMEL_LCDC_DMA2DEN (0x1 << 4) + +#define ATMEL_LCDC_DMA2DCFG0x20 +#defineATMEL_LCDC_ADDRINC_OFFSET 0 +#defineATMEL_LCDC_ADDRINC (0x) +#defineATMEL_LCDC_PIXELOFF_OFFSET 24 +#defineATMEL_LCDC_PIXELOFF (0x1f << 24) + +#define ATMEL_LCDC_LCDCON1 0x0800 +#defineATMEL_LCDC_BYPASS (1 << 0) +#defineATMEL_LCDC_CLKVAL_OFFSET12 +#defineATMEL_LCDC_CLKVAL (0x1ff << ATMEL_LCDC_CLKVAL_OFFSET) +#defineATMEL_LCDC_LINCNT (0x7ff << 21) + +#define ATMEL_LCDC_LCDCON2 0x0804 +#defineATMEL_LCDC_DISTYPE (3 << 0) +#defineATMEL_LCDC_DISTYPE_STNMONO (0 << 0) +#defineATMEL_LCDC_DISTYPE_STNCOLOR (1 << 0) +#defineATMEL_LCDC_DISTYPE_TFT (2 << 0) +#defineATMEL_LCDC_SCANMOD (1 << 2) +#defineATMEL_LCDC_SCANMOD_SINGLE (0 << 2) +#defineATMEL_LCDC_SCANMOD_DUAL (1 << 2) +#defineATMEL_LCDC_IFWIDTH (3 << 3) +#defineATMEL_LCDC_IFWIDTH_4(0 << 3) +#defineATMEL_LCDC_IFWIDTH_8(1 << 3) +#defineATMEL_LCDC_IFWIDTH_16 (2 << 3) +#defineATMEL_LCDC_PIXELSIZE(7 << 5) +#defineATMEL_LCDC_PIXELSIZE_1 (0 << 5) +#defineATMEL_LCDC_PIXELSIZE_2 (1 << 5) +#defineATMEL_LCDC_PIXELSIZE_4 (2 << 5) +#defineATMEL_LCDC_PIXELSIZE_8 (3 << 5) +#defineATMEL_LCDC_PIXELSIZE_16 (4 << 5) +#defineATMEL_LCDC_PIXELSIZE_24 (5 << 5) +#define
Re: [Linux-fbdev-devel] [PATCH] atmel_lcdfb: AT91/AT32 LCD Controller framebuffer driver
Hi Antonio, Thanks for the feedback. I'm just going to reply to one of your comments and leave the rest for Nicolas... On Tue, 08 May 2007 05:40:17 +0800 "Antonino A. Daplas" <[EMAIL PROTECTED]> wrote: > > +static int __init atmel_lcdfb_init(void) > > +{ > > + return platform_driver_probe(&atmel_lcdfb_driver, atmel_lcdfb_probe); > > +} > > Is this intentional? Why not platform_driver_register()? Yes, it's intentional. This way, the atmel_lcdfb_probe function can be __init since it doesn't need to be referenced from atmel_lcdfb_driver. Saves a bit of memory at run time. The downside is that hot plugging won't work, but that isn't very relevant for on-chip devices anyway. Haavard - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [Linux-fbdev-devel] [PATCH] atmel_lcdfb: AT91/AT32 LCD Controller framebuffer driver
On Mon, 2007-05-07 at 16:11 +0200, Nicolas Ferre wrote: > From: Nicolas Ferre <[EMAIL PROTECTED]> > > Adds a framebuffer driver to ATMEL AT91SAM9x and AT32 > aka AVR32 platforms. Those chips share quite the same > IP and this code is suitable for both architectures. > > Signed-off-by: Nicolas Ferre <[EMAIL PROTECTED]> > --- > > +#if defined(CONFIG_ARCH_AT91) > +#define ATMEL_LCDFB_FBINFO_DEFAULT FBINFO_DEFAULT > + > +static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo, > + struct fb_var_screeninfo *var) > +{ > + > +} Or #define atmel_lcdfb_update(...) do {} while (0) ? > + > +static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = { > + .type = FB_TYPE_PACKED_PIXELS, > + .visual = FB_VISUAL_TRUECOLOR, > + .xpanstep = 0, > + .ypanstep = 0, > + .ywrapstep = 0, > + .accel = FB_ACCEL_NONE, > +}; > + This driver has fb_pan_display() which I assume works. However, you also need to set ypanstep and/or xpanstep and/or ywrapstep to a nonzero value, depending on the hardware/drive capability. > +static u32 pseudo_palette[16] = { > + 0x00, > + 0xaa, > + 0x00aa00, > + 0xaa5500, > + 0xaa, > + 0xaa00aa, > + 0x00, > + 0xaa, > + 0x55, > + 0xff, > + 0x55ff55, > + 0x55, > + 0xff, > + 0xff55ff, > + 0x55, > + 0xff > +}; > + Do you really need to pre-fill pseudo_palette[]? The contents are going to be overwritten by the console anyway (The pseudo_palette is for fbcon's use only). You can also include pseudo_palette[] as part of struct atmel_lcdfb_info, then in your probe routine: info->pseudo_palette = par->pseudo_palette; to reduce the size of the kernel image. > + > +static inline u_int chan_to_field(u_int chan, const struct fb_bitfield *bf) Might as well change u_int to u32 or unsigned int, for consistency. > +{ > + chan &= 0x; > + chan >>= 16 - bf->length; > + return chan << bf->offset; > +} > + > + > + > + > +static int __init atmel_lcdfb_init_fbinfo(struct atmel_lcdfb_info *sinfo) > +{ > + struct fb_info *info = sinfo->info; > + int ret = 0; > + > + memset(info->screen_base, 0, info->fix.smem_len); memset_io? > + info->var.activate |= FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW; > + > + dev_info(info->device, > +"%luKiB frame buffer at %08lx (mapped at %p)\n", > +(unsigned long)info->fix.smem_len / 1024, > +(unsigned long)info->fix.smem_start, > +info->screen_base); > + > + /* Allocate colormap */ > + ret = fb_alloc_cmap(&info->cmap, 256, 0); > + if (ret < 0) > + dev_err(info->device, "Alloc color map failed\n"); > + > + return ret; > +} > + > + > + > +static int __init atmel_lcdfb_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct fb_info *info; > + struct atmel_lcdfb_info *sinfo; > + struct atmel_lcdfb_info *pdata_sinfo; > + struct resource *regs = NULL; > + struct resource *map = NULL; > + int ret; > + > + dev_dbg(dev, "%s BEGIN\n", __func__); > + > + ret = -ENOMEM; > + info = framebuffer_alloc(sizeof(struct atmel_lcdfb_info), dev); > + if (!info) { > + dev_err(dev, "cannot allocate memory\n"); > + goto out; > + } > + > + sinfo = info->par; > + > + if (dev->platform_data) { > + pdata_sinfo = (struct atmel_lcdfb_info *)dev->platform_data; > + sinfo->default_bpp = pdata_sinfo->default_bpp; > + sinfo->default_dmacon = pdata_sinfo->default_dmacon; > + sinfo->default_lcdcon2 = pdata_sinfo->default_lcdcon2; > + sinfo->default_monspecs = pdata_sinfo->default_monspecs; > + sinfo->atmel_lcdfb_power_control = > pdata_sinfo->atmel_lcdfb_power_control; > + sinfo->guard_time = pdata_sinfo->guard_time; > + } else { > + dev_err(dev, "cannot get default configuration\n"); > + goto out; Wrong goto? Should be goto free_info? > + > +free_cmap: > + fb_dealloc_cmap(&info->cmap); > +unregister_irqs: > + free_irq(sinfo->irq_base, info); > +unmap_mmio: > + iounmap(sinfo->mmio); > +release_mem: > + release_mem_region(info->fix.mmio_start, info->fix.mmio_len); > +free_fb: > + if (map) { > + iounmap(info->screen_base); > + } else { > + atmel_lcdfb_free_video_memory(sinfo); > + } > + > +release_intmem: > + if (map) { > + release_mem_region(info->fix.smem_start, info->fix.smem_len); > + } Unnecessary curly braces > + > +static struct platform_driver atmel_lcdfb_driver = { > + .remove = __exit_p(atmel_lcdfb_remove), > + .driver = { > + .name = "atmel_lcdfb", > + .owner = THIS_MODULE, > + }, > +}; > + > +static int __init