[patch] VRAM detection in controlfb

Michel Lanners mlan at cpu.lu
Thu Jun 1 08:43:53 EST 2000


Hi list,

I've finally gotten bored by control's VRAM detection code that is only
semi-functional (either 7x00 or 8x00 VRAM is incorrectly detected).
Until somebody comes up with a failsafe method to detect VRAM, I've
added a command line option to control the amount of VRAM used:

- either kernel command line (compiled-in):

	video=controlfb:vram:3

- or insmod option (no idea whether controlfb works as module):

	insmod controlfb vram=3

Possible values are:

	0 = autodetect (default)
	1 = 2MB bank1
	2 = 2MB bank2
	3 = 4MB (most useful; 4MB doesn't always get detected right)

Larger values get cropped to bits 0 & 1.

If I hear no opposition, I'll send this off to Alan; it might make it
into 2.4.0-final.

Cheers

Michel

-------------------------------------------------------------------------
Michel Lanners                 |  " Read Philosophy.  Study Art.
23, Rue Paul Henkes            |    Ask Questions.  Make Mistakes.
L-1710 Luxembourg              |
email   mlan at cpu.lu            |
http://www.cpu.lu/~mlan        |                     Learn Always. "
-------------- next part --------------
--- linux-2.3.paul/drivers/video/controlfb.c	Fri Apr 21 09:47:27 2000
+++ linux-2.3.paul-work/drivers/video/controlfb.c	Thu Jun  1 00:14:56 2000
@@ -109,6 +109,11 @@
 	} fbcon_cmap;
 };

+static int vram = 0;    /* VRAM config: 1 = 2MB bank1; 2 = 2MB bank2;
+					3 = 4MB */
+MODULE_PARM(vram, "i");
+MODULE_PARM_DESC(vram, "Override VRAM detection: 1 = 2MB bank1; 2 = 2MB bank2; 3 = 4MB");
+
 /******************** Prototypes for exported functions ********************/
 static int control_open(struct fb_info *info, int user);
 static int control_release(struct fb_info *info, int user);
@@ -628,8 +633,8 @@
 	out_le32(&p->control_regs->flags.r, flags);
 	out_le32(&p->control_regs->start_addr.r,
 	    par->yoffset * (par->vxres << cmode));
-	out_le32(&p->control_regs->reg18.r, 0x1e5);
-	out_le32(&p->control_regs->reg19.r, 0);
+       out_le32(&p->control_regs->refr_cnt.r, 0x1e5);
+       out_le32(&p->control_regs->int_en.r, 0);

 	for (i = 0; i < 16; ++i) {
 		controlfb_setcolreg(color_table[i], default_red[i]<<8,
@@ -715,6 +720,29 @@
 	 * - with 4M vram, it appears only as a 4M block at offset 0.
 	 */

+	/* Unfortunately, above is only true on 8x00 machines. 7x00 machines
+	 * behave differently. Until somebody comes up with a way to
+	 * differentiate between the two, you can use the vram= insmod or
+	 * video=controlfb:vram: command-line option to force a specific
+	 * VRAM config.
+	 * 				Michel Lanners <mlan at cpu.lu>
+	 */
+
+	if(vram != 0) {
+		bank1 = vram & 1;
+		bank2 = (vram & 2) / 2;
+		printk(KERN_INFO "controlfb: Overriding VRAM detection, set to"
+			" %s%s%s.\n", (bank1 && bank2) ? "4MB" : "2MB ",
+			(bank1 && !bank2) ? "(bank1)" : "",
+			(!bank1 && bank2) ? "(bank2)" : "");
+		if(!bank1) {
+			p->control_use_bank2 = 1;
+			p->frame_buffer += 0x600000;
+			p->frame_buffer_phys += 0x600000;
+		}
+		goto detect_done;
+	}
+
 	/* We know there is something at 2M if there is something at 0M. */
 	out_8(&p->frame_buffer[0x200000], 0xa5);
 	out_8(&p->frame_buffer[0x200001], 0x38);
@@ -743,7 +771,8 @@
 		p->frame_buffer += 0x600000;
 		p->frame_buffer_phys += 0x600000;
 	}
-
+
+detect_done:
 	p->total_vram = (bank1 + bank2) * 0x200000;

 	printk(KERN_INFO "controlfb: Memory bank 1 %s, bank 2 %s, total VRAM %dMB\n",
@@ -1194,11 +1223,10 @@
 					break;
 			memcpy(fontname, this_opt + 5, i);
 			fontname[i] = 0;
-		}
-		if (!strncmp(this_opt, "vmode:", 6)) {
+		} else if (!strncmp(this_opt, "vmode:", 6)) {
 			int vmode = simple_strtoul(this_opt+6, NULL, 0);
-		if (vmode > 0 && vmode <= VMODE_MAX)
-			default_vmode = vmode;
+			if (vmode > 0 && vmode <= VMODE_MAX)
+				default_vmode = vmode;
 		} else if (!strncmp(this_opt, "cmode:", 6)) {
 			int depth = simple_strtoul(this_opt+6, NULL, 0);
 			switch (depth) {
@@ -1219,6 +1247,8 @@
 				default_cmode = CMODE_32;
 				break;
 			}
+		} else if (!strncmp(this_opt, "vram:", 5)) {
+			vram = 3 & simple_strtoul(this_opt+5, NULL, 0);
 		}
 	}
 }
