You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(8) |
Nov
(9) |
Dec
(3) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(12) |
Feb
(10) |
Mar
|
Apr
(5) |
May
(3) |
Jun
|
Jul
(5) |
Aug
(7) |
Sep
(15) |
Oct
(4) |
Nov
(3) |
Dec
(7) |
2003 |
Jan
(5) |
Feb
(30) |
Mar
(5) |
Apr
(13) |
May
(12) |
Jun
(11) |
Jul
(1) |
Aug
(7) |
Sep
(2) |
Oct
|
Nov
(2) |
Dec
(7) |
2004 |
Jan
(4) |
Feb
(9) |
Mar
(16) |
Apr
(42) |
May
(5) |
Jun
(11) |
Jul
(3) |
Aug
(39) |
Sep
(5) |
Oct
(32) |
Nov
(27) |
Dec
|
2005 |
Jan
(11) |
Feb
(8) |
Mar
(22) |
Apr
(26) |
May
(9) |
Jun
(10) |
Jul
(7) |
Aug
(43) |
Sep
(23) |
Oct
(18) |
Nov
(15) |
Dec
(15) |
2006 |
Jan
(7) |
Feb
(16) |
Mar
(10) |
Apr
(1) |
May
(16) |
Jun
(8) |
Jul
(3) |
Aug
(35) |
Sep
(7) |
Oct
(4) |
Nov
(5) |
Dec
(1) |
2007 |
Jan
(2) |
Feb
(30) |
Mar
(6) |
Apr
(7) |
May
(5) |
Jun
|
Jul
(15) |
Aug
(12) |
Sep
(22) |
Oct
(48) |
Nov
(9) |
Dec
(7) |
2008 |
Jan
(3) |
Feb
(1) |
Mar
(1) |
Apr
|
May
(4) |
Jun
(1) |
Jul
(5) |
Aug
(4) |
Sep
(4) |
Oct
(2) |
Nov
(5) |
Dec
(1) |
2009 |
Jan
(3) |
Feb
|
Mar
|
Apr
(4) |
May
(2) |
Jun
(2) |
Jul
|
Aug
(1) |
Sep
(3) |
Oct
(2) |
Nov
(2) |
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(2) |
Dec
|
2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
From: <lyn...@fr...> - 2006-03-13 07:25:52
|
Hallo! I posted before the wish of 1280x1024 resolution of my external TFT-monitor to this list. It seems not to be possible but incidentally I found out that 1400x1050 mode is possible. It is not the native resolution of the TFT but better than 1024x768. I can change the width to fit to the screen but I can't change the hight, so I have a 1050-1024=26 rows of pixels I can't see. Is there a way to change that? (How can I prevent drawing below 1024?) It would even help, if I could make the kernel switch to a console with 175x64 and not 65 rows. Is there a way to pass the number or rows to the kernel before booting? (arch/i386/boot/video.S seems to deal with something like that, but I couldn't find the kernel-parameter that changes it). Any help and hint appreciated Thanks a lot Lynx |
From: Ritesh R. S. <rr...@re...> - 2006-03-02 18:51:47
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Rajinder paul on Thursday 02 Mar 2006 16:09 wrote: > Hi > i am having a problem: how to use two virtual framebuffer devices > /dev/fb0, /dev/fb1 at the same time. > mplayer is running by default on /dev/fb1 and it disable /dev/fb0. > but my application form written in QT is using /dev/fb0. > when mplayer is running the movie,i want to show a qt form on the movie. > but mplayer disbles /dev/fb0 so form is not being shown on the movie. > I am looking forward for your response. > I guess that it's more of a problem with mplayer than linuxfb. rrs - -- Ritesh Raj Sarraf RESEARCHUT -- http://www.researchut.com "Stealing logic from one person is plagiarism, stealing from many is research." "Necessity is the mother of invention." -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (GNU/Linux) iD8DBQFEBzby4Rhi6gTxMLwRAm7tAKCSzrartDDDXqFKSlaUxtedjlmtugCfaDND 7SckL6gS2WyRgN+NwdOYLFE= =SkuN -----END PGP SIGNATURE----- |
From: Rajinder p. <pau...@ne...> - 2006-03-02 10:38:19
|
Hi i am having a problem: how to use two virtual framebuffer devices /dev/fb0, /dev/fb1 at the same time. mplayer is running by default on /dev/fb1 and it disable /dev/fb0. but my application form written in QT is using /dev/fb0. when mplayer is running the movie,i want to show a qt form on the movie. but mplayer disbles /dev/fb0 so form is not being shown on the movie. I am looking forward for your response. Thanks & Regards Rajinder Paul |
From: <fb...@co...> - 2006-02-27 21:32:58
|
Hi all, This is a patch submission I'm making for my framebuffer Enhanced functionality module, whose purpose is to expand the range of graphics capabilities available within the kernel, and later available to userspace via my FBUI project (fbui.org). I also plan to use Enhanced to support an anti-aliased console font feature sometime in the near future. The generic graphics routines that I've written are taken from FBUI and are therefore written for use with vesafb; but they should work with other drivers. I've done this as a "diff -Naur" patch to kernel 2.6.15.4. If you need something else let me know. I've also placed the patch here: http://home.comcast.net/~fbui/Enhanced_0.txt Zack T. Smith diff -Naur linux-2.6.15.4-original/drivers/video/Kconfig linux-2.6.15.4/drivers/video/Kconfig --- linux-2.6.15.4-original/drivers/video/Kconfig 2006-02-10 07:22:48.000000000 +0000 +++ linux-2.6.15.4/drivers/video/Kconfig 2006-02-26 12:15:19.000000000 +0000 @@ -38,6 +38,64 @@ (e.g. an accelerated X server) and that are not frame buffer device-aware may cause unexpected results. If unsure, say N. +config FB_ENHANCED + tristate "Enhanced Functionality for a generic framebuffer" + depends on FB + default y + ---help--- + Enhanced Functionality is a compact and robust set of routines + derived from the FramebufferUI project (see http://fbui.org). + + They implement: + + drawing routines that are clippable and + which support pixel-level transparency (alpha blending) + - line draw + - rectangle fill + - triangle fill + + robust and optimized clippable image blit from userspace + and kernel memory, supporting images of these types: + - opaque 16, 24, 32 bpp + - 1 bpp bitmap + - 8 bit alpha with foreground color + + robust copy area, also clippable, supporting + up, down, left and right directions, currently + supporting 16/24/32 bpp. + + In future, this code will be used to permit anti-aliased + console fonts and will be necessary for the next FramebufferUI. + + Enhanced Functionality provides the paradigm for future + hardware-based accelerated versions of the functionality + it provides. + +config FB_ENHANCED_32BPP + bool "Support 32 bits per pixel drawing" + depends on FB_ENHANCED + default n + help + 32bpp (8 red, 8 green, 8 blue). This offers + good color realism however it is often slower + than 16bpp. + +config FB_ENHANCED_24BPP + bool "Support 24 bits per pixel drawing" + depends on FB_ENHANCED + default n + help + 24bpp drawing. It's memory-efficient but + in VESA it will probably always be slower + than either 16bpp or 32bpp. + +config FB_ENHANCED_16BPP + bool "Support 16 bits per pixel drawing" + depends on FB_ENHANCED + default y + help + 16bpp mode uses 5 bits for red, 6 for green, + and 5 for blue. In VESA mode, this depth + is sometimes twice as fast as 32bpp, other + times slower. + config FB_CFB_FILLRECT tristate depends on FB diff -Naur linux-2.6.15.4-original/drivers/video/Makefile linux-2.6.15.4/drivers/video/Makefile --- linux-2.6.15.4-original/drivers/video/Makefile 2006-02-10 07:22:48.000000000 +0000 +++ linux-2.6.15.4/drivers/video/Makefile 2006-02-24 12:59:50.000000000 +0000 @@ -13,6 +13,8 @@ modedb.o fbcvt.o fb-objs := $(fb-y) +obj-$(CONFIG_FB_ENHANCED) += fb_enhanced.o + obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o diff -Naur linux-2.6.15.4-original/drivers/video/fb_enhanced.c linux-2.6.15.4/drivers/video/fb_enhanced.c --- linux-2.6.15.4-original/drivers/video/fb_enhanced.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.15.4/drivers/video/fb_enhanced.c 2006-02-24 12:56:40.000000000 +0000 @@ -0,0 +1,3086 @@ +/* Framebuffer Enhanced Functionality + * + * Copyright (C) 2004-2006 Zack T Smith, fb...@co.... + * + * This code is derived from my FBUI project; see fbui.org. + * This code is covered by the GNU Public License and is provided AS-IS + * with no warranty or guarantee of any kind in any respect. + * + * It provides much, in a small space. Specifically: + * + * (1) a paradigm for more robust use of graphics hardware, involving + * + clippability + * + alpha blending + * + image blit for several useful image types + * + line draw + * + triangle fill + * + robust copyarea + * + * (2) generic routines to implement these features for + * 16/24/32bpp framebuffers, such as VESA. + * + * Still to do list: + * - offscreen drawing + * - offscreen to onscreen copy + * - overlay support + * - reimplementation of my former alpha+foreground drawing + * - alpha image blit + * - video RAM allocation, deallocation, mapping, unmapping + * - PCI-burst fillrect + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/fb.h> +#include <linux/tty.h> +#include <linux/console.h> +#include <linux/ctype.h> +#include <asm/types.h> +#include <asm/uaccess.h> + + + +/*----------------------------------------------------------------------------- + * Change log: + * 05 Sep 2005, fb...@co...: removed 8bpp code. + * 05 Sep 2005, fb...@co...: transparent hline speedup. + * 10 Sep 2005, fb...@co...: merged point/hline/vline/fillrect. + * 12 Sep 2005, fb...@co...: optimized right/leftward copyarea. + * 12 Sep 2005, fb...@co...: optimized 32bpp image draw RGB4. + * 12 Sep 2005, fb...@co...: optimized 32bpp image draw RGB3. + * 12 Sep 2005, fb...@co...: optimized 32bpp image draw RGB2. + * 12 Sep 2005, fb...@co...: optimized 32bpp image draw GREY. + * 12 Sep 2005, fb...@co...: optimized 32bpp opaque fillrect. + * 12 Sep 2005, fb...@co...: optimized 24bpp opaque fillrect. + * 13 Sep 2005, fb...@co...: unrolled loops for further speed-up. + * 17 Sep 2005, fb...@co...: putimage optimizations using memcpy_toio. + * 18 Sep 2005, fb...@co...: copyarea optimizations using memcpy_to/fromio. + * 20 Sep 2005, fb...@co...: added 1bpp monochrome putimage. + * 22 Sep 2005, fb...@co...: reimplemented fb_enh_line for speedup. + * 22 Sep 2005, fb...@co...: speed up of mono putimage by 52%. + * 02 Oct 2005, fb...@co...: 24bpp improvements & speedups. + * 31 Dec 2005, fb...@co...: created Advanced Functionality from fbui code. + *----------------------------------------------------------------------------- + */ + +#ifdef CONFIG_FB_ENHANCED + +u32 fb_pixel_from_rgb (struct fb_info *info, u32 value) +{ + u32 r,g,b; + unsigned long tmp; + unsigned long pixel; + + value &= 0xffffff; +#ifdef CONFIG_FB_UI + if (info->mode24) + return value; + if (info->mode565) { + return ((value >> 8) & 0xf800) | + ((value >> 5) & 0x7e0) | + ((value >> 3) & 31); + } + if (info->mode555) { + return ((value >> 9) & 0x7c00) | + ((value >> 6) & 0x3e0) | + ((value >> 3) & 31); + } +#endif + + tmp = 0xff; + b = tmp & value; + value >>= 8; + g = tmp & value; + value >>= 8; + r = tmp & value; + tmp = 8; + r >>= (tmp - info->var.red.length); + g >>= (tmp - info->var.green.length); + b >>= (tmp - info->var.blue.length); + r <<= info->var.red.offset; + g <<= info->var.green.offset; + b <<= info->var.blue.offset; + pixel = r | g | b; + return pixel; +} + + +u32 fb_pixel_to_rgb (struct fb_info *info, u32 value) +{ + u32 r,g,b; + unsigned char tmp = 8; + +#ifdef CONFIG_FB_UI + if (info->mode24) + return value & 0xffffff; + if (info->mode565) { + return ((value << 8) & 0xf80000) | + ((value << 5) & 0xfc00) | + ((value << 3) & 0xf8); + } + if (info->mode555) { + return ((value << 9) & 0xf80000) | + ((value << 6) & 0xf800) | + ((value << 3) & 0xf8); + } +#endif + + r = value >> info->var.red.offset; + g = value >> info->var.green.offset; + b = value >> info->var.blue.offset; + r &= (1 << info->var.red.length) - 1; + b &= (1 << info->var.blue.length) - 1; + g &= (1 << info->var.green.length) - 1; + r <<= (tmp - info->var.red.length); + g <<= (tmp - info->var.green.length); + b <<= (tmp - info->var.blue.length); + r <<= 16; + g <<= 8; + return r | g | b; +} + + +/* This routine combines two pixels based on an 8-bit alpha. + */ +inline u32 fb_combine_rgb_pixels (u32 orig_value, u32 value, u32 transp) +{ + u32 r,g,b; + u32 t; + register u32 m = 255; + transp &= 255; + t = m - transp; + r = transp * (m & (orig_value>>16)) + t * (m & (value>>16)); + g = transp * (m & (orig_value>>8)) + t * (m & (value>>8)); + b = transp * (m & orig_value) + t * (m & value); + r >>= 8; + g >>= 8; + b >>= 8; + value = (r<<16) | (g<<8) | b; + return value; +} + + +#ifdef CONFIG_FB_ENHANCED_32BPP +/* Optimized function to put opaque image data to a 32bpp display. + */ +static void fb_enh_putimage_opaque32 (struct fb_info *info, struct fb_put *p) +{ + int i, j; + u32 offset; + short xres, yres; + short width, height; + short x0, y0; + u8 src_bytes_per_pixel; + u32 *dest, *dest_save; + u8 *src0; + short stride; + short x1, y1; + short xstart,xend,ystart,yend; + + if (!info || !p) + return; + + xstart = p->xstart; + xend = p->xend; + if (xstart > xend) { + short tmp = xstart; + xstart = xend; + xend = tmp; + } + ystart = p->ystart; + yend = p->yend; + if (ystart > yend) { + short tmp = ystart; + ystart = yend; + yend = tmp; + } + if (xend < 0 || yend < 0 || xstart >= p->width || ystart >= p->height) + return; + if (xstart < 0) + xstart = 0; + if (ystart < 0) + ystart = 0; + if (xend >= p->width) + xend = p->width - 1; + if (yend >= p->height) + yend = p->height - 1; + + src0 = p->pixels; + xres = info->var.xres; + yres = info->var.yres; + width = p->xend - p->xstart + 1; + height = p->yend - p->ystart + 1; + x0 = p->x0 + xstart; + y0 = p->y0 + ystart; + x1 = p->x0 + xend; + y1 = p->y0 + yend; + stride = p->width; + + switch (p->type) { + case FB_IMAGETYPE_ALPHA: + src_bytes_per_pixel = 1; + break; + case FB_IMAGETYPE_GREY: + src_bytes_per_pixel = 1; + break; + case FB_IMAGETYPE_RGB2: + src_bytes_per_pixel = 2; + break; + case FB_IMAGETYPE_RGB3: + src_bytes_per_pixel = 3; + break; + case FB_IMAGETYPE_RGB4: + src_bytes_per_pixel = 4; + break; + default: + return; + } + + if (!src0 || width <= 0 || height <= 0 || + x1 < 0 || y1 < 0 || x0 >= xres || y0 >= yres || + stride <= 0) + return; + src0 += src_bytes_per_pixel * (stride * ystart + xstart); + if (x0 < 0) { + x0 = -x0; + width -= x0; + src0 += x0 * src_bytes_per_pixel; + x0 = 0; + } + if (x1 >= xres) { + short diff = x1 - xres + 1; + width -= diff; + x1 = xres - 1; + } + if (y0 < 0) { + y0 = -y0; + height -= y0; + src0 += y0 * stride * src_bytes_per_pixel; + y0 = 0; + } + if (y1 >= yres) { + short diff = y1 - yres + 1; + height -= diff; + y1 = yres - 1; + } + + if (p->clip_valid) { + if (y0 > p->clip_y1 || x0 > p->clip_x1 || + y1 < p->clip_y0 || x1 < p->clip_x0) + return; + if (x0 < p->clip_x0) { + short diff = p->clip_x0 - x0; + width -= diff; + src0 += diff * src_bytes_per_pixel; + x0 = p->clip_x0; + } + if (x1 > p->clip_x1) { + short diff = x1 - p->clip_x1; + width -= diff; + } + if (y0 < p->clip_y0) { + short diff = p->clip_y0 - y0; + height -= diff; + src0 += diff * stride * src_bytes_per_pixel; + y0 = p->clip_y0; + } + if (y1 > p->clip_y1) { + short diff = y1 - p->clip_y1; + height -= diff; + } + } + /*----------*/ + + dest = (u32*) info->screen_base; + offset = y0 * (info->fix.line_length>>2) + x0; + dest += offset; + dest_save = dest; + + switch (p->type) { + case FB_IMAGETYPE_RGB4: { + u32 *src, *src_save; + u32 *buffer; +#define BUFSIZE32 4096 + + /* What is needed is a function to transfer from memory chunks + * directly from userspace to memory mapped I/O. Without that, + * gotta kmalloc. + */ + buffer = kmalloc(BUFSIZE32, GFP_KERNEL); + if (!buffer) { + printk(KERN_INFO "fb_enh_putimage_opaque32: no memory\n"); + return; + } + + src = (u32*) src0; + src_save = src; + + j = height; + while (j-- > 0) { + i = width; + while (i > 0) { + u32 pixels = i > (BUFSIZE32/4) ? (BUFSIZE32/4) : i; + u32 bytes = pixels << 2; + + /* Data -> L2 cache */ + if (copy_from_user((u8*)buffer,(u8*)src, bytes)) + goto dealloc; + src += pixels; + + /* L2 cache -> VRAM */ + memcpy_toio ((u8*)dest, (u8*)buffer, bytes); + dest += pixels; + i -= pixels; + } + src_save += stride; + src = src_save; + dest_save += (info->fix.line_length>>2); + dest = dest_save; + } + +dealloc: + if (buffer) + kfree (buffer); + } + break; + + case FB_IMAGETYPE_RGB3: { + u8 *src = (u8*) src0, *src_save; + src_save = src; + + j = height; + while (j-- > 0) { + u32 value; + i = width; + while (i > 0) { +#if 0 + if (!(3 & (u32)src)) { + if (get_user(value, ((u32*)src))) + return; + value &= 0xffffff; + } else { +#endif + u8 tmp; + src += 2; + if (get_user(tmp, src)) /* red << 16 */ + return; + value = tmp; + value <<= 8; + src--; + if (get_user(tmp, src)) /* green << 8 */ + return; + value |= tmp; + value <<= 8; + src--; + if (get_user(tmp, src)) /* blue << 0 */ + return; + value |= tmp; + //} + src += 3; + + fb_writel (value, dest); + dest++; + i--; + } + src_save += stride * 3; + src = src_save; + dest_save += (info->fix.line_length>>2); + dest = dest_save; + } + } + break; + + case FB_IMAGETYPE_RGB2: { + u16 *src, *src_save; + src = (u16*) src0; + src_save = src; + + j = height; + while (j-- > 0) { + u32 value,value2; + i = width; + while (i > 0) { + u32 tmp; + if (i >= 2) { + if (get_user(tmp, ((u32*)src))) + return; + value = ((tmp << 8) & 0xf80000) | + ((tmp << 5) & 0xfc00) | + ((tmp << 3) & 0xf8); + value2 = ((tmp >> 8) & 0xf80000) | + ((tmp >> 11) & 0xfc00) | + ((tmp >> 13) & 0xf8); + src += 2; + fb_writel (value, dest); dest++; + fb_writel (value2, dest); dest++; + i -= 2; + } else { + if (get_user(tmp, src)) + return; + value = ((tmp << 8) & 0xf80000) | + ((tmp << 5) & 0xfc00) | + ((tmp << 3) & 0xf8); + src++; + fb_writel (value, dest); + dest++; + i--; + } + } + src_save += stride; + src = src_save; + dest_save += (info->fix.line_length>>2); + dest = dest_save; + } + } + break; + + case FB_IMAGETYPE_GREY: { + u8 *src, *src_save; + src = src0; + src_save = src; + + j = height; + while (j-- > 0) { + i = width; + while (i > 0) { + if (!(3 & (u32)src) && i >= 4) { + u32 *s = (u32*) src; + u32 value, value2; + if (get_user(value, s)) + return; + src += 4; + i -= 4; + + value2 = value & 0xff; + value2 |= (value2<<8) | (value2<<16); + value >>= 8; + fb_writel (value2, dest); + dest++; + + value2 = value & 0xff; + value2 |= (value2<<8) | (value2<<16); + value >>= 8; + fb_writel (value2, dest); + dest++; + + value2 = value & 0xff; + value2 |= (value2<<8) | (value2<<16); + value >>= 8; + fb_writel (value2, dest); + dest++; + + value2 = value & 0xff; + value2 |= (value2<<8) | (value2<<16); + fb_writel (value2, dest); + dest++; + } else { + u32 value; + if (get_user(value, src)) + return; + value &= 0xff; + value |= (value<<8) | (value<<16); + src++; + fb_writel (value, dest); + dest++; + i--; + } + } + src_save += stride; + src = src_save; + dest_save += (info->fix.line_length>>2); + dest = dest_save; + } + } + break; + } + +} +#endif + + + +/* Optimized function to put monochrome image. 1's put color, 0's put nothing. + */ +static void fb_enh_putimage_mono (struct fb_info *info, struct fb_put *p) +{ + int i,j; + u32 offset; + short xres, yres; + short width, height; + short x0, y0; + u8 *src0; + u8 *src, *src_save; + short stride; + short x1, y1; + short xstart, xend, ystart, yend; + u8 ix0; + + if (!info || !p) + return; + if (p->type != FB_IMAGETYPE_MONO) + return; + xstart = p->xstart; + xend = p->xend; + if (xstart > xend) { + short tmp = xstart; + xstart = xend; + xend = tmp; + } + ystart = p->ystart; + yend = p->yend; + if (ystart > yend) { + short tmp = ystart; + ystart = yend; + yend = tmp; + } + if (xend < 0 || yend < 0 || xstart >= p->width || ystart >= p->height) + return; + if (xstart < 0) + xstart = 0; + if (ystart < 0) + ystart = 0; + if (xend >= p->width) + xend = p->width - 1; + if (yend >= p->height) + yend = p->height - 1; + xres = info->var.xres; + yres = info->var.yres; + width = xend - xstart + 1; + height = yend - ystart + 1; + x0 = p->x0 + xstart; + y0 = p->y0 + ystart; + x1 = p->x0 + xend; + y1 = p->y0 + yend; + stride = p->width; + src0 = p->pixels; + + if (!src0 || width <= 0 || height <= 0 || + x1 < 0 || y1 < 0 || x0 >= xres || y0 >= yres || + stride <= 0) + return; + if (x0 < 0) { + x0 = -x0; + width -= x0; + xstart += x0; + x0 = 0; + } + if (x1 >= xres) { + short diff = x1 - xres + 1; + width -= diff; + x1 = xres - 1; + xend -= diff; + } + if (y0 < 0) { + y0 = -y0; + height -= y0; + ystart += y0; + y0 = 0; + } + if (y1 >= yres) { + short diff = y1 - yres + 1; + height -= diff; + y1 = yres - 1; + yend -= diff; + } + + if (p->clip_valid) { + if (y0 > p->clip_y1 || x0 > p->clip_x1 || + y1 < p->clip_y0 || x1 < p->clip_x0) + return; + if (x0 < p->clip_x0) { + short diff = p->clip_x0 - x0; + width -= diff; + x0 = p->clip_x0; + xstart += diff; + } + if (x1 > p->clip_x1) { + short diff = x1 - p->clip_x1; + width -= diff; + xend -= diff; + } + if (y0 < p->clip_y0) { + short diff = p->clip_y0 - y0; + height -= diff; + y0 = p->clip_y0; + ystart += diff; + } + if (y1 > p->clip_y1) { + short diff = y1 - p->clip_y1; + height -= diff; + yend -= diff; + } + } + /*----------*/ + + switch ((info->var.bits_per_pixel + 7) >> 3) { +#ifdef CONFIG_FB_ENHANCED_32BPP + case 4: { + u32 *dest, *dest_save; + dest = (u32*) info->screen_base; + offset = y0 * (info->fix.line_length>>2) + x0; + dest += offset; + dest_save = dest; + + src0 += ((stride+7)>>3) * ystart + (xstart>>3); + ix0 = xstart & 7; + + src = src0; + src_save = src; + + j = height; + while (j-- > 0) { + u8 k = 1 << ix0; + i = width; + + while (i > 0) { + if (i >= 32 && !(3 & (u32)src)) { + /* 52% faster using this code. + */ + register u32 k2, value, *s=(u32*)src; + register u32 *d = dest; + register u32 c = p->color; + if (get_user(value, s)) + return; + src += 4; + + k2 = k; + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + if (k2 & value) fb_writel (c, d); + k2 <<= 1; d++; + + dest = d; + k = 1; + i-=32; + } else { + register u8 value; + register u32 c = p->color, *s=(u32*)src; + if (get_user(value, s)) + return; + src++; + + while (i > 0 && k) { + if (k & value) + fb_writel (c, dest); + dest++; + k <<= 1; + i--; + } + + k = 1; + } + } + src_save += (stride+7)>>3; + src = src_save; + dest_save += (info->fix.line_length>>2); + dest = dest_save; + } + break; + } +#endif + +#ifdef CONFIG_FB_ENHANCED_24BPP + case 3: { + u8 *dest, *dest_save; + dest = info->screen_base; + offset = y0 * info->fix.line_length + x0*3; + dest += offset; + dest_save = dest; + + src0 += ((stride+7)>>3) * ystart + (xstart>>3); + ix0 = xstart & 7; + + src = src0; + src_save = src; + + j = height; + while (j-- > 0) { + u8 k = 1 << ix0; + u32 c = p->color; + + i = width; + while (i > 0) { + if (i >= 32 && k == 1) { + register u32 k2 = k; + register u32 value, *s; + register u8 *d2 = dest; + register u8 r, g; + g = c>>8; + r = c>>16; + s = (u32*) src; + + if (get_user(value, s)) + return; + src += 4; + + while (k2) { + if (k2 & value) { + fb_writeb (c, d2); + fb_writeb (g, (1+d2)); + fb_writeb (r, (2+d2)); + } + d2 += 3; + k2 <<= 1; + } + + dest += 96; + i -= 32; + } else { + u8 value; + u32 c = p->color; + register u8 r, g; + g = c>>8; + r = c>>16; + + if (get_user(value, src)) + return; + src++; + + while (i > 0 && k) { + if (k & value) { + fb_writeb (c, dest); + fb_writeb (g, (1+dest)); + fb_writeb (r, (2+dest)); + } + dest += 3; + k <<= 1; + i--; + } + } + k = 1; + } + + src_save += (stride+7)>>3; + src = src_save; + dest_save += info->fix.line_length; + dest = dest_save; + } + break; + } +#endif + +#ifdef CONFIG_FB_ENHANCED_16BPP + case 2: { + u16 *dest, *dest_save; + u16 pixel; + dest = (u16*) info->screen_base; + offset = y0 * (info->fix.line_length>>1) + x0; + dest += offset; + dest_save = dest; + + src0 += ((stride+7)>>3) * ystart + (xstart>>3); + ix0 = xstart & 7; + + pixel = fb_pixel_from_rgb (info, p->color); + + src = src0; + src_save = src; + + j = height; + while (j-- > 0) { + u8 k = 1 << ix0; + i = width; + + while (i > 0) { + if (i >= 16 && !(3 & (u32)src)) { + register u16 k2, value, *s=(u16*)src; + register u16 *d = dest; + register u16 c = pixel; + if (get_user(value, s)) + return; + src += 2; + k2 = k; + + if (k2 & value) fb_writew (c, d); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+1)); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+2)); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+3)); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+4)); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+5)); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+6)); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+7)); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+8)); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+9)); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+10)); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+11)); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+12)); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+13)); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+14)); + k2 <<= 1; + + if (k2 & value) fb_writew (c, (d+15)); + + dest += 16; + k = 1; + i -= 16; + } else { + u8 value; + if (get_user(value, src)) + return; + src++; + + while (i > 0 && k) { + if (k & value) + fb_writew (pixel, dest); + + dest++; + k <<= 1; + i--; + } + + k = 1; + } + } + src_save += (stride+7)>>3; + src = src_save; + dest_save += (info->fix.line_length>>1); + dest = dest_save; + } + } +#endif + } +} + + +#ifdef CONFIG_FB_ENHANCED_16BPP +/* Optimized function to put opaque image data to a 16bpp display. + */ +static void fb_enh_putimage_opaque16 (struct fb_info *info, struct fb_put *p) +{ + int i, j; + u32 offset; + short xres, yres; + short width, height; + short x0, y0; + u8 *src0; + u8 src_bytes_per_pixel; + u16 *dest, *dest_save; + short stride; + short x1, y1; + short xstart, xend, ystart, yend; + + if (!info || !p) + return; + + xstart = p->xstart; + xend = p->xend; + if (xstart > xend) { + short tmp = xstart; + xstart = xend; + xend = tmp; + } + ystart = p->ystart; + yend = p->yend; + if (ystart > yend) { + short tmp = ystart; + ystart = yend; + yend = tmp; + } + if (xend < 0 || yend < 0 || xstart >= p->width || ystart >= p->height) + return; + if (xstart < 0) + xstart = 0; + if (ystart < 0) + ystart = 0; + if (xend >= p->width) + xend = p->width - 1; + if (yend >= p->height) + yend = p->height - 1; + + src0 = p->pixels; + xres = info->var.xres; + yres = info->var.yres; + width = p->xend - p->xstart + 1; + height = p->yend - p->ystart + 1; + x0 = p->x0 + xstart; + y0 = p->y0 + ystart; + x1 = p->x0 + xend; + y1 = p->y0 + yend; + stride = p->width; + + switch (p->type) { + case FB_IMAGETYPE_ALPHA: + src_bytes_per_pixel = 1; + break; + case FB_IMAGETYPE_GREY: + src_bytes_per_pixel = 1; + break; + case FB_IMAGETYPE_RGB2: + src_bytes_per_pixel = 2; + break; + case FB_IMAGETYPE_RGB3: + src_bytes_per_pixel = 3; + break; + case FB_IMAGETYPE_RGB4: + src_bytes_per_pixel = 4; + break; + default: + return; + } + + if (!src0 || width <= 0 || height <= 0 || + x1 < 0 || y1 < 0 || x0 >= xres || y0 >= yres || + stride <= 0) + return; + src0 += src_bytes_per_pixel * (stride * ystart + xstart); + if (x0 < 0) { + x0 = -x0; + width -= x0; + src0 += x0 * src_bytes_per_pixel; + x0 = 0; + } + if (x1 >= xres) { + short diff = x1 - xres + 1; + width -= diff; + x1 = xres - 1; + } + if (y0 < 0) { + y0 = -y0; + height -= y0; + src0 += y0 * stride * src_bytes_per_pixel; + y0 = 0; + } + if (y1 >= yres) { + short diff = y1 - yres + 1; + height -= diff; + y1 = yres - 1; + } + + if (p->clip_valid) { + if (y0 > p->clip_y1 || x0 > p->clip_x1 || + y1 < p->clip_y0 || x1 < p->clip_x0) + return; + if (x0 < p->clip_x0) { + short diff = p->clip_x0 - x0; + width -= diff; + src0 += diff * src_bytes_per_pixel; + x0 = p->clip_x0; + } + if (x1 > p->clip_x1) { + short diff = x1 - p->clip_x1; + width -= diff; + /* x1 = p->clip_x1; */ + } + if (y0 < p->clip_y0) { + short diff = p->clip_y0 - y0; + height -= diff; + src0 += diff * stride * src_bytes_per_pixel; + y0 = p->clip_y0; + } + if (y1 > p->clip_y1) { + short diff = y1 - p->clip_y1; + height -= diff; + /* y1 = p->clip_y1; */ + } + } + /*----------*/ + + dest = (u16*) info->screen_base; + offset = y0 * (info->fix.line_length >> 1) + x0; + dest += offset; + dest_save = dest; + + switch (p->type) { + case FB_IMAGETYPE_RGB4: { + u32 *src, *src_save; + src = (u32*) src0; + src_save = src; + + j = height; + while (j-- > 0) { + u32 value; + i = width; + while (i-- > 0) { + if (get_user(value, src)) + return; + src++; + value = ((value >> 8) & 0xf800) | + ((value >> 5) & 0x7e0) | + ((value >> 3) & 31); + fb_writew (value, dest); + dest++; + } + src_save += stride; + src = src_save; + dest_save += (info->fix.line_length>>1); + dest = dest_save; + } + } + break; + + case FB_IMAGETYPE_RGB3: { + u8 *src = (u8*) src0, *src_save; + src_save = src; + + j = height; + while (j-- > 0) { + u32 value; + i = width; + while (i-- > 0) { + if (!(3 & (u32)src)) { + if (get_user(value, ((u32*)src))) + return; + value &= 0xffffff; + } else { + u8 tmp; + src += 2; + if (get_user(tmp, src)) + return; + value = tmp; + value <<= 8; + src--; + if (get_user(tmp, src)) + return; + value |= tmp; + value <<= 8; + src--; + if (get_user(tmp, src)) + return; + value |= tmp; + } + src += 3; + + value = ((value >> 8) & 0xf800) | + ((value >> 5) & 0x7e0) | + ((value >> 3) & 31); + fb_writew (value, dest); + dest++; + } + src_save += stride * 3; + src = src_save; + dest_save += (info->fix.line_length>>1); + dest = dest_save; + } + } + break; + + case FB_IMAGETYPE_RGB2: { + u16 *src, *src_save; + u8* buffer; + src = (u16*) src0; + src_save = src; + + /* What is needed is a function to transfer from memory chunks + * directly from userspace to memory mapped I/O. Without that, + * gotta kmalloc. + */ +#define BUFSIZE16 2040 + buffer = kmalloc(BUFSIZE16, GFP_KERNEL); + if (!buffer) { + printk(KERN_INFO "fb_enh_putimage_opaque16: no memory\n"); + return; + } + + j = height; + while (j-- > 0) { + i = width; + while (i > 0) { + u32 pixels = i > (BUFSIZE16/2) ? (BUFSIZE16/2) : i; + u32 bytes = pixels << 1; + + /* Userspace -> L2 cache */ + if (copy_from_user((u8*)buffer,(u8*)src, bytes)) + goto dealloc2; + src += pixels; + + /* L2 cache -> VRAM */ + memcpy_toio ((u8*)dest, (u8*)buffer, bytes); + dest += pixels; + i -= pixels; +#if 0 + + /* This runs at one half the speed of the + * above buffer-based code. + */ + if (!(3 & (u32)src) && i >= 4) { + u32 a, b, *s=(u32*)src; + if (get_user(a, s)) + return; + s++; + if (get_user(b, s)) + return; + src+=4; + + fb_writew (a, dest); + dest++; + fb_writew (a>>16, dest); + dest++; + fb_writew (b, dest); + dest++; + fb_writew (b>>16, dest); + dest++; + i-=4; + } else { + u32 tmp; + if (get_user(tmp, src)) + return; + tmp &= 0xffff; + src++; + + fb_writew (tmp, dest); + dest++; + i--; + } +#endif + } + src_save += stride; + src = src_save; + dest_save += (info->fix.line_length>>1); + dest = dest_save; + } + +dealloc2: + if (buffer) + kfree (buffer); + } + break; + + case FB_IMAGETYPE_GREY: { + u8 *src, *src_save; + src = src0; + src_save = src; + + j = height; + while (j-- > 0) { + i = width; + while (i > 0) { + if (!(3 & (u32)src) && i >= 4) { + u32 value, value2, *s=(u32*)src; + if (get_user(value, s)) + return; + src += 4; + i -= 4; + + value2 = value & 0xff; + value >>= 8; + value2 = ((value2 << 8) & 0xf800) | + ((value2 << 3) & 0x7e0) | + ((value2 >> 3) & 31); + fb_writew (value2, dest); + dest++; + + value2 = value & 0xff; + value >>= 8; + value2 = ((value2 << 8) & 0xf800) | + ((value2 << 3) & 0x7e0) | + ((value2 >> 3) & 31); + fb_writew (value2, dest); + dest++; + + value2 = value & 0xff; + value >>= 8; + value2 = ((value2 << 8) & 0xf800) | + ((value2 << 3) & 0x7e0) | + ((value2 >> 3) & 31); + fb_writew (value2, dest); + dest++; + + value2 = value & 0xff; + value >>= 8; + value2 = ((value2 << 8) & 0xf800) | + ((value2 << 3) & 0x7e0) | + ((value2 >> 3) & 31); + fb_writew (value2, dest); + dest++; + } else { + u32 value; + if (get_user(value, src)) + return; + value &= 0xff; + value = ((value << 8) & 0xf800) | + ((value << 3) & 0x7e0) | + ((value >> 3) & 31); + src++; + + fb_writew (value, dest); + dest++; + i--; + } + } + src_save += stride; + src = src_save; + dest_save += (info->fix.line_length>>1); + dest = dest_save; + } + } + break; + } +} +#endif + + +#ifdef CONFIG_FB_ENHANCED_24BPP +/* Optimized function to put opaque image data to a 24bpp display. + */ +static void fb_enh_putimage_opaque24 (struct fb_info *info, struct fb_put *p) +{ + int i, j; + u32 offset; + short xres, yres; + short width, height; + short x0, y0; + u8 *src0; + u8 src_bytes_per_pixel; + u8 *dest, *dest_save; + short stride; + short x1, y1; + short xstart, xend, ystart, yend; + + if (!info || !p) + return; + + xstart = p->xstart; + xend = p->xend; + if (xstart > xend) { + short tmp = xstart; + xstart = xend; + xend = tmp; + } + ystart = p->ystart; + yend = p->yend; + if (ystart > yend) { + short tmp = ystart; + ystart = yend; + yend = tmp; + } + if (xend < 0 || yend < 0 || xstart >= p->width || ystart >= p->height) + return; + if (xstart < 0) + xstart = 0; + if (ystart < 0) + ystart = 0; + if (xend >= p->width) + xend = p->width - 1; + if (yend >= p->height) + yend = p->height - 1; + + src0 = p->pixels; + xres = info->var.xres; + yres = info->var.yres; + width = p->xend - p->xstart + 1; + height = p->yend - p->ystart + 1; + x0 = p->x0 + xstart; + y0 = p->y0 + ystart; + x1 = p->x0 + xend; + y1 = p->y0 + yend; + stride = p->width; + + switch (p->type) { + case FB_IMAGETYPE_ALPHA: + src_bytes_per_pixel = 1; + break; + case FB_IMAGETYPE_GREY: + src_bytes_per_pixel = 1; + break; + case FB_IMAGETYPE_RGB2: + src_bytes_per_pixel = 2; + break; + case FB_IMAGETYPE_RGB3: + src_bytes_per_pixel = 3; + break; + case FB_IMAGETYPE_RGB4: + src_bytes_per_pixel = 4; + break; + default: + return; + } + + if (!src0 || width <= 0 || height <= 0 || + x1 < 0 || y1 < 0 || x0 >= xres || y0 >= yres || + stride <= 0) + return; + src0 += src_bytes_per_pixel * (stride * ystart + xstart); + if (x0 < 0) { + x0 = -x0; + width -= x0; + src0 += x0 * src_bytes_per_pixel; + x0 = 0; + } + if (x1 >= xres) { + short diff = x1 - xres + 1; + width -= diff; + x1 = xres - 1; + } + if (y0 < 0) { + y0 = -y0; + height -= y0; + src0 += y0 * stride * src_bytes_per_pixel; + y0 = 0; + } + if (y1 >= yres) { + short diff = y1 - yres + 1; + height -= diff; + y1 = yres - 1; + } + + if (p->clip_valid) { + if (y0 > p->clip_y1 || x0 > p->clip_x1 || + y1 < p->clip_y0 || x1 < p->clip_x0) + return; + if (x0 < p->clip_x0) { + short diff = p->clip_x0 - x0; + width -= diff; + src0 += diff * src_bytes_per_pixel; + x0 = p->clip_x0; + } + if (x1 > p->clip_x1) { + short diff = x1 - p->clip_x1; + width -= diff; + /* x1 = p->clip_x1; */ + } + if (y0 < p->clip_y0) { + short diff = p->clip_y0 - y0; + height -= diff; + src0 += diff * stride * src_bytes_per_pixel; + y0 = p->clip_y0; + } + if (y1 > p->clip_y1) { + short diff = y1 - p->clip_y1; + height -= diff; + /* y1 = p->clip_y1; */ + } + } + /*----------*/ + + dest = (u8*) info->screen_base; + offset = y0 * info->fix.line_length + 3 * x0; + dest += offset; + dest_save = dest; + + switch (p->type) { + case FB_IMAGETYPE_RGB4: { + u32 *src, *src_save; + src = (u32*) src0; + src_save = src; + + j = height; + while (j-- > 0) { + u32 value; + i = width; + while (i-- > 0) { + if (get_user(value, src)) + return; + src++; + + fb_writeb (value, dest); dest++; + fb_writeb (value>>8, dest); dest++; + fb_writeb (value>>16, dest); dest++; + } + src_save += stride; + src = src_save; + dest_save += info->fix.line_length; + dest = dest_save; + } + } + break; + + case FB_IMAGETYPE_RGB3: { + u8 *src = (u8*) src0, *src_save; + u8 *buffer; + + /* What is needed is a function to transfer from memory chunks + * directly from userspace to memory mapped I/O. Without that, + * gotta kmalloc. + */ +#define BUFSIZE24 3072 + buffer = kmalloc(BUFSIZE24, GFP_KERNEL); + if (!buffer) { + printk(KERN_INFO "fb_enh_putimage_opaque16: no memory\n"); + return; + } + + src_save = src; + + j = height; + while (j-- > 0) { + i = width; + while (i > 0) { + u32 pixels = i > (BUFSIZE24/3) ? (BUFSIZE24/3) : i; + u32 bytes = pixels * 3; + + /* Userspace -> L2 cache */ + if (copy_from_user((u8*)buffer,(u8*)src, bytes)) + goto dealloc3; + src += pixels; + + /* L2 cache -> VRAM */ + memcpy_toio ((u8*)dest, (u8*)buffer, bytes); + dest += pixels; + i -= pixels; + +#if 0 + j = height; + while (j-- > 0) { + u32 value; + i = width; + while (i-- > 0) { + u8 a,b,c; + + if (get_user(a, src)) + return; + src++; + if (get_user(b, src)) + return; + src++; + if (get_user(c, src)) + return; + src++; + + fb_writeb (a, dest); dest++; + fb_writeb (b, dest); dest++; + fb_writeb (c, dest); dest++; +#endif + } + src_save += stride * 3; + src = src_save; + dest_save += info->fix.line_length; + dest = dest_save; + } +dealloc3: + if (buffer) + kfree (buffer); + } + break; + + case FB_IMAGETYPE_RGB2: { + u16 *src, *src_save; + src = (u16*) src0; + src_save = src; + + j = height; + while (j-- > 0) { + i = width; + while (i > 0) { + u32 value; + u32 tmp; + + if (get_user(tmp, src)) + return; + src++; + + value = ((tmp << 8) & 0xf80000) | + ((tmp << 5) & 0xfc00) | + ((tmp << 3) & 0xf8); + fb_writeb (value, dest); dest++; value >>= 8; + fb_writeb (value, dest); dest++; value >>= 8; + fb_writeb (value, dest); dest++; + i--; + } + src_save += stride; + src = src_save; + dest_save += info->fix.line_length; + dest = dest_save; + } + } + break; + + case FB_IMAGETYPE_GREY: { + u8 *src, *src_save; + src = src0; + src_save = src; + + j = height; + while (j-- > 0) { + i = width; + while (i > 0) { + u8 value; + if (get_user(value, src)) + return; + src++; + + fb_writeb (value, dest); dest++; + fb_writeb (value, dest); dest++; + fb_writeb (value, dest); dest++; + i--; + } + src_save += stride; + src = src_save; + dest_save += info->fix.line_length; + dest = dest_save; + } + } + break; + } +} +#endif + + +/* generic_putimage + * + * Supports source images of: + * . native depth + * . 24 bits per pixel + * . 32 bits per pixel with transparency + * . 8 bits grey + * + * Re transparency: + * 0 is opaque, 255 is 100% transparent. + */ + +static void generic_putimage (struct fb_info *info, struct fb_put *p) +{ + int i, j; + int offset; + u16 bytes_per_pixel; + unsigned char *dest; + unsigned char *dest_save; + unsigned char *src, *src_save; + short xres, yres; + short width, height; + short x0, y0; + short x1, y1; + u32 src_bytes_per_pixel; + short stride; + + if (!info || !p) + return; + if (p->type == FB_IMAGETYPE_MONO) + return; + if (p->xend < 0 || p->yend < 0 || p->xstart >= p->width || p->ystart >= p->height) + return; + if (p->xstart > p->xend) { + short tmp = p->xstart; + p->xstart = p->xend; + p->xend = tmp; + } + if (p->ystart > p->yend) { + short tmp = p->ystart; + p->ystart = p->yend; + p->yend = tmp; + } + if (p->xstart < 0) + p->xstart = 0; + if (p->ystart < 0) + p->ystart = 0; + if (p->xend >= p->width) + p->xend = p->width - 1; + if (p->yend >= p->height) + p->yend = p->height - 1; + src = p->pixels; + xres = info->var.xres; + yres = info->var.yres; + width = p->xend - p->xstart + 1; + height = p->yend - p->ystart + 1; + x0 = p->x0; + y0 = p->y0; + x1 = p->x1; + y1 = p->y1; + stride = p->width; + + switch (p->type) { + case FB_IMAGETYPE_GREY: + src_bytes_per_pixel = 1; + break; + case FB_IMAGETYPE_RGB2: + src_bytes_per_pixel = 2; + break; + case FB_IMAGETYPE_RGB3: + src_bytes_per_pixel = 3; + break; + case FB_IMAGETYPE_RGB4: + case FB_IMAGETYPE_RGBA: + src_bytes_per_pixel = 4; + break; + default: + return; + } + + if (!src || width <= 0 || height <= 0 || + x1 < 0 || y1 < 0 || x0 >= xres || y0 >= yres || + stride <= 0) + return; + src += src_bytes_per_pixel * (p->width * p->ystart + p->xstart); + if (x0 < 0) { + x0 = -x0; + width -= x0; + src += x0 * src_bytes_per_pixel; + x0 = 0; + } + if (x1 >= xres) { + short diff = x1 - xres + 1; + width -= diff; + x1 = xres - 1; + } + if (y0 < 0) { + y0 = -y0; + height -= y0; + src += y0 * stride * src_bytes_per_pixel; + y0 = 0; + } + if (y1 >= yres) { + short diff = y1 - yres + 1; + height -= diff; + y1 = yres - 1; + } + + if (p->clip_valid) { + if (y0 > p->clip_y1 || x0 > p->clip_x1 || + y1 < p->clip_y0 || x1 < p->clip_x0) + return; + if (x0 < p->clip_x0) { + short diff = p->clip_x0 - x0; + width -= diff; + src += diff * src_bytes_per_pixel; + x0 = p->clip_x0; + } + if (x1 > p->clip_x1) { + short diff = x1 - p->clip_x1; + width -= diff; + } + if (y0 < p->clip_y0) { + short diff = p->clip_y0 - y0; + height -= diff; + src += diff * stride * src_bytes_per_pixel; + y0 = p->clip_y0; + } + if (y1 > p->clip_y1) { + short diff = y1 - p->clip_y1; + height -= diff; + } + } + /*----------*/ + + bytes_per_pixel = (info->var.bits_per_pixel + 7) >> 3; + dest = info->screen_base; + offset = (y0 + p->ystart) * info->fix.line_length + + (x0 + p->xstart) * bytes_per_pixel; + dest += offset; + dest_save = dest; + src_save = src; + + j = height; + while (j-- > 0) { + i = width; + while (i-- > 0) { + u32 value=0; + u32 transp=0; + u32 orig_value; + + switch (p->location) { + case FB_LOCATION_KERNEL: + switch (src_bytes_per_pixel) { + case 1: + value = *src++; + break; + case 2: + value = *(unsigned short*) src; + src += 2; + break; + case 3: { + value = src[2]; + value <<= 8; + value |= src[1]; + value <<= 8; + value |= *src++; + src += 2; + break; + } + case 4: + value = *(unsigned long*) src; + src += 4; + } + break; + + case FB_LOCATION_USER: + switch (src_bytes_per_pixel) { + case 1: { + u8 tmp=0; + if (get_user(tmp, src)) + return; + src++; + value = tmp; + break; + } + case 2: { + u16 tmp=0, *s=(u16*)src; + if (get_user(tmp, s)) + return; + src+=2; + value = tmp; + break; + } + case 3: { + u8 tmp; + src += 2; + if (get_user(tmp, src)) + return; + value = tmp; + value <<= 8; + src--; + if (get_user(tmp, src)) + return; + value |= tmp; + value <<= 8; + src--; + if (get_user(tmp, src)) + return; + value |= tmp; + src += 3; + break; + } + case 4: { + u32 *s=(u32*)src; + if (get_user(value, s)) + return; + src+=4; + break; + } + } + break; + + case FB_LOCATION_VRAM: + value = 0; + break; + + default: + return; + } + + switch (p->type) { + case FB_IMAGETYPE_RGBA: + transp = value >> 24; + break; + case FB_IMAGETYPE_RGB2: { + u32 r,g,b; + r = (value >> 11) & 31; + g = (value >> 5) & 63; + b = value & 31; + r <<= 19; + g <<= 10; + b <<= 3; + value = r | g | b; + } + break; + case FB_IMAGETYPE_GREY: + value |= (value<<8) | (value<<16); + } + + if (transp > 0 && transp < 255) { + orig_value = 0; + switch (bytes_per_pixel) { +#ifdef CONFIG_FB_ENHANCED_32BPP + case 4: + orig_value = fb_readl (dest); + break; +#endif + +#ifdef CONFIG_FB_ENHANCED_24BPP + case 3: { + u32 tmp; + orig_value = 0xff & fb_readb (dest); + dest++; + tmp = 0xff & fb_readb (dest); + dest++; + tmp <<= 8; + orig_value |= tmp; + tmp = 0xff & fb_readb (dest); + tmp <<= 16; + orig_value |= tmp; + dest -= 2; + break; + } +#endif + +#ifdef CONFIG_FB_ENHANCED_16BPP + case 2: + orig_value = fb_readw (dest); + break; +#endif + + } + + orig_value = fb_pixel_to_rgb (info, orig_value); + value = fb_combine_rgb_pixels (orig_value, value, transp); + } + + if (transp == 255) + dest += bytes_per_pixel; + else { + value = fb_pixel_from_rgb (info, value); + + switch (bytes_per_pixel) + { +#ifdef CONFIG_FB_ENHANCED_32BPP + case 4: + fb_writel (value, dest); + dest += 4; + break; +#endif + +#ifdef CONFIG_FB_ENHANCED_24BPP + case 3: + fb_writeb (value, dest); dest++; value >>= 8; + fb_writeb (value, dest); dest++; value >>= 8; + fb_writeb (value, dest); dest++; + break; +#endif + +#ifdef CONFIG_FB_ENHANCED_16BPP + case 2: + fb_writew (value, dest); + dest += 2; + break; +#endif + + default: + break; + } + } + } + src_save += stride * src_bytes_per_pixel; + src = src_save; + dest_save += info->fix.line_length; + dest = dest_save; + } +} + +static void fb_enh_putimage (struct fb_info *info, struct fb_put *p) +{ + u8 bytes_per_pixel; + + if (!info || !p) + return; + /*----------*/ + + bytes_per_pixel = (info->var.bits_per_pixel + 7) >> 3; + + if (p->type == FB_IMAGETYPE_MONO) { + fb_enh_putimage_mono (info, p); + return; + } + else + if (p->type != FB_IMAGETYPE_RGBA) { + if (bytes_per_pixel==2 && + info->var.red.length == 5 && + info->var.green.length == 6 && + info->var.blue.length == 5) { +#ifdef CONFIG_FB_ENHANCED_16BPP + fb_enh_putimage_opaque16 (info, p); + return; +#endif + } else + if (info->var.red.length == 8 && + info->var.green.length == 8 && + info->var.blue.length == 8) { + if (bytes_per_pixel==4) { +#ifdef CONFIG_FB_ENHANCED_32BPP + fb_enh_putimage_opaque32 (info, p); +#endif + } else { +#ifdef CONFIG_FB_ENHANCED_24BPP + fb_enh_putimage_opaque24 (info, p); +#endif + } + return; + } + } + + generic_putimage (info, p); +} + + +static void generic_fillrect (struct fb_info *info, struct fb_draw *p) +{ + u32 pixel, bytes_per_pixel, offset; + short xres, yres; + unsigned char *ptr, *ptr_save; + u32 transp; + short x0,x1,y0,y1; + int i, j; + + if (!info || !p) + return; + x0 = p->x0; + y0 = p->y0; + x1 = p->x1; + y1 = p->y1; + transp = p->color >> 24; + if (transp == 255) + return; + if (x0 > x1) { + short tmp = x0; + x0 = x1; + x1 = tmp; + } + if (y0 > y1) { + short tmp = y0; + y0 = y1; + y1 = tmp; + } + if (y1 < 0 || x1 < 0) + return; + xres = info->var.xres; + yres = info->var.yres; + if (x0 >= xres || y0 >= yres) + return; + if (x0 < 0) + x0 = 0; + if (x1 >= xres) + x1 = xres-1; + if (y0 < 0) + y0 = 0; + if (y1 >= yres) + y1 = yres-1; + if (p->clip_valid) { + if (y1 < p->clip_y0 || y0 > p->clip_y1 || + x1 < p->clip_x0 || x0 > p->clip_x1) + return; + + if (x0 < p->clip_x0) + x0 = p->clip_x0; + if (x1 > p->clip_x1) + x1 = p->clip_x1; + if (y0 < p->clip_y0) + y0 = p->clip_y0; + if (y1 > p->clip_y1) + y1 = p->clip_y1; + } + /*----------*/ + + bytes_per_pixel = (info->var.bits_per_pixel + 7) >> 3; + offset = y0 * info->fix.line_length + x0 * bytes_per_pixel; + ptr = ((unsigned char*)info->screen_base); + ptr += offset; + ptr_save = ptr; + pixel = fb_pixel_from_rgb (info, p->color); + + j = y1 - y0 + 1; + while (j--) { + ptr = ptr_save; + + i = x1 - x0 + 1; + + while (i--) { + if (transp) { + u32 orig_value = 0; + u32 value = p->color; + + switch (bytes_per_pixel) { +#ifdef CONFIG_FB_ENHANCED_32BPP + case 4: + orig_value = fb_readl (ptr); + break; +#endif + +#ifdef CONFIG_FB_ENHANCED_24BPP + case 3: { + u32 tmp; + orig_value = 0xff & fb_readb (ptr); + ptr++; + tmp = 0xff & fb_readb (ptr); + ptr++; + tmp <<= 8; + orig_value |= tmp; + tmp = 0xff & fb_readb (ptr); + tmp <<= 16; + orig_value |= tmp; + ptr -= 2; + break; + } +#endif + +#ifdef CONFIG_FB_ENHANCED_16BPP + case 2: + orig_value = fb_readw (ptr); + break; +#endif + + } + + orig_value = fb_pixel_to_rgb (info, orig_value); + value = fb_combine_rgb_pixels (orig_value, value, transp); + pixel = fb_pixel_from_rgb (info, value); + } + + switch (bytes_per_pixel) { +#ifdef CONFIG_FB_ENHANCED_32BPP + case 4: + fb_writel (pixel, ptr); + ptr += 4; + break; +#endif + +#ifdef CONFIG_FB_ENHANCED_24BPP + case 3: { + register u32 c = pixel; + fb_writeb (c, ptr); ptr++; c >>= 8; + fb_writeb (c, ptr); ptr++; c >>= 8; + fb_writeb (c, ptr); ptr++; + break; + } +#endif + +#ifdef CONFIG_FB_ENHANCED_16BPP + case 2: + fb_writew (pixel, ptr); + ptr += 2; + break; +#endif + }/*switch*/ + } + + ptr_save += info->fix.line_length; + } +} + +static void fb_enh_fillrect (struct fb_info *info, struct fb_draw *p) +{ + u32 offset; + short xres, yres; + short x0,x1,y0,y1; + int i, j; + + if (!info || !p) + return; + x0 = p->x0; + y0 = p->y0; + x1 = p->x1; + y1 = p->y1; + if (p->color >> 24) { + generic_fillrect (info, p); + return; + } + + if (x0 > x1) { + short tmp = x0; + x0 = x1; + x1 = tmp; + } + if (y0 > y1) { + short tmp = y0; + y0 = y1; + y1 = tmp; + } + + if (y1 < 0 || x1 < 0) + return; + xres = info->var.xres; + yres = info->var.yres; + if (x0 >= xres || y0 >= yres) + return; + if (x0 < 0) + x0 = 0; + if (x1 >= xres) + x1 = xres-1; + if (y0 < 0) + y0 = 0; + if (y1 >= yres) + y1 = yres-1; + if (p->clip_valid) { + if (y1 < p->clip_y0 || y0 > p->clip_y1 || + x1 < p->clip_x0 || x0 > p->clip_x1) + return; + + if (x0 < p->clip_x0) + x0 = p->clip_x0; + if (x1 > p->clip_x1) + x1 = p->clip_x1; + if (y0 < p->clip_y0) + y0 = p->clip_y0; + if (y1 > p->clip_y1) + y1 = p->clip_y1; + } + /*----------*/ + + switch (((info->var.bits_per_pixel + 7) >> 3)) { + case 4: { +#ifdef CONFIG_FB_ENHANCED_32BPP + u32 *ptr, *ptr_save; + short w = x1 - x0 + 1; + + ptr = ((u32*)info->screen_base); + offset = y0 * (info->fix.line_length>>2) + x0; + ptr += offset; + ptr_save = ptr; + + j = y1 - y0 + 1; + while (j-- > 0) { + register u32 px = p->color; + i = w; + + while (i > 0) { + if (i >= 8) { + register u32 *p = ptr; + fb_writel (px, p); + fb_writel (px, (p+1)); + fb_writel (px, (p+2)); + fb_writel (px, (p+3)); + fb_writel (px, (p+4)); + fb_writel (px, (p+5)); + fb_writel (px, (p+6)); + fb_writel (px, (p+7)); + ptr += 8; + i -= 8; + } else { + fb_writel (px, ptr); ptr++; + i--; + } + } + + ptr_save += info->fix.line_length>>2; + ptr = ptr_save; + } +#endif + } + break; + + case 3: { +#ifdef CONFIG_FB_ENHANCED_24BPP + u8 *ptr, *ptr_save; + u8 r,g,b; + short w = x1 - x0 + 1; + union { + u32 l[3]; + u8 c[12]; + } stripe; + r = p->color >> 16; + g = p->color >> 8; + b = p->color; + for (i=0; i<=9; i+=3) { + stripe.c[i] = b; + stripe.c[i+1] = g; + stripe.c[i+2] = r; + } + + ptr = ((u8*)info->screen_base); + offset = y0 * info->fix.line_length + x0*3; + ptr += offset; + ptr_save = ptr; + + j = y1 - y0 + 1; + while (j-- > 0) { + i = w; + + while (i > 0) { + if (i>=12 && !(3 & (u32)ptr)) { + register u32 a,b,c; + register u32 *p = (u32*)ptr; + a = stripe.l[0]; + b = stripe.l[1]; + c = stripe.l[2]; + fb_writel (a, p); p++; + fb_writel (b, p); p++; + fb_writel (c, p); p++; + fb_writel (a, p); p++; + fb_writel (b, p); p++; + fb_writel (c, p); p++; + fb_writel (a, p); p++; + fb_writel (b, p); p++; + fb_writel (c, p); p++; + ptr += 36; + i -= 12; + } else { + fb_writeb (b, ptr); ptr++; + fb_writeb (g, ptr); ptr++; + fb_writeb (r, ptr); ptr++; + i--; + } + } + + ptr_save += info->fix.line_length; + ptr = ptr_save; + } +#endif + } + break; + + case 2: { +#ifdef CONFIG_FB_ENHANCED_16BPP + u16 *ptr, *ptr_save; + u16 pix; + u32 pix2; + short w = x1 - x0 + 1; + + pix = fb_pixel_from_rgb (info,p->color); + pix2 = pix; + pix2 <<= 16; + pix2 |= pix; + ptr = ((u16*)info->screen_base); + offset = y0 * (info->fix.line_length >> 1) + x0; + ptr += offset; + ptr_save = ptr; + + j = y1 - y0 + 1; + while (j-- > 0) { + i = w; + + while (i > 0) { + if (!(3 & (u32)ptr) && i >= 8) { + register u32 *p = (u32*) ptr; + fb_writel (pix2, p); + fb_writel (pix2, (1+p)); + fb_writel (pix2, (2+p)); + fb_writel (pix2, (3+p)); + ptr += 8; + i -= 8; + } else { + fb_writew (pix, ptr); + ptr++; + i--; + } + } + + ptr_save += info->fix.line_length>>1; + ptr = ptr_save; + } +#endif + } + break; + } +} + + +static void fb_enh_copy_within (unsigned char *dest, unsigned char *src, u32 n) +{ + int dif = dest < src ? src - dest : dest - src; + while (n) { + if (dif >= 4 && n >= 16 && !(3 & (u32)src) && !(3 & (u32)dest)){ + /* This is most effective on pre-Pentium CPUs. + * and maybe could be shrunk down for >= Pentium. + */ + fb_writel (fb_readl (src), dest); src+=4; dest+=4; + fb_writel (fb_readl (src), dest); src+=4; dest+=4; + fb_writel (fb_readl (src), dest); src+=4; dest+=4; + fb_writel (fb_readl (src), dest); src+=4; dest+=4; + n -= 16; + } else { + fb_writeb (fb_readb (src), dest); src++; dest++; + n--; + } + } +} + + +/* Robust copyarea, supporting 16/24/32bpp, shifting up/down/left/right. + */ +static void fb_enh_copyarea (struct fb_info *info, struct fb_draw *p) +{ + u32 bytes_per_pixel, offset, rasterlen; + unsigned char *src; + unsigned char *dest; + short w, h; + short xres, yres; + u32 stride; + short x0,y0,x1,y1,x2,y2; + + if (!info || !p) + return; + x0 = p->x0; + y0 = p->y0; + x1 = p->x1; + y1 = p->y1; + x2 = p->x2; + y2 = p->y2; + if (x0 > x1) { + short tmp = x0; + x0 = x1; + x1 = tmp; + } + if (y0 > y1) { + short tmp = y0; + y0 = y1; + y1 = tmp; + } + if (x1 < 0 || y1 < 0) + return; + xres = info->var.xres; + yres = info->var.yres; + if (x0 >= xres || y0 >= yres || x2 >= xres || y2 >= yres) + return; + w = x1 - x0 + 1; + h = y1 - y0 + 1; + if (w<=0 || h<=0) + return; + if (x2+w-1 < 0 || y2+h-1 < 0) + return; + if (x0 < 0) { + x2 -= x0; + w += x0; + x0=0; + } + if (y0 < 0) { + y2 -= y0; + h += y0; + y0=0; + } + if (x1 >= xres) { + short diff = x1 - xres + 1; + w -= diff; + x1 = xres-1; + } + if (y1 >= yres) { + short diff = y1 - yres + 1; + h -= diff; + y1 = yres-1; + } + if (x2+w-1 >= xres) { + short diff = x2 + w - xres; + w -= diff; + } + if (y2+h-1 >= yres) { + short diff = y2+h - yres; + h -= diff; + } + if (p->clip_valid) { + if (x1 < p->clip_x0 || y1 < p->clip_y0) + return; + if (x2+w-1 < p->clip_x0 || y2+h-1 < p->clip_y0) + return; + if (x0 > p->clip_x1 || y0 > p->clip_y1) + return; + if (x2 > p->clip_x1 || y2 > p->clip_y1) + return; + if (x0 < p->clip_x0) { + short diff = p->clip_x0 - x0; + x2 += diff; + w -= diff; + x0 = p->clip_x0; + } + if (y0 < p->clip_y0) { + short diff = p->clip_y0 - y0; + y2 += diff; + h -= diff; + y0 = p->clip_y0; + } + if (x1 > p->clip_x1) { + short diff = x1 - p->clip_x1; + w -= diff; + x1 = p->clip_x1; + } + if (y1 > p->clip_y1) { + short diff = y1 - p->clip_y1; + h -= diff; + y1 = p->clip_y1; + } + if (x2 < p->clip_x0) { + short diff = p->clip_x0 - x2; + x0 += diff; + w -= diff; + x2 = p->clip_x0; + } + if (y2 < p->clip_y0) { + short diff = p->clip_y0 - y2; + y0 += diff; + h -= diff; + y2 = p->clip_y0; + } + if (x2+w-1 > p->clip_x1) { + short diff = x2+w-1 - p->clip_x1; + w -= diff; + } + if (y2+h-1 > p->clip_y1) { + short diff = y2+h-1 - p->clip_y1; + h -= diff; + } + } + /*----------*/ + +/*printk (KERN_INFO "copyarea: w=%d h=%d\n", w, h);*/ + bytes_per_pixel = (info->var.bits_per_pixel + 7) >> 3; + rasterlen = info->fix.line_length; + src = dest = info->screen_base; + offset = y0 * rasterlen + x0 * bytes_per_pixel; + src += offset; + offset = y2 * rasterlen + x2 * bytes_per_pixel; + dest += offset; + stride = w * bytes_per_pixel; + + if (y2 < y0) { + int j=0; + +#define BUFSIZECOPY 4096 + u8 *buffer = NULL; + buffer = kmalloc (BUFSIZECOPY, GFP_KERNEL); + + /* moving upward */ + while (j < h) { + if (!buffer) + fb_enh_copy_within (dest,src,stride); + else { + u8 *d = dest; + u8 *s = src; + long st = stride; + while (st > 0) { + u32 len = st > BUFSIZECOPY ? + BUFSIZECOPY : st; + memcpy_fromio (buffer, s, len); + memcpy_toio (d, buffer, len); + st -= len; + s += len; + d += len; + } + } + dest += rasterlen; + src += rasterlen; + j++; + } + if (buffer) + kfree (buffer); + } else + if (y2 > y0) { + u8 *buffer = NULL; + int j=h-1; + + buffer = kmalloc (BUFSIZECOPY, GFP_KERNEL); + + /* moving downward */ + dest += rasterlen * h; + src += rasterlen * h; + while (j >= 0) { + dest -= rasterlen; + src -= rasterlen; + if (!buffer) + fb_enh_copy_within (dest,src,stride); + else { + u8 *d = dest; + u8 *s = src; + long st = stride; + while (st > 0) { + u32 len = st > BUFSIZECOPY ? + BUFSIZECOPY : st; + memcpy_fromio (buffer, s, len); + memcpy_toio (d, buffer, len); + st -= len; + s += len; + d += len; + } + } + j--; + } + kfree (buffer); + } else { + int j=0; + /* y equal */ + + u8 *buffer = NULL; + buffer = kmalloc (BUFSIZECOPY, GFP_KERNEL); + + /* moving upward */ + while (j < h) { + if (!buffer) + fb_enh_copy_within (dest,src,stride); + else { + u8 *d = dest; + u8 *s = src; + long st = stride; + while (st > 0) { + u32 len = st > BUFSIZECOPY ? + BUFSIZECOPY : st; + memcpy_fromio (buffer, s, len); + memcpy_toio (d, buffer, len); + st -= len; + s += len; + d += len; + } + } + dest += rasterlen; + src += rasterlen; + j++; + } + kfree (buffer); + } +} + + + +static void init_bresenham (struct fb_dda *p, short x0, short y0, short x1, short y1) +{ + if (!p) + return; + + p->x = p->xprev = x0; + p->y = p->yprev = y0; + p->s1 = 1; + p->s2 = 1; + + p->dx = x1 - x0; + if (p->dx < 0) { + p->dx = -p->dx; + p->s1 = -1; + } + + p->dy = y1 - y0; + if (p->dy < 0) { + p->dy = -p->dy; + p->s2 = -1; + } + + p->xchange = 0; + + if (p->dy > p->dx) { + int tmp = p->dx; + p->dx = p->dy; + p->dy = tmp; + p->xchange = 1; + } + + p->e = (p->dy<<1) - p->dx; + p->j = 0; +} + + +static void fb_enh_filltriangle (struct fb_info *info, struct fb_draw *p) +{ + struct fb_dda left; + struct fb_dda right; + struct fb_draw p2; + short xres, yres; + + if (!info || !p) + return; + yres = info->var.yres; + if (p->x0 < 0 && p->x1 < 0 && p->x2 < 0) + return; + if (p->y0 < 0 && p->y1 < 0 && p->y2 < 0) + return; + if (p->y0 > p->y1) { + short tmp = p->x0; p->x0 = p->x1; p->x1 = tmp; + tmp = p->y0; p->y0 = p->y1; p->y1 = tmp; + } + if (p->y1 > p->y2) { + short tmp = p->x2; p->x2 = p->x1; p->x1 = tmp; + tmp = p->y2; p->y2 = p->y1; p->y1 = tmp; + } + if (p->y0 > p->y1) { + short tmp = p->x0; p->x0 = p->x1; p->x1 = tmp; + tmp = p->y0; p->y0 = p->y1; p->y1 = tmp; + } + if (p->y1 > p->y2) { + short tmp = p->x2; p->x2 = p->x1; p->x1 = tmp; + tmp = p->y2; p->y2 = p->y1; p->y1 = tmp; + } + xres = info->var.xres; + yres = info->var.yres; + if ((p->x0 >= xres && p->x1 >= xres && p->x2 >= xres) || + (p->y0 >= yres && p->y1 >= yres && p->y2 >= yres)) + return; + /*----------*/ + + init_bresenham (&left, p->x0, p->y0, p->x1, p->y1); + init_bresenham (&right, p->x0, p->y0, p->x2, p->y2); + + if ((p2.clip_valid = p->clip_valid)) { + p2.clip_x0 = p->clip_x0; + p2.clip_y0 = p->clip_y0; + p2.clip_x1 = p->clip_x1; + p2.clip_y1 = p->clip_y1; + } + + while (1) { + char got_ychange = 0; + + if (left.xprev < right.xprev) { + p2.x0 = left.xprev; + p2.x1 = right.xprev; + } else { + p2.x1 = left.xprev; + p2.x0 = right.xprev; + } + p2.y0 = p2.y1 = left.yprev; + p2.color = p->color; + info->enhanced_ops->fb_fillrect (info, &p2); + + /* Advance the left line */ + left.xprev = left.x; + left.yprev = left.y; + + while (!got_ychange) { + if (left.j == left.dx) { + if (left.y == p->y2) + return; + init_bresenham (&left, p->x1, p->y1, p->x2, p->y2); + } + left.j++; + if (left.e >= 0) { + if (left.xchange) + left.x += left.s1; + else { + got_ychange = 1; + left.y += left.s2; + } + left.e -= (left.dx << 1); + } + if (left.xchange) { + got_ychange = 1; + left.y += lef... [truncated message content] |
From: cga <cg...@gm...> - 2006-02-27 06:47:43
|
Miernik wrote: >cga <cg...@gm...> wrote: > > >>I have experimented with linux kernels 2.6.8 and 2.6.12 with the >>"video=atyfb:1400x1050" boot param and this only gives me a black >>screen. >> >> > >There is an option CONFIG_FB_ATY_XL_INIT which is broken. For many >Mach64 cards it won't work if set to "y". Try stting >CONFIG_FB_ATY_XL_INIT=n in your kernel config, and recompile, it should >work. This option will be or already is removed in 2.6.16 kernel, so >when that one is released it should work 'out of the box'. Also in the >latest Debian sid/unstable kernel from package linux-image-2.6.15-1-686 >version 2.6.15-7 it is already removed and ATI Mach64 works OK. > > > Great news..! I may need some time to confirm it works ok with my particular chip due to hardware problems.. I need to install a replacement keyboard on the laptop which hopefully should get here some time this week.. I'll keep you posted. |
From: Miernik <mi...@ff...> - 2006-02-27 04:44:18
|
cga <cg...@gm...> wrote: > I have experimented with linux kernels 2.6.8 and 2.6.12 with the > "video=atyfb:1400x1050" boot param and this only gives me a black > screen. There is an option CONFIG_FB_ATY_XL_INIT which is broken. For many Mach64 cards it won't work if set to "y". Try stting CONFIG_FB_ATY_XL_INIT=n in your kernel config, and recompile, it should work. This option will be or already is removed in 2.6.16 kernel, so when that one is released it should work 'out of the box'. Also in the latest Debian sid/unstable kernel from package linux-image-2.6.15-1-686 version 2.6.15-7 it is already removed and ATI Mach64 works OK. -- Miernik _________________________ xmpp:mi...@am... ___________________/_______________________/ mailto:mi...@ff... Protect Europe from a legal disaster. Petition against software patents http://www.noepatents.org/index_html?LANG=en |
From: cga <cg...@gm...> - 2006-02-26 00:29:24
|
The 2.4 version of the atyfb framebuffer driver works great at my old laptop's native 1400x1050 resolution. I have experimented with linux kernels 2.6.8 and 2.6.12 with the "video=atyfb:1400x1050" boot param and this only gives me a black screen. I assume that the Rage Mobility chip is not supported at this point by the 2.6 version of atyfb (?). Will this be provided in the future or has support for this old chip been dropped altogether..? Thanks. |
From: Geert U. <ge...@li...> - 2006-02-25 08:46:56
|
On Fri, 24 Feb 2006, Mike Bourgeous wrote: > I'm working on a framebuffer driver for a high-definition tuner > card's OSD, and I have two equally bad options for pixel format. > I can choose 24-bit pixels, with every FOUR bytes in reverse > order (even though pixels are three bytes long - that makes for > some interesting pictures when it's not set up right), or 32-bit > pixels, with mandatory transparency. [...] > work without too much work in userspace. My main goal is > to get X to display on the framebuffer. Getting tinyX to work is not that difficult. Using its shadow screen feature, you let it draw to a `normal' 24 bit image of the screen in RAM, and convert all modified rectangular areas to the hardware's format. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li... In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds |
From: Torgeir V. <to...@po...> - 2006-02-25 03:13:55
|
On Fri, 2006-02-24 at 02:26 -0800, Mike Bourgeous wrote: > My main goal is to get X to display on the framebuffer. Isn't it too slow for X? I'd be thinking going the dvb driver route would be the way, since the card is similar in function to full features dvb-s cards? -- Torgeir Veimo <to...@po...> |
From: <fb...@co...> - 2006-02-24 17:43:09
|
Just a quick note, the latest FBUI deals with transparency to an extent. Although not yet implemented, the goal is to eventually use overlays to have semi-transparent windows. Right now transparency is handled in drawing. See here: http://fbui.org Zack Smith -------------- Original message -------------- From: "Mike Bourgeous" <i_a...@ho...> > I'm working on a framebuffer driver for a high-definition tuner > card's OSD, and I have two equally bad options for pixel format. > I can choose 24-bit pixels, with every FOUR bytes in reverse > order (even though pixels are three bytes long - that makes for > some interesting pictures when it's not set up right), or 32-bit > pixels, with mandatory transparency. > > When I try the 24-bit route, I get video, but it looks kind of like > someone took the color columns of an LCD screen and mixed > them up, so the red of one pixel will be before the green of the > pixel to its left or something. > > When I do 32-bit, it seems that no programs pay attention to > the transparency field of fb_var_screeninfo. fbi, for example, > clears the screen to 0x00000000 before drawing its image > data, leaving the screen black. If I manually set all of the > alpha bytes to 0x7f (full opacity), the fbi image is displayed, > but as soon as fbi updates the display everything's black > again. > > Is it possible, without modifying userland software, to either > 1. byte-swap every four bytes with three-byte wide pixels > or > 2. force the transparency byte of all 32-bit pixels to 0x7f > ?? > > I have a modified version of libfbx (u4x.sf.net/projects/libfbx) > that sets the transparency value correctly, which I used to > test the framebuffer driver, but I'd really prefer to have this > work without too much work in userspace. My main goal is > to get X to display on the framebuffer. > > Any help or suggestions would be greatly appreciated. > > My framebuffer driver uses the following driver as a backend: > > http://myhd.sf.net/ > > Mike Bourgeous > > _________________________________________________________________ > Express yourself instantly with MSN Messenger! Download today - it's FREE! > http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/ > > > > ------------------------------------------------------- > This SF.Net email is sponsored by xPML, a groundbreaking scripting language > that extends applications into web and mobile media. Attend the live webcast > and join the prime developer group breaking into this new coding territory! > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 > _______________________________________________ > Linux-fbdev-users mailing list > Lin...@li... > https://lists.sourceforge.net/lists/listinfo/linux-fbdev-users |
From: Mike B. <i_a...@ho...> - 2006-02-24 10:26:38
|
I'm working on a framebuffer driver for a high-definition tuner card's OSD, and I have two equally bad options for pixel format. I can choose 24-bit pixels, with every FOUR bytes in reverse order (even though pixels are three bytes long - that makes for some interesting pictures when it's not set up right), or 32-bit pixels, with mandatory transparency. When I try the 24-bit route, I get video, but it looks kind of like someone took the color columns of an LCD screen and mixed them up, so the red of one pixel will be before the green of the pixel to its left or something. When I do 32-bit, it seems that no programs pay attention to the transparency field of fb_var_screeninfo. fbi, for example, clears the screen to 0x00000000 before drawing its image data, leaving the screen black. If I manually set all of the alpha bytes to 0x7f (full opacity), the fbi image is displayed, but as soon as fbi updates the display everything's black again. Is it possible, without modifying userland software, to either 1. byte-swap every four bytes with three-byte wide pixels or 2. force the transparency byte of all 32-bit pixels to 0x7f ?? I have a modified version of libfbx (u4x.sf.net/projects/libfbx) that sets the transparency value correctly, which I used to test the framebuffer driver, but I'd really prefer to have this work without too much work in userspace. My main goal is to get X to display on the framebuffer. Any help or suggestions would be greatly appreciated. My framebuffer driver uses the following driver as a backend: http://myhd.sf.net/ Mike Bourgeous _________________________________________________________________ Express yourself instantly with MSN Messenger! Download today - it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/ |
From: James S. <jam...@op...> - 2006-02-20 05:39:07
|
On Mon, 2006-02-20 at 12:57 +0800, Antonino A. Daplas wrote: > James Steward wrote: > > On Mon, 2006-02-20 at 09:03 +0800, Antonino A. Daplas wrote: > >> James Steward wrote: > >>> On Mon, 2006-02-20 at 08:28 +0800, Antonino A. Daplas wrote: > >>>> James Steward wrote: > >>>>> On Sat, 2006-02-18 at 12:52 +1100, James Steward wrote: > >>>>>> On Fri, 2006-02-17 at 17:31 +0800, Antonino A. Daplas wrote: > >>>>>>> James Steward wrote: > >>>>> End of set_ctrlr_state state 1->1 {old state -> new state} > >>>>> FDADR0 0xea000210 > >>>>> FDADR1 0xa73f0fc0 > >>>>> LCCR0 0x0030187a <-- bit[0] for some reason now cleared!! > >>>>> LCCR1 0x0000013f > >>>>> LCCR2 0x010108ef > >>>>> LCCR3 0x00400020 > >>>>> > >>>>> So set_ctrlr_state is called a second time and afterwards the enable bit > >>>>> is cleared. > >>>>> > >>>>> Any further thoughts? > >>>> pxafb_set_par is called first by the pxafb before register_framebuffer, then > >>>> pxafb_set_par() will be called a second time during fbcon initialization. For > >>>> some reason, the second set_par() disables your controller. > >>>> > >>>> Temporarily, find out first if your driver works. You can comment out the explicit > >>>> pxafb_set_par() call in pxafb_probe() (or for correctness sake, enclose it in #ifndef CONFIG_FRAMEBUFFER_CONSOLE/#endif). > >>>> > >>>> Or, just add something like this in the beginning of pxafb_set_par(). > >>>> > >>>> static int initialized = 0; > >>>> > >>>> if (initialized) > >>>> return 0; > >>>> > >>>> initialized = 1; > >>> CONFIG_FRAMEBUFFER_CONSOLE doesn't appear in my .config so I tried the > >>> second method of making sure set_par() is only called once. > >>> > >>>> The above 2 methods will hopefully eliminate the extra call to set_par(). > >>>> > >>>> Once you've verified that your driver first, then it's time to debug why the enable bit > >>>> is cleared. > >>>> > >>>> On the first call, the state is CM_STARTUP, on the second call, the state is CM_ENABLE. > >>>> You can probably debug how the code differs depending on the state. > >>> The debug messages I posted contained all debug messages - there were > >>> no snips in between. set_par() is only called once by the looks. > >> Okay. > >> > >>> The only other place I see set_ctrlr_state() called possibly is > >>> pxafb_task(), as CONFIG_PM is not set and neither is CONFIG_CPU_FREQ. > >>> > >>> So after the initial enable in pxafb_probe(), pxafb_task() is the only > >>> other candidate I can see. I'll command out the call to > >>> set_ctrlr_state() there and see what happens. > >> pxafb_task is the callback of the workqueue. Check what functions call > >> pxafb_schedule_work(). > > > >>From further debugging code, I still can't see what calls > > set_ctrlr_state(). If I comment out the call in pxafb_task() it's not > > enabled to begin with. > > > > I have noticed that on the last call to set_ctrlr_state() that FDADR0 is > > changed. > > > > I'm not building any console drivers by the way. > > > > I see where set_ctrlr_state() is called. It's after register_framebuffer() in > pxafb_probe(). Ok, so it's called near the end of pxafb_probe() as you say, also in pxafb_task(), as well as pxafb_freq_transition() however CONFIG_CPU_FREQ is not defined so that doesn't count, neither does the calls in pxafb_suspend() or pxafb_resume() as CONFIG_PM is not defined. So it appears the pxafb_probe() happens after the pxafb_task(). I shall disable the pxafb_probe call and see if it stays enabled. ...rebooting now... So now the second call to set_ctrlr_state() is commented out, but the controller is still disabled! End of set_ctrlr_state state 7->1 FDADR0 0x00000000 FDADR1 0xa7354fc0 LCCR0 0x0030187b <--looks good here LCCR1 0x0000013f LCCR2 0x010108ef LCCR3 0x00400020 # pxaregs LCCR0 LCD Controller Control Register 0 (7-23) LCCR0 0x0030187a 00000000 00110000 00011000 01111010 LCCR0_ENB 0 LCD controller enable Not enabled now. In any case, as the previous state was C_ENABLE and the state sent from pxafb_probe() is also C_ENABLE, set_ctrlr_state() shouldn't do anything. So somewhere inbetween is where the disablement is happening. Feel like I need a white cane here. I'm sure the answer is there - I just don't see it. Regards, James. |
From: Antonino A. D. <ad...@gm...> - 2006-02-20 04:05:38
|
James Steward wrote: > On Sat, 2006-02-18 at 12:52 +1100, James Steward wrote: >> On Fri, 2006-02-17 at 17:31 +0800, Antonino A. Daplas wrote: >>> James Steward wrote: > End of set_ctrlr_state state 1->1 {old state -> new state} > FDADR0 0xea000210 > FDADR1 0xa73f0fc0 > LCCR0 0x0030187a <-- bit[0] for some reason now cleared!! > LCCR1 0x0000013f > LCCR2 0x010108ef > LCCR3 0x00400020 > > So set_ctrlr_state is called a second time and afterwards the enable bit > is cleared. > > Any further thoughts? pxafb_set_par is called first by the pxafb before register_framebuffer, then pxafb_set_par() will be called a second time during fbcon initialization. For some reason, the second set_par() disables your controller. Temporarily, find out first if your driver works. You can comment out the explicit pxafb_set_par() call in pxafb_probe() (or for correctness sake, enclose it in #ifndef CONFIG_FRAMEBUFFER_CONSOLE/#endif). Or, just add something like this in the beginning of pxafb_set_par(). static int initialized = 0; if (initialized) return 0; initialized = 1; The above 2 methods will hopefully eliminate the extra call to set_par(). Once you've verified that your driver first, then it's time to debug why the enable bit is cleared. On the first call, the state is CM_STARTUP, on the second call, the state is CM_ENABLE. You can probably debug how the code differs depending on the state. Tony |
From: James S. <jam...@op...> - 2006-02-19 22:44:43
|
On Sat, 2006-02-18 at 12:52 +1100, James Steward wrote: > On Fri, 2006-02-17 at 17:31 +0800, Antonino A. Daplas wrote: > > James Steward wrote: > > > pxa2xx-fb pxa2xx-fb: Upper and lower margins must be 0 in passive mode > > > > > > *** Why is this so? It worked with uboot with these settings!*** > > > > These are just over-verbose messages... > > Ok, I'll ignore then. > > > > So who's disabling the FB? > > > > Try unconditinally calling pxafb_schedule_work() in pxafb_activate_var(). > > Then reread the register. > > > > Thanks Tony! I'll give it a try first thing Monday morning. > Sorry Tony but that didn't seem to do anything for me. I've since added more debuggery... pxafb: Configuring PXA LCD var: xres=320 hslen=1 lm=1 rm=1 var: yres=240 vslen=3 um=1 bm=1 var: pixclock=643023 pcd=32 nlccr0 = 0x0030187a <-- The enable bit[0] is not set. nlccr1 = 0x0000013f nlccr2 = 0x010108ef nlccr3 = 0x00400020 fbi->dmadesc_fblow_cpu = 0xffc00fc8 fbi->dmadesc_fbhigh_cpu = 0xffc00fd8 fbi->dmadesc_palette_cpu = 0xffc00fe8 fbi->dmadesc_fblow_dma = 0xa73f0fc8 fbi->dmadesc_fbhigh_dma = 0xa73f0fd8 fbi->dmadesc_palette_dma = 0xa73f0fe8 fbi->dmadesc_fblow_cpu->fdadr = 0xa73f0fc8 fbi->dmadesc_fbhigh_cpu->fdadr = 0xa73f0fe8 fbi->dmadesc_palette_cpu->fdadr = 0xa73f0fd8 fbi->dmadesc_fblow_cpu->fsadr = 0xa73f3580 fbi->dmadesc_fbhigh_cpu->fsadr = 0xa73f1000 fbi->dmadesc_palette_cpu->fsadr = 0xa73f0ff8 fbi->dmadesc_fblow_cpu->ldcmd = 0x2580 fbi->dmadesc_fbhigh_cpu->ldcmd = 0x2580 fbi->dmadesc_palette_cpu->ldcmd = 0x4000008 pxafb: Enabling LCD controller fdadr0 0xa73f0fe8 fdadr1 0xa73f0fc8 reg_lccr0 0x0030187a <-- The enable bit[0] is still not set. reg_lccr1 0x0000013f reg_lccr2 0x010108ef reg_lccr3 0x00400020 pxafb: End of enabling LCD controller FDADR0 0x00000000 FDADR1 0xa73f0fc0 LCCR0 0x0030187b <-- Code in the enable routine sets bit[0] LCCR1 0x0000013f LCCR2 0x010108ef LCCR3 0x00400020 pxafb: LCD power on pxafb: backlight on End of set_ctrlr_state state 7->1 {old state -> new state} FDADR0 0x00000000 FDADR1 0xa73f0fc0 LCCR0 0x0030187b <-- bit[0] still set at the end of set_ctrlr_state LCCR1 0x0000013f LCCR2 0x010108ef LCCR3 0x00400020 End of set_ctrlr_state state 1->1 {old state -> new state} FDADR0 0xea000210 FDADR1 0xa73f0fc0 LCCR0 0x0030187a <-- bit[0] for some reason now cleared!! LCCR1 0x0000013f LCCR2 0x010108ef LCCR3 0x00400020 So set_ctrlr_state is called a second time and afterwards the enable bit is cleared. Any further thoughts? Regards, James. |
From: James S. <jam...@op...> - 2006-02-18 01:40:59
|
On Fri, 2006-02-17 at 17:31 +0800, Antonino A. Daplas wrote: > James Steward wrote: > > pxa2xx-fb pxa2xx-fb: Upper and lower margins must be 0 in passive mode > > > > *** Why is this so? It worked with uboot with these settings!*** > > These are just over-verbose messages... Ok, I'll ignore then. > > So who's disabling the FB? > > Try unconditinally calling pxafb_schedule_work() in pxafb_activate_var(). > Then reread the register. > Thanks Tony! I'll give it a try first thing Monday morning. Regards, James. |
From: Antonino A. D. <ad...@gm...> - 2006-02-17 13:16:27
|
James Steward wrote: > Hi All, > > Please note that I am now a suscribed member so if a previous email of > the same subject does make it through the moderator, ignore it. > > I have a question regarding the PXA framebuffer support. I've emailed > the ARM linux list but to no avail. We've configured uboot to talk to > the LCD connected to our board and the LCD works fine. > > Setting up the pxafb for the kernel is proving somewhat more testing. > Kernel is 2.6.15.1 with no patches to the video drivers. > > My current modprobe looks like this; > modprobe pxafb \ > options=mode:320x240-1,mono,single,vsynclen:3,hsynclen:1,left:1, \ > right:1,upper:1,lower:1,vsync:1,hsync:1,pixclockpol:0,4pix, \ > pixclock:643023 > > This gives the same LCCRX register setup as uboot was configured for, > with just 2 differences. > LCCR0_PDD=1 in uboot, =0 from pxafb. > LCCR0_QDM=0 in uboot, =1 from pxafb. > > I forced LCCR0_PDD on but with no effect. > > I turned on some debugging and got the following; > pxa2xx-fb pxa2xx-fb: overriding resolution: 320x240 > pxa2xx-fb pxa2xx-fb: overriding bit depth: 1 > pxa2xx-fb pxa2xx-fb: override vsynclen: 3 > pxa2xx-fb pxa2xx-fb: override hsynclen: 1 > pxa2xx-fb pxa2xx-fb: override left: 1 > pxa2xx-fb pxa2xx-fb: override right: 1 > pxa2xx-fb pxa2xx-fb: override upper: 1 > pxa2xx-fb pxa2xx-fb: override lower: 1 > pxa2xx-fb pxa2xx-fb: override vsync: Active High > pxa2xx-fb pxa2xx-fb: override hsync: Active High > pxa2xx-fb pxa2xx-fb: override pixel clock polarity: falling edge > pxa2xx-fb pxa2xx-fb: override pixclock: 643023 > pxa2xx-fb pxa2xx-fb: Upper and lower margins must be 0 in passive mode > > *** Why is this so? It worked with uboot with these settings!*** These are just over-verbose messages... > > pxafb: palette_mem_size = 0x00000020 > pxafb: set_par > pxafb: palette_mem_size = 0x00000008 > pxafb: true_color = 0 > pxafb: Configuring PXA LCD > var: xres=320 hslen=1 lm=1 rm=1 > var: yres=240 vslen=3 um=1 bm=1 > var: pixclock=643023 pcd=32 > nlccr0 = 0x0030187a > nlccr1 = 0x0000013f > nlccr2 = 0x010108ef > nlccr3 = 0x00400020 > pxafb: Enabling LCD controller > fdadr0 0xa7fd4fe8 > fdadr1 0xa7fd4fc8 > reg_lccr0 0x0030187a > reg_lccr1 0x0000013f > reg_lccr2 0x010108ef > reg_lccr3 0x00400020 > FDADR0 0xa7fd4fe0 > FDADR1 0xa7fd4fc0 > LCCR0 0x0030187b > LCCR1 0x0000013f > LCCR2 0x010108ef > LCCR3 0x00400020 > pxafb: LCD power on > pxafb: backlight on > > However when I run pxaregs LCCR0 I find that the LCCR0_ENB is not set - > but the debug shows it was set by the driver. > > So who's disabling the FB? Try unconditinally calling pxafb_schedule_work() in pxafb_activate_var(). Then reread the register. Tony |
From: James S. <jam...@op...> - 2006-02-17 03:19:50
|
Hi All, Please note that I am now a suscribed member so if a previous email of the same subject does make it through the moderator, ignore it. I have a question regarding the PXA framebuffer support. I've emailed the ARM linux list but to no avail. We've configured uboot to talk to the LCD connected to our board and the LCD works fine. Setting up the pxafb for the kernel is proving somewhat more testing. Kernel is 2.6.15.1 with no patches to the video drivers. My current modprobe looks like this; modprobe pxafb \ options=mode:320x240-1,mono,single,vsynclen:3,hsynclen:1,left:1, \ right:1,upper:1,lower:1,vsync:1,hsync:1,pixclockpol:0,4pix, \ pixclock:643023 This gives the same LCCRX register setup as uboot was configured for, with just 2 differences. LCCR0_PDD=1 in uboot, =0 from pxafb. LCCR0_QDM=0 in uboot, =1 from pxafb. I forced LCCR0_PDD on but with no effect. I turned on some debugging and got the following; pxa2xx-fb pxa2xx-fb: overriding resolution: 320x240 pxa2xx-fb pxa2xx-fb: overriding bit depth: 1 pxa2xx-fb pxa2xx-fb: override vsynclen: 3 pxa2xx-fb pxa2xx-fb: override hsynclen: 1 pxa2xx-fb pxa2xx-fb: override left: 1 pxa2xx-fb pxa2xx-fb: override right: 1 pxa2xx-fb pxa2xx-fb: override upper: 1 pxa2xx-fb pxa2xx-fb: override lower: 1 pxa2xx-fb pxa2xx-fb: override vsync: Active High pxa2xx-fb pxa2xx-fb: override hsync: Active High pxa2xx-fb pxa2xx-fb: override pixel clock polarity: falling edge pxa2xx-fb pxa2xx-fb: override pixclock: 643023 pxa2xx-fb pxa2xx-fb: Upper and lower margins must be 0 in passive mode *** Why is this so? It worked with uboot with these settings!*** pxafb: palette_mem_size = 0x00000020 pxafb: set_par pxafb: palette_mem_size = 0x00000008 pxafb: true_color = 0 pxafb: Configuring PXA LCD var: xres=320 hslen=1 lm=1 rm=1 var: yres=240 vslen=3 um=1 bm=1 var: pixclock=643023 pcd=32 nlccr0 = 0x0030187a nlccr1 = 0x0000013f nlccr2 = 0x010108ef nlccr3 = 0x00400020 pxafb: Enabling LCD controller fdadr0 0xa7fd4fe8 fdadr1 0xa7fd4fc8 reg_lccr0 0x0030187a reg_lccr1 0x0000013f reg_lccr2 0x010108ef reg_lccr3 0x00400020 FDADR0 0xa7fd4fe0 FDADR1 0xa7fd4fc0 LCCR0 0x0030187b LCCR1 0x0000013f LCCR2 0x010108ef LCCR3 0x00400020 pxafb: LCD power on pxafb: backlight on However when I run pxaregs LCCR0 I find that the LCCR0_ENB is not set - but the debug shows it was set by the driver. So who's disabling the FB? If I spec 320x240-8, the enable bit stays set and I get a screen full of beautiful vertical lines about 4 pixels appart - not very useful. Any ideas where I'm going wrong? I did RTFM and googled too but still don't see what the problem is. Regards, James. |
From: James S. <jam...@op...> - 2006-02-17 02:42:02
|
Hi All, Please note that I am not a suscribed member so please reply direct to me (jamessteward_AT_optusnet.com.au replacing the _AT_ with you know what :-) I have a question regarding the PXA framebuffer support. I've emailed the ARM linux list but to no avail. We've configured uboot to talk to the LCD connected to our board and the LCD works fine. Setting up the pxafb for the kernel is proving somewhat more testing. My current modprobe looks like this; modprobe pxafb \ options=mode:320x240-1,mono,single,vsynclen:3,hsynclen:1,left:1, \ right:1,upper:1,lower:1,vsync:1,hsync:1,pixclockpol:0,4pix, \ pixclock:643023 This gives the same LCCRX register setup as uboot was configured for, with just 2 differences. LCCR0_PDD=1 in uboot, =0 from pxafb. LCCR0_QDM=0 in uboot, =1 from pxafb. I forced LCCR0_PDD on but with no effect. I turned on some debugging and got the following; pxa2xx-fb pxa2xx-fb: overriding resolution: 320x240 pxa2xx-fb pxa2xx-fb: overriding bit depth: 1 pxa2xx-fb pxa2xx-fb: override vsynclen: 3 pxa2xx-fb pxa2xx-fb: override hsynclen: 1 pxa2xx-fb pxa2xx-fb: override left: 1 pxa2xx-fb pxa2xx-fb: override right: 1 pxa2xx-fb pxa2xx-fb: override upper: 1 pxa2xx-fb pxa2xx-fb: override lower: 1 pxa2xx-fb pxa2xx-fb: override vsync: Active High pxa2xx-fb pxa2xx-fb: override hsync: Active High pxa2xx-fb pxa2xx-fb: override pixel clock polarity: falling edge pxa2xx-fb pxa2xx-fb: override pixclock: 643023 pxa2xx-fb pxa2xx-fb: Upper and lower margins must be 0 in passive mode *** Why is this so? It worked with uboot with these settings!*** pxafb: palette_mem_size = 0x00000020 pxafb: set_par pxafb: palette_mem_size = 0x00000008 pxafb: true_color = 0 pxafb: Configuring PXA LCD var: xres=320 hslen=1 lm=1 rm=1 var: yres=240 vslen=3 um=1 bm=1 var: pixclock=643023 pcd=32 nlccr0 = 0x0030187a nlccr1 = 0x0000013f nlccr2 = 0x010108ef nlccr3 = 0x00400020 pxafb: Enabling LCD controller fdadr0 0xa7fd4fe8 fdadr1 0xa7fd4fc8 reg_lccr0 0x0030187a reg_lccr1 0x0000013f reg_lccr2 0x010108ef reg_lccr3 0x00400020 FDADR0 0xa7fd4fe0 FDADR1 0xa7fd4fc0 LCCR0 0x0030187b LCCR1 0x0000013f LCCR2 0x010108ef LCCR3 0x00400020 pxafb: LCD power on pxafb: backlight on However when I run pxaregs LCCR0 I find that the LCCR0_ENB is not set - but the debug shows it was set by the driver. So who's disabling the FB? If I spec 320x240-8, the enable bit stays set and I get a screen full of beautiful vertical lines about 4 pixels appart - not very useful. Any ideas where I'm going wrong? I did RTFM and googled too but still don't see what the problem is. Regards, James. |
From: Jenkins, C. <Cli...@xe...> - 2006-02-01 12:04:07
|
> /* Open the file for reading and writing */ > fbfd =3D open("/dev/fb0", O_RDWR); > printf("\nfbfd =3D %d",fbfd); =20 > Return Values of > > fbfd =3D -1 I suggest you change your code to give you more information about the type of error occurring. When a system call such as open() returns a negative value, the global value "errno" also gets set. You can use "perror()" to print it. Use the "man" command to find out all about open, errno, perror etc. Read all the FB documentation in the kernel Documentation directory. Use search engines. One possibility is that there is no "/dev/fb0" device node in the filesystem. Clive |
From: Crazy B. <cra...@ya...> - 2006-01-31 15:10:48
|
Hi, First of all, I would like to thankful to you for your fast response. Please forget about yesterdays mail. In my previous mail, I did a mistake. I have one more doubt. i.e., When I am trying to execute the below Framebuffer example program in Lepton (http://mulinux.dotsrc.org/lepton.html) linux and Redhat Linux, My program is unable to open the framebuffer device (/dev/fb0). This program is successfully running in SuSe Linux 9.3. How can I open the framebuffer (/dev/fb0) device in Redhat or Lepton Linux? What can I do? Please show me a solution. The example program is: #include <unistd.h> #include <stdio.h> #include <fcntl.h> #include <linux/fb.h> #include <sys/mman.h> int main(void) { int fbfd,fbfd1,fbfd2; struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; printf("\nReturn Values of \n\n"); /* Open the file for reading and writing */ fbfd = open("/dev/fb0", O_RDWR); printf("\nfbfd = %d",fbfd); /* Get fixed screen information */ fbfd1 = ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo); printf("\n fbfd1 = %d",fbfd1); /* Get variable screen information */ fbfd2 = ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo); printf("\nfbfd2 = %d\n",fbfd2); printf("\n\n%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel ); close(fbfd); return 0; } The output of the above program is : Return Values of fbfd = -1 fbfd1 = -1 fbfd2 = -1 Thatmeans, Framebuffer device is not opening. So, to achieve this problem, what can I do? This is really very urgent. Please show me a solution. I will be waiting for your reply. Thank you very much for considering your valuable time for me. With regards, Chandra. --------------------------------- Yahoo! Autos. Looking for a sweet ride? Get pricing, reviews, & more on new and used cars. |
From: interzone <int...@fr...> - 2006-01-28 12:37:10
|
Hi, i am new to this list. Is there a way to use the accelerated functions of a framebuffer driver (hitfb in my case) , like bitblt, fillrect, etc... from an userland program ? the fb_info structure , perhaps can be reach by userland via a specific ioctl ? or do I have to access directly to the hardware registers specific to hitfb driver, to use the accelerated functions... thank in advance for your help... |
From: Antonino A. D. <ad...@gm...> - 2006-01-23 09:07:20
|
Crazy Boy wrote: > Hi, > > I am using Lepton Floppy Linux and Redhat Linux. When I am trying to > execute the Framebuffer sample program, It is displaying the below error > message: > > The framebuffer device was opened successfully. > Error reading fixed screen information. > Error reading variable screen information. > > Actually, It is opening Framebuffer (/dev/fb0) device successfully. Opening /dev/fb0 will always be successful even if the device does not exist. What's the output of 'cat /proc/fb' If it is empty, then you need to configure a framebuffer device. Tony |
From: Crazy B. <cra...@ya...> - 2006-01-23 07:22:12
|
Hi, I am using Lepton Floppy Linux and Redhat Linux. When I am trying to execute the Framebuffer sample program, It is displaying the below error message: The framebuffer device was opened successfully. Error reading fixed screen information. Error reading variable screen information. Actually, It is opening Framebuffer (/dev/fb0) device successfully. But, it is unable to read the Fixed screen information (FBIOGET_FSCREENINFO) and Variable screen information (FBIOGET_VSCREENINFO). fbset command is also not working. What can I do? Please give me the solution. Here, I am giving the sample code of framebuffer. Please run this and see the output. #include <unistd.h> #include <stdio.h> #include <fcntl.h> #include <linux/fb.h> #include <sys/mman.h> int main(void) { int fbfd = 0; struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; long int screensize = 0; char *fbp = 0; /* Open the file for reading and writing */ fbfd = open("/dev/fb0", O_RDWR); if (!fbfd) { printf("Error: cannot open framebuffer device.\n"); exit(1); } printf("The framebuffer device was opened successfully.\n"); /* Get fixed screen information */ if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) { printf("Error reading fixed screen information.\n"); exit(2); } else printf("\nSuccesfully Read the Fixed Screen Information\n"); /* Get variable screen information */ if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) { printf("Error reading variable screen information.\n"); exit(3); } else printf("\n Successfully Read the Variable Information\n"); printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel ); /* Figure out the size of the screen in bytes */ screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; /* Map the device to memory */ fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); if ((int)fbp == -1) { printf("Error: failed to map framebuffer device to memory.\n"); exit(4); } printf("The framebuffer device was mapped to memory successfully.\n"); munmap(fbp, screensize); close(fbfd); return 0; } I will be waiting for your reply. Thank you. With regards, Chandra. --------------------------------- What are the most popular cars? Find out at Yahoo! Autos |
From: Crazy B. <cra...@ya...> - 2006-01-21 06:24:31
|
Hi Friends, When I am opening /dev/fb0 device, it is opening successfully. But, Through Ioctl, When I am trying to read the framebuffer screen information (Fixed screen information and variable screen information), it is not reading the information and display the error message i.e., "Error reading fixed screen information". What can i do? I will be waiting for your reply. Thank you. With regards, Chandra. --------------------------------- What are the most popular cars? Find out at Yahoo! Autos |
From: Antonino A. D. <ad...@gm...> - 2006-01-09 01:12:28
|
Tanel Käär wrote: > Hi > > I've been given an assignement to write the fb driver to S3 Tio 64 PCI > card, which should work under linux kernel 2.6. > > I read the basic concepts about fb drivers but haven't found any clues > an tutorials how to start writing the code and how to test it. I'm also > not very familiar with compiling kernel from source and adding moules to > kernel. > > Has anyone already written some code for this piece or does a fb driver > already exist for this device under 2.6 or previous linux kernel versions? > There's a driver for the S3trio in 2.4, but still not ported to 2.6. It is also a non-x86 driver. > All hints are welcome :) You can try looking at drivers/video/skeletonfb.c (preferably the one in the latest mm tree, as I've made some changes to it). You can first write a driver with a static var (does not change modes on the fly) to keep it simple. Then slowly advance to a more complete driver. vesafb is one of the simplest driver, which only supports the most essential functionality. You can always write to the list (fbdev-devel) whenever you're stuck :-) Tony |