0988eed04e
- apple_backlight.patch: Make sure that this loads on all hardware. - efifb_update.patch: Fixes for the 11 inch Macbook Air - acpi_reboot.patch: Should make reboot work better on most hardware - efi_default_physical.patch: Some machines dislike EFI virtual mode
218 lines
8.5 KiB
Diff
218 lines
8.5 KiB
Diff
Fix up efifb so it works properly on the 11" Macbook Air. Upstream in .38?
|
|
|
|
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
|
|
index 70477c2..476ffb1 100644
|
|
--- a/drivers/video/efifb.c
|
|
+++ b/drivers/video/efifb.c
|
|
@@ -53,6 +53,7 @@ enum {
|
|
M_MB_7_1, /* MacBook, 7th rev. */
|
|
M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */
|
|
M_MBA, /* MacBook Air */
|
|
+ M_MBA_3, /* Macbook Air, 3rd rev */
|
|
M_MBP, /* MacBook Pro */
|
|
M_MBP_2, /* MacBook Pro 2nd gen */
|
|
M_MBP_2_2, /* MacBook Pro 2,2nd gen */
|
|
@@ -67,40 +68,49 @@ 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_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 },
|
|
+ /* 11" Macbook Air 3,1 passes the wrong stride */
|
|
+ [M_MBA_3] = { "mba3", 0, 2048 * 4, 0, 0, OVERRIDE_STRIDE },
|
|
+ [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_UNKNOWN] = { NULL, 0, 0, 0, 0, OVERRIDE_NONE }
|
|
};
|
|
|
|
static int set_system(const struct dmi_system_id *id);
|
|
@@ -138,6 +148,7 @@ static const struct dmi_system_id dmi_system_table[] __initconst = {
|
|
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1),
|
|
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1),
|
|
EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA),
|
|
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir3,1", M_MBA_3),
|
|
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP),
|
|
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2),
|
|
EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2),
|
|
@@ -154,16 +165,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) {
|
|
@@ -171,40 +188,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 {
|
|
@@ -214,6 +238,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;
|
|
}
|
|
|