--- linux-2.3.paul/drivers/video/controlfb.h	Mon Jan  4 01:44:06 1999
+++ linux-2.3.paul-work/drivers/video/controlfb.h	Thu May 25 21:40:41 2000
@@ -21,13 +21,13 @@
  * Structure of the registers for the RADACAL colormap device.
  */
 struct cmap_regs {
-	unsigned char addr;
+	unsigned char addr; 	/* REG-ADDR */
 	char pad1[15];
-	unsigned char d1;
+	unsigned char d1;	/* CRSR-PALETTE */
 	char pad2[15];
-	unsigned char d2;
+	unsigned char d2;	/* REG-DATA */
 	char pad3[15];
-	unsigned char lut;
+	unsigned char lut;	/* COLOR-PALETTE */
 	char pad4[15];
 };

@@ -51,26 +51,27 @@
 	struct preg vesync;	/* vert end sync */
 	struct preg vssync;	/* vert start sync */
 	struct preg vperiod;	/* vert period */
-	struct preg reg8;
+	struct preg reg8;	/* PipeDelayHWCursor */
 	/* Horizontal params are in units of 2 pixels */
 	struct preg hperiod;	/* horiz period - 2 */
 	struct preg hsblank;	/* horiz start blank */
 	struct preg heblank;	/* horiz end blank */
 	struct preg hesync;	/* horiz end sync */
 	struct preg hssync;	/* horiz start sync */
-	struct preg rege;
-	struct preg regf;
-	struct preg reg10;
-	struct preg reg11;
+	struct preg rege;	/* HEQ */
+	struct preg regf;	/* HLFLN */
+	struct preg reg10;	/* HSERR */
+	struct preg reg11;	/* CNTTST */
 	struct preg ctrl;	/* display control */
 	struct preg start_addr;	/* start address: 5 lsbs zero */
 	struct preg pitch;	/* addrs diff between scan lines */
 	struct preg mon_sense;	/* monitor sense bits */
 	struct preg flags;
 	struct preg mode;
-	struct preg reg18;
-	struct preg reg19;
-	struct preg res[6];
+	struct preg refr_cnt;	/* REFRESH-COUNT */
+	struct preg int_en;	/* interrupt enable */
+	struct preg int_st;	/* interrupt status */
+	struct preg res[5];
 };

 struct control_regints {

--134392852-1804289383-959813033=:660-
ontent-Type: TEXT/plain; CHARSET=US-ASCII
Content-Disposition: attachment; filename="controlfb.diff"



More information about the Linuxppc-dev mailing list