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