linux-fbdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Petr Vandrovec <vandrove@vc.cvut.cz>
To: linux-fbdev-devel@lists.sourceforge.net
Subject: [PATCH] Make vesafb usable with Matrox Parhelia & Px50
Date: Mon, 29 Sep 2003 19:19:37 +0200	[thread overview]
Message-ID: <20030929171937.GA4920@vana.vc.cvut.cz> (raw)

Hi,
  in the case that you are unhappy owner of Matrox Parhelia card, patch below
makes vesafb driver in the kernel able to drive card. Problem is that card is
not VGA compatible beast, and so you must use video=vesafb:pmipal. But you cannot
use pmipal because (1) code which checks whether BIOS requires MMIO regions
or not is broken and (2) code does not support MMIO regions.

  Patch below (for 2.6.0-test6) fixes both problems. VESA interface has strange
idea about possible line lengths, but maybe that it is hardware limitation...

vesafb: framebuffer at 0xcc000000, mapped to 0xe080a000, size 16384k
vesafb: mode is 1280x1024x8, linelength=2048, pages=6
vesafb: protected mode interface info at c000:7960
vesafb: pmi: set display start = c00c7ac3, set palette = c00c7bed
vesafb: pmi: ports =
vesafb: MMIO 0xC9800000/8192 mapped at e180b000
vesafb: scrolling: redraw
Console: switching to colour frame buffer device 160x64
fb0: VESA VGA frame buffer device

Patch is also available at ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/vesafb-parhelia.gz.

						Best regards,
							Petr Vandrovec
							vandrove@vc.cvut.cz

diff -urdN linux/drivers/video/vesafb.c linux/drivers/video/vesafb.c
--- linux/drivers/video/vesafb.c	2003-09-28 20:42:06.000000000 +0200
+++ linux/drivers/video/vesafb.c	2003-09-29 18:53:59.000000000 +0200
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #ifdef __i386__
 #include <video/edid.h>
+#include <asm/desc.h>
 #endif
 #include <asm/io.h>
 #include <asm/mtrr.h>
@@ -79,13 +80,18 @@
 	offset = (var->yoffset * info->fix.line_length + var->xoffset) / 4;
 
         __asm__ __volatile__(
-                "call *(%%edi)"
+		"pushl %%es\n\t"
+		"pushl %5\n\t"
+		"popl %%es\n\t"
+                "call *%%edi\n\t"
+		"popl %%es\n\t"
                 : /* no return value */
                 : "a" (0x4f07),         /* EAX */
                   "b" (0),              /* EBX */
                   "c" (offset),         /* ECX */
                   "d" (offset >> 16),   /* EDX */
-                  "D" (&pmi_start));    /* EDI */
+                  "D" (pmi_start),      /* EDI */
+		  "i" (GDT_ENTRY_VGABIOS_BASE*8));
 #endif
 	return 0;
 }
