SOURCES (LINUX_2_6): kernel-uvesafb.patch (NEW) - http://dev.gento...

zbyniu zbyniu at pld-linux.org
Tue Mar 18 01:52:44 CET 2008


Author: zbyniu                       Date: Tue Mar 18 00:52:44 2008 GMT
Module: SOURCES                       Tag: LINUX_2_6
---- Log message:
- http://dev.gentoo.org/~spock/projects/uvesafb/archive/uvesafb-0.1-rc3-2.6.23-rc3.patch

---- Files affected:
SOURCES:
   kernel-uvesafb.patch (NONE -> 1.1.2.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/kernel-uvesafb.patch
diff -u /dev/null SOURCES/kernel-uvesafb.patch:1.1.2.1
--- /dev/null	Tue Mar 18 01:52:44 2008
+++ SOURCES/kernel-uvesafb.patch	Tue Mar 18 01:52:39 2008
@@ -0,0 +1,2583 @@
+diff --git a/Documentation/fb/uvesafb.txt b/Documentation/fb/uvesafb.txt
+new file mode 100644
+index 0000000..1a3b65b
+--- /dev/null
++++ b/Documentation/fb/uvesafb.txt
+@@ -0,0 +1,188 @@
++
++uvesafb - A Generic Driver for VBE2+ compliant video cards
++==========================================================
++
++1. Requirements
++---------------
++
++uvesafb should work with any video card that has a Video BIOS compliant
++with the VBE 2.0 standard.
++
++Unlike other drivers, uvesafb makes use of a userspace helper called
++v86d.  v86d is used to run the x86 Video BIOS code in a simulated and
++controlled environment.  This allows uvesafb to function on arches other
++than x86.  Check the v86d documentation for a list of currently supported
++arches.
++
++v86d source code can be downloaded from the following website:
++  http://dev.gentoo.org/~spock/projects/uvesafb
++
++Please refer to the v86d documentation for detailed configuration and
++installation instructions.
++
++Note that the v86d userspace helper has to be available at all times in
++order for uvesafb to work properly.  If you want to use uvesafb during
++early boot, you will have to include v86d into an initramfs image, and
++either compile it into the kernel or use it as an initrd.
++
++2. Caveats and limitations
++--------------------------
++
++uvesafb is a _generic_ driver which supports a wide variety of video
++cards, but which is ultimately limited by the Video BIOS interface.
++The most important limitations are:
++
++- Lack of any type of acceleration.
++- A strict and limited set of supported video modes.  Often the native
++  or most optimal resolution/refresh rate for your setup will not work
++  with uvesafb, simply because the Video BIOS doesn't support the
++  video mode you want to use.  This can be especially painful with
++  widescreen panels, where native video modes don't have the 4:3 aspect
++  ratio, which is what most BIOS-es are limited to.
++- Adjusting the refresh rate is only possible with a VBE 3.0 compliant
++  Video BIOS.  Note that many nVidia Video BIOS-es claim to be VBE 3.0
++  compliant, while they simply ignore any refresh rate settings.
++
++3. Configuration
++----------------
++
++uvesafb can be compiled either as a module, or directly into the kernel.
++In both cases it supports the same set of configuration options, which
++are either given on the kernel command line or as module parameters, e.g.:
++
++ video=uvesafb:1024x768-32,mtrr:3,ywrap (compiled into the kernel)
++
++ # modprobe uvesafb mode=1024x768-32 mtrr=3 scroll=ywrap  (module)
++
++Accepted options:
++
++ypan    Enable display panning using the VESA protected mode
++        interface.  The visible screen is just a window of the
++        video memory, console scrolling is done by changing the
++        start of the window.  Available on x86 only.
++
++ywrap   Same as ypan, but assumes your gfx board can wrap-around
++        the video memory (i.e. starts reading from top if it
++        reaches the end of video memory).  Faster than ypan.
++		Available on x86 only.
++
++redraw  Scroll by redrawing the affected part of the screen, this
++        is the safe (and slow) default.
++
++(If you're using uvesafb as a module, the above three options are
++ used a parameter of the scroll option, e.g. scroll=ypan.)
++
++vgapal  Use the standard VGA registers for palette changes.
++
++pmipal  Use the protected mode interface for palette changes.
++        This is the default if the protected mode interface is
++        available.  Available on x86 only.
++
++mtrr:n  Setup memory type range registers for the framebuffer
++        where n:
++              0 - disabled (equivalent to nomtrr) (default)
++              1 - uncachable
++              2 - write-back
++              3 - write-combining
++              4 - write-through
++
++        If you see the following in dmesg, choose the type that matches
++        the old one.  In this example, use "mtrr:2".
++...
++mtrr: type mismatch for e0000000,8000000 old: write-back new: write-combining
++...
++
++nomtrr  Do not use memory type range registers.
++
++vremap:n
++        Remap 'n' MiB of video RAM.  If 0 or not specified, remap memory
++        according to video mode.
++
++vtotal:n
++        If the video BIOS of your card incorrectly determines the total
++        amount of video RAM, use this option to override the BIOS (in MiB).
++
++<mode>  The mode you want to set, in the standard modedb format.  Refer to
++        modedb.txt for a detailed description.  When uvesafb is compiled as
++        a module, the mode string should be provided as a value of the
++        'mode' option.
++
++vbemode:x
++        Force the use of VBE mode x.  The mode will only be set if it's
++        found in the VBE-provided list of supported modes.
++        NOTE: The mode number 'x' should be specified in VESA mode number
++        notation, not the Linux kernel one (eg. 257 instead of 769).
++        HINT: If you use this option because normal <mode> parameter does
++        not work for you and you use a X server, you'll probably want to
++        set the 'nocrtc' option to ensure that the video mode is properly
++        restored after console <-> X switches.
++
++nocrtc  Do not use CRTC timings while setting the video mode.  This option
++        has any effect only if the Video BIOS is VBE 3.0 compliant.  Use it
++        if you have problems with modes set the standard way.  Note that
++        using this option implies that any refresh rate adjustments will
++        be ignored and the refresh rate will stay at your BIOS default (60 Hz).
++
++noedid  Do not try to fetch and use EDID-provided modes.
++
++noblank Disable hardware blanking.
++
++v86d:path
++        Set path to the v86d executable. This option is only available as
++        a module parameter, and not as a part of the video= string.  If you
++        need to use it and have uvesafb built into the kernel, use
++        uvesafb.v86d="path".
++
++Additionally, the following parameters may be provided.  They all override the
++EDID-provided values and BIOS defaults.  Refer to your monitor's specs to get
++the correct values for maxhf, maxvf and maxclk for your hardware.
++
++maxhf:n     Maximum horizontal frequency (in kHz).
++maxvf:n     Maximum vertical frequency (in Hz).
++maxclk:n    Maximum pixel clock (in MHz).
++
++4. The sysfs interface
++----------------------
++
++uvesafb provides several sysfs nodes for configurable parameters and
++additional information.
++
++Driver attributes:
++
++/sys/bus/platform/drivers/uvesafb
++  - v86d (default: /sbin/v86d)
++    Path to the v86d executable. v86d is started by uvesafb
++    if an instance of the daemon isn't already running.
++
++Device attributes:
++
++/sys/bus/platform/drivers/uvesafb/uvesafb.0
++  - nocrtc
++    Use the default refresh rate (60 Hz) if set to 1.
++
++  - oem_product_name
++  - oem_product_rev
++  - oem_string
++  - oem_vendor
++    Information about the card and its maker.
++
++  - vbe_modes
++    A list of video modes supported by the Video BIOS along with their
++    VBE mode numbers in hex.
++
++  - vbe_version
++    A BCD value indicating the implemented VBE standard.
++
++5. Miscellaneous
++----------------
++
++Uvesafb will set a video mode with the default refresh rate and timings
++from the Video BIOS if you set pixclock to 0 in fb_var_screeninfo.
++
++
++--
++ Michal Januszewski <spock at gentoo.org>
++ Last updated: 2007-06-16
++
++ Documentation of the uvesafb options is loosely based on vesafb.txt.
++
+diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
+index 5216c11..e152eed 100644
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -592,6 +592,25 @@ config FB_TGA
+ 
+ 	  Say Y if you have one of those.
+ 
++config FB_UVESA
++	tristate "Userspace VESA VGA graphics support"
++	depends on FB
++	select CONNECTOR
++	select FB_CFB_FILLRECT
++	select FB_CFB_COPYAREA
++	select FB_CFB_IMAGEBLIT
++	select FB_MODE_HELPERS
++	help
++	  This is the frame buffer driver for generic VBE 2.0 compliant
++	  graphic cards. It can also take advantage of VBE 3.0 features,
++	  such as refresh rate adjustment.
++
++	  This driver generally provides more features than vesafb but
++	  requires a userspace helper application called 'v86d'. See
++	  <file:Documentation/fb/uvesafb.txt> for more information.
++
++	  If unsure, say N.
++
+ config FB_VESA
+ 	bool "VESA VGA graphics support"
+ 	depends on (FB = y) && X86
+diff --git a/drivers/video/Makefile b/drivers/video/Makefile
+index 06eec7b..67dc278 100644
+--- a/drivers/video/Makefile
++++ b/drivers/video/Makefile
+@@ -115,6 +115,7 @@ obj-$(CONFIG_FB_XILINX)           += xilinxfb.o
+ obj-$(CONFIG_FB_OMAP)             += omap/
+ 
+ # Platform or fallback drivers go here
++obj-$(CONFIG_FB_UVESA)            += uvesafb.o
+ obj-$(CONFIG_FB_VESA)             += vesafb.o
+ obj-$(CONFIG_FB_IMAC)             += imacfb.o
+ obj-$(CONFIG_FB_VGA16)            += vga16fb.o
+diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
+index 3741ad7..912075c 100644
+--- a/drivers/video/modedb.c
++++ b/drivers/video/modedb.c
+@@ -606,26 +606,29 @@ done:
+ 	DPRINTK("Trying specified video mode%s %ix%i\n",
+ 	    refresh_specified ? "" : " (ignoring refresh rate)", xres, yres);
+ 
+-	diff = refresh;
++	if (!refresh_specified)
++		diff = 0;
++	else
++		diff = refresh;
++
+ 	best = -1;
+ 	for (i = 0; i < dbsize; i++) {
+-		if (name_matches(db[i], name, namelen) ||
+-		    (res_specified && res_matches(db[i], xres, yres))) {
+-			if(!fb_try_mode(var, info, &db[i], bpp)) {
+-				if(!refresh_specified || db[i].refresh == refresh)
+-					return 1;
+-				else {
+-					if(diff > abs(db[i].refresh - refresh)) {
+-						diff = abs(db[i].refresh - refresh);
+-						best = i;
+-					}
++		if ((name_matches(db[i], name, namelen) ||
++		    (res_specified && res_matches(db[i], xres, yres))) &&
++		    !fb_try_mode(var, info, &db[i], bpp)) {
++			if (refresh_specified && db[i].refresh == refresh) {
++				return 1;
++			} else {
++				if (diff < db[i].refresh) {
++					diff = db[i].refresh;
++					best = i;
+ 				}
+ 			}
+ 		}
+ 	}
+ 	if (best != -1) {
+ 		fb_try_mode(var, info, &db[best], bpp);
+-		return 2;
++		return (refresh_specified) ? 2 : 1;
+ 	}
+ 
+ 	diff = xres + yres;
+@@ -938,6 +941,7 @@ void fb_destroy_modelist(struct list_head *head)
+ 		kfree(pos);
+ 	}
+ }
++EXPORT_SYMBOL_GPL(fb_destroy_modelist);
+ 
+ /**
+  * fb_videomode_to_modelist: convert mode array to mode list
+diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
+new file mode 100644
+index 0000000..853323e
+--- /dev/null
++++ b/drivers/video/uvesafb.c
+@@ -0,0 +1,2058 @@
++/*
++ * A framebuffer driver for VBE 2.0+ compliant video cards
++ *
++ * (c) 2007 Michal Januszewski <spock at gentoo.org>
++ *     Loosely based upon the vesafb driver.
++ *
++ */
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/skbuff.h>
++#include <linux/timer.h>
++#include <linux/completion.h>
++#include <linux/connector.h>
++#include <linux/random.h>
++#include <linux/platform_device.h>
++#include <linux/limits.h>
++#include <linux/fb.h>
++#include <linux/io.h>
++#include <linux/mutex.h>
++#include <video/edid.h>
++#include <video/vga.h>
++#include <video/uvesafb.h>
++#ifdef CONFIG_MTRR
++#include <asm/mtrr.h>
++#endif
++#include "edid.h"
++
++static struct cb_id uvesafb_cn_id = {
++	.idx = CN_IDX_V86D,
++	.val = CN_VAL_V86D_UVESAFB
++};
++static char v86d_path[PATH_MAX] = "/sbin/v86d";
++static char v86d_started;	/* has v86d been started by uvesafb? */
++
++static struct fb_fix_screeninfo uvesafb_fix __devinitdata = {
++	.id	= "VESA VGA",
++	.type	= FB_TYPE_PACKED_PIXELS,
++	.accel	= FB_ACCEL_NONE,
++	.visual = FB_VISUAL_TRUECOLOR,
++};
++
++static int mtrr		__devinitdata = 3; /* enable mtrr by default */
++static int blank	__devinitdata = 1; /* enable blanking by default */
++static int ypan		__devinitdata = 1; /* 0: scroll, 1: ypan, 2: ywrap */
++static int pmi_setpal	__devinitdata = 1; /* use PMI for palette changes */
++static int nocrtc	__devinitdata; /* ignore CRTC settings */
++static int noedid	__devinitdata; /* don't try DDC transfers */
++static int vram_remap	__devinitdata; /* set amt. of memory to be used */
++static int vram_total	__devinitdata; /* set total amount of memory */
++static u16 maxclk	__devinitdata; /* maximum pixel clock */
++static u16 maxvf	__devinitdata; /* maximum vertical frequency */
++static u16 maxhf	__devinitdata; /* maximum horizontal frequency */
++static u16 vbemode	__devinitdata; /* force use of a specific VBE mode */
++static char *mode_option __devinitdata;
++
++static struct uvesafb_ktask *uvfb_tasks[UVESAFB_TASKS_MAX];
++static DEFINE_MUTEX(uvfb_lock);
++
++/*
++ * A handler for replies from userspace.
++ *
++ * Make sure each message passes consistency checks and if it does,
++ * find the kernel part of the task struct, copy the registers and
++ * the buffer contents and then complete the task.
++ */
++static void uvesafb_cn_callback(void *data)
++{
++	struct cn_msg *msg = data;
++	struct uvesafb_task *utask;
++	struct uvesafb_ktask *task;
++
++	if (msg->seq >= UVESAFB_TASKS_MAX)
++		return;
++
++	mutex_lock(&uvfb_lock);
++	task = uvfb_tasks[msg->seq];
++
++	if (!task || msg->ack != task->ack) {
++		mutex_unlock(&uvfb_lock);
++		return;
++	}
++
++	utask = (struct uvesafb_task *)msg->data;
++
++	/* Sanity checks for the buffer length. */
++	if (task->t.buf_len < utask->buf_len ||
++	    utask->buf_len > msg->len - sizeof(*utask)) {
++		mutex_unlock(&uvfb_lock);
++		return;
++	}
++
++	uvfb_tasks[msg->seq] = NULL;
++	mutex_unlock(&uvfb_lock);
++
++	memcpy(&task->t, utask, sizeof(*utask));
++
++	if (task->t.buf_len && task->buf)
++		memcpy(task->buf, utask + 1, task->t.buf_len);
++
++	complete(task->done);
++	return;
++}
++
++static int uvesafb_helper_start(void)
++{
++	char *envp[] = {
++		"HOME=/",
++		"PATH=/sbin:/bin",
++		NULL,
++	};
++
++	char *argv[] = {
++		v86d_path,
++		NULL,
++	};
++
++	return call_usermodehelper(v86d_path, argv, envp, 1);
++}
++
++/*
++ * Execute a uvesafb task.
++ *
++ * Returns 0 if the task is executed successfully.
++ *
++ * A message sent to the userspace consists of the uvesafb_task
++ * struct and (optionally) a buffer. The uvesafb_task struct is
++ * a simplified version of uvesafb_ktask (its kernel counterpart)
++ * containing only the register values, flags and the length of
++ * the buffer.
++ *
++ * Each message is assigned a sequence number (increased linearly)
++ * and a random ack number. The sequence number is used as a key
++ * for the uvfb_tasks array which holds pointers to uvesafb_ktask
++ * structs for all requests.
++ */
++static int uvesafb_exec(struct uvesafb_ktask *task)
++{
++	static int seq;
++	struct cn_msg *m;
++	int err;
++	int len = sizeof(task->t) + task->t.buf_len;
++
++	/*
++	 * Check whether the message isn't longer than the maximum
++	 * allowed by connector.
++	 */
++	if (sizeof(*m) + len > CONNECTOR_MAX_MSG_SIZE) {
++		printk(KERN_WARNING "uvesafb: message too long (%d), "
++			"can't execute task\n", (int)(sizeof(*m) + len));
++		return -E2BIG;
++	}
++
++	m = kzalloc(sizeof(*m) + len, GFP_KERNEL);
++	if (!m)
++		return -ENOMEM;
++
++	init_completion(task->done);
++
++	memcpy(&m->id, &uvesafb_cn_id, sizeof(m->id));
++	m->seq = seq;
++	m->len = len;
++	m->ack = random32();
++
++	/* uvesafb_task structure */
++	memcpy(m + 1, &task->t, sizeof(task->t));
++
++	/* Buffer */
++	memcpy((u8 *)(m + 1) + sizeof(task->t), task->buf, task->t.buf_len);
++
++	/*
++	 * Save the message ack number so that we can find the kernel
++	 * part of this task when a reply is received from userspace.
++	 */
++	task->ack = m->ack;
++
++	mutex_lock(&uvfb_lock);
++
++	/* If all slots are taken -- bail out. */
++	if (uvfb_tasks[seq]) {
++		mutex_unlock(&uvfb_lock);
++		return -EBUSY;
++	}
++
++	/* Save a pointer to the kernel part of the task struct. */
++	uvfb_tasks[seq] = task;
++	mutex_unlock(&uvfb_lock);
++
++	err = cn_netlink_send(m, 0, gfp_any());
++	if (err == -ESRCH) {
++		/*
++		 * Try to start the userspace helper if sending
++		 * the request failed the first time.
++		 */
++		err = uvesafb_helper_start();
++		if (err) {
++			printk(KERN_ERR "uvesafb: failed to execute %s\n",
++					v86d_path);
++			printk(KERN_ERR "uvesafb: make sure that the v86d "
++					"helper is installed and executable\n");
++		} else {
++			v86d_started = 1;
++			err = cn_netlink_send(m, 0, gfp_any());
++		}
++	}
++	kfree(m);
++
++	if (!err && !(task->t.flags & TF_EXIT))
++		err = !wait_for_completion_timeout(task->done,
++				msecs_to_jiffies(UVESAFB_TIMEOUT));
++
++	mutex_lock(&uvfb_lock);
++	uvfb_tasks[seq] = NULL;
++	mutex_unlock(&uvfb_lock);
++
++	seq++;
++	if (seq >= UVESAFB_TASKS_MAX)
++		seq = 0;
++
++	return err;
++}
++
++/*
++ * Free a uvesafb_ktask struct.
++ */
++static void uvesafb_free(struct uvesafb_ktask *task)
++{
++	if (task) {
++		if (task->done)
++			kfree(task->done);
++		kfree(task);
++	}
++}
++
++/*
++ * Prepare a uvesafb_ktask struct to be used again.
++ */
++static void uvesafb_reset(struct uvesafb_ktask *task)
++{
++	struct completion *cpl = task->done;
++
++	memset(task, 0, sizeof(*task));
++	task->done = cpl;
++}
++
++/*
++ * Allocate and prepare a uvesafb_ktask struct.
++ */
++static struct uvesafb_ktask *uvesafb_prep(void)
++{
++	struct uvesafb_ktask *task;
++
++	task = kzalloc(sizeof(*task), GFP_KERNEL);
++	if (task) {
++		task->done = kzalloc(sizeof(*task->done), GFP_KERNEL);
++		if (!task->done) {
++			kfree(task);
++			task = NULL;
++		}
++	}
++	return task;
++}
++
++static void uvesafb_setup_var(struct fb_var_screeninfo *var,
++		struct fb_info *info, struct vbe_mode_ib *mode)
++{
++	struct uvesafb_par *par = info->par;
++
++	var->vmode = FB_VMODE_NONINTERLACED;
++	var->sync = FB_SYNC_VERT_HIGH_ACT;
++
++	var->xres = mode->x_res;
++	var->yres = mode->y_res;
++	var->xres_virtual = mode->x_res;
++	var->yres_virtual = (par->ypan) ?
++			info->fix.smem_len / mode->bytes_per_scan_line :
++			mode->y_res;
++	var->xoffset = 0;
++	var->yoffset = 0;
++	var->bits_per_pixel = mode->bits_per_pixel;
++
++	if (var->bits_per_pixel == 15)
++		var->bits_per_pixel = 16;
++
++	if (var->bits_per_pixel > 8) {
++		var->red.offset    = mode->red_off;
++		var->red.length    = mode->red_len;
++		var->green.offset  = mode->green_off;
++		var->green.length  = mode->green_len;
++		var->blue.offset   = mode->blue_off;
++		var->blue.length   = mode->blue_len;
++		var->transp.offset = mode->rsvd_off;
++		var->transp.length = mode->rsvd_len;
++	} else {
++		var->red.offset    = 0;
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list