summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-rp-2.6.23/uvesafb-0.1-rc3-2.6.22.patch
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-kernel/linux/linux-rp-2.6.23/uvesafb-0.1-rc3-2.6.22.patch
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadpoky-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-kernel/linux/linux-rp-2.6.23/uvesafb-0.1-rc3-2.6.22.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.23/uvesafb-0.1-rc3-2.6.22.patch2590
1 files changed, 2590 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.23/uvesafb-0.1-rc3-2.6.22.patch b/meta/recipes-kernel/linux/linux-rp-2.6.23/uvesafb-0.1-rc3-2.6.22.patch
new file mode 100644
index 0000000000..711375114f
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.23/uvesafb-0.1-rc3-2.6.22.patch
@@ -0,0 +1,2590 @@
1---
2 Documentation/fb/uvesafb.txt | 188 +++
3 drivers/video/Kconfig | 18
4 drivers/video/Makefile | 1
5 drivers/video/modedb.c | 28
6 drivers/video/uvesafb.c | 2058 +++++++++++++++++++++++++++++++++++++++++++
7 include/linux/connector.h | 7
8 include/video/Kbuild | 2
9 include/video/uvesafb.h | 193 ++++
10 8 files changed, 2479 insertions(+), 16 deletions(-)
11
12Index: linux-2.6.22/Documentation/fb/uvesafb.txt
13===================================================================
14--- /dev/null 1970-01-01 00:00:00.000000000 +0000
15+++ linux-2.6.22/Documentation/fb/uvesafb.txt 2007-08-28 21:56:34.000000000 +0100
16@@ -0,0 +1,188 @@
17+
18+uvesafb - A Generic Driver for VBE2+ compliant video cards
19+==========================================================
20+
21+1. Requirements
22+---------------
23+
24+uvesafb should work with any video card that has a Video BIOS compliant
25+with the VBE 2.0 standard.
26+
27+Unlike other drivers, uvesafb makes use of a userspace helper called
28+v86d. v86d is used to run the x86 Video BIOS code in a simulated and
29+controlled environment. This allows uvesafb to function on arches other
30+than x86. Check the v86d documentation for a list of currently supported
31+arches.
32+
33+v86d source code can be downloaded from the following website:
34+ http://dev.gentoo.org/~spock/projects/uvesafb
35+
36+Please refer to the v86d documentation for detailed configuration and
37+installation instructions.
38+
39+Note that the v86d userspace helper has to be available at all times in
40+order for uvesafb to work properly. If you want to use uvesafb during
41+early boot, you will have to include v86d into an initramfs image, and
42+either compile it into the kernel or use it as an initrd.
43+
44+2. Caveats and limitations
45+--------------------------
46+
47+uvesafb is a _generic_ driver which supports a wide variety of video
48+cards, but which is ultimately limited by the Video BIOS interface.
49+The most important limitations are:
50+
51+- Lack of any type of acceleration.
52+- A strict and limited set of supported video modes. Often the native
53+ or most optimal resolution/refresh rate for your setup will not work
54+ with uvesafb, simply because the Video BIOS doesn't support the
55+ video mode you want to use. This can be especially painful with
56+ widescreen panels, where native video modes don't have the 4:3 aspect
57+ ratio, which is what most BIOS-es are limited to.
58+- Adjusting the refresh rate is only possible with a VBE 3.0 compliant
59+ Video BIOS. Note that many nVidia Video BIOS-es claim to be VBE 3.0
60+ compliant, while they simply ignore any refresh rate settings.
61+
62+3. Configuration
63+----------------
64+
65+uvesafb can be compiled either as a module, or directly into the kernel.
66+In both cases it supports the same set of configuration options, which
67+are either given on the kernel command line or as module parameters, e.g.:
68+
69+ video=uvesafb:1024x768-32,mtrr:3,ywrap (compiled into the kernel)
70+
71+ # modprobe uvesafb mode=1024x768-32 mtrr=3 scroll=ywrap (module)
72+
73+Accepted options:
74+
75+ypan Enable display panning using the VESA protected mode
76+ interface. The visible screen is just a window of the
77+ video memory, console scrolling is done by changing the
78+ start of the window. Available on x86 only.
79+
80+ywrap Same as ypan, but assumes your gfx board can wrap-around
81+ the video memory (i.e. starts reading from top if it
82+ reaches the end of video memory). Faster than ypan.
83+ Available on x86 only.
84+
85+redraw Scroll by redrawing the affected part of the screen, this
86+ is the safe (and slow) default.
87+
88+(If you're using uvesafb as a module, the above three options are
89+ used a parameter of the scroll option, e.g. scroll=ypan.)
90+
91+vgapal Use the standard VGA registers for palette changes.
92+
93+pmipal Use the protected mode interface for palette changes.
94+ This is the default if the protected mode interface is
95+ available. Available on x86 only.
96+
97+mtrr:n Setup memory type range registers for the framebuffer
98+ where n:
99+ 0 - disabled (equivalent to nomtrr) (default)
100+ 1 - uncachable
101+ 2 - write-back
102+ 3 - write-combining
103+ 4 - write-through
104+
105+ If you see the following in dmesg, choose the type that matches
106+ the old one. In this example, use "mtrr:2".
107+...
108+mtrr: type mismatch for e0000000,8000000 old: write-back new: write-combining
109+...
110+
111+nomtrr Do not use memory type range registers.
112+
113+vremap:n
114+ Remap 'n' MiB of video RAM. If 0 or not specified, remap memory
115+ according to video mode.
116+
117+vtotal:n
118+ If the video BIOS of your card incorrectly determines the total
119+ amount of video RAM, use this option to override the BIOS (in MiB).
120+
121+<mode> The mode you want to set, in the standard modedb format. Refer to
122+ modedb.txt for a detailed description. When uvesafb is compiled as
123+ a module, the mode string should be provided as a value of the
124+ 'mode' option.
125+
126+vbemode:x
127+ Force the use of VBE mode x. The mode will only be set if it's
128+ found in the VBE-provided list of supported modes.
129+ NOTE: The mode number 'x' should be specified in VESA mode number
130+ notation, not the Linux kernel one (eg. 257 instead of 769).
131+ HINT: If you use this option because normal <mode> parameter does
132+ not work for you and you use a X server, you'll probably want to
133+ set the 'nocrtc' option to ensure that the video mode is properly
134+ restored after console <-> X switches.
135+
136+nocrtc Do not use CRTC timings while setting the video mode. This option
137+ has any effect only if the Video BIOS is VBE 3.0 compliant. Use it
138+ if you have problems with modes set the standard way. Note that
139+ using this option implies that any refresh rate adjustments will
140+ be ignored and the refresh rate will stay at your BIOS default (60 Hz).
141+
142+noedid Do not try to fetch and use EDID-provided modes.
143+
144+noblank Disable hardware blanking.
145+
146+v86d:path
147+ Set path to the v86d executable. This option is only available as
148+ a module parameter, and not as a part of the video= string. If you
149+ need to use it and have uvesafb built into the kernel, use
150+ uvesafb.v86d="path".
151+
152+Additionally, the following parameters may be provided. They all override the
153+EDID-provided values and BIOS defaults. Refer to your monitor's specs to get
154+the correct values for maxhf, maxvf and maxclk for your hardware.
155+
156+maxhf:n Maximum horizontal frequency (in kHz).
157+maxvf:n Maximum vertical frequency (in Hz).
158+maxclk:n Maximum pixel clock (in MHz).
159+
160+4. The sysfs interface
161+----------------------
162+
163+uvesafb provides several sysfs nodes for configurable parameters and
164+additional information.
165+
166+Driver attributes:
167+
168+/sys/bus/platform/drivers/uvesafb
169+ - v86d (default: /sbin/v86d)
170+ Path to the v86d executable. v86d is started by uvesafb
171+ if an instance of the daemon isn't already running.
172+
173+Device attributes:
174+
175+/sys/bus/platform/drivers/uvesafb/uvesafb.0
176+ - nocrtc
177+ Use the default refresh rate (60 Hz) if set to 1.
178+
179+ - oem_product_name
180+ - oem_product_rev
181+ - oem_string
182+ - oem_vendor
183+ Information about the card and its maker.
184+
185+ - vbe_modes
186+ A list of video modes supported by the Video BIOS along with their
187+ VBE mode numbers in hex.
188+
189+ - vbe_version
190+ A BCD value indicating the implemented VBE standard.
191+
192+5. Miscellaneous
193+----------------
194+
195+Uvesafb will set a video mode with the default refresh rate and timings
196+from the Video BIOS if you set pixclock to 0 in fb_var_screeninfo.
197+
198+
199+--
200+ Michal Januszewski <spock@gentoo.org>
201+ Last updated: 2007-06-16
202+
203+ Documentation of the uvesafb options is loosely based on vesafb.txt.
204+
205Index: linux-2.6.22/drivers/video/Kconfig
206===================================================================
207--- linux-2.6.22.orig/drivers/video/Kconfig 2007-08-28 21:56:33.000000000 +0100
208+++ linux-2.6.22/drivers/video/Kconfig 2007-08-28 21:56:34.000000000 +0100
209@@ -592,6 +592,24 @@ config FB_TGA
210
211 Say Y if you have one of those.
212
213+config FB_UVESA
214+ tristate "Userspace VESA VGA graphics support"
215+ depends on FB && CONNECTOR
216+ select FB_CFB_FILLRECT
217+ select FB_CFB_COPYAREA
218+ select FB_CFB_IMAGEBLIT
219+ select FB_MODE_HELPERS
220+ help
221+ This is the frame buffer driver for generic VBE 2.0 compliant
222+ graphic cards. It can also take advantage of VBE 3.0 features,
223+ such as refresh rate adjustment.
224+
225+ This driver generally provides more features than vesafb but
226+ requires a userspace helper application called 'v86d'. See
227+ <file:Documentation/fb/uvesafb.txt> for more information.
228+
229+ If unsure, say N.
230+
231 config FB_VESA
232 bool "VESA VGA graphics support"
233 depends on (FB = y) && X86
234Index: linux-2.6.22/drivers/video/Makefile
235===================================================================
236--- linux-2.6.22.orig/drivers/video/Makefile 2007-08-28 21:56:33.000000000 +0100
237+++ linux-2.6.22/drivers/video/Makefile 2007-08-28 21:56:34.000000000 +0100
238@@ -116,6 +116,7 @@ obj-$(CONFIG_FB_XILINX) += xil
239 obj-$(CONFIG_FB_OMAP) += omap/
240
241 # Platform or fallback drivers go here
242+obj-$(CONFIG_FB_UVESA) += uvesafb.o
243 obj-$(CONFIG_FB_VESA) += vesafb.o
244 obj-$(CONFIG_FB_IMAC) += imacfb.o
245 obj-$(CONFIG_FB_VGA16) += vga16fb.o
246Index: linux-2.6.22/drivers/video/modedb.c
247===================================================================
248--- linux-2.6.22.orig/drivers/video/modedb.c 2007-08-28 21:54:13.000000000 +0100
249+++ linux-2.6.22/drivers/video/modedb.c 2007-08-28 21:56:34.000000000 +0100
250@@ -606,26 +606,29 @@ done:
251 DPRINTK("Trying specified video mode%s %ix%i\n",
252 refresh_specified ? "" : " (ignoring refresh rate)", xres, yres);
253
254- diff = refresh;
255+ if (!refresh_specified)
256+ diff = 0;
257+ else
258+ diff = refresh;
259+
260 best = -1;
261 for (i = 0; i < dbsize; i++) {
262- if (name_matches(db[i], name, namelen) ||
263- (res_specified && res_matches(db[i], xres, yres))) {
264- if(!fb_try_mode(var, info, &db[i], bpp)) {
265- if(!refresh_specified || db[i].refresh == refresh)
266- return 1;
267- else {
268- if(diff > abs(db[i].refresh - refresh)) {
269- diff = abs(db[i].refresh - refresh);
270- best = i;
271- }
272+ if ((name_matches(db[i], name, namelen) ||
273+ (res_specified && res_matches(db[i], xres, yres))) &&
274+ !fb_try_mode(var, info, &db[i], bpp)) {
275+ if (refresh_specified && db[i].refresh == refresh) {
276+ return 1;
277+ } else {
278+ if (diff < db[i].refresh) {
279+ diff = db[i].refresh;
280+ best = i;
281 }
282 }
283 }
284 }
285 if (best != -1) {
286 fb_try_mode(var, info, &db[best], bpp);
287- return 2;
288+ return (refresh_specified) ? 2 : 1;
289 }
290
291 diff = xres + yres;
292@@ -938,6 +941,7 @@ void fb_destroy_modelist(struct list_hea
293 kfree(pos);
294 }
295 }
296+EXPORT_SYMBOL_GPL(fb_destroy_modelist);
297
298 /**
299 * fb_videomode_to_modelist: convert mode array to mode list
300Index: linux-2.6.22/drivers/video/uvesafb.c
301===================================================================
302--- /dev/null 1970-01-01 00:00:00.000000000 +0000
303+++ linux-2.6.22/drivers/video/uvesafb.c 2007-08-28 21:56:34.000000000 +0100
304@@ -0,0 +1,2058 @@
305+/*
306+ * A framebuffer driver for VBE 2.0+ compliant video cards
307+ *
308+ * (c) 2007 Michal Januszewski <spock@gentoo.org>
309+ * Loosely based upon the vesafb driver.
310+ *
311+ */
312+#include <linux/init.h>
313+#include <linux/module.h>
314+#include <linux/moduleparam.h>
315+#include <linux/skbuff.h>
316+#include <linux/timer.h>
317+#include <linux/completion.h>
318+#include <linux/connector.h>
319+#include <linux/random.h>
320+#include <linux/platform_device.h>
321+#include <linux/limits.h>
322+#include <linux/fb.h>
323+#include <linux/io.h>
324+#include <linux/mutex.h>
325+#include <video/edid.h>
326+#include <video/vga.h>
327+#include <video/uvesafb.h>
328+#ifdef CONFIG_MTRR
329+#include <asm/mtrr.h>
330+#endif
331+#include "edid.h"
332+
333+static struct cb_id uvesafb_cn_id = {
334+ .idx = CN_IDX_V86D,
335+ .val = CN_VAL_V86D_UVESAFB
336+};
337+static char v86d_path[PATH_MAX] = "/sbin/v86d";
338+static char v86d_started; /* has v86d been started by uvesafb? */
339+
340+static struct fb_fix_screeninfo uvesafb_fix __devinitdata = {
341+ .id = "VESA VGA",
342+ .type = FB_TYPE_PACKED_PIXELS,
343+ .accel = FB_ACCEL_NONE,
344+ .visual = FB_VISUAL_TRUECOLOR,
345+};
346+
347+static int mtrr __devinitdata = 3; /* enable mtrr by default */
348+static int blank __devinitdata = 1; /* enable blanking by default */
349+static int ypan __devinitdata = 1; /* 0: scroll, 1: ypan, 2: ywrap */
350+static int pmi_setpal __devinitdata = 1; /* use PMI for palette changes */
351+static int nocrtc __devinitdata; /* ignore CRTC settings */
352+static int noedid __devinitdata; /* don't try DDC transfers */
353+static int vram_remap __devinitdata; /* set amt. of memory to be used */
354+static int vram_total __devinitdata; /* set total amount of memory */
355+static u16 maxclk __devinitdata; /* maximum pixel clock */
356+static u16 maxvf __devinitdata; /* maximum vertical frequency */
357+static u16 maxhf __devinitdata; /* maximum horizontal frequency */
358+static u16 vbemode __devinitdata; /* force use of a specific VBE mode */
359+static char *mode_option __devinitdata;
360+
361+static struct uvesafb_ktask *uvfb_tasks[UVESAFB_TASKS_MAX];
362+static DEFINE_MUTEX(uvfb_lock);
363+
364+/*
365+ * A handler for replies from userspace.
366+ *
367+ * Make sure each message passes consistency checks and if it does,
368+ * find the kernel part of the task struct, copy the registers and
369+ * the buffer contents and then complete the task.
370+ */
371+static void uvesafb_cn_callback(void *data)
372+{
373+ struct cn_msg *msg = data;
374+ struct uvesafb_task *utask;
375+ struct uvesafb_ktask *task;
376+
377+ if (msg->seq >= UVESAFB_TASKS_MAX)
378+ return;
379+
380+ mutex_lock(&uvfb_lock);
381+ task = uvfb_tasks[msg->seq];
382+
383+ if (!task || msg->ack != task->ack) {
384+ mutex_unlock(&uvfb_lock);
385+ return;
386+ }
387+
388+ utask = (struct uvesafb_task *)msg->data;
389+
390+ /* Sanity checks for the buffer length. */
391+ if (task->t.buf_len < utask->buf_len ||
392+ utask->buf_len > msg->len - sizeof(*utask)) {
393+ mutex_unlock(&uvfb_lock);
394+ return;
395+ }
396+
397+ uvfb_tasks[msg->seq] = NULL;
398+ mutex_unlock(&uvfb_lock);
399+
400+ memcpy(&task->t, utask, sizeof(*utask));
401+
402+ if (task->t.buf_len && task->buf)
403+ memcpy(task->buf, utask + 1, task->t.buf_len);
404+
405+ complete(task->done);
406+ return;
407+}
408+
409+static int uvesafb_helper_start(void)
410+{
411+ char *envp[] = {
412+ "HOME=/",
413+ "PATH=/sbin:/bin",
414+ NULL,
415+ };
416+
417+ char *argv[] = {
418+ v86d_path,
419+ NULL,
420+ };
421+
422+ return call_usermodehelper(v86d_path, argv, envp, 1);
423+}
424+
425+/*
426+ * Execute a uvesafb task.
427+ *
428+ * Returns 0 if the task is executed successfully.
429+ *
430+ * A message sent to the userspace consists of the uvesafb_task
431+ * struct and (optionally) a buffer. The uvesafb_task struct is
432+ * a simplified version of uvesafb_ktask (its kernel counterpart)
433+ * containing only the register values, flags and the length of
434+ * the buffer.
435+ *
436+ * Each message is assigned a sequence number (increased linearly)
437+ * and a random ack number. The sequence number is used as a key
438+ * for the uvfb_tasks array which holds pointers to uvesafb_ktask
439+ * structs for all requests.
440+ */
441+static int uvesafb_exec(struct uvesafb_ktask *task)
442+{
443+ static int seq;
444+ struct cn_msg *m;
445+ int err;
446+ int len = sizeof(task->t) + task->t.buf_len;
447+
448+ /*
449+ * Check whether the message isn't longer than the maximum
450+ * allowed by connector.
451+ */
452+ if (sizeof(*m) + len > CONNECTOR_MAX_MSG_SIZE) {
453+ printk(KERN_WARNING "uvesafb: message too long (%d), "
454+ "can't execute task\n", (int)(sizeof(*m) + len));
455+ return -E2BIG;
456+ }
457+
458+ m = kzalloc(sizeof(*m) + len, GFP_KERNEL);
459+ if (!m)
460+ return -ENOMEM;
461+
462+ init_completion(task->done);
463+
464+ memcpy(&m->id, &uvesafb_cn_id, sizeof(m->id));
465+ m->seq = seq;
466+ m->len = len;
467+ m->ack = random32();
468+
469+ /* uvesafb_task structure */
470+ memcpy(m + 1, &task->t, sizeof(task->t));
471+
472+ /* Buffer */
473+ memcpy((u8 *)(m + 1) + sizeof(task->t), task->buf, task->t.buf_len);
474+
475+ /*
476+ * Save the message ack number so that we can find the kernel
477+ * part of this task when a reply is received from userspace.
478+ */
479+ task->ack = m->ack;
480+
481+ mutex_lock(&uvfb_lock);
482+
483+ /* If all slots are taken -- bail out. */
484+ if (uvfb_tasks[seq]) {
485+ mutex_unlock(&uvfb_lock);
486+ return -EBUSY;
487+ }
488+
489+ /* Save a pointer to the kernel part of the task struct. */
490+ uvfb_tasks[seq] = task;
491+ mutex_unlock(&uvfb_lock);
492+
493+ err = cn_netlink_send(m, 0, gfp_any());
494+ if (err == -ESRCH) {
495+ /*
496+ * Try to start the userspace helper if sending
497+ * the request failed the first time.
498+ */
499+ err = uvesafb_helper_start();
500+ if (err) {
501+ printk(KERN_ERR "uvesafb: failed to execute %s\n",
502+ v86d_path);
503+ printk(KERN_ERR "uvesafb: make sure that the v86d "
504+ "helper is installed and executable\n");
505+ } else {
506+ v86d_started = 1;
507+ err = cn_netlink_send(m, 0, gfp_any());
508+ }
509+ }
510+ kfree(m);
511+
512+ if (!err && !(task->t.flags & TF_EXIT))
513+ err = !wait_for_completion_timeout(task->done,
514+ msecs_to_jiffies(UVESAFB_TIMEOUT));
515+
516+ mutex_lock(&uvfb_lock);
517+ uvfb_tasks[seq] = NULL;
518+ mutex_unlock(&uvfb_lock);
519+
520+ seq++;
521+ if (seq >= UVESAFB_TASKS_MAX)
522+ seq = 0;
523+
524+ return err;
525+}
526+
527+/*
528+ * Free a uvesafb_ktask struct.
529+ */
530+static void uvesafb_free(struct uvesafb_ktask *task)
531+{
532+ if (task) {
533+ if (task->done)
534+ kfree(task->done);
535+ kfree(task);
536+ }
537+}
538+
539+/*
540+ * Prepare a uvesafb_ktask struct to be used again.
541+ */
542+static void uvesafb_reset(struct uvesafb_ktask *task)
543+{
544+ struct completion *cpl = task->done;
545+
546+ memset(task, 0, sizeof(*task));
547+ task->done = cpl;
548+}
549+
550+/*
551+ * Allocate and prepare a uvesafb_ktask struct.
552+ */
553+static struct uvesafb_ktask *uvesafb_prep(void)
554+{
555+ struct uvesafb_ktask *task;
556+
557+ task = kzalloc(sizeof(*task), GFP_KERNEL);
558+ if (task) {
559+ task->done = kzalloc(sizeof(*task->done), GFP_KERNEL);
560+ if (!task->done) {
561+ kfree(task);
562+ task = NULL;
563+ }
564+ }
565+ return task;
566+}
567+
568+static void uvesafb_setup_var(struct fb_var_screeninfo *var,
569+ struct fb_info *info, struct vbe_mode_ib *mode)
570+{
571+ struct uvesafb_par *par = info->par;
572+
573+ var->vmode = FB_VMODE_NONINTERLACED;
574+ var->sync = FB_SYNC_VERT_HIGH_ACT;
575+
576+ var->xres = mode->x_res;
577+ var->yres = mode->y_res;
578+ var->xres_virtual = mode->x_res;
579+ var->yres_virtual = (par->ypan) ?
580+ info->fix.smem_len / mode->bytes_per_scan_line :
581+ mode->y_res;
582+ var->xoffset = 0;
583+ var->yoffset = 0;
584+ var->bits_per_pixel = mode->bits_per_pixel;
585+
586+ if (var->bits_per_pixel == 15)
587+ var->bits_per_pixel = 16;
588+
589+ if (var->bits_per_pixel > 8) {
590+ var->red.offset = mode->red_off;
591+ var->red.length = mode->red_len;
592+ var->green.offset = mode->green_off;
593+ var->green.length = mode->green_len;
594+ var->blue.offset = mode->blue_off;
595+ var->blue.length = mode->blue_len;
596+ var->transp.offset = mode->rsvd_off;
597+ var->transp.length = mode->rsvd_len;
598+ } else {
599+ var->red.offset = 0;
600+ var->green.offset = 0;
601+ var->blue.offset = 0;
602+ var->transp.offset = 0;
603+
604+ /*
605+ * We're assuming that we can switch the DAC to 8 bits. If
606+ * this proves to be incorrect, we'll update the fields
607+ * later in set_par().
608+ */
609+ if (par->vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC) {
610+ var->red.length = 8;
611+ var->green.length = 8;
612+ var->blue.length = 8;
613+ var->transp.length = 0;
614+ } else {
615+ var->red.length = 6;
616+ var->green.length = 6;
617+ var->blue.length = 6;
618+ var->transp.length = 0;
619+ }
620+ }
621+}
622+
623+static int uvesafb_vbe_find_mode(struct uvesafb_par *par,
624+ int xres, int yres, int depth, unsigned char flags)
625+{
626+ int i, match = -1, h = 0, d = 0x7fffffff;
627+
628+ for (i = 0; i < par->vbe_modes_cnt; i++) {
629+ h = abs(par->vbe_modes[i].x_res - xres) +
630+ abs(par->vbe_modes[i].y_res - yres) +
631+ abs(depth - par->vbe_modes[i].depth);
632+
633+ /*
634+ * We have an exact match in terms of resolution
635+ * and depth.
636+ */
637+ if (h == 0)
638+ return i;
639+
640+ if (h < d || (h == d && par->vbe_modes[i].depth > depth)) {
641+ d = h;
642+ match = i;
643+ }
644+ }
645+ i = 1;
646+
647+ if (flags & UVESAFB_EXACT_DEPTH &&
648+ par->vbe_modes[match].depth != depth)
649+ i = 0;
650+
651+ if (flags & UVESAFB_EXACT_RES && d > 24)
652+ i = 0;
653+
654+ if (i != 0)
655+ return match;
656+ else
657+ return -1;
658+}
659+
660+static u8 *uvesafb_vbe_state_save(struct uvesafb_par *par)
661+{
662+ struct uvesafb_ktask *task;
663+ u8 *state;
664+ int err;
665+
666+ if (!par->vbe_state_size)
667+ return NULL;
668+
669+ state = kmalloc(par->vbe_state_size, GFP_KERNEL);
670+ if (!state)
671+ return NULL;
672+
673+ task = uvesafb_prep();
674+ if (!task) {
675+ kfree(state);
676+ return NULL;
677+ }
678+
679+ task->t.regs.eax = 0x4f04;
680+ task->t.regs.ecx = 0x000f;
681+ task->t.regs.edx = 0x0001;
682+ task->t.flags = TF_BUF_RET | TF_BUF_ESBX;
683+ task->t.buf_len = par->vbe_state_size;
684+ task->buf = state;
685+ err = uvesafb_exec(task);
686+
687+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
688+ printk(KERN_WARNING "uvesafb: VBE get state call "
689+ "failed (eax=0x%x, err=%d)\n",
690+ task->t.regs.eax, err);
691+ kfree(state);
692+ state = NULL;
693+ }
694+
695+ uvesafb_free(task);
696+ return state;
697+}
698+
699+static void uvesafb_vbe_state_restore(struct uvesafb_par *par, u8 *state_buf)
700+{
701+ struct uvesafb_ktask *task;
702+ int err;
703+
704+ if (!state_buf)
705+ return;
706+
707+ task = uvesafb_prep();
708+ if (!task)
709+ return;
710+
711+ task->t.regs.eax = 0x4f04;
712+ task->t.regs.ecx = 0x000f;
713+ task->t.regs.edx = 0x0002;
714+ task->t.buf_len = par->vbe_state_size;
715+ task->t.flags = TF_BUF_ESBX;
716+ task->buf = state_buf;
717+
718+ err = uvesafb_exec(task);
719+ if (err || (task->t.regs.eax & 0xffff) != 0x004f)
720+ printk(KERN_WARNING "uvesafb: VBE state restore call "
721+ "failed (eax=0x%x, err=%d)\n",
722+ task->t.regs.eax, err);
723+
724+ uvesafb_free(task);
725+}
726+
727+static int __devinit uvesafb_vbe_getinfo(struct uvesafb_ktask *task,
728+ struct uvesafb_par *par)
729+{
730+ int err;
731+
732+ task->t.regs.eax = 0x4f00;
733+ task->t.flags = TF_VBEIB;
734+ task->t.buf_len = sizeof(struct vbe_ib);
735+ task->buf = &par->vbe_ib;
736+ strncpy(par->vbe_ib.vbe_signature, "VBE2", 4);
737+
738+ err = uvesafb_exec(task);
739+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
740+ printk(KERN_ERR "uvesafb: Getting VBE info block failed "
741+ "(eax=0x%x, err=%d)\n", (u32)task->t.regs.eax,
742+ err);
743+ return -EINVAL;
744+ }
745+
746+ if (par->vbe_ib.vbe_version < 0x0200) {
747+ printk(KERN_ERR "uvesafb: Sorry, pre-VBE 2.0 cards are "
748+ "not supported.\n");
749+ return -EINVAL;
750+ }
751+
752+ if (!par->vbe_ib.mode_list_ptr) {
753+ printk(KERN_ERR "uvesafb: Missing mode list!\n");
754+ return -EINVAL;
755+ }
756+
757+ printk(KERN_INFO "uvesafb: ");
758+
759+ /*
760+ * Convert string pointers and the mode list pointer into
761+ * usable addresses. Print informational messages about the
762+ * video adapter and its vendor.
763+ */
764+ if (par->vbe_ib.oem_vendor_name_ptr)
765+ printk("%s, ",
766+ ((char *)task->buf) + par->vbe_ib.oem_vendor_name_ptr);
767+
768+ if (par->vbe_ib.oem_product_name_ptr)
769+ printk("%s, ",
770+ ((char *)task->buf) + par->vbe_ib.oem_product_name_ptr);
771+
772+ if (par->vbe_ib.oem_product_rev_ptr)
773+ printk("%s, ",
774+ ((char *)task->buf) + par->vbe_ib.oem_product_rev_ptr);
775+
776+ if (par->vbe_ib.oem_string_ptr)
777+ printk("OEM: %s, ",
778+ ((char *)task->buf) + par->vbe_ib.oem_string_ptr);
779+
780+ printk("VBE v%d.%d\n", ((par->vbe_ib.vbe_version & 0xff00) >> 8),
781+ par->vbe_ib.vbe_version & 0xff);
782+
783+ return 0;
784+}
785+
786+static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
787+ struct uvesafb_par *par)
788+{
789+ int off = 0, err;
790+ u16 *mode;
791+
792+ par->vbe_modes_cnt = 0;
793+
794+ /* Count available modes. */
795+ mode = (u16 *) (((u8 *)&par->vbe_ib) + par->vbe_ib.mode_list_ptr);
796+ while (*mode != 0xffff) {
797+ par->vbe_modes_cnt++;
798+ mode++;
799+ }
800+
801+ par->vbe_modes = kzalloc(sizeof(struct vbe_mode_ib) *
802+ par->vbe_modes_cnt, GFP_KERNEL);
803+ if (!par->vbe_modes)
804+ return -ENOMEM;
805+
806+ /* Get info about all available modes. */
807+ mode = (u16 *) (((u8 *)&par->vbe_ib) + par->vbe_ib.mode_list_ptr);
808+ while (*mode != 0xffff) {
809+ struct vbe_mode_ib *mib;
810+
811+ uvesafb_reset(task);
812+ task->t.regs.eax = 0x4f01;
813+ task->t.regs.ecx = (u32) *mode;
814+ task->t.flags = TF_BUF_RET | TF_BUF_ESDI;
815+ task->t.buf_len = sizeof(struct vbe_mode_ib);
816+ task->buf = par->vbe_modes + off;
817+
818+ err = uvesafb_exec(task);
819+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
820+ printk(KERN_ERR "uvesafb: Getting mode info block "
821+ "for mode 0x%x failed (eax=0x%x, err=%d)\n",
822+ *mode, (u32)task->t.regs.eax, err);
823+ return -EINVAL;
824+ }
825+
826+ mib = task->buf;
827+ mib->mode_id = *mode;
828+
829+ /*
830+ * We only want modes that are supported with the current
831+ * hardware configuration, color, graphics and that have
832+ * support for the LFB.
833+ */
834+ if ((mib->mode_attr & VBE_MODE_MASK) == VBE_MODE_MASK &&
835+ mib->bits_per_pixel >= 8)
836+ off++;
837+ else
838+ par->vbe_modes_cnt--;
839+
840+ mode++;
841+ mib->depth = mib->red_len + mib->green_len + mib->blue_len;
842+
843+ /*
844+ * Handle 8bpp modes and modes with broken color component
845+ * lengths.
846+ */
847+ if (mib->depth == 0 || (mib->depth == 24 &&
848+ mib->bits_per_pixel == 32))
849+ mib->depth = mib->bits_per_pixel;
850+ }
851+
852+ return 0;
853+}
854+
855+/*
856+ * The Protected Mode Interface is 32-bit x86 code, so we only run it on
857+ * x86 and not x86_64.
858+ */
859+#ifdef CONFIG_X86_32
860+static int __devinit uvesafb_vbe_getpmi(struct uvesafb_ktask *task,
861+ struct uvesafb_par *par)
862+{
863+ int i, err;
864+
865+ uvesafb_reset(task);
866+ task->t.regs.eax = 0x4f0a;
867+ task->t.regs.ebx = 0x0;
868+ err = uvesafb_exec(task);
869+
870+ if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
871+ par->pmi_setpal = par->ypan = 0;
872+ } else {
873+ par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
874+ + task->t.regs.edi);
875+ par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
876+ par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
877+ printk(KERN_INFO "uvesafb: protected mode interface info at "
878+ "%04x:%04x\n",
879+ (u16)task->t.regs.es, (u16)task->t.regs.edi);
880+ printk(KERN_INFO "uvesafb: pmi: set display start = %p, "
881+ "set palette = %p\n", par->pmi_start,
882+ par->pmi_pal);
883+
884+ if (par->pmi_base[3]) {
885+ printk(KERN_INFO "uvesafb: pmi: ports = ");
886+ for (i = par->pmi_base[3]/2;
887+ par->pmi_base[i] != 0xffff; i++)
888+ printk("%x ", par->pmi_base[i]);
889+ printk("\n");
890+
891+ if (par->pmi_base[i] != 0xffff) {
892+ printk(KERN_INFO "uvesafb: can't handle memory"
893+ " requests, pmi disabled\n");
894+ par->ypan = par->pmi_setpal = 0;
895+ }
896+ }
897+ }
898+ return 0;
899+}
900+#endif /* CONFIG_X86_32 */
901+
902+/*
903+ * Check whether a video mode is supported by the Video BIOS and is
904+ * compatible with the monitor limits.
905+ */
906+static int __devinit uvesafb_is_valid_mode(struct fb_videomode *mode,
907+ struct fb_info *info)
908+{
909+ if (info->monspecs.gtf) {
910+ fb_videomode_to_var(&info->var, mode);
911+ if (fb_validate_mode(&info->var, info))
912+ return 0;
913+ }
914+
915+ if (uvesafb_vbe_find_mode(info->par, mode->xres, mode->yres, 8,
916+ UVESAFB_EXACT_RES) == -1)
917+ return 0;
918+
919+ return 1;
920+}
921+
922+static int __devinit uvesafb_vbe_getedid(struct uvesafb_ktask *task,
923+ struct fb_info *info)
924+{
925+ struct uvesafb_par *par = info->par;
926+ int err = 0;
927+
928+ if (noedid || par->vbe_ib.vbe_version < 0x0300)
929+ return -EINVAL;
930+
931+ task->t.regs.eax = 0x4f15;
932+ task->t.regs.ebx = 0;
933+ task->t.regs.ecx = 0;
934+ task->t.buf_len = 0;
935+ task->t.flags = 0;
936+
937+ err = uvesafb_exec(task);
938+
939+ if ((task->t.regs.eax & 0xffff) != 0x004f || err)
940+ return -EINVAL;
941+
942+ if ((task->t.regs.ebx & 0x3) == 3) {
943+ printk(KERN_INFO "uvesafb: VBIOS/hardware supports both "
944+ "DDC1 and DDC2 transfers\n");
945+ } else if ((task->t.regs.ebx & 0x3) == 2) {
946+ printk(KERN_INFO "uvesafb: VBIOS/hardware supports DDC2 "
947+ "transfers\n");
948+ } else if ((task->t.regs.ebx & 0x3) == 1) {
949+ printk(KERN_INFO "uvesafb: VBIOS/hardware supports DDC1 "
950+ "transfers\n");
951+ } else {
952+ printk(KERN_INFO "uvesafb: VBIOS/hardware doesn't support "
953+ "DDC transfers\n");
954+ return -EINVAL;
955+ }
956+
957+ task->t.regs.eax = 0x4f15;
958+ task->t.regs.ebx = 1;
959+ task->t.regs.ecx = task->t.regs.edx = 0;
960+ task->t.flags = TF_BUF_RET | TF_BUF_ESDI;
961+ task->t.buf_len = EDID_LENGTH;
962+ task->buf = kzalloc(EDID_LENGTH, GFP_KERNEL);
963+
964+ err = uvesafb_exec(task);
965+
966+ if ((task->t.regs.eax & 0xffff) == 0x004f && !err) {
967+ fb_edid_to_monspecs(task->buf, &info->monspecs);
968+
969+ if (info->monspecs.vfmax && info->monspecs.hfmax) {
970+ /*
971+ * If the maximum pixel clock wasn't specified in
972+ * the EDID block, set it to 300 MHz.
973+ */
974+ if (info->monspecs.dclkmax == 0)
975+ info->monspecs.dclkmax = 300 * 1000000;
976+ info->monspecs.gtf = 1;
977+ }
978+ } else {
979+ err = -EINVAL;
980+ }
981+
982+ kfree(task->buf);
983+ return err;
984+}
985+
986+static void __devinit uvesafb_vbe_getmonspecs(struct uvesafb_ktask *task,
987+ struct fb_info *info)
988+{
989+ struct uvesafb_par *par = info->par;
990+ int i;
991+
992+ memset(&info->monspecs, 0, sizeof(info->monspecs));
993+
994+ /*
995+ * If we don't get all necessary data from the EDID block,
996+ * mark it as incompatible with the GTF and set nocrtc so
997+ * that we always use the default BIOS refresh rate.
998+ */
999+ if (uvesafb_vbe_getedid(task, info)) {
1000+ info->monspecs.gtf = 0;
1001+ par->nocrtc = 1;
1002+ }
1003+
1004+ /* Kernel command line overrides. */
1005+ if (maxclk)
1006+ info->monspecs.dclkmax = maxclk * 1000000;
1007+ if (maxvf)
1008+ info->monspecs.vfmax = maxvf;
1009+ if (maxhf)
1010+ info->monspecs.hfmax = maxhf * 1000;
1011+
1012+ /*
1013+ * In case DDC transfers are not supported, the user can provide
1014+ * monitor limits manually. Lower limits are set to "safe" values.
1015+ */
1016+ if (info->monspecs.gtf == 0 && maxclk && maxvf && maxhf) {
1017+ info->monspecs.dclkmin = 0;
1018+ info->monspecs.vfmin = 60;
1019+ info->monspecs.hfmin = 29000;
1020+ info->monspecs.gtf = 1;
1021+ par->nocrtc = 0;
1022+ }
1023+
1024+ if (info->monspecs.gtf)
1025+ printk(KERN_INFO
1026+ "uvesafb: monitor limits: vf = %d Hz, hf = %d kHz, "
1027+ "clk = %d MHz\n", info->monspecs.vfmax,
1028+ (int)(info->monspecs.hfmax / 1000),
1029+ (int)(info->monspecs.dclkmax / 1000000));
1030+ else
1031+ printk(KERN_INFO "uvesafb: no monitor limits have been set, "
1032+ "default refresh rate will be used\n");
1033+
1034+ /* Add VBE modes to the modelist. */
1035+ for (i = 0; i < par->vbe_modes_cnt; i++) {
1036+ struct fb_var_screeninfo var;
1037+ struct vbe_mode_ib *mode;
1038+ struct fb_videomode vmode;
1039+
1040+ mode = &par->vbe_modes[i];
1041+ memset(&var, 0, sizeof(var));
1042+
1043+ var.xres = mode->x_res;
1044+ var.yres = mode->y_res;
1045+
1046+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60, &var, info);
1047+ fb_var_to_videomode(&vmode, &var);
1048+ fb_add_videomode(&vmode, &info->modelist);
1049+ }
1050+
1051+ /* Add valid VESA modes to our modelist. */
1052+ for (i = 0; i < VESA_MODEDB_SIZE; i++) {
1053+ if (uvesafb_is_valid_mode((struct fb_videomode *)
1054+ &vesa_modes[i], info))
1055+ fb_add_videomode(&vesa_modes[i], &info->modelist);
1056+ }
1057+
1058+ for (i = 0; i < info->monspecs.modedb_len; i++) {
1059+ if (uvesafb_is_valid_mode(&info->monspecs.modedb[i], info))
1060+ fb_add_videomode(&info->monspecs.modedb[i],
1061+ &info->modelist);
1062+ }
1063+
1064+ return;
1065+}
1066+
1067+static void __devinit uvesafb_vbe_getstatesize(struct uvesafb_ktask *task,
1068+ struct uvesafb_par *par)
1069+{
1070+ int err;
1071+
1072+ uvesafb_reset(task);
1073+
1074+ /*
1075+ * Get the VBE state buffer size. We want all available
1076+ * hardware state data (CL = 0x0f).
1077+ */
1078+ task->t.regs.eax = 0x4f04;
1079+ task->t.regs.ecx = 0x000f;
1080+ task->t.regs.edx = 0x0000;
1081+ task->t.flags = 0;
1082+
1083+ err = uvesafb_exec(task);
1084+
1085+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
1086+ printk(KERN_WARNING "uvesafb: VBE state buffer size "
1087+ "cannot be determined (eax=0x%x, err=%d)\n",
1088+ task->t.regs.eax, err);
1089+ par->vbe_state_size = 0;
1090+ return;
1091+ }
1092+
1093+ par->vbe_state_size = 64 * (task->t.regs.ebx & 0xffff);
1094+}
1095+
1096+static int __devinit uvesafb_vbe_init(struct fb_info *info)
1097+{
1098+ struct uvesafb_ktask *task = NULL;
1099+ struct uvesafb_par *par = info->par;
1100+ int err;
1101+
1102+ task = uvesafb_prep();
1103+ if (!task)
1104+ return -ENOMEM;
1105+
1106+ err = uvesafb_vbe_getinfo(task, par);
1107+ if (err)
1108+ goto out;
1109+
1110+ err = uvesafb_vbe_getmodes(task, par);
1111+ if (err)
1112+ goto out;
1113+
1114+ par->nocrtc = nocrtc;
1115+#ifdef CONFIG_X86_32
1116+ par->pmi_setpal = pmi_setpal;
1117+ par->ypan = ypan;
1118+
1119+ if (par->pmi_setpal || par->ypan)
1120+ uvesafb_vbe_getpmi(task, par);
1121+#else
1122+ /* The protected mode interface is not available on non-x86. */
1123+ par->pmi_setpal = par->ypan = 0;
1124+#endif
1125+
1126+ INIT_LIST_HEAD(&info->modelist);
1127+ uvesafb_vbe_getmonspecs(task, info);
1128+ uvesafb_vbe_getstatesize(task, par);
1129+
1130+out: uvesafb_free(task);
1131+ return err;
1132+}
1133+
1134+static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
1135+{
1136+ struct list_head *pos;
1137+ struct fb_modelist *modelist;
1138+ struct fb_videomode *mode;
1139+ struct uvesafb_par *par = info->par;
1140+ int i, modeid;
1141+
1142+ /* Has the user requested a specific VESA mode? */
1143+ if (vbemode) {
1144+ for (i = 0; i < par->vbe_modes_cnt; i++) {
1145+ if (par->vbe_modes[i].mode_id == vbemode) {
1146+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
1147+ &info->var, info);
1148+ /*
1149+ * With pixclock set to 0, the default BIOS
1150+ * timings will be used in set_par().
1151+ */
1152+ info->var.pixclock = 0;
1153+ modeid = i;
1154+ goto gotmode;
1155+ }
1156+ }
1157+ printk(KERN_INFO "uvesafb: requested VBE mode 0x%x is "
1158+ "unavailable\n", vbemode);
1159+ vbemode = 0;
1160+ }
1161+
1162+ /* Count the modes in the modelist */
1163+ i = 0;
1164+ list_for_each(pos, &info->modelist)
1165+ i++;
1166+
1167+ /*
1168+ * Convert the modelist into a modedb so that we can use it with
1169+ * fb_find_mode().
1170+ */
1171+ mode = kzalloc(i * sizeof(*mode), GFP_KERNEL);
1172+ if (mode) {
1173+ i = 0;
1174+ list_for_each(pos, &info->modelist) {
1175+ modelist = list_entry(pos, struct fb_modelist, list);
1176+ mode[i] = modelist->mode;
1177+ i++;
1178+ }
1179+
1180+ if (!mode_option)
1181+ mode_option = UVESAFB_DEFAULT_MODE;
1182+
1183+ i = fb_find_mode(&info->var, info, mode_option, mode, i,
1184+ NULL, 8);
1185+
1186+ kfree(mode);
1187+ }
1188+
1189+ /* fb_find_mode() failed */
1190+ if (i == 0 || i >= 3) {
1191+ info->var.xres = 640;
1192+ info->var.yres = 480;
1193+ mode = (struct fb_videomode *)
1194+ fb_find_best_mode(&info->var, &info->modelist);
1195+
1196+ if (mode) {
1197+ fb_videomode_to_var(&info->var, mode);
1198+ } else {
1199+ modeid = par->vbe_modes[0].mode_id;
1200+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
1201+ &info->var, info);
1202+ goto gotmode;
1203+ }
1204+ }
1205+
1206+ /* Look for a matching VBE mode. */
1207+ modeid = uvesafb_vbe_find_mode(par, info->var.xres, info->var.yres,
1208+ info->var.bits_per_pixel, UVESAFB_EXACT_RES);
1209+
1210+ if (modeid == -1)
1211+ return -EINVAL;
1212+
1213+gotmode:
1214+ uvesafb_setup_var(&info->var, info, &par->vbe_modes[modeid]);
1215+
1216+ /*
1217+ * If we are not VBE3.0+ compliant, we're done -- the BIOS will
1218+ * ignore our timings anyway.
1219+ */
1220+ if (par->vbe_ib.vbe_version < 0x0300 || par->nocrtc)
1221+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
1222+ &info->var, info);
1223+
1224+ return modeid;
1225+}
1226+
1227+static int uvesafb_setpalette(struct uvesafb_pal_entry *entries, int count,
1228+ int start, struct fb_info *info)
1229+{
1230+ struct uvesafb_ktask *task;
1231+ struct uvesafb_par *par = info->par;
1232+ int i = par->mode_idx;
1233+ int err = 0;
1234+
1235+ /*
1236+ * We support palette modifications for 8 bpp modes only, so
1237+ * there can never be more than 256 entries.
1238+ */
1239+ if (start + count > 256)
1240+ return -EINVAL;
1241+
1242+ /* Use VGA registers if mode is VGA-compatible. */
1243+ if (i >= 0 && i < par->vbe_modes_cnt &&
1244+ par->vbe_modes[i].mode_attr & VBE_MODE_VGACOMPAT) {
1245+ for (i = 0; i < count; i++) {
1246+ outb_p(start + i, dac_reg);
1247+ outb_p(entries[i].red, dac_val);
1248+ outb_p(entries[i].green, dac_val);
1249+ outb_p(entries[i].blue, dac_val);
1250+ }
1251+ }
1252+#ifdef CONFIG_X86_32
1253+ else if (par->pmi_setpal) {
1254+ __asm__ __volatile__(
1255+ "call *(%%esi)"
1256+ : /* no return value */
1257+ : "a" (0x4f09), /* EAX */
1258+ "b" (0), /* EBX */
1259+ "c" (count), /* ECX */
1260+ "d" (start), /* EDX */
1261+ "D" (entries), /* EDI */
1262+ "S" (&par->pmi_pal)); /* ESI */
1263+ }
1264+#endif
1265+ else {
1266+ task = uvesafb_prep();
1267+ if (!task)
1268+ return -ENOMEM;
1269+
1270+ task->t.regs.eax = 0x4f09;
1271+ task->t.regs.ebx = 0x0;
1272+ task->t.regs.ecx = count;
1273+ task->t.regs.edx = start;
1274+ task->t.flags = TF_BUF_ESDI;
1275+ task->t.buf_len = sizeof(struct uvesafb_pal_entry) * count;
1276+ task->buf = entries;
1277+
1278+ err = uvesafb_exec(task);
1279+ if ((task->t.regs.eax & 0xffff) != 0x004f)
1280+ err = 1;
1281+
1282+ uvesafb_free(task);
1283+ }
1284+ return err;
1285+}
1286+
1287+static int uvesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
1288+ unsigned blue, unsigned transp,
1289+ struct fb_info *info)
1290+{
1291+ struct uvesafb_pal_entry entry;
1292+ int shift = 16 - info->var.green.length;
1293+ int err = 0;
1294+
1295+ if (regno >= info->cmap.len)
1296+ return -EINVAL;
1297+
1298+ if (info->var.bits_per_pixel == 8) {
1299+ entry.red = red >> shift;
1300+ entry.green = green >> shift;
1301+ entry.blue = blue >> shift;
1302+ entry.pad = 0;
1303+
1304+ err = uvesafb_setpalette(&entry, 1, regno, info);
1305+ } else if (regno < 16) {
1306+ switch (info->var.bits_per_pixel) {
1307+ case 16:
1308+ if (info->var.red.offset == 10) {
1309+ /* 1:5:5:5 */
1310+ ((u32 *) (info->pseudo_palette))[regno] =
1311+ ((red & 0xf800) >> 1) |
1312+ ((green & 0xf800) >> 6) |
1313+ ((blue & 0xf800) >> 11);
1314+ } else {
1315+ /* 0:5:6:5 */
1316+ ((u32 *) (info->pseudo_palette))[regno] =
1317+ ((red & 0xf800) ) |
1318+ ((green & 0xfc00) >> 5) |
1319+ ((blue & 0xf800) >> 11);
1320+ }
1321+ break;
1322+
1323+ case 24:
1324+ case 32:
1325+ red >>= 8;
1326+ green >>= 8;
1327+ blue >>= 8;
1328+ ((u32 *)(info->pseudo_palette))[regno] =
1329+ (red << info->var.red.offset) |
1330+ (green << info->var.green.offset) |
1331+ (blue << info->var.blue.offset);
1332+ break;
1333+ }
1334+ }
1335+ return err;
1336+}
1337+
1338+static int uvesafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
1339+{
1340+ struct uvesafb_pal_entry *entries;
1341+ int shift = 16 - info->var.green.length;
1342+ int i, err = 0;
1343+
1344+ if (info->var.bits_per_pixel == 8) {
1345+ if (cmap->start + cmap->len > info->cmap.start +
1346+ info->cmap.len || cmap->start < info->cmap.start)
1347+ return -EINVAL;
1348+
1349+ entries = kmalloc(sizeof(*entries) * cmap->len, GFP_KERNEL);
1350+ if (!entries)
1351+ return -ENOMEM;
1352+
1353+ for (i = 0; i < cmap->len; i++) {
1354+ entries[i].red = cmap->red[i] >> shift;
1355+ entries[i].green = cmap->green[i] >> shift;
1356+ entries[i].blue = cmap->blue[i] >> shift;
1357+ entries[i].pad = 0;
1358+ }
1359+ err = uvesafb_setpalette(entries, cmap->len, cmap->start, info);
1360+ kfree(entries);
1361+ } else {
1362+ /*
1363+ * For modes with bpp > 8, we only set the pseudo palette in
1364+ * the fb_info struct. We rely on uvesafb_setcolreg to do all
1365+ * sanity checking.
1366+ */
1367+ for (i = 0; i < cmap->len; i++) {
1368+ err |= uvesafb_setcolreg(cmap->start + i, cmap->red[i],
1369+ cmap->green[i], cmap->blue[i],
1370+ 0, info);
1371+ }
1372+ }
1373+ return err;
1374+}
1375+
1376+static int uvesafb_pan_display(struct fb_var_screeninfo *var,
1377+ struct fb_info *info)
1378+{
1379+#ifdef CONFIG_X86_32
1380+ int offset;
1381+ struct uvesafb_par *par = info->par;
1382+
1383+ offset = (var->yoffset * info->fix.line_length + var->xoffset) / 4;
1384+
1385+ /*
1386+ * It turns out it's not the best idea to do panning via vm86,
1387+ * so we only allow it if we have a PMI.
1388+ */
1389+ if (par->pmi_start) {
1390+ __asm__ __volatile__(
1391+ "call *(%%edi)"
1392+ : /* no return value */
1393+ : "a" (0x4f07), /* EAX */
1394+ "b" (0), /* EBX */
1395+ "c" (offset), /* ECX */
1396+ "d" (offset >> 16), /* EDX */
1397+ "D" (&par->pmi_start)); /* EDI */
1398+ }
1399+#endif
1400+ return 0;
1401+}
1402+
1403+static int uvesafb_blank(int blank, struct fb_info *info)
1404+{
1405+ struct uvesafb_par *par = info->par;
1406+ struct uvesafb_ktask *task;
1407+ int err = 1;
1408+
1409+ if (par->vbe_ib.capabilities & VBE_CAP_VGACOMPAT) {
1410+ int loop = 10000;
1411+ u8 seq = 0, crtc17 = 0;
1412+
1413+ if (blank == FB_BLANK_POWERDOWN) {
1414+ seq = 0x20;
1415+ crtc17 = 0x00;
1416+ err = 0;
1417+ } else {
1418+ seq = 0x00;
1419+ crtc17 = 0x80;
1420+ err = (blank == FB_BLANK_UNBLANK) ? 0 : -EINVAL;
1421+ }
1422+
1423+ vga_wseq(NULL, 0x00, 0x01);
1424+ seq |= vga_rseq(NULL, 0x01) & ~0x20;
1425+ vga_wseq(NULL, 0x00, seq);
1426+
1427+ crtc17 |= vga_rcrt(NULL, 0x17) & ~0x80;
1428+ while (loop--);
1429+ vga_wcrt(NULL, 0x17, crtc17);
1430+ vga_wseq(NULL, 0x00, 0x03);
1431+ } else {
1432+ task = uvesafb_prep();
1433+ if (!task)
1434+ return -ENOMEM;
1435+
1436+ task->t.regs.eax = 0x4f10;
1437+ switch (blank) {
1438+ case FB_BLANK_UNBLANK:
1439+ task->t.regs.ebx = 0x0001;
1440+ break;
1441+ case FB_BLANK_NORMAL:
1442+ task->t.regs.ebx = 0x0101; /* standby */
1443+ break;
1444+ case FB_BLANK_POWERDOWN:
1445+ task->t.regs.ebx = 0x0401; /* powerdown */
1446+ break;
1447+ default:
1448+ goto out;
1449+ }
1450+
1451+ err = uvesafb_exec(task);
1452+ if (err || (task->t.regs.eax & 0xffff) != 0x004f)
1453+ err = 1;
1454+out: uvesafb_free(task);
1455+ }
1456+ return err;
1457+}
1458+
1459+static int uvesafb_open(struct fb_info *info, int user)
1460+{
1461+ struct uvesafb_par *par = info->par;
1462+ int cnt = atomic_read(&par->ref_count);
1463+
1464+ if (!cnt && par->vbe_state_size)
1465+ par->vbe_state_orig = uvesafb_vbe_state_save(par);
1466+
1467+ atomic_inc(&par->ref_count);
1468+ return 0;
1469+}
1470+
1471+static int uvesafb_release(struct fb_info *info, int user)
1472+{
1473+ struct uvesafb_ktask *task = NULL;
1474+ struct uvesafb_par *par = info->par;
1475+ int cnt = atomic_read(&par->ref_count);
1476+
1477+ if (!cnt)
1478+ return -EINVAL;
1479+
1480+ if (cnt != 1)
1481+ goto out;
1482+
1483+ task = uvesafb_prep();
1484+ if (!task)
1485+ goto out;
1486+
1487+ /* First, try to set the standard 80x25 text mode. */
1488+ task->t.regs.eax = 0x0003;
1489+ uvesafb_exec(task);
1490+
1491+ /*
1492+ * Now try to restore whatever hardware state we might have
1493+ * saved when the fb device was first opened.
1494+ */
1495+ uvesafb_vbe_state_restore(par, par->vbe_state_orig);
1496+out:
1497+ atomic_dec(&par->ref_count);
1498+ if (task)
1499+ uvesafb_free(task);
1500+ return 0;
1501+}
1502+
1503+static int uvesafb_set_par(struct fb_info *info)
1504+{
1505+ struct uvesafb_par *par = info->par;
1506+ struct uvesafb_ktask *task = NULL;
1507+ struct vbe_crtc_ib *crtc = NULL;
1508+ struct vbe_mode_ib *mode = NULL;
1509+ int i, err = 0, depth = info->var.bits_per_pixel;
1510+
1511+ if (depth > 8 && depth != 32)
1512+ depth = info->var.red.length + info->var.green.length +
1513+ info->var.blue.length;
1514+
1515+ i = uvesafb_vbe_find_mode(par, info->var.xres, info->var.yres, depth,
1516+ UVESAFB_EXACT_RES | UVESAFB_EXACT_DEPTH);
1517+ if (i >= 0)
1518+ mode = &par->vbe_modes[i];
1519+ else
1520+ return -EINVAL;
1521+
1522+ task = uvesafb_prep();
1523+ if (!task)
1524+ return -ENOMEM;
1525+setmode:
1526+ task->t.regs.eax = 0x4f02;
1527+ task->t.regs.ebx = mode->mode_id | 0x4000; /* use LFB */
1528+
1529+ if (par->vbe_ib.vbe_version >= 0x0300 && !par->nocrtc &&
1530+ info->var.pixclock != 0) {
1531+ task->t.regs.ebx |= 0x0800; /* use CRTC data */
1532+ task->t.flags = TF_BUF_ESDI;
1533+ crtc = kzalloc(sizeof(struct vbe_crtc_ib), GFP_KERNEL);
1534+ if (!crtc) {
1535+ err = -ENOMEM;
1536+ goto out;
1537+ }
1538+ crtc->horiz_start = info->var.xres + info->var.right_margin;
1539+ crtc->horiz_end = crtc->horiz_start + info->var.hsync_len;
1540+ crtc->horiz_total = crtc->horiz_end + info->var.left_margin;
1541+
1542+ crtc->vert_start = info->var.yres + info->var.lower_margin;
1543+ crtc->vert_end = crtc->vert_start + info->var.vsync_len;
1544+ crtc->vert_total = crtc->vert_end + info->var.upper_margin;
1545+
1546+ crtc->pixel_clock = PICOS2KHZ(info->var.pixclock) * 1000;
1547+ crtc->refresh_rate = (u16)(100 * (crtc->pixel_clock /
1548+ (crtc->vert_total * crtc->horiz_total)));
1549+
1550+ if (info->var.vmode & FB_VMODE_DOUBLE)
1551+ crtc->flags |= 0x1;
1552+ if (info->var.vmode & FB_VMODE_INTERLACED)
1553+ crtc->flags |= 0x2;
1554+ if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
1555+ crtc->flags |= 0x4;
1556+ if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
1557+ crtc->flags |= 0x8;
1558+ memcpy(&par->crtc, crtc, sizeof(*crtc));
1559+ } else {
1560+ memset(&par->crtc, 0, sizeof(*crtc));
1561+ }
1562+
1563+ task->t.buf_len = sizeof(struct vbe_crtc_ib);
1564+ task->buf = &par->crtc;
1565+
1566+ err = uvesafb_exec(task);
1567+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
1568+ /*
1569+ * The mode switch might have failed because we tried to
1570+ * use our own timings. Try again with the default timings.
1571+ */
1572+ if (crtc != NULL) {
1573+ printk(KERN_WARNING "uvesafb: mode switch failed "
1574+ "(eax=0x%x, err=%d). Trying again with "
1575+ "default timings.\n", task->t.regs.eax, err);
1576+ uvesafb_reset(task);
1577+ kfree(crtc);
1578+ crtc = NULL;
1579+ info->var.pixclock = 0;
1580+ goto setmode;
1581+ } else {
1582+ printk(KERN_ERR "uvesafb: mode switch failed (eax="
1583+ "0x%x, err=%d)\n", task->t.regs.eax, err);
1584+ err = -EINVAL;
1585+ goto out;
1586+ }
1587+ }
1588+ par->mode_idx = i;
1589+
1590+ /* For 8bpp modes, always try to set the DAC to 8 bits. */
1591+ if (par->vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC &&
1592+ mode->bits_per_pixel <= 8) {
1593+ uvesafb_reset(task);
1594+ task->t.regs.eax = 0x4f08;
1595+ task->t.regs.ebx = 0x0800;
1596+
1597+ err = uvesafb_exec(task);
1598+ if (err || (task->t.regs.eax & 0xffff) != 0x004f ||
1599+ ((task->t.regs.ebx & 0xff00) >> 8) != 8) {
1600+ /*
1601+ * We've failed to set the DAC palette format -
1602+ * time to correct var.
1603+ */
1604+ info->var.red.length = 6;
1605+ info->var.green.length = 6;
1606+ info->var.blue.length = 6;
1607+ }
1608+ }
1609+
1610+ info->fix.visual = (info->var.bits_per_pixel == 8) ?
1611+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
1612+ info->fix.line_length = mode->bytes_per_scan_line;
1613+
1614+out: if (crtc != NULL)
1615+ kfree(crtc);
1616+ uvesafb_free(task);
1617+
1618+ return err;
1619+}
1620+
1621+static void uvesafb_check_limits(struct fb_var_screeninfo *var,
1622+ struct fb_info *info)
1623+{
1624+ const struct fb_videomode *mode;
1625+ struct uvesafb_par *par = info->par;
1626+
1627+ /*
1628+ * If pixclock is set to 0, then we're using default BIOS timings
1629+ * and thus don't have to perform any checks here.
1630+ */
1631+ if (!var->pixclock)
1632+ return;
1633+
1634+ if (par->vbe_ib.vbe_version < 0x0300) {
1635+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60, var, info);
1636+ return;
1637+ }
1638+
1639+ if (!fb_validate_mode(var, info))
1640+ return;
1641+
1642+ mode = fb_find_best_mode(var, &info->modelist);
1643+ if (mode) {
1644+ if (mode->xres == var->xres && mode->yres == var->yres &&
1645+ !(mode->vmode & (FB_VMODE_INTERLACED | FB_VMODE_DOUBLE))) {
1646+ fb_videomode_to_var(var, mode);
1647+ return;
1648+ }
1649+ }
1650+
1651+ if (info->monspecs.gtf && !fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1652+ return;
1653+ /* Use default refresh rate */
1654+ var->pixclock = 0;
1655+}
1656+
1657+static int uvesafb_check_var(struct fb_var_screeninfo *var,
1658+ struct fb_info *info)
1659+{
1660+ struct uvesafb_par *par = info->par;
1661+ struct vbe_mode_ib *mode = NULL;
1662+ int match = -1;
1663+ int depth = var->red.length + var->green.length + var->blue.length;
1664+
1665+ /*
1666+ * Various apps will use bits_per_pixel to set the color depth,
1667+ * which is theoretically incorrect, but which we'll try to handle
1668+ * here.
1669+ */
1670+ if (depth == 0 || abs(depth - var->bits_per_pixel) >= 8)
1671+ depth = var->bits_per_pixel;
1672+
1673+ match = uvesafb_vbe_find_mode(par, var->xres, var->yres, depth,
1674+ UVESAFB_EXACT_RES);
1675+ if (match == -1)
1676+ return -EINVAL;
1677+
1678+ mode = &par->vbe_modes[match];
1679+ uvesafb_setup_var(var, info, mode);
1680+
1681+ /*
1682+ * Check whether we have remapped enough memory for this mode.
1683+ * We might be called at an early stage, when we haven't remapped
1684+ * any memory yet, in which case we simply skip the check.
1685+ */
1686+ if (var->yres * mode->bytes_per_scan_line > info->fix.smem_len
1687+ && info->fix.smem_len)
1688+ return -EINVAL;
1689+
1690+ if ((var->vmode & FB_VMODE_DOUBLE) &&
1691+ !(par->vbe_modes[match].mode_attr & 0x100))
1692+ var->vmode &= ~FB_VMODE_DOUBLE;
1693+
1694+ if ((var->vmode & FB_VMODE_INTERLACED) &&
1695+ !(par->vbe_modes[match].mode_attr & 0x200))
1696+ var->vmode &= ~FB_VMODE_INTERLACED;
1697+
1698+ uvesafb_check_limits(var, info);
1699+
1700+ var->xres_virtual = var->xres;
1701+ var->yres_virtual = (par->ypan) ?
1702+ info->fix.smem_len / mode->bytes_per_scan_line :
1703+ var->yres;
1704+ return 0;
1705+}
1706+
1707+static void uvesafb_save_state(struct fb_info *info)
1708+{
1709+ struct uvesafb_par *par = info->par;
1710+
1711+ if (par->vbe_state_saved)
1712+ kfree(par->vbe_state_saved);
1713+
1714+ par->vbe_state_saved = uvesafb_vbe_state_save(par);
1715+}
1716+
1717+static void uvesafb_restore_state(struct fb_info *info)
1718+{
1719+ struct uvesafb_par *par = info->par;
1720+
1721+ uvesafb_vbe_state_restore(par, par->vbe_state_saved);
1722+}
1723+
1724+static struct fb_ops uvesafb_ops = {
1725+ .owner = THIS_MODULE,
1726+ .fb_open = uvesafb_open,
1727+ .fb_release = uvesafb_release,
1728+ .fb_setcolreg = uvesafb_setcolreg,
1729+ .fb_setcmap = uvesafb_setcmap,
1730+ .fb_pan_display = uvesafb_pan_display,
1731+ .fb_blank = uvesafb_blank,
1732+ .fb_fillrect = cfb_fillrect,
1733+ .fb_copyarea = cfb_copyarea,
1734+ .fb_imageblit = cfb_imageblit,
1735+ .fb_check_var = uvesafb_check_var,
1736+ .fb_set_par = uvesafb_set_par,
1737+ .fb_save_state = uvesafb_save_state,
1738+ .fb_restore_state = uvesafb_restore_state,
1739+};
1740+
1741+static void __devinit uvesafb_init_info(struct fb_info *info,
1742+ struct vbe_mode_ib *mode)
1743+{
1744+ unsigned int size_vmode;
1745+ unsigned int size_remap;
1746+ unsigned int size_total;
1747+ struct uvesafb_par *par = info->par;
1748+ int i, h;
1749+
1750+ info->pseudo_palette = ((u8 *)info->par + sizeof(struct uvesafb_par));
1751+ info->fix = uvesafb_fix;
1752+ info->fix.ypanstep = par->ypan ? 1 : 0;
1753+ info->fix.ywrapstep = (par->ypan > 1) ? 1 : 0;
1754+
1755+ /*
1756+ * If we were unable to get the state buffer size, disable
1757+ * functions for saving and restoring the hardware state.
1758+ */
1759+ if (par->vbe_state_size == 0) {
1760+ info->fbops->fb_save_state = NULL;
1761+ info->fbops->fb_restore_state = NULL;
1762+ }
1763+
1764+ /* Disable blanking if the user requested so. */
1765+ if (!blank)
1766+ info->fbops->fb_blank = NULL;
1767+
1768+ /*
1769+ * Find out how much IO memory is required for the mode with
1770+ * the highest resolution.
1771+ */
1772+ size_remap = 0;
1773+ for (i = 0; i < par->vbe_modes_cnt; i++) {
1774+ h = par->vbe_modes[i].bytes_per_scan_line *
1775+ par->vbe_modes[i].y_res;
1776+ if (h > size_remap)
1777+ size_remap = h;
1778+ }
1779+ size_remap *= 2;
1780+
1781+ /*
1782+ * size_vmode -- that is the amount of memory needed for the
1783+ * used video mode, i.e. the minimum amount of
1784+ * memory we need.
1785+ */
1786+ if (mode != NULL) {
1787+ size_vmode = info->var.yres * mode->bytes_per_scan_line;
1788+ } else {
1789+ size_vmode = info->var.yres * info->var.xres *
1790+ ((info->var.bits_per_pixel + 7) >> 3);
1791+ }
1792+
1793+ /*
1794+ * size_total -- all video memory we have. Used for mtrr
1795+ * entries, resource allocation and bounds
1796+ * checking.
1797+ */
1798+ size_total = par->vbe_ib.total_memory * 65536;
1799+ if (vram_total)
1800+ size_total = vram_total * 1024 * 1024;
1801+ if (size_total < size_vmode)
1802+ size_total = size_vmode;
1803+
1804+ /*
1805+ * size_remap -- the amount of video memory we are going to
1806+ * use for vesafb. With modern cards it is no
1807+ * option to simply use size_total as th
1808+ * wastes plenty of kernel address space.
1809+ */
1810+ if (vram_remap)
1811+ size_remap = vram_remap * 1024 * 1024;
1812+ if (size_remap < size_vmode)
1813+ size_remap = size_vmode;
1814+ if (size_remap > size_total)
1815+ size_remap = size_total;
1816+
1817+ info->fix.smem_len = size_remap;
1818+ info->fix.smem_start = mode->phys_base_ptr;
1819+
1820+ /*
1821+ * We have to set yres_virtual here because when setup_var() was
1822+ * called, smem_len wasn't defined yet.
1823+ */
1824+ info->var.yres_virtual = info->fix.smem_len /
1825+ mode->bytes_per_scan_line;
1826+
1827+ if (par->ypan && info->var.yres_virtual > info->var.yres) {
1828+ printk(KERN_INFO "uvesafb: scrolling: %s "
1829+ "using protected mode interface, "
1830+ "yres_virtual=%d\n",
1831+ (par->ypan > 1) ? "ywrap" : "ypan",
1832+ info->var.yres_virtual);
1833+ } else {
1834+ printk(KERN_INFO "uvesafb: scrolling: redraw\n");
1835+ info->var.yres_virtual = info->var.yres;
1836+ par->ypan = 0;
1837+ }
1838+
1839+ info->flags = FBINFO_FLAG_DEFAULT |
1840+ (par->ypan) ? FBINFO_HWACCEL_YPAN : 0;
1841+
1842+ if (!par->ypan)
1843+ info->fbops->fb_pan_display = NULL;
1844+}
1845+
1846+static void uvesafb_init_mtrr(struct fb_info *info)
1847+{
1848+#ifdef CONFIG_MTRR
1849+ if (mtrr && !(info->fix.smem_start & (PAGE_SIZE - 1))) {
1850+ int temp_size = info->fix.smem_len;
1851+ unsigned int type = 0;
1852+
1853+ switch (mtrr) {
1854+ case 1:
1855+ type = MTRR_TYPE_UNCACHABLE;
1856+ break;
1857+ case 2:
1858+ type = MTRR_TYPE_WRBACK;
1859+ break;
1860+ case 3:
1861+ type = MTRR_TYPE_WRCOMB;
1862+ break;
1863+ case 4:
1864+ type = MTRR_TYPE_WRTHROUGH;
1865+ break;
1866+ default:
1867+ type = 0;
1868+ break;
1869+ }
1870+
1871+ if (type) {
1872+ int rc;
1873+
1874+ /* Find the largest power-of-two */
1875+ while (temp_size & (temp_size - 1))
1876+ temp_size &= (temp_size - 1);
1877+
1878+ /* Try and find a power of two to add */
1879+ do {
1880+ rc = mtrr_add(info->fix.smem_start,
1881+ temp_size, type, 1);
1882+ temp_size >>= 1;
1883+ } while (temp_size >= PAGE_SIZE && rc == -EINVAL);
1884+ }
1885+ }
1886+#endif /* CONFIG_MTRR */
1887+}
1888+
1889+
1890+static ssize_t uvesafb_show_vbe_ver(struct device *dev,
1891+ struct device_attribute *attr, char *buf)
1892+{
1893+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1894+ struct uvesafb_par *par = info->par;
1895+
1896+ return snprintf(buf, PAGE_SIZE, "%.4x\n", par->vbe_ib.vbe_version);
1897+}
1898+
1899+static DEVICE_ATTR(vbe_version, S_IRUGO, uvesafb_show_vbe_ver, NULL);
1900+
1901+static ssize_t uvesafb_show_vbe_modes(struct device *dev,
1902+ struct device_attribute *attr, char *buf)
1903+{
1904+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1905+ struct uvesafb_par *par = info->par;
1906+ int ret = 0, i;
1907+
1908+ for (i = 0; i < par->vbe_modes_cnt && ret < PAGE_SIZE; i++) {
1909+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
1910+ "%dx%d-%d, 0x%.4x\n",
1911+ par->vbe_modes[i].x_res, par->vbe_modes[i].y_res,
1912+ par->vbe_modes[i].depth, par->vbe_modes[i].mode_id);
1913+ }
1914+
1915+ return ret;
1916+}
1917+
1918+static DEVICE_ATTR(vbe_modes, S_IRUGO, uvesafb_show_vbe_modes, NULL);
1919+
1920+static ssize_t uvesafb_show_vendor(struct device *dev,
1921+ struct device_attribute *attr, char *buf)
1922+{
1923+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1924+ struct uvesafb_par *par = info->par;
1925+
1926+ if (par->vbe_ib.oem_vendor_name_ptr)
1927+ return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
1928+ (&par->vbe_ib) + par->vbe_ib.oem_vendor_name_ptr);
1929+ else
1930+ return 0;
1931+}
1932+
1933+static DEVICE_ATTR(oem_vendor, S_IRUGO, uvesafb_show_vendor, NULL);
1934+
1935+static ssize_t uvesafb_show_product_name(struct device *dev,
1936+ struct device_attribute *attr, char *buf)
1937+{
1938+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1939+ struct uvesafb_par *par = info->par;
1940+
1941+ if (par->vbe_ib.oem_product_name_ptr)
1942+ return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
1943+ (&par->vbe_ib) + par->vbe_ib.oem_product_name_ptr);
1944+ else
1945+ return 0;
1946+}
1947+
1948+static DEVICE_ATTR(oem_product_name, S_IRUGO, uvesafb_show_product_name, NULL);
1949+
1950+static ssize_t uvesafb_show_product_rev(struct device *dev,
1951+ struct device_attribute *attr, char *buf)
1952+{
1953+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1954+ struct uvesafb_par *par = info->par;
1955+
1956+ if (par->vbe_ib.oem_product_rev_ptr)
1957+ return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
1958+ (&par->vbe_ib) + par->vbe_ib.oem_product_rev_ptr);
1959+ else
1960+ return 0;
1961+}
1962+
1963+static DEVICE_ATTR(oem_product_rev, S_IRUGO, uvesafb_show_product_rev, NULL);
1964+
1965+static ssize_t uvesafb_show_oem_string(struct device *dev,
1966+ struct device_attribute *attr, char *buf)
1967+{
1968+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1969+ struct uvesafb_par *par = info->par;
1970+
1971+ if (par->vbe_ib.oem_string_ptr)
1972+ return snprintf(buf, PAGE_SIZE, "%s\n",
1973+ (char *)(&par->vbe_ib) + par->vbe_ib.oem_string_ptr);
1974+ else
1975+ return 0;
1976+}
1977+
1978+static DEVICE_ATTR(oem_string, S_IRUGO, uvesafb_show_oem_string, NULL);
1979+
1980+static ssize_t uvesafb_show_nocrtc(struct device *dev,
1981+ struct device_attribute *attr, char *buf)
1982+{
1983+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1984+ struct uvesafb_par *par = info->par;
1985+
1986+ return snprintf(buf, PAGE_SIZE, "%d\n", par->nocrtc);
1987+}
1988+
1989+static ssize_t uvesafb_store_nocrtc(struct device *dev,
1990+ struct device_attribute *attr, const char *buf, size_t count)
1991+{
1992+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1993+ struct uvesafb_par *par = info->par;
1994+
1995+ if (count > 0) {
1996+ if (buf[0] == '0')
1997+ par->nocrtc = 0;
1998+ else
1999+ par->nocrtc = 1;
2000+ }
2001+ return count;
2002+}
2003+
2004+static DEVICE_ATTR(nocrtc, S_IRUGO | S_IWUSR, uvesafb_show_nocrtc,
2005+ uvesafb_store_nocrtc);
2006+
2007+static struct attribute *uvesafb_dev_attrs[] = {
2008+ &dev_attr_vbe_version.attr,
2009+ &dev_attr_vbe_modes.attr,
2010+ &dev_attr_oem_vendor.attr,
2011+ &dev_attr_oem_product_name.attr,
2012+ &dev_attr_oem_product_rev.attr,
2013+ &dev_attr_oem_string.attr,
2014+ &dev_attr_nocrtc.attr,
2015+ NULL,
2016+};
2017+
2018+static struct attribute_group uvesafb_dev_attgrp = {
2019+ .name = NULL,
2020+ .attrs = uvesafb_dev_attrs,
2021+};
2022+
2023+static int __devinit uvesafb_probe(struct platform_device *dev)
2024+{
2025+ struct fb_info *info;
2026+ struct vbe_mode_ib *mode = NULL;
2027+ struct uvesafb_par *par;
2028+ int err = 0, i;
2029+
2030+ info = framebuffer_alloc(sizeof(*par) + sizeof(u32) * 256, &dev->dev);
2031+ if (!info)
2032+ return -ENOMEM;
2033+
2034+ par = info->par;
2035+
2036+ err = uvesafb_vbe_init(info);
2037+ if (err) {
2038+ printk(KERN_ERR "uvesafb: vbe_init() failed with %d\n", err);
2039+ goto out;
2040+ }
2041+
2042+ info->fbops = &uvesafb_ops;
2043+
2044+ i = uvesafb_vbe_init_mode(info);
2045+ if (i < 0) {
2046+ err = -EINVAL;
2047+ goto out;
2048+ } else {
2049+ mode = &par->vbe_modes[i];
2050+ }
2051+
2052+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
2053+ err = -ENXIO;
2054+ goto out;
2055+ }
2056+
2057+ uvesafb_init_info(info, mode);
2058+
2059+ if (!request_mem_region(info->fix.smem_start, info->fix.smem_len,
2060+ "uvesafb")) {
2061+ printk(KERN_ERR "uvesafb: cannot reserve video memory at "
2062+ "0x%lx\n", info->fix.smem_start);
2063+ err = -EIO;
2064+ goto out_mode;
2065+ }
2066+
2067+ info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
2068+
2069+ if (!info->screen_base) {
2070+ printk(KERN_ERR
2071+ "uvesafb: abort, cannot ioremap 0x%x bytes of video "
2072+ "memory at 0x%lx\n",
2073+ info->fix.smem_len, info->fix.smem_start);
2074+ err = -EIO;
2075+ goto out_mem;
2076+ }
2077+
2078+ if (!request_region(0x3c0, 32, "uvesafb")) {
2079+ printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
2080+ err = -EIO;
2081+ goto out_unmap;
2082+ }
2083+
2084+ uvesafb_init_mtrr(info);
2085+ platform_set_drvdata(dev, info);
2086+
2087+ if (register_framebuffer(info) < 0) {
2088+ printk(KERN_ERR
2089+ "uvesafb: failed to register framebuffer device\n");
2090+ err = -EINVAL;
2091+ goto out_reg;
2092+ }
2093+
2094+ printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, "
2095+ "using %dk, total %dk\n", info->fix.smem_start,
2096+ info->screen_base, info->fix.smem_len/1024,
2097+ par->vbe_ib.total_memory * 64);
2098+ printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
2099+ info->fix.id);
2100+
2101+ err = sysfs_create_group(&dev->dev.kobj, &uvesafb_dev_attgrp);
2102+ if (err != 0)
2103+ printk(KERN_WARNING "fb%d: failed to register attributes\n",
2104+ info->node);
2105+
2106+ return 0;
2107+
2108+out_reg:
2109+ release_region(0x3c0, 32);
2110+out_unmap:
2111+ iounmap(info->screen_base);
2112+out_mem:
2113+ release_mem_region(info->fix.smem_start, info->fix.smem_len);
2114+out_mode:
2115+ if (!list_empty(&info->modelist))
2116+ fb_destroy_modelist(&info->modelist);
2117+ fb_destroy_modedb(info->monspecs.modedb);
2118+ fb_dealloc_cmap(&info->cmap);
2119+out:
2120+ if (par->vbe_modes)
2121+ kfree(par->vbe_modes);
2122+
2123+ framebuffer_release(info);
2124+ return err;
2125+}
2126+
2127+static int uvesafb_remove(struct platform_device *dev)
2128+{
2129+ struct fb_info *info = platform_get_drvdata(dev);
2130+
2131+ if (info) {
2132+ struct uvesafb_par *par = info->par;
2133+
2134+ sysfs_remove_group(&dev->dev.kobj, &uvesafb_dev_attgrp);
2135+ unregister_framebuffer(info);
2136+ release_region(0x3c0, 32);
2137+ iounmap(info->screen_base);
2138+ release_mem_region(info->fix.smem_start, info->fix.smem_len);
2139+ fb_destroy_modedb(info->monspecs.modedb);
2140+ fb_dealloc_cmap(&info->cmap);
2141+
2142+ if (par) {
2143+ if (par->vbe_modes)
2144+ kfree(par->vbe_modes);
2145+ if (par->vbe_state_orig)
2146+ kfree(par->vbe_state_orig);
2147+ if (par->vbe_state_saved)
2148+ kfree(par->vbe_state_saved);
2149+ }
2150+
2151+ framebuffer_release(info);
2152+ }
2153+ return 0;
2154+}
2155+
2156+static struct platform_driver uvesafb_driver = {
2157+ .probe = uvesafb_probe,
2158+ .remove = uvesafb_remove,
2159+ .driver = {
2160+ .name = "uvesafb",
2161+ },
2162+};
2163+
2164+static struct platform_device *uvesafb_device;
2165+
2166+#ifndef MODULE
2167+static int __devinit uvesafb_setup(char *options)
2168+{
2169+ char *this_opt;
2170+
2171+ if (!options || !*options)
2172+ return 0;
2173+
2174+ while ((this_opt = strsep(&options, ",")) != NULL) {
2175+ if (!*this_opt) continue;
2176+
2177+ if (!strcmp(this_opt, "redraw"))
2178+ ypan = 0;
2179+ else if (!strcmp(this_opt, "ypan"))
2180+ ypan = 1;
2181+ else if (!strcmp(this_opt, "ywrap"))
2182+ ypan = 2;
2183+ else if (!strcmp(this_opt, "vgapal"))
2184+ pmi_setpal = 0;
2185+ else if (!strcmp(this_opt, "pmipal"))
2186+ pmi_setpal = 1;
2187+ else if (!strncmp(this_opt, "mtrr:", 5))
2188+ mtrr = simple_strtoul(this_opt+5, NULL, 0);
2189+ else if (!strcmp(this_opt, "nomtrr"))
2190+ mtrr = 0;
2191+ else if (!strcmp(this_opt, "nocrtc"))
2192+ nocrtc = 1;
2193+ else if (!strcmp(this_opt, "noedid"))
2194+ noedid = 1;
2195+ else if (!strcmp(this_opt, "noblank"))
2196+ blank = 0;
2197+ else if (!strncmp(this_opt, "vtotal:", 7))
2198+ vram_total = simple_strtoul(this_opt + 7, NULL, 0);
2199+ else if (!strncmp(this_opt, "vremap:", 7))
2200+ vram_remap = simple_strtoul(this_opt + 7, NULL, 0);
2201+ else if (!strncmp(this_opt, "maxhf:", 6))
2202+ maxhf = simple_strtoul(this_opt + 6, NULL, 0);
2203+ else if (!strncmp(this_opt, "maxvf:", 6))
2204+ maxvf = simple_strtoul(this_opt + 6, NULL, 0);
2205+ else if (!strncmp(this_opt, "maxclk:", 7))
2206+ maxclk = simple_strtoul(this_opt + 7, NULL, 0);
2207+ else if (!strncmp(this_opt, "vbemode:", 8))
2208+ vbemode = simple_strtoul(this_opt + 8, NULL, 0);
2209+ else if (this_opt[0] >= '0' && this_opt[0] <= '9') {
2210+ mode_option = this_opt;
2211+ } else {
2212+ printk(KERN_WARNING
2213+ "uvesafb: unrecognized option %s\n", this_opt);
2214+ }
2215+ }
2216+
2217+ return 0;
2218+}
2219+#endif /* !MODULE */
2220+
2221+static ssize_t show_v86d(struct device_driver *dev, char *buf)
2222+{
2223+ return snprintf(buf, PAGE_SIZE, "%s\n", v86d_path);
2224+}
2225+
2226+static ssize_t store_v86d(struct device_driver *dev, const char *buf,
2227+ size_t count)
2228+{
2229+ strncpy(v86d_path, buf, PATH_MAX);
2230+ return count;
2231+}
2232+
2233+static DRIVER_ATTR(v86d, S_IRUGO | S_IWUSR, show_v86d, store_v86d);
2234+
2235+static int __devinit uvesafb_init(void)
2236+{
2237+ int err;
2238+
2239+#ifndef MODULE
2240+ char *option = NULL;
2241+
2242+ if (fb_get_options("uvesafb", &option))
2243+ return -ENODEV;
2244+ uvesafb_setup(option);
2245+#endif
2246+ err = cn_add_callback(&uvesafb_cn_id, "uvesafb", uvesafb_cn_callback);
2247+ if (err)
2248+ return err;
2249+
2250+ err = platform_driver_register(&uvesafb_driver);
2251+
2252+ if (!err) {
2253+ uvesafb_device = platform_device_alloc("uvesafb", 0);
2254+ if (uvesafb_device)
2255+ err = platform_device_add(uvesafb_device);
2256+ else
2257+ err = -ENOMEM;
2258+
2259+ if (err) {
2260+ platform_device_put(uvesafb_device);
2261+ platform_driver_unregister(&uvesafb_driver);
2262+ cn_del_callback(&uvesafb_cn_id);
2263+ return err;
2264+ }
2265+
2266+ err = driver_create_file(&uvesafb_driver.driver,
2267+ &driver_attr_v86d);
2268+ if (err) {
2269+ printk(KERN_WARNING "uvesafb: failed to register "
2270+ "attributes\n");
2271+ err = 0;
2272+ }
2273+ }
2274+ return err;
2275+}
2276+
2277+module_init(uvesafb_init);
2278+
2279+static void __devexit uvesafb_exit(void)
2280+{
2281+ struct uvesafb_ktask *task;
2282+
2283+ if (v86d_started) {
2284+ task = uvesafb_prep();
2285+ if (task) {
2286+ task->t.flags = TF_EXIT;
2287+ uvesafb_exec(task);
2288+ uvesafb_free(task);
2289+ }
2290+ }
2291+
2292+ cn_del_callback(&uvesafb_cn_id);
2293+ driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d);
2294+ platform_device_unregister(uvesafb_device);
2295+ platform_driver_unregister(&uvesafb_driver);
2296+}
2297+
2298+module_exit(uvesafb_exit);
2299+
2300+static inline int param_get_scroll(char *buffer, struct kernel_param *kp)
2301+{
2302+ return 0;
2303+}
2304+
2305+static inline int param_set_scroll(const char *val, struct kernel_param *kp)
2306+{
2307+ ypan = 0;
2308+
2309+ if (!strcmp(val, "redraw"))
2310+ ypan = 0;
2311+ else if (!strcmp(val, "ypan"))
2312+ ypan = 1;
2313+ else if (!strcmp(val, "ywrap"))
2314+ ypan = 2;
2315+
2316+ return 0;
2317+}
2318+
2319+#define param_check_scroll(name, p) __param_check(name, p, void);
2320+
2321+module_param_named(scroll, ypan, scroll, 0);
2322+MODULE_PARM_DESC(scroll,
2323+ "Scrolling mode, set to 'redraw', ''ypan' or 'ywrap'");
2324+module_param_named(vgapal, pmi_setpal, invbool, 0);
2325+MODULE_PARM_DESC(vgapal, "Set palette using VGA registers");
2326+module_param_named(pmipal, pmi_setpal, bool, 0);
2327+MODULE_PARM_DESC(pmipal, "Set palette using PMI calls");
2328+module_param(mtrr, uint, 0);
2329+MODULE_PARM_DESC(mtrr,
2330+ "Memory Type Range Registers setting. Use 0 to disable.");
2331+module_param(blank, bool, 0);
2332+MODULE_PARM_DESC(blank, "Enable hardware blanking");
2333+module_param(nocrtc, bool, 0);
2334+MODULE_PARM_DESC(nocrtc, "Ignore CRTC timings when setting modes");
2335+module_param(noedid, bool, 0);
2336+MODULE_PARM_DESC(noedid,
2337+ "Ignore EDID-provided monitor limits when setting modes");
2338+module_param(vram_remap, uint, 0);
2339+MODULE_PARM_DESC(vram_remap, "Set amount of video memory to be used [MiB]");
2340+module_param(vram_total, uint, 0);
2341+MODULE_PARM_DESC(vram_total, "Set total amount of video memoery [MiB]");
2342+module_param(maxclk, ushort, 0);
2343+MODULE_PARM_DESC(maxclk, "Maximum pixelclock [MHz], overrides EDID data");
2344+module_param(maxhf, ushort, 0);
2345+MODULE_PARM_DESC(maxhf,
2346+ "Maximum horizontal frequency [kHz], overrides EDID data");
2347+module_param(maxvf, ushort, 0);
2348+MODULE_PARM_DESC(maxvf,
2349+ "Maximum vertical frequency [Hz], overrides EDID data");
2350+module_param_named(mode, mode_option, charp, 0);
2351+MODULE_PARM_DESC(mode,
2352+ "Specify initial video mode as \"<xres>x<yres>[-<bpp>][@<refresh>]\"");
2353+module_param(vbemode, ushort, 0);
2354+MODULE_PARM_DESC(vbemode,
2355+ "VBE mode number to set, overrides the 'mode' option");
2356+module_param_string(v86d, v86d_path, PATH_MAX, 0660);
2357+MODULE_PARM_DESC(v86d, "Path to the v86d userspace helper.");
2358+
2359+MODULE_LICENSE("GPL");
2360+MODULE_AUTHOR("Michal Januszewski <spock@gentoo.org>");
2361+MODULE_DESCRIPTION("Framebuffer driver for VBE2.0+ compliant graphics boards");
2362+
2363Index: linux-2.6.22/include/linux/connector.h
2364===================================================================
2365--- linux-2.6.22.orig/include/linux/connector.h 2007-08-28 21:54:13.000000000 +0100
2366+++ linux-2.6.22/include/linux/connector.h 2007-08-28 21:56:34.000000000 +0100
2367@@ -36,14 +36,15 @@
2368 #define CN_VAL_CIFS 0x1
2369 #define CN_W1_IDX 0x3 /* w1 communication */
2370 #define CN_W1_VAL 0x1
2371+#define CN_IDX_V86D 0x4
2372+#define CN_VAL_V86D_UVESAFB 0x1
2373
2374-
2375-#define CN_NETLINK_USERS 4
2376+#define CN_NETLINK_USERS 5
2377
2378 /*
2379 * Maximum connector's message size.
2380 */
2381-#define CONNECTOR_MAX_MSG_SIZE 1024
2382+#define CONNECTOR_MAX_MSG_SIZE 16384
2383
2384 /*
2385 * idx and val are unique identifiers which
2386Index: linux-2.6.22/include/video/Kbuild
2387===================================================================
2388--- linux-2.6.22.orig/include/video/Kbuild 2007-08-28 21:54:13.000000000 +0100
2389+++ linux-2.6.22/include/video/Kbuild 2007-08-28 21:56:34.000000000 +0100
2390@@ -1 +1 @@
2391-unifdef-y += sisfb.h
2392+unifdef-y += sisfb.h uvesafb.h
2393Index: linux-2.6.22/include/video/uvesafb.h
2394===================================================================
2395--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2396+++ linux-2.6.22/include/video/uvesafb.h 2007-08-28 21:56:34.000000000 +0100
2397@@ -0,0 +1,193 @@
2398+#ifndef _UVESAFB_H
2399+#define _UVESAFB_H
2400+
2401+struct v86_regs {
2402+ __u32 ebx;
2403+ __u32 ecx;
2404+ __u32 edx;
2405+ __u32 esi;
2406+ __u32 edi;
2407+ __u32 ebp;
2408+ __u32 eax;
2409+ __u32 eip;
2410+ __u32 eflags;
2411+ __u32 esp;
2412+ __u16 cs;
2413+ __u16 ss;
2414+ __u16 es;
2415+ __u16 ds;
2416+ __u16 fs;
2417+ __u16 gs;
2418+};
2419+
2420+/* Task flags */
2421+#define TF_VBEIB 0x01
2422+#define TF_BUF_ESDI 0x02
2423+#define TF_BUF_ESBX 0x04
2424+#define TF_BUF_RET 0x08
2425+#define TF_EXIT 0x10
2426+
2427+struct uvesafb_task {
2428+ __u8 flags;
2429+ int buf_len;
2430+ struct v86_regs regs;
2431+};
2432+
2433+/* Constants for the capabilities field
2434+ * in vbe_ib */
2435+#define VBE_CAP_CAN_SWITCH_DAC 0x01
2436+#define VBE_CAP_VGACOMPAT 0x02
2437+
2438+/* The VBE Info Block */
2439+struct vbe_ib {
2440+ char vbe_signature[4];
2441+ __u16 vbe_version;
2442+ __u32 oem_string_ptr;
2443+ __u32 capabilities;
2444+ __u32 mode_list_ptr;
2445+ __u16 total_memory;
2446+ __u16 oem_software_rev;
2447+ __u32 oem_vendor_name_ptr;
2448+ __u32 oem_product_name_ptr;
2449+ __u32 oem_product_rev_ptr;
2450+ __u8 reserved[222];
2451+ char oem_data[256];
2452+ char misc_data[512];
2453+} __attribute__ ((packed));
2454+
2455+#ifdef __KERNEL__
2456+
2457+/* VBE CRTC Info Block */
2458+struct vbe_crtc_ib {
2459+ u16 horiz_total;
2460+ u16 horiz_start;
2461+ u16 horiz_end;
2462+ u16 vert_total;
2463+ u16 vert_start;
2464+ u16 vert_end;
2465+ u8 flags;
2466+ u32 pixel_clock;
2467+ u16 refresh_rate;
2468+ u8 reserved[40];
2469+} __attribute__ ((packed));
2470+
2471+#define VBE_MODE_VGACOMPAT 0x20
2472+#define VBE_MODE_COLOR 0x08
2473+#define VBE_MODE_SUPPORTEDHW 0x01
2474+#define VBE_MODE_GRAPHICS 0x10
2475+#define VBE_MODE_LFB 0x80
2476+
2477+#define VBE_MODE_MASK (VBE_MODE_COLOR | VBE_MODE_SUPPORTEDHW | \
2478+ VBE_MODE_GRAPHICS | VBE_MODE_LFB)
2479+
2480+/* VBE Mode Info Block */
2481+struct vbe_mode_ib {
2482+ /* for all VBE revisions */
2483+ u16 mode_attr;
2484+ u8 winA_attr;
2485+ u8 winB_attr;
2486+ u16 win_granularity;
2487+ u16 win_size;
2488+ u16 winA_seg;
2489+ u16 winB_seg;
2490+ u32 win_func_ptr;
2491+ u16 bytes_per_scan_line;
2492+
2493+ /* for VBE 1.2+ */
2494+ u16 x_res;
2495+ u16 y_res;
2496+ u8 x_char_size;
2497+ u8 y_char_size;
2498+ u8 planes;
2499+ u8 bits_per_pixel;
2500+ u8 banks;
2501+ u8 memory_model;
2502+ u8 bank_size;
2503+ u8 image_pages;
2504+ u8 reserved1;
2505+
2506+ /* Direct color fields for direct/6 and YUV/7 memory models. */
2507+ /* Offsets are bit positions of lsb in the mask. */
2508+ u8 red_len;
2509+ u8 red_off;
2510+ u8 green_len;
2511+ u8 green_off;
2512+ u8 blue_len;
2513+ u8 blue_off;
2514+ u8 rsvd_len;
2515+ u8 rsvd_off;
2516+ u8 direct_color_info; /* direct color mode attributes */
2517+
2518+ /* for VBE 2.0+ */
2519+ u32 phys_base_ptr;
2520+ u8 reserved2[6];
2521+
2522+ /* for VBE 3.0+ */
2523+ u16 lin_bytes_per_scan_line;
2524+ u8 bnk_image_pages;
2525+ u8 lin_image_pages;
2526+ u8 lin_red_len;
2527+ u8 lin_red_off;
2528+ u8 lin_green_len;
2529+ u8 lin_green_off;
2530+ u8 lin_blue_len;
2531+ u8 lin_blue_off;
2532+ u8 lin_rsvd_len;
2533+ u8 lin_rsvd_off;
2534+ u32 max_pixel_clock;
2535+ u16 mode_id;
2536+ u8 depth;
2537+} __attribute__ ((packed));
2538+
2539+#define UVESAFB_DEFAULT_MODE "640x480-16"
2540+
2541+/* How long to wait for a reply from userspace [ms] */
2542+#define UVESAFB_TIMEOUT 5000
2543+
2544+/* Max number of concurrent tasks */
2545+#define UVESAFB_TASKS_MAX 16
2546+
2547+#define dac_reg (0x3c8)
2548+#define dac_val (0x3c9)
2549+
2550+struct uvesafb_pal_entry {
2551+ u_char blue, green, red, pad;
2552+} __attribute__ ((packed));
2553+
2554+struct uvesafb_ktask {
2555+ struct uvesafb_task t;
2556+ void *buf;
2557+ struct completion *done;
2558+ u32 ack;
2559+};
2560+
2561+static int uvesafb_exec(struct uvesafb_ktask *tsk);
2562+
2563+#define UVESAFB_EXACT_RES 1
2564+#define UVESAFB_EXACT_DEPTH 2
2565+
2566+struct uvesafb_par {
2567+ struct vbe_ib vbe_ib; /* VBE Info Block */
2568+ struct vbe_mode_ib *vbe_modes; /* list of supported VBE modes */
2569+ int vbe_modes_cnt;
2570+
2571+ u8 nocrtc;
2572+ u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
2573+ u8 pmi_setpal; /* PMI for palette changes */
2574+ u16 *pmi_base; /* protected mode interface location */
2575+ void *pmi_start;
2576+ void *pmi_pal;
2577+ u8 *vbe_state_orig; /*
2578+ * original hardware state, before the
2579+ * driver was loaded
2580+ */
2581+ u8 *vbe_state_saved; /* state saved by fb_save_state */
2582+ int vbe_state_size;
2583+ atomic_t ref_count;
2584+
2585+ int mode_idx;
2586+ struct vbe_crtc_ib crtc;
2587+};
2588+
2589+#endif /* __KERNEL__ */
2590+#endif /* _UVESAFB_H */