@@ -101,14 +107,19 @@
 		entry.blue  = blue  >> 10;
 		entry.pad   = 0;
 	        __asm__ __volatile__(
-                "call *(%%esi)"
+		"pushl %%ds\n\t"
+		"pushl %6\n\t"
+		"popl %%ds\n\t"
+                "call *%%esi\n\t"
+		"popl %%ds\n\t"
                 : /* no return value */
                 : "a" (0x4f09),         /* EAX */
                   "b" (0),              /* EBX */
                   "c" (1),              /* ECX */
                   "d" (regno),          /* EDX */
                   "D" (&entry),         /* EDI */
-                  "S" (&pmi_pal));      /* ESI */
+                  "S" (pmi_pal),        /* ESI */
+		  "i" (GDT_ENTRY_VGABIOS_BASE*8));
 	} else {
 		/* without protected mode interface, try VGA registers... */
 		outb_p(regno,       dac_reg);
@@ -218,6 +229,7 @@
 {
 	int video_cmap_len;
 	int i;
+	int cpunr;
 
 	if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
 		return -ENXIO;
@@ -273,6 +285,13 @@
 	if (screen_info.vesapm_seg < 0xc000)
 		ypan = pmi_setpal = 0; /* not available or some DOS TSR ... */
 
+	for (cpunr = 0; cpunr < NR_CPUS; cpunr++) {
+		/* 
+		 * Create loadable but inaccessible segment - you can load it into the segment
+		 * register, but you cannot access even single byte through this.
+		 */
+		_set_tssldt_desc(&cpu_gdt_table[cpunr][GDT_ENTRY_VGABIOS_BASE], 0, 0xFFFF, 0x97);
+	}
 	if (ypan || pmi_setpal) {
 		pmi_base  = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
 		pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
@@ -280,18 +299,36 @@
 		printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
 		if (pmi_base[3]) {
 			printk(KERN_INFO "vesafb: pmi: ports = ");
-				for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++)
-					printk("%x ",pmi_base[i]);
+			for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++)
+				printk("%x ",pmi_base[i]);
 			printk("\n");
+			i++;
 			if (pmi_base[i] != 0xffff) {
-				/*
-				 * memory areas not supported (yet?)
-				 *
-				 * Rules are: we have to set up a descriptor for the requested
-				 * memory area and pass it in the ES register to the BIOS function.
-				 */
-				printk(KERN_INFO "vesafb: can't handle memory requests, pmi disabled\n");
-				ypan = pmi_setpal = 0;
+				unsigned long base = pmi_base[i] | (pmi_base[i+1] << 16);
+				unsigned int size = pmi_base[i+2];
+				void* mmio;
+
+				i += 3;
+				mmio = ioremap(base, size);
+				if (!mmio) {
+					printk(KERN_INFO "vesafb: can't get access to MMIO at 0x%lX/%u. PMI disabled\n", base, size);
+					ypan = pmi_setpal = 0;
+				} else {
+					printk(KERN_INFO "vesafb: MMIO 0x%lX/%u mapped at %p\n", base, size, mmio);
+					for (cpunr = 0; cpunr < NR_CPUS; cpunr++) {
+						_set_tssldt_desc(&cpu_gdt_table[cpunr][GDT_ENTRY_VGABIOS_BASE], mmio, size-1, 0x93);
+					}
+					if (pmi_base[i] != 0xffff) {
+						/*
+						 * memory areas
+						 *
+						 * Rules are: we have to set up a descriptor for the requested
+						 * memory area and pass it in the ES register to the BIOS function.
+						 */
+						printk(KERN_INFO "vesafb: can't handle memory requests, pmi disabled\n");
+						ypan = pmi_setpal = 0;
+					}
+				}
 			}
 		}
 	}
diff -urdN linux/include/asm-i386/segment.h linux/include/asm-i386/segment.h
--- linux/include/asm-i386/segment.h	2003-09-28 20:43:29.000000000 +0200
+++ linux/include/asm-i386/segment.h	2003-09-29 18:00:48.000000000 +0200
@@ -37,8 +37,8 @@
  *  23 - APM BIOS support
  *  24 - APM BIOS support
  *  25 - APM BIOS support 
+ *  26 - VGA BIOS support (MMIO)
  *
- *  26 - unused
  *  27 - unused
  *  28 - unused
  *  29 - unused
@@ -70,6 +70,7 @@
 
 #define GDT_ENTRY_PNPBIOS_BASE		(GDT_ENTRY_KERNEL_BASE + 6)
 #define GDT_ENTRY_APMBIOS_BASE		(GDT_ENTRY_KERNEL_BASE + 11)
+#define GDT_ENTRY_VGABIOS_BASE		(GDT_ENTRY_KERNEL_BASE + 14)
 
 #define GDT_ENTRY_DOUBLEFAULT_TSS	31
 


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf

             reply	other threads:[~2003-09-29 17:22 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-09-29 17:19 Petr Vandrovec [this message]
2003-09-30 14:53 ` [PATCH] Make vesafb usable with Matrox Parhelia & Px50 Jurriaan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030929171937.GA4920@vana.vc.cvut.cz \
    --to=vandrove@vc.cvut.cz \
    --cc=linux-fbdev-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).