All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Jones <pjones@redhat.com>
To: linux-fbdev@vger.kernel.org
Subject: [PATCH 1/2] Support overriding fields FW tells us with the DMI data.
Date: Wed, 06 Apr 2011 17:34:58 +0000	[thread overview]
Message-ID: <1302111299-10561-1-git-send-email-pjones@redhat.com> (raw)
In-Reply-To: <1301582030-10607-2-git-send-email-pjones@redhat.com>

Some machines apparently give us bogus linelength/stride/pitch data, so
we need to support letting the DMI table override the supplied data.

I bet you can't guess whose machines I'm talking about.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
 drivers/video/efifb.c |  149 +++++++++++++++++++++++++++++--------------------
 1 files changed, 88 insertions(+), 61 deletions(-)

diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index a9645b8..2359b64 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -68,41 +68,48 @@ enum {
 	M_UNKNOWN	/* placeholder */
 };
 
+#define OVERRIDE_NONE	0x0
+#define OVERRIDE_BASE	0x1
+#define OVERRIDE_STRIDE	0x2
+#define OVERRIDE_HEIGHT	0x4
+#define OVERRIDE_WIDTH	0x8
+
 static struct efifb_dmi_info {
 	char *optname;
 	unsigned long base;
 	int stride;
 	int width;
 	int height;
+	int flags;
 } dmi_list[] __initdata = {
-	[M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900 },
-	[M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */
-	[M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 },
-	[M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */
-	[M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200 },
-	[M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080 },
-	[M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440 },
-	[M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 },
-	[M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768 },
-	[M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200 },
-	[M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 },
-	[M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800 },
-	[M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800 },
-	[M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800 },
-	[M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 },
-	[M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 },
-	[M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */
-	[M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900 },
-	[M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 },
-	[M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 },
-	[M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 },
-	[M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200 },
-	[M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900 },
-	[M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200 },
-	[M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050 },
-	[M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800 },
-	[M_MBP_8_2] = { "mbp82", 0x90010000, 1472 * 4, 1440, 900 },
-	[M_UNKNOWN] = { NULL, 0, 0, 0, 0 }
+	[M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
+	[M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, /* guess */
+	[M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE },
+	[M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, /* guess */
+	[M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
+	[M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080, OVERRIDE_NONE },
+	[M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440, OVERRIDE_NONE },
+	[M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768, OVERRIDE_NONE },
+	[M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768, OVERRIDE_NONE },
+	[M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
+	[M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
+	[M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
+	[M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
+	[M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
+	[M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
+	[M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
+	[M_MBP_2] = { "mbp2", 0, 0, 0, 0, OVERRIDE_NONE }, /* placeholder */
+	[M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
+	[M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900, OVERRIDE_NONE },
+	[M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
+	[M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE },
+	[M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
+	[M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE },
+	[M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
+	[M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050, OVERRIDE_NONE },
+	[M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
+	[M_MBP_8_2] = { "mbp82", 0x90010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
+	[M_UNKNOWN] = { NULL, 0, 0, 0, 0, OVERRIDE_NONE }
 };
 
 static int set_system(const struct dmi_system_id *id);
@@ -157,16 +164,22 @@ static const struct dmi_system_id dmi_system_table[] __initconst = {
 	{},
 };
 
+#define choose_value(dmivalue, fwvalue, field, flags) ({	\
+		typeof(fwvalue) _ret_ = fwvalue;		\
+		if ((flags) & (field))				\
+			_ret_ = dmivalue;			\
+		else if ((fwvalue) = 0)			\
+			_ret_ = dmivalue;			\
+		_ret_;						\
+	})
+
 static int set_system(const struct dmi_system_id *id)
 {
 	struct efifb_dmi_info *info = id->driver_data;
-	if (info->base = 0)
-		return 0;
 
-	printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p "
-			 "(%dx%d, stride %d)\n", id->ident,
-			 (void *)info->base, info->width, info->height,
-			 info->stride);
+	if (info->base = 0 && info->height = 0 && info->width = 0
+			&& info->stride = 0)
+		return 0;
 
 	/* Trust the bootloader over the DMI tables */
 	if (screen_info.lfb_base = 0) {
@@ -174,40 +187,47 @@ static int set_system(const struct dmi_system_id *id)
 		struct pci_dev *dev = NULL;
 		int found_bar = 0;
 #endif
-		screen_info.lfb_base = info->base;
+		if (info->base) {
+			screen_info.lfb_base = choose_value(info->base,
+				screen_info.lfb_base, OVERRIDE_BASE,
+				info->flags);
 
 #if defined(CONFIG_PCI)
-		/* make sure that the address in the table is actually on a
-		 * VGA device's PCI BAR */
-
-		for_each_pci_dev(dev) {
-			int i;
-			if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
-				continue;
-			for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-				resource_size_t start, end;
-
-				start = pci_resource_start(dev, i);
-				if (start = 0)
-					break;
-				end = pci_resource_end(dev, i);
-				if (screen_info.lfb_base >= start &&
-						screen_info.lfb_base < end) {
-					found_bar = 1;
+			/* make sure that the address in the table is actually
+			 * on a VGA device's PCI BAR */
+
+			for_each_pci_dev(dev) {
+				int i;
+				if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+					continue;
+				for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+					resource_size_t start, end;
+
+					start = pci_resource_start(dev, i);
+					if (start = 0)
+						break;
+					end = pci_resource_end(dev, i);
+					if (screen_info.lfb_base >= start &&
+					    screen_info.lfb_base < end) {
+						found_bar = 1;
+					}
 				}
 			}
-		}
-		if (!found_bar)
-			screen_info.lfb_base = 0;
+			if (!found_bar)
+				screen_info.lfb_base = 0;
 #endif
+		}
 	}
 	if (screen_info.lfb_base) {
-		if (screen_info.lfb_linelength = 0)
-			screen_info.lfb_linelength = info->stride;
-		if (screen_info.lfb_width = 0)
-			screen_info.lfb_width = info->width;
-		if (screen_info.lfb_height = 0)
-			screen_info.lfb_height = info->height;
+		screen_info.lfb_linelength = choose_value(info->stride,
+			screen_info.lfb_linelength, OVERRIDE_STRIDE,
+			info->flags);
+		screen_info.lfb_width = choose_value(info->width,
+			screen_info.lfb_width, OVERRIDE_WIDTH,
+			info->flags);
+		screen_info.lfb_height = choose_value(info->height,
+			screen_info.lfb_height, OVERRIDE_HEIGHT,
+			info->flags);
 		if (screen_info.orig_video_isVGA = 0)
 			screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
 	} else {
@@ -217,6 +237,13 @@ static int set_system(const struct dmi_system_id *id)
 		screen_info.orig_video_isVGA = 0;
 		return 0;
 	}
+
+	printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p "
+			 "(%dx%d, stride %d)\n", id->ident,
+			 (void *)screen_info.lfb_base, screen_info.lfb_width,
+			 screen_info.lfb_height, screen_info.lfb_linelength);
+
+
 	return 1;
 }
 
-- 
1.7.4


  parent reply	other threads:[~2011-04-06 17:34 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-31 14:33 [PATCH 1/2] Support overriding fields FW tells us with the DMI data Peter Jones
2011-04-06 16:42 ` Paul Mundt
2011-04-06 17:31 ` [PATCH 1/2] Support overriding fields FW tells us with the DMI Peter Jones
2011-04-06 17:34 ` Peter Jones [this message]
2011-04-06 17:59 ` [PATCH 1/2] Support overriding fields FW tells us with the DMI data Paul Mundt

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=1302111299-10561-1-git-send-email-pjones@redhat.com \
    --to=pjones@redhat.com \
    --cc=linux-fbdev@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.