diff options
-rw-r--r-- | arch/x86/Kconfig | 26 | ||||
-rw-r--r-- | arch/x86/include/asm/sysfb.h | 98 | ||||
-rw-r--r-- | arch/x86/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/x86/kernel/sysfb.c | 74 | ||||
-rw-r--r-- | arch/x86/kernel/sysfb_efi.c | 214 | ||||
-rw-r--r-- | arch/x86/kernel/sysfb_simplefb.c | 95 | ||||
-rw-r--r-- | drivers/video/Kconfig | 5 | ||||
-rw-r--r-- | drivers/video/console/Kconfig | 3 | ||||
-rw-r--r-- | drivers/video/efifb.c | 302 | ||||
-rw-r--r-- | drivers/video/simplefb.c | 58 | ||||
-rw-r--r-- | drivers/video/vesafb.c | 55 | ||||
-rw-r--r-- | include/linux/platform_data/simplefb.h | 63 |
12 files changed, 666 insertions, 330 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f16fc34e6608..ff47e230d355 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -2270,6 +2270,32 @@ config RAPIDIO | |||
2270 | 2270 | ||
2271 | source "drivers/rapidio/Kconfig" | 2271 | source "drivers/rapidio/Kconfig" |
2272 | 2272 | ||
2273 | config X86_SYSFB | ||
2274 | bool "Mark VGA/VBE/EFI FB as generic system framebuffer" | ||
2275 | help | ||
2276 | Firmwares often provide initial graphics framebuffers so the BIOS, | ||
2277 | bootloader or kernel can show basic video-output during boot for | ||
2278 | user-guidance and debugging. Historically, x86 used the VESA BIOS | ||
2279 | Extensions and EFI-framebuffers for this, which are mostly limited | ||
2280 | to x86. | ||
2281 | This option, if enabled, marks VGA/VBE/EFI framebuffers as generic | ||
2282 | framebuffers so the new generic system-framebuffer drivers can be | ||
2283 | used on x86. If the framebuffer is not compatible with the generic | ||
2284 | modes, it is adverticed as fallback platform framebuffer so legacy | ||
2285 | drivers like efifb, vesafb and uvesafb can pick it up. | ||
2286 | If this option is not selected, all system framebuffers are always | ||
2287 | marked as fallback platform framebuffers as usual. | ||
2288 | |||
2289 | Note: Legacy fbdev drivers, including vesafb, efifb, uvesafb, will | ||
2290 | not be able to pick up generic system framebuffers if this option | ||
2291 | is selected. You are highly encouraged to enable simplefb as | ||
2292 | replacement if you select this option. simplefb can correctly deal | ||
2293 | with generic system framebuffers. But you should still keep vesafb | ||
2294 | and others enabled as fallback if a system framebuffer is | ||
2295 | incompatible with simplefb. | ||
2296 | |||
2297 | If unsure, say Y. | ||
2298 | |||
2273 | endmenu | 2299 | endmenu |
2274 | 2300 | ||
2275 | 2301 | ||
diff --git a/arch/x86/include/asm/sysfb.h b/arch/x86/include/asm/sysfb.h new file mode 100644 index 000000000000..2aeb3e25579c --- /dev/null +++ b/arch/x86/include/asm/sysfb.h | |||
@@ -0,0 +1,98 @@ | |||
1 | #ifndef _ARCH_X86_KERNEL_SYSFB_H | ||
2 | #define _ARCH_X86_KERNEL_SYSFB_H | ||
3 | |||
4 | /* | ||
5 | * Generic System Framebuffers on x86 | ||
6 | * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the Free | ||
10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
11 | * any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/platform_data/simplefb.h> | ||
16 | #include <linux/screen_info.h> | ||
17 | |||
18 | enum { | ||
19 | M_I17, /* 17-Inch iMac */ | ||
20 | M_I20, /* 20-Inch iMac */ | ||
21 | M_I20_SR, /* 20-Inch iMac (Santa Rosa) */ | ||
22 | M_I24, /* 24-Inch iMac */ | ||
23 | M_I24_8_1, /* 24-Inch iMac, 8,1th gen */ | ||
24 | M_I24_10_1, /* 24-Inch iMac, 10,1th gen */ | ||
25 | M_I27_11_1, /* 27-Inch iMac, 11,1th gen */ | ||
26 | M_MINI, /* Mac Mini */ | ||
27 | M_MINI_3_1, /* Mac Mini, 3,1th gen */ | ||
28 | M_MINI_4_1, /* Mac Mini, 4,1th gen */ | ||
29 | M_MB, /* MacBook */ | ||
30 | M_MB_2, /* MacBook, 2nd rev. */ | ||
31 | M_MB_3, /* MacBook, 3rd rev. */ | ||
32 | M_MB_5_1, /* MacBook, 5th rev. */ | ||
33 | M_MB_6_1, /* MacBook, 6th rev. */ | ||
34 | M_MB_7_1, /* MacBook, 7th rev. */ | ||
35 | M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ | ||
36 | M_MBA, /* MacBook Air */ | ||
37 | M_MBA_3, /* Macbook Air, 3rd rev */ | ||
38 | M_MBP, /* MacBook Pro */ | ||
39 | M_MBP_2, /* MacBook Pro 2nd gen */ | ||
40 | M_MBP_2_2, /* MacBook Pro 2,2nd gen */ | ||
41 | M_MBP_SR, /* MacBook Pro (Santa Rosa) */ | ||
42 | M_MBP_4, /* MacBook Pro, 4th gen */ | ||
43 | M_MBP_5_1, /* MacBook Pro, 5,1th gen */ | ||
44 | M_MBP_5_2, /* MacBook Pro, 5,2th gen */ | ||
45 | M_MBP_5_3, /* MacBook Pro, 5,3rd gen */ | ||
46 | M_MBP_6_1, /* MacBook Pro, 6,1th gen */ | ||
47 | M_MBP_6_2, /* MacBook Pro, 6,2th gen */ | ||
48 | M_MBP_7_1, /* MacBook Pro, 7,1th gen */ | ||
49 | M_MBP_8_2, /* MacBook Pro, 8,2nd gen */ | ||
50 | M_UNKNOWN /* placeholder */ | ||
51 | }; | ||
52 | |||
53 | struct efifb_dmi_info { | ||
54 | char *optname; | ||
55 | unsigned long base; | ||
56 | int stride; | ||
57 | int width; | ||
58 | int height; | ||
59 | int flags; | ||
60 | }; | ||
61 | |||
62 | #ifdef CONFIG_EFI | ||
63 | |||
64 | extern struct efifb_dmi_info efifb_dmi_list[]; | ||
65 | void sysfb_apply_efi_quirks(void); | ||
66 | |||
67 | #else /* CONFIG_EFI */ | ||
68 | |||
69 | static inline void sysfb_apply_efi_quirks(void) | ||
70 | { | ||
71 | } | ||
72 | |||
73 | #endif /* CONFIG_EFI */ | ||
74 | |||
75 | #ifdef CONFIG_X86_SYSFB | ||
76 | |||
77 | bool parse_mode(const struct screen_info *si, | ||
78 | struct simplefb_platform_data *mode); | ||
79 | int create_simplefb(const struct screen_info *si, | ||
80 | const struct simplefb_platform_data *mode); | ||
81 | |||
82 | #else /* CONFIG_X86_SYSFB */ | ||
83 | |||
84 | static inline bool parse_mode(const struct screen_info *si, | ||
85 | struct simplefb_platform_data *mode) | ||
86 | { | ||
87 | return false; | ||
88 | } | ||
89 | |||
90 | static inline int create_simplefb(const struct screen_info *si, | ||
91 | const struct simplefb_platform_data *mode) | ||
92 | { | ||
93 | return -EINVAL; | ||
94 | } | ||
95 | |||
96 | #endif /* CONFIG_X86_SYSFB */ | ||
97 | |||
98 | #endif /* _ARCH_X86_KERNEL_SYSFB_H */ | ||
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 88d99ea77723..a5408b965c9d 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -103,6 +103,9 @@ obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o | |||
103 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o | 103 | obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o |
104 | obj-$(CONFIG_OF) += devicetree.o | 104 | obj-$(CONFIG_OF) += devicetree.o |
105 | obj-$(CONFIG_UPROBES) += uprobes.o | 105 | obj-$(CONFIG_UPROBES) += uprobes.o |
106 | obj-y += sysfb.o | ||
107 | obj-$(CONFIG_X86_SYSFB) += sysfb_simplefb.o | ||
108 | obj-$(CONFIG_EFI) += sysfb_efi.o | ||
106 | 109 | ||
107 | obj-$(CONFIG_PERF_EVENTS) += perf_regs.o | 110 | obj-$(CONFIG_PERF_EVENTS) += perf_regs.o |
108 | obj-$(CONFIG_TRACING) += tracepoint.o | 111 | obj-$(CONFIG_TRACING) += tracepoint.o |
diff --git a/arch/x86/kernel/sysfb.c b/arch/x86/kernel/sysfb.c new file mode 100644 index 000000000000..193ec2ce46c7 --- /dev/null +++ b/arch/x86/kernel/sysfb.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * Generic System Framebuffers on x86 | ||
3 | * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the Free | ||
7 | * Software Foundation; either version 2 of the License, or (at your option) | ||
8 | * any later version. | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * Simple-Framebuffer support for x86 systems | ||
13 | * Create a platform-device for any available boot framebuffer. The | ||
14 | * simple-framebuffer platform device is already available on DT systems, so | ||
15 | * this module parses the global "screen_info" object and creates a suitable | ||
16 | * platform device compatible with the "simple-framebuffer" DT object. If | ||
17 | * the framebuffer is incompatible, we instead create a legacy | ||
18 | * "vesa-framebuffer", "efi-framebuffer" or "platform-framebuffer" device and | ||
19 | * pass the screen_info as platform_data. This allows legacy drivers | ||
20 | * to pick these devices up without messing with simple-framebuffer drivers. | ||
21 | * The global "screen_info" is still valid at all times. | ||
22 | * | ||
23 | * If CONFIG_X86_SYSFB is not selected, we never register "simple-framebuffer" | ||
24 | * platform devices, but only use legacy framebuffer devices for | ||
25 | * backwards compatibility. | ||
26 | * | ||
27 | * TODO: We set the dev_id field of all platform-devices to 0. This allows | ||
28 | * other x86 OF/DT parsers to create such devices, too. However, they must | ||
29 | * start at offset 1 for this to work. | ||
30 | */ | ||
31 | |||
32 | #include <linux/err.h> | ||
33 | #include <linux/init.h> | ||
34 | #include <linux/kernel.h> | ||
35 | #include <linux/mm.h> | ||
36 | #include <linux/platform_data/simplefb.h> | ||
37 | #include <linux/platform_device.h> | ||
38 | #include <linux/screen_info.h> | ||
39 | #include <asm/sysfb.h> | ||
40 | |||
41 | static __init int sysfb_init(void) | ||
42 | { | ||
43 | struct screen_info *si = &screen_info; | ||
44 | struct simplefb_platform_data mode; | ||
45 | struct platform_device *pd; | ||
46 | const char *name; | ||
47 | bool compatible; | ||
48 | int ret; | ||
49 | |||
50 | sysfb_apply_efi_quirks(); | ||
51 | |||
52 | /* try to create a simple-framebuffer device */ | ||
53 | compatible = parse_mode(si, &mode); | ||
54 | if (compatible) { | ||
55 | ret = create_simplefb(si, &mode); | ||
56 | if (!ret) | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | /* if the FB is incompatible, create a legacy framebuffer device */ | ||
61 | if (si->orig_video_isVGA == VIDEO_TYPE_EFI) | ||
62 | name = "efi-framebuffer"; | ||
63 | else if (si->orig_video_isVGA == VIDEO_TYPE_VLFB) | ||
64 | name = "vesa-framebuffer"; | ||
65 | else | ||
66 | name = "platform-framebuffer"; | ||
67 | |||
68 | pd = platform_device_register_resndata(NULL, name, 0, | ||
69 | NULL, 0, si, sizeof(*si)); | ||
70 | return IS_ERR(pd) ? PTR_ERR(pd) : 0; | ||
71 | } | ||
72 | |||
73 | /* must execute after PCI subsystem for EFI quirks */ | ||
74 | device_initcall(sysfb_init); | ||
diff --git a/arch/x86/kernel/sysfb_efi.c b/arch/x86/kernel/sysfb_efi.c new file mode 100644 index 000000000000..b285d4e8c68e --- /dev/null +++ b/arch/x86/kernel/sysfb_efi.c | |||
@@ -0,0 +1,214 @@ | |||
1 | /* | ||
2 | * Generic System Framebuffers on x86 | ||
3 | * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com> | ||
4 | * | ||
5 | * EFI Quirks Copyright (c) 2006 Edgar Hucek <gimli@dark-green.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the Free | ||
9 | * Software Foundation; either version 2 of the License, or (at your option) | ||
10 | * any later version. | ||
11 | */ | ||
12 | |||
13 | /* | ||
14 | * EFI Quirks | ||
15 | * Several EFI systems do not correctly advertise their boot framebuffers. | ||
16 | * Hence, we use this static table of known broken machines and fix up the | ||
17 | * information so framebuffer drivers can load corectly. | ||
18 | */ | ||
19 | |||
20 | #include <linux/dmi.h> | ||
21 | #include <linux/err.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/mm.h> | ||
25 | #include <linux/pci.h> | ||
26 | #include <linux/screen_info.h> | ||
27 | #include <video/vga.h> | ||
28 | #include <asm/sysfb.h> | ||
29 | |||
30 | enum { | ||
31 | OVERRIDE_NONE = 0x0, | ||
32 | OVERRIDE_BASE = 0x1, | ||
33 | OVERRIDE_STRIDE = 0x2, | ||
34 | OVERRIDE_HEIGHT = 0x4, | ||
35 | OVERRIDE_WIDTH = 0x8, | ||
36 | }; | ||
37 | |||
38 | struct efifb_dmi_info efifb_dmi_list[] = { | ||
39 | [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
40 | [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, /* guess */ | ||
41 | [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, | ||
42 | [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, /* guess */ | ||
43 | [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
44 | [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080, OVERRIDE_NONE }, | ||
45 | [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440, OVERRIDE_NONE }, | ||
46 | [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768, OVERRIDE_NONE }, | ||
47 | [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768, OVERRIDE_NONE }, | ||
48 | [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
49 | [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
50 | [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
51 | [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
52 | [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
53 | [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
54 | /* 11" Macbook Air 3,1 passes the wrong stride */ | ||
55 | [M_MBA_3] = { "mba3", 0, 2048 * 4, 0, 0, OVERRIDE_STRIDE }, | ||
56 | [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
57 | [M_MBP_2] = { "mbp2", 0, 0, 0, 0, OVERRIDE_NONE }, /* placeholder */ | ||
58 | [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
59 | [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, | ||
60 | [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
61 | [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, | ||
62 | [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
63 | [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, | ||
64 | [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
65 | [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050, OVERRIDE_NONE }, | ||
66 | [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
67 | [M_MBP_8_2] = { "mbp82", 0x90010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
68 | [M_UNKNOWN] = { NULL, 0, 0, 0, 0, OVERRIDE_NONE } | ||
69 | }; | ||
70 | |||
71 | #define choose_value(dmivalue, fwvalue, field, flags) ({ \ | ||
72 | typeof(fwvalue) _ret_ = fwvalue; \ | ||
73 | if ((flags) & (field)) \ | ||
74 | _ret_ = dmivalue; \ | ||
75 | else if ((fwvalue) == 0) \ | ||
76 | _ret_ = dmivalue; \ | ||
77 | _ret_; \ | ||
78 | }) | ||
79 | |||
80 | static int __init efifb_set_system(const struct dmi_system_id *id) | ||
81 | { | ||
82 | struct efifb_dmi_info *info = id->driver_data; | ||
83 | |||
84 | if (info->base == 0 && info->height == 0 && info->width == 0 && | ||
85 | info->stride == 0) | ||
86 | return 0; | ||
87 | |||
88 | /* Trust the bootloader over the DMI tables */ | ||
89 | if (screen_info.lfb_base == 0) { | ||
90 | #if defined(CONFIG_PCI) | ||
91 | struct pci_dev *dev = NULL; | ||
92 | int found_bar = 0; | ||
93 | #endif | ||
94 | if (info->base) { | ||
95 | screen_info.lfb_base = choose_value(info->base, | ||
96 | screen_info.lfb_base, OVERRIDE_BASE, | ||
97 | info->flags); | ||
98 | |||
99 | #if defined(CONFIG_PCI) | ||
100 | /* make sure that the address in the table is actually | ||
101 | * on a VGA device's PCI BAR */ | ||
102 | |||
103 | for_each_pci_dev(dev) { | ||
104 | int i; | ||
105 | if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) | ||
106 | continue; | ||
107 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | ||
108 | resource_size_t start, end; | ||
109 | |||
110 | start = pci_resource_start(dev, i); | ||
111 | if (start == 0) | ||
112 | break; | ||
113 | end = pci_resource_end(dev, i); | ||
114 | if (screen_info.lfb_base >= start && | ||
115 | screen_info.lfb_base < end) { | ||
116 | found_bar = 1; | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | if (!found_bar) | ||
121 | screen_info.lfb_base = 0; | ||
122 | #endif | ||
123 | } | ||
124 | } | ||
125 | if (screen_info.lfb_base) { | ||
126 | screen_info.lfb_linelength = choose_value(info->stride, | ||
127 | screen_info.lfb_linelength, OVERRIDE_STRIDE, | ||
128 | info->flags); | ||
129 | screen_info.lfb_width = choose_value(info->width, | ||
130 | screen_info.lfb_width, OVERRIDE_WIDTH, | ||
131 | info->flags); | ||
132 | screen_info.lfb_height = choose_value(info->height, | ||
133 | screen_info.lfb_height, OVERRIDE_HEIGHT, | ||
134 | info->flags); | ||
135 | if (screen_info.orig_video_isVGA == 0) | ||
136 | screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; | ||
137 | } else { | ||
138 | screen_info.lfb_linelength = 0; | ||
139 | screen_info.lfb_width = 0; | ||
140 | screen_info.lfb_height = 0; | ||
141 | screen_info.orig_video_isVGA = 0; | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | printk(KERN_INFO "efifb: dmi detected %s - framebuffer at 0x%08x " | ||
146 | "(%dx%d, stride %d)\n", id->ident, | ||
147 | screen_info.lfb_base, screen_info.lfb_width, | ||
148 | screen_info.lfb_height, screen_info.lfb_linelength); | ||
149 | |||
150 | return 1; | ||
151 | } | ||
152 | |||
153 | #define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \ | ||
154 | { \ | ||
155 | efifb_set_system, \ | ||
156 | name, \ | ||
157 | { \ | ||
158 | DMI_MATCH(DMI_BIOS_VENDOR, vendor), \ | ||
159 | DMI_MATCH(DMI_PRODUCT_NAME, name) \ | ||
160 | }, \ | ||
161 | &efifb_dmi_list[enumid] \ | ||
162 | } | ||
163 | |||
164 | static const struct dmi_system_id efifb_dmi_system_table[] __initconst = { | ||
165 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17), | ||
166 | /* At least one of these two will be right; maybe both? */ | ||
167 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20), | ||
168 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac5,1", M_I20), | ||
169 | /* At least one of these two will be right; maybe both? */ | ||
170 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24), | ||
171 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24), | ||
172 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR), | ||
173 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1), | ||
174 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1), | ||
175 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1), | ||
176 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI), | ||
177 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1), | ||
178 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1), | ||
179 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB), | ||
180 | /* At least one of these two will be right; maybe both? */ | ||
181 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB), | ||
182 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook2,1", M_MB), | ||
183 | /* At least one of these two will be right; maybe both? */ | ||
184 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB), | ||
185 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB), | ||
186 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB), | ||
187 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1), | ||
188 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1), | ||
189 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1), | ||
190 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), | ||
191 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir3,1", M_MBA_3), | ||
192 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), | ||
193 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), | ||
194 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2), | ||
195 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2), | ||
196 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR), | ||
197 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR), | ||
198 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4), | ||
199 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1), | ||
200 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2), | ||
201 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3), | ||
202 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1), | ||
203 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2), | ||
204 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1), | ||
205 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro8,2", M_MBP_8_2), | ||
206 | {}, | ||
207 | }; | ||
208 | |||
209 | __init void sysfb_apply_efi_quirks(void) | ||
210 | { | ||
211 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || | ||
212 | !(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS)) | ||
213 | dmi_check_system(efifb_dmi_system_table); | ||
214 | } | ||
diff --git a/arch/x86/kernel/sysfb_simplefb.c b/arch/x86/kernel/sysfb_simplefb.c new file mode 100644 index 000000000000..22513e96b012 --- /dev/null +++ b/arch/x86/kernel/sysfb_simplefb.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * Generic System Framebuffers on x86 | ||
3 | * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the Free | ||
7 | * Software Foundation; either version 2 of the License, or (at your option) | ||
8 | * any later version. | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * simple-framebuffer probing | ||
13 | * Try to convert "screen_info" into a "simple-framebuffer" compatible mode. | ||
14 | * If the mode is incompatible, we return "false" and let the caller create | ||
15 | * legacy nodes instead. | ||
16 | */ | ||
17 | |||
18 | #include <linux/err.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/mm.h> | ||
22 | #include <linux/platform_data/simplefb.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/screen_info.h> | ||
25 | #include <asm/sysfb.h> | ||
26 | |||
27 | static const char simplefb_resname[] = "BOOTFB"; | ||
28 | static const struct simplefb_format formats[] = SIMPLEFB_FORMATS; | ||
29 | |||
30 | /* try parsing x86 screen_info into a simple-framebuffer mode struct */ | ||
31 | __init bool parse_mode(const struct screen_info *si, | ||
32 | struct simplefb_platform_data *mode) | ||
33 | { | ||
34 | const struct simplefb_format *f; | ||
35 | __u8 type; | ||
36 | unsigned int i; | ||
37 | |||
38 | type = si->orig_video_isVGA; | ||
39 | if (type != VIDEO_TYPE_VLFB && type != VIDEO_TYPE_EFI) | ||
40 | return false; | ||
41 | |||
42 | for (i = 0; i < ARRAY_SIZE(formats); ++i) { | ||
43 | f = &formats[i]; | ||
44 | if (si->lfb_depth == f->bits_per_pixel && | ||
45 | si->red_size == f->red.length && | ||
46 | si->red_pos == f->red.offset && | ||
47 | si->green_size == f->green.length && | ||
48 | si->green_pos == f->green.offset && | ||
49 | si->blue_size == f->blue.length && | ||
50 | si->blue_pos == f->blue.offset && | ||
51 | si->rsvd_size == f->transp.length && | ||
52 | si->rsvd_pos == f->transp.offset) { | ||
53 | mode->format = f->name; | ||
54 | mode->width = si->lfb_width; | ||
55 | mode->height = si->lfb_height; | ||
56 | mode->stride = si->lfb_linelength; | ||
57 | return true; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | return false; | ||
62 | } | ||
63 | |||
64 | __init int create_simplefb(const struct screen_info *si, | ||
65 | const struct simplefb_platform_data *mode) | ||
66 | { | ||
67 | struct platform_device *pd; | ||
68 | struct resource res; | ||
69 | unsigned long len; | ||
70 | |||
71 | /* don't use lfb_size as it may contain the whole VMEM instead of only | ||
72 | * the part that is occupied by the framebuffer */ | ||
73 | len = mode->height * mode->stride; | ||
74 | len = PAGE_ALIGN(len); | ||
75 | if (len > si->lfb_size << 16) { | ||
76 | printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n"); | ||
77 | return -EINVAL; | ||
78 | } | ||
79 | |||
80 | /* setup IORESOURCE_MEM as framebuffer memory */ | ||
81 | memset(&res, 0, sizeof(res)); | ||
82 | res.flags = IORESOURCE_MEM; | ||
83 | res.name = simplefb_resname; | ||
84 | res.start = si->lfb_base; | ||
85 | res.end = si->lfb_base + len - 1; | ||
86 | if (res.end <= res.start) | ||
87 | return -EINVAL; | ||
88 | |||
89 | pd = platform_device_register_resndata(NULL, "simple-framebuffer", 0, | ||
90 | &res, 1, mode, sizeof(*mode)); | ||
91 | if (IS_ERR(pd)) | ||
92 | return PTR_ERR(pd); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 4cf1e1dd5621..34c3d960634d 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -2457,7 +2457,7 @@ config FB_HYPERV | |||
2457 | 2457 | ||
2458 | config FB_SIMPLE | 2458 | config FB_SIMPLE |
2459 | bool "Simple framebuffer support" | 2459 | bool "Simple framebuffer support" |
2460 | depends on (FB = y) && OF | 2460 | depends on (FB = y) |
2461 | select FB_CFB_FILLRECT | 2461 | select FB_CFB_FILLRECT |
2462 | select FB_CFB_COPYAREA | 2462 | select FB_CFB_COPYAREA |
2463 | select FB_CFB_IMAGEBLIT | 2463 | select FB_CFB_IMAGEBLIT |
@@ -2469,8 +2469,7 @@ config FB_SIMPLE | |||
2469 | pre-allocated frame buffer surface. | 2469 | pre-allocated frame buffer surface. |
2470 | 2470 | ||
2471 | Configuration re: surface address, size, and format must be provided | 2471 | Configuration re: surface address, size, and format must be provided |
2472 | through device tree, or potentially plain old platform data in the | 2472 | through device tree, or plain old platform data. |
2473 | future. | ||
2474 | 2473 | ||
2475 | source "drivers/video/omap/Kconfig" | 2474 | source "drivers/video/omap/Kconfig" |
2476 | source "drivers/video/omap2/Kconfig" | 2475 | source "drivers/video/omap2/Kconfig" |
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 8c30603e0a86..846caab75a46 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig | |||
@@ -92,7 +92,8 @@ config DUMMY_CONSOLE_ROWS | |||
92 | 92 | ||
93 | config FRAMEBUFFER_CONSOLE | 93 | config FRAMEBUFFER_CONSOLE |
94 | tristate "Framebuffer Console support" | 94 | tristate "Framebuffer Console support" |
95 | depends on FB | 95 | depends on FB && !UML |
96 | select VT_HW_CONSOLE_BINDING | ||
96 | select CRC32 | 97 | select CRC32 |
97 | select FONT_SUPPORT | 98 | select FONT_SUPPORT |
98 | help | 99 | help |
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c index 50fe668c6172..2a8286ef2645 100644 --- a/drivers/video/efifb.c +++ b/drivers/video/efifb.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/dmi.h> | 15 | #include <linux/dmi.h> |
16 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
17 | #include <video/vga.h> | 17 | #include <video/vga.h> |
18 | #include <asm/sysfb.h> | ||
18 | 19 | ||
19 | static bool request_mem_succeeded = false; | 20 | static bool request_mem_succeeded = false; |
20 | 21 | ||
@@ -38,223 +39,6 @@ static struct fb_fix_screeninfo efifb_fix = { | |||
38 | .visual = FB_VISUAL_TRUECOLOR, | 39 | .visual = FB_VISUAL_TRUECOLOR, |
39 | }; | 40 | }; |
40 | 41 | ||
41 | enum { | ||
42 | M_I17, /* 17-Inch iMac */ | ||
43 | M_I20, /* 20-Inch iMac */ | ||
44 | M_I20_SR, /* 20-Inch iMac (Santa Rosa) */ | ||
45 | M_I24, /* 24-Inch iMac */ | ||
46 | M_I24_8_1, /* 24-Inch iMac, 8,1th gen */ | ||
47 | M_I24_10_1, /* 24-Inch iMac, 10,1th gen */ | ||
48 | M_I27_11_1, /* 27-Inch iMac, 11,1th gen */ | ||
49 | M_MINI, /* Mac Mini */ | ||
50 | M_MINI_3_1, /* Mac Mini, 3,1th gen */ | ||
51 | M_MINI_4_1, /* Mac Mini, 4,1th gen */ | ||
52 | M_MB, /* MacBook */ | ||
53 | M_MB_2, /* MacBook, 2nd rev. */ | ||
54 | M_MB_3, /* MacBook, 3rd rev. */ | ||
55 | M_MB_5_1, /* MacBook, 5th rev. */ | ||
56 | M_MB_6_1, /* MacBook, 6th rev. */ | ||
57 | M_MB_7_1, /* MacBook, 7th rev. */ | ||
58 | M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ | ||
59 | M_MBA, /* MacBook Air */ | ||
60 | M_MBA_3, /* Macbook Air, 3rd rev */ | ||
61 | M_MBP, /* MacBook Pro */ | ||
62 | M_MBP_2, /* MacBook Pro 2nd gen */ | ||
63 | M_MBP_2_2, /* MacBook Pro 2,2nd gen */ | ||
64 | M_MBP_SR, /* MacBook Pro (Santa Rosa) */ | ||
65 | M_MBP_4, /* MacBook Pro, 4th gen */ | ||
66 | M_MBP_5_1, /* MacBook Pro, 5,1th gen */ | ||
67 | M_MBP_5_2, /* MacBook Pro, 5,2th gen */ | ||
68 | M_MBP_5_3, /* MacBook Pro, 5,3rd gen */ | ||
69 | M_MBP_6_1, /* MacBook Pro, 6,1th gen */ | ||
70 | M_MBP_6_2, /* MacBook Pro, 6,2th gen */ | ||
71 | M_MBP_7_1, /* MacBook Pro, 7,1th gen */ | ||
72 | M_MBP_8_2, /* MacBook Pro, 8,2nd gen */ | ||
73 | M_UNKNOWN /* placeholder */ | ||
74 | }; | ||
75 | |||
76 | #define OVERRIDE_NONE 0x0 | ||
77 | #define OVERRIDE_BASE 0x1 | ||
78 | #define OVERRIDE_STRIDE 0x2 | ||
79 | #define OVERRIDE_HEIGHT 0x4 | ||
80 | #define OVERRIDE_WIDTH 0x8 | ||
81 | |||
82 | static struct efifb_dmi_info { | ||
83 | char *optname; | ||
84 | unsigned long base; | ||
85 | int stride; | ||
86 | int width; | ||
87 | int height; | ||
88 | int flags; | ||
89 | } dmi_list[] __initdata = { | ||
90 | [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
91 | [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, /* guess */ | ||
92 | [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, | ||
93 | [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, /* guess */ | ||
94 | [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
95 | [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080, OVERRIDE_NONE }, | ||
96 | [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440, OVERRIDE_NONE }, | ||
97 | [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768, OVERRIDE_NONE }, | ||
98 | [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768, OVERRIDE_NONE }, | ||
99 | [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
100 | [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
101 | [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
102 | [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
103 | [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
104 | [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
105 | /* 11" Macbook Air 3,1 passes the wrong stride */ | ||
106 | [M_MBA_3] = { "mba3", 0, 2048 * 4, 0, 0, OVERRIDE_STRIDE }, | ||
107 | [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
108 | [M_MBP_2] = { "mbp2", 0, 0, 0, 0, OVERRIDE_NONE }, /* placeholder */ | ||
109 | [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
110 | [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, | ||
111 | [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
112 | [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, | ||
113 | [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
114 | [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, | ||
115 | [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
116 | [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050, OVERRIDE_NONE }, | ||
117 | [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
118 | [M_MBP_8_2] = { "mbp82", 0x90010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
119 | [M_UNKNOWN] = { NULL, 0, 0, 0, 0, OVERRIDE_NONE } | ||
120 | }; | ||
121 | |||
122 | static int set_system(const struct dmi_system_id *id); | ||
123 | |||
124 | #define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \ | ||
125 | { set_system, name, { \ | ||
126 | DMI_MATCH(DMI_BIOS_VENDOR, vendor), \ | ||
127 | DMI_MATCH(DMI_PRODUCT_NAME, name) }, \ | ||
128 | &dmi_list[enumid] } | ||
129 | |||
130 | static const struct dmi_system_id dmi_system_table[] __initconst = { | ||
131 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17), | ||
132 | /* At least one of these two will be right; maybe both? */ | ||
133 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20), | ||
134 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac5,1", M_I20), | ||
135 | /* At least one of these two will be right; maybe both? */ | ||
136 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24), | ||
137 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24), | ||
138 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR), | ||
139 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1), | ||
140 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1), | ||
141 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1), | ||
142 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI), | ||
143 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1), | ||
144 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1), | ||
145 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB), | ||
146 | /* At least one of these two will be right; maybe both? */ | ||
147 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB), | ||
148 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook2,1", M_MB), | ||
149 | /* At least one of these two will be right; maybe both? */ | ||
150 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB), | ||
151 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB), | ||
152 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB), | ||
153 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1), | ||
154 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1), | ||
155 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1), | ||
156 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), | ||
157 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir3,1", M_MBA_3), | ||
158 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), | ||
159 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), | ||
160 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2), | ||
161 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2), | ||
162 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR), | ||
163 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR), | ||
164 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4), | ||
165 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1), | ||
166 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2), | ||
167 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3), | ||
168 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1), | ||
169 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2), | ||
170 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1), | ||
171 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro8,2", M_MBP_8_2), | ||
172 | {}, | ||
173 | }; | ||
174 | |||
175 | #define choose_value(dmivalue, fwvalue, field, flags) ({ \ | ||
176 | typeof(fwvalue) _ret_ = fwvalue; \ | ||
177 | if ((flags) & (field)) \ | ||
178 | _ret_ = dmivalue; \ | ||
179 | else if ((fwvalue) == 0) \ | ||
180 | _ret_ = dmivalue; \ | ||
181 | _ret_; \ | ||
182 | }) | ||
183 | |||
184 | static int set_system(const struct dmi_system_id *id) | ||
185 | { | ||
186 | struct efifb_dmi_info *info = id->driver_data; | ||
187 | |||
188 | if (info->base == 0 && info->height == 0 && info->width == 0 | ||
189 | && info->stride == 0) | ||
190 | return 0; | ||
191 | |||
192 | /* Trust the bootloader over the DMI tables */ | ||
193 | if (screen_info.lfb_base == 0) { | ||
194 | #if defined(CONFIG_PCI) | ||
195 | struct pci_dev *dev = NULL; | ||
196 | int found_bar = 0; | ||
197 | #endif | ||
198 | if (info->base) { | ||
199 | screen_info.lfb_base = choose_value(info->base, | ||
200 | screen_info.lfb_base, OVERRIDE_BASE, | ||
201 | info->flags); | ||
202 | |||
203 | #if defined(CONFIG_PCI) | ||
204 | /* make sure that the address in the table is actually | ||
205 | * on a VGA device's PCI BAR */ | ||
206 | |||
207 | for_each_pci_dev(dev) { | ||
208 | int i; | ||
209 | if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) | ||
210 | continue; | ||
211 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | ||
212 | resource_size_t start, end; | ||
213 | |||
214 | start = pci_resource_start(dev, i); | ||
215 | if (start == 0) | ||
216 | break; | ||
217 | end = pci_resource_end(dev, i); | ||
218 | if (screen_info.lfb_base >= start && | ||
219 | screen_info.lfb_base < end) { | ||
220 | found_bar = 1; | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | if (!found_bar) | ||
225 | screen_info.lfb_base = 0; | ||
226 | #endif | ||
227 | } | ||
228 | } | ||
229 | if (screen_info.lfb_base) { | ||
230 | screen_info.lfb_linelength = choose_value(info->stride, | ||
231 | screen_info.lfb_linelength, OVERRIDE_STRIDE, | ||
232 | info->flags); | ||
233 | screen_info.lfb_width = choose_value(info->width, | ||
234 | screen_info.lfb_width, OVERRIDE_WIDTH, | ||
235 | info->flags); | ||
236 | screen_info.lfb_height = choose_value(info->height, | ||
237 | screen_info.lfb_height, OVERRIDE_HEIGHT, | ||
238 | info->flags); | ||
239 | if (screen_info.orig_video_isVGA == 0) | ||
240 | screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; | ||
241 | } else { | ||
242 | screen_info.lfb_linelength = 0; | ||
243 | screen_info.lfb_width = 0; | ||
244 | screen_info.lfb_height = 0; | ||
245 | screen_info.orig_video_isVGA = 0; | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | printk(KERN_INFO "efifb: dmi detected %s - framebuffer at 0x%08x " | ||
250 | "(%dx%d, stride %d)\n", id->ident, | ||
251 | screen_info.lfb_base, screen_info.lfb_width, | ||
252 | screen_info.lfb_height, screen_info.lfb_linelength); | ||
253 | |||
254 | |||
255 | return 1; | ||
256 | } | ||
257 | |||
258 | static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, | 42 | static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, |
259 | unsigned blue, unsigned transp, | 43 | unsigned blue, unsigned transp, |
260 | struct fb_info *info) | 44 | struct fb_info *info) |
@@ -312,7 +96,7 @@ void vga_set_default_device(struct pci_dev *pdev) | |||
312 | default_vga = pdev; | 96 | default_vga = pdev; |
313 | } | 97 | } |
314 | 98 | ||
315 | static int __init efifb_setup(char *options) | 99 | static int efifb_setup(char *options) |
316 | { | 100 | { |
317 | char *this_opt; | 101 | char *this_opt; |
318 | int i; | 102 | int i; |
@@ -323,12 +107,12 @@ static int __init efifb_setup(char *options) | |||
323 | if (!*this_opt) continue; | 107 | if (!*this_opt) continue; |
324 | 108 | ||
325 | for (i = 0; i < M_UNKNOWN; i++) { | 109 | for (i = 0; i < M_UNKNOWN; i++) { |
326 | if (!strcmp(this_opt, dmi_list[i].optname) && | 110 | if (!strcmp(this_opt, efifb_dmi_list[i].optname) && |
327 | dmi_list[i].base != 0) { | 111 | efifb_dmi_list[i].base != 0) { |
328 | screen_info.lfb_base = dmi_list[i].base; | 112 | screen_info.lfb_base = efifb_dmi_list[i].base; |
329 | screen_info.lfb_linelength = dmi_list[i].stride; | 113 | screen_info.lfb_linelength = efifb_dmi_list[i].stride; |
330 | screen_info.lfb_width = dmi_list[i].width; | 114 | screen_info.lfb_width = efifb_dmi_list[i].width; |
331 | screen_info.lfb_height = dmi_list[i].height; | 115 | screen_info.lfb_height = efifb_dmi_list[i].height; |
332 | } | 116 | } |
333 | } | 117 | } |
334 | if (!strncmp(this_opt, "base:", 5)) | 118 | if (!strncmp(this_opt, "base:", 5)) |
@@ -369,13 +153,28 @@ static int __init efifb_setup(char *options) | |||
369 | return 0; | 153 | return 0; |
370 | } | 154 | } |
371 | 155 | ||
372 | static int __init efifb_probe(struct platform_device *dev) | 156 | static int efifb_probe(struct platform_device *dev) |
373 | { | 157 | { |
374 | struct fb_info *info; | 158 | struct fb_info *info; |
375 | int err; | 159 | int err; |
376 | unsigned int size_vmode; | 160 | unsigned int size_vmode; |
377 | unsigned int size_remap; | 161 | unsigned int size_remap; |
378 | unsigned int size_total; | 162 | unsigned int size_total; |
163 | char *option = NULL; | ||
164 | |||
165 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) | ||
166 | return -ENODEV; | ||
167 | |||
168 | if (fb_get_options("efifb", &option)) | ||
169 | return -ENODEV; | ||
170 | efifb_setup(option); | ||
171 | |||
172 | /* We don't get linelength from UGA Draw Protocol, only from | ||
173 | * EFI Graphics Protocol. So if it's not in DMI, and it's not | ||
174 | * passed in from the user, we really can't use the framebuffer. | ||
175 | */ | ||
176 | if (!screen_info.lfb_linelength) | ||
177 | return -ENODEV; | ||
379 | 178 | ||
380 | if (!screen_info.lfb_depth) | 179 | if (!screen_info.lfb_depth) |
381 | screen_info.lfb_depth = 32; | 180 | screen_info.lfb_depth = 32; |
@@ -539,55 +338,12 @@ err_release_mem: | |||
539 | } | 338 | } |
540 | 339 | ||
541 | static struct platform_driver efifb_driver = { | 340 | static struct platform_driver efifb_driver = { |
542 | .driver = { | 341 | .driver = { |
543 | .name = "efifb", | 342 | .name = "efi-framebuffer", |
343 | .owner = THIS_MODULE, | ||
544 | }, | 344 | }, |
345 | .probe = efifb_probe, | ||
545 | }; | 346 | }; |
546 | 347 | ||
547 | static struct platform_device efifb_device = { | 348 | module_platform_driver(efifb_driver); |
548 | .name = "efifb", | ||
549 | }; | ||
550 | |||
551 | static int __init efifb_init(void) | ||
552 | { | ||
553 | int ret; | ||
554 | char *option = NULL; | ||
555 | |||
556 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || | ||
557 | !(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS)) | ||
558 | dmi_check_system(dmi_system_table); | ||
559 | |||
560 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) | ||
561 | return -ENODEV; | ||
562 | |||
563 | if (fb_get_options("efifb", &option)) | ||
564 | return -ENODEV; | ||
565 | efifb_setup(option); | ||
566 | |||
567 | /* We don't get linelength from UGA Draw Protocol, only from | ||
568 | * EFI Graphics Protocol. So if it's not in DMI, and it's not | ||
569 | * passed in from the user, we really can't use the framebuffer. | ||
570 | */ | ||
571 | if (!screen_info.lfb_linelength) | ||
572 | return -ENODEV; | ||
573 | |||
574 | ret = platform_device_register(&efifb_device); | ||
575 | if (ret) | ||
576 | return ret; | ||
577 | |||
578 | /* | ||
579 | * This is not just an optimization. We will interfere | ||
580 | * with a real driver if we get reprobed, so don't allow | ||
581 | * it. | ||
582 | */ | ||
583 | ret = platform_driver_probe(&efifb_driver, efifb_probe); | ||
584 | if (ret) { | ||
585 | platform_device_unregister(&efifb_device); | ||
586 | return ret; | ||
587 | } | ||
588 | |||
589 | return ret; | ||
590 | } | ||
591 | module_init(efifb_init); | ||
592 | |||
593 | MODULE_LICENSE("GPL"); | 349 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c index e2e9e3e61b72..8d7810613058 100644 --- a/drivers/video/simplefb.c +++ b/drivers/video/simplefb.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/fb.h> | 24 | #include <linux/fb.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/platform_data/simplefb.h> | ||
27 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
28 | 29 | ||
29 | static struct fb_fix_screeninfo simplefb_fix = { | 30 | static struct fb_fix_screeninfo simplefb_fix = { |
@@ -73,18 +74,7 @@ static struct fb_ops simplefb_ops = { | |||
73 | .fb_imageblit = cfb_imageblit, | 74 | .fb_imageblit = cfb_imageblit, |
74 | }; | 75 | }; |
75 | 76 | ||
76 | struct simplefb_format { | 77 | static struct simplefb_format simplefb_formats[] = SIMPLEFB_FORMATS; |
77 | const char *name; | ||
78 | u32 bits_per_pixel; | ||
79 | struct fb_bitfield red; | ||
80 | struct fb_bitfield green; | ||
81 | struct fb_bitfield blue; | ||
82 | struct fb_bitfield transp; | ||
83 | }; | ||
84 | |||
85 | static struct simplefb_format simplefb_formats[] = { | ||
86 | { "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0} }, | ||
87 | }; | ||
88 | 78 | ||
89 | struct simplefb_params { | 79 | struct simplefb_params { |
90 | u32 width; | 80 | u32 width; |
@@ -139,6 +129,33 @@ static int simplefb_parse_dt(struct platform_device *pdev, | |||
139 | return 0; | 129 | return 0; |
140 | } | 130 | } |
141 | 131 | ||
132 | static int simplefb_parse_pd(struct platform_device *pdev, | ||
133 | struct simplefb_params *params) | ||
134 | { | ||
135 | struct simplefb_platform_data *pd = pdev->dev.platform_data; | ||
136 | int i; | ||
137 | |||
138 | params->width = pd->width; | ||
139 | params->height = pd->height; | ||
140 | params->stride = pd->stride; | ||
141 | |||
142 | params->format = NULL; | ||
143 | for (i = 0; i < ARRAY_SIZE(simplefb_formats); i++) { | ||
144 | if (strcmp(pd->format, simplefb_formats[i].name)) | ||
145 | continue; | ||
146 | |||
147 | params->format = &simplefb_formats[i]; | ||
148 | break; | ||
149 | } | ||
150 | |||
151 | if (!params->format) { | ||
152 | dev_err(&pdev->dev, "Invalid format value\n"); | ||
153 | return -EINVAL; | ||
154 | } | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
142 | static int simplefb_probe(struct platform_device *pdev) | 159 | static int simplefb_probe(struct platform_device *pdev) |
143 | { | 160 | { |
144 | int ret; | 161 | int ret; |
@@ -149,7 +166,12 @@ static int simplefb_probe(struct platform_device *pdev) | |||
149 | if (fb_get_options("simplefb", NULL)) | 166 | if (fb_get_options("simplefb", NULL)) |
150 | return -ENODEV; | 167 | return -ENODEV; |
151 | 168 | ||
152 | ret = simplefb_parse_dt(pdev, ¶ms); | 169 | ret = -ENODEV; |
170 | if (pdev->dev.platform_data) | ||
171 | ret = simplefb_parse_pd(pdev, ¶ms); | ||
172 | else if (pdev->dev.of_node) | ||
173 | ret = simplefb_parse_dt(pdev, ¶ms); | ||
174 | |||
153 | if (ret) | 175 | if (ret) |
154 | return ret; | 176 | return ret; |
155 | 177 | ||
@@ -180,8 +202,16 @@ static int simplefb_probe(struct platform_device *pdev) | |||
180 | info->var.blue = params.format->blue; | 202 | info->var.blue = params.format->blue; |
181 | info->var.transp = params.format->transp; | 203 | info->var.transp = params.format->transp; |
182 | 204 | ||
205 | info->apertures = alloc_apertures(1); | ||
206 | if (!info->apertures) { | ||
207 | framebuffer_release(info); | ||
208 | return -ENOMEM; | ||
209 | } | ||
210 | info->apertures->ranges[0].base = info->fix.smem_start; | ||
211 | info->apertures->ranges[0].size = info->fix.smem_len; | ||
212 | |||
183 | info->fbops = &simplefb_ops; | 213 | info->fbops = &simplefb_ops; |
184 | info->flags = FBINFO_DEFAULT; | 214 | info->flags = FBINFO_DEFAULT | FBINFO_MISC_FIRMWARE; |
185 | info->screen_base = devm_ioremap(&pdev->dev, info->fix.smem_start, | 215 | info->screen_base = devm_ioremap(&pdev->dev, info->fix.smem_start, |
186 | info->fix.smem_len); | 216 | info->fix.smem_len); |
187 | if (!info->screen_base) { | 217 | if (!info->screen_base) { |
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 501b3406c6d5..bd83233ec227 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c | |||
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | /* --------------------------------------------------------------------- */ | 30 | /* --------------------------------------------------------------------- */ |
31 | 31 | ||
32 | static struct fb_var_screeninfo vesafb_defined __initdata = { | 32 | static struct fb_var_screeninfo vesafb_defined = { |
33 | .activate = FB_ACTIVATE_NOW, | 33 | .activate = FB_ACTIVATE_NOW, |
34 | .height = -1, | 34 | .height = -1, |
35 | .width = -1, | 35 | .width = -1, |
@@ -40,7 +40,7 @@ static struct fb_var_screeninfo vesafb_defined __initdata = { | |||
40 | .vmode = FB_VMODE_NONINTERLACED, | 40 | .vmode = FB_VMODE_NONINTERLACED, |
41 | }; | 41 | }; |
42 | 42 | ||
43 | static struct fb_fix_screeninfo vesafb_fix __initdata = { | 43 | static struct fb_fix_screeninfo vesafb_fix = { |
44 | .id = "VESA VGA", | 44 | .id = "VESA VGA", |
45 | .type = FB_TYPE_PACKED_PIXELS, | 45 | .type = FB_TYPE_PACKED_PIXELS, |
46 | .accel = FB_ACCEL_NONE, | 46 | .accel = FB_ACCEL_NONE, |
@@ -48,8 +48,8 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = { | |||
48 | 48 | ||
49 | static int inverse __read_mostly; | 49 | static int inverse __read_mostly; |
50 | static int mtrr __read_mostly; /* disable mtrr */ | 50 | static int mtrr __read_mostly; /* disable mtrr */ |
51 | static int vram_remap __initdata; /* Set amount of memory to be used */ | 51 | static int vram_remap; /* Set amount of memory to be used */ |
52 | static int vram_total __initdata; /* Set total amount of memory */ | 52 | static int vram_total; /* Set total amount of memory */ |
53 | static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */ | 53 | static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */ |
54 | static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */ | 54 | static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */ |
55 | static void (*pmi_start)(void) __read_mostly; | 55 | static void (*pmi_start)(void) __read_mostly; |
@@ -192,7 +192,7 @@ static struct fb_ops vesafb_ops = { | |||
192 | .fb_imageblit = cfb_imageblit, | 192 | .fb_imageblit = cfb_imageblit, |
193 | }; | 193 | }; |
194 | 194 | ||
195 | static int __init vesafb_setup(char *options) | 195 | static int vesafb_setup(char *options) |
196 | { | 196 | { |
197 | char *this_opt; | 197 | char *this_opt; |
198 | 198 | ||
@@ -226,13 +226,18 @@ static int __init vesafb_setup(char *options) | |||
226 | return 0; | 226 | return 0; |
227 | } | 227 | } |
228 | 228 | ||
229 | static int __init vesafb_probe(struct platform_device *dev) | 229 | static int vesafb_probe(struct platform_device *dev) |
230 | { | 230 | { |
231 | struct fb_info *info; | 231 | struct fb_info *info; |
232 | int i, err; | 232 | int i, err; |
233 | unsigned int size_vmode; | 233 | unsigned int size_vmode; |
234 | unsigned int size_remap; | 234 | unsigned int size_remap; |
235 | unsigned int size_total; | 235 | unsigned int size_total; |
236 | char *option = NULL; | ||
237 | |||
238 | /* ignore error return of fb_get_options */ | ||
239 | fb_get_options("vesafb", &option); | ||
240 | vesafb_setup(option); | ||
236 | 241 | ||
237 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) | 242 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) |
238 | return -ENODEV; | 243 | return -ENODEV; |
@@ -496,40 +501,12 @@ err: | |||
496 | } | 501 | } |
497 | 502 | ||
498 | static struct platform_driver vesafb_driver = { | 503 | static struct platform_driver vesafb_driver = { |
499 | .driver = { | 504 | .driver = { |
500 | .name = "vesafb", | 505 | .name = "vesa-framebuffer", |
506 | .owner = THIS_MODULE, | ||
501 | }, | 507 | }, |
508 | .probe = vesafb_probe, | ||
502 | }; | 509 | }; |
503 | 510 | ||
504 | static struct platform_device *vesafb_device; | 511 | module_platform_driver(vesafb_driver); |
505 | |||
506 | static int __init vesafb_init(void) | ||
507 | { | ||
508 | int ret; | ||
509 | char *option = NULL; | ||
510 | |||
511 | /* ignore error return of fb_get_options */ | ||
512 | fb_get_options("vesafb", &option); | ||
513 | vesafb_setup(option); | ||
514 | |||
515 | vesafb_device = platform_device_alloc("vesafb", 0); | ||
516 | if (!vesafb_device) | ||
517 | return -ENOMEM; | ||
518 | |||
519 | ret = platform_device_add(vesafb_device); | ||
520 | if (!ret) { | ||
521 | ret = platform_driver_probe(&vesafb_driver, vesafb_probe); | ||
522 | if (ret) | ||
523 | platform_device_del(vesafb_device); | ||
524 | } | ||
525 | |||
526 | if (ret) { | ||
527 | platform_device_put(vesafb_device); | ||
528 | vesafb_device = NULL; | ||
529 | } | ||
530 | |||
531 | return ret; | ||
532 | } | ||
533 | module_init(vesafb_init); | ||
534 | |||
535 | MODULE_LICENSE("GPL"); | 512 | MODULE_LICENSE("GPL"); |
diff --git a/include/linux/platform_data/simplefb.h b/include/linux/platform_data/simplefb.h new file mode 100644 index 000000000000..53774b0cd8e9 --- /dev/null +++ b/include/linux/platform_data/simplefb.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * simplefb.h - Simple Framebuffer Device | ||
3 | * | ||
4 | * Copyright (C) 2013 David Herrmann <dh.herrmann@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifndef __PLATFORM_DATA_SIMPLEFB_H__ | ||
13 | #define __PLATFORM_DATA_SIMPLEFB_H__ | ||
14 | |||
15 | #include <drm/drm_fourcc.h> | ||
16 | #include <linux/fb.h> | ||
17 | #include <linux/kernel.h> | ||
18 | |||
19 | /* format array, use it to initialize a "struct simplefb_format" array */ | ||
20 | #define SIMPLEFB_FORMATS \ | ||
21 | { \ | ||
22 | { "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0}, DRM_FORMAT_RGB565 }, \ | ||
23 | { "x1r5g5b5", 16, {10, 5}, {5, 5}, {0, 5}, {0, 0}, DRM_FORMAT_XRGB1555 }, \ | ||
24 | { "a1r5g5b5", 16, {10, 5}, {5, 5}, {0, 5}, {15, 1}, DRM_FORMAT_ARGB1555 }, \ | ||
25 | { "r8g8b8", 24, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_RGB888 }, \ | ||
26 | { "x8r8g8b8", 32, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_XRGB8888 }, \ | ||
27 | { "a8r8g8b8", 32, {16, 8}, {8, 8}, {0, 8}, {24, 8}, DRM_FORMAT_ARGB8888 }, \ | ||
28 | { "x2r10g10b10", 32, {20, 10}, {10, 10}, {0, 10}, {0, 0}, DRM_FORMAT_XRGB2101010 }, \ | ||
29 | { "a2r10g10b10", 32, {20, 10}, {10, 10}, {0, 10}, {30, 2}, DRM_FORMAT_ARGB2101010 }, \ | ||
30 | } | ||
31 | |||
32 | /* | ||
33 | * Data-Format for Simple-Framebuffers | ||
34 | * @name: unique 0-terminated name that can be used to identify the mode | ||
35 | * @red,green,blue: Offsets and sizes of the single RGB parts | ||
36 | * @transp: Offset and size of the alpha bits. length=0 means no alpha | ||
37 | * @fourcc: 32bit DRM four-CC code (see drm_fourcc.h) | ||
38 | */ | ||
39 | struct simplefb_format { | ||
40 | const char *name; | ||
41 | u32 bits_per_pixel; | ||
42 | struct fb_bitfield red; | ||
43 | struct fb_bitfield green; | ||
44 | struct fb_bitfield blue; | ||
45 | struct fb_bitfield transp; | ||
46 | u32 fourcc; | ||
47 | }; | ||
48 | |||
49 | /* | ||
50 | * Simple-Framebuffer description | ||
51 | * If the arch-boot code creates simple-framebuffers without DT support, it | ||
52 | * can pass the width, height, stride and format via this platform-data object. | ||
53 | * The framebuffer location must be given as IORESOURCE_MEM resource. | ||
54 | * @format must be a format as described in "struct simplefb_format" above. | ||
55 | */ | ||
56 | struct simplefb_platform_data { | ||
57 | u32 width; | ||
58 | u32 height; | ||
59 | u32 stride; | ||
60 | const char *format; | ||
61 | }; | ||
62 | |||
63 | #endif /* __PLATFORM_DATA_SIMPLEFB_H__ */ | ||