static efi_status_t
__gop_query32(struct efi_graphics_output_protocol_32 *gop32,
struct efi_graphics_output_mode_info **info,
- unsigned long *size, u32 *fb_base)
+ unsigned long *size, u64 *fb_base)
{
struct efi_graphics_output_protocol_mode_32 *mode;
efi_status_t status;
unsigned long nr_gops;
u16 width, height;
u32 pixels_per_scan_line;
- u32 fb_base;
+ u32 ext_lfb_base;
+ u64 fb_base;
struct efi_pixel_bitmask pixel_info;
int pixel_format;
efi_status_t status;
si->lfb_width = width;
si->lfb_height = height;
si->lfb_base = fb_base;
+
+ ext_lfb_base = (u64)(unsigned long)fb_base >> 32;
+ if (ext_lfb_base) {
+ si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
+ si->ext_lfb_base = ext_lfb_base;
+ }
+
si->pages = 1;
setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format);
static efi_status_t
__gop_query64(struct efi_graphics_output_protocol_64 *gop64,
struct efi_graphics_output_mode_info **info,
- unsigned long *size, u32 *fb_base)
+ unsigned long *size, u64 *fb_base)
{
struct efi_graphics_output_protocol_mode_64 *mode;
efi_status_t status;
unsigned long nr_gops;
u16 width, height;
u32 pixels_per_scan_line;
- u32 fb_base;
+ u32 ext_lfb_base;
+ u64 fb_base;
struct efi_pixel_bitmask pixel_info;
int pixel_format;
efi_status_t status;
si->lfb_width = width;
si->lfb_height = height;
si->lfb_base = fb_base;
+
+ ext_lfb_base = (u64)(unsigned long)fb_base >> 32;
+ if (ext_lfb_base) {
+ si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
+ si->ext_lfb_base = ext_lfb_base;
+ }
+
si->pages = 1;
setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format);
return 0;
}
+static inline bool fb_base_is_valid(void)
+{
+ if (screen_info.lfb_base)
+ return true;
+
+ if (!(screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE))
+ return false;
+
+ if (screen_info.ext_lfb_base)
+ return true;
+
+ return false;
+}
+
static int efifb_probe(struct platform_device *dev)
{
struct fb_info *info;
screen_info.lfb_depth = 32;
if (!screen_info.pages)
screen_info.pages = 1;
- if (!screen_info.lfb_base) {
+ if (!fb_base_is_valid()) {
printk(KERN_DEBUG "efifb: invalid framebuffer address\n");
return -ENODEV;
}
}
efifb_fix.smem_start = screen_info.lfb_base;
+
+ if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) {
+ u64 ext_lfb_base;
+
+ ext_lfb_base = (u64)(unsigned long)screen_info.ext_lfb_base << 32;
+ efifb_fix.smem_start |= ext_lfb_base;
+ }
+
efifb_defined.bits_per_pixel = screen_info.lfb_depth;
efifb_defined.xres = screen_info.lfb_width;
efifb_defined.yres = screen_info.lfb_height;
__u16 pages; /* 0x32 */
__u16 vesa_attributes; /* 0x34 */
__u32 capabilities; /* 0x36 */
- __u8 _reserved[6]; /* 0x3a */
+ __u32 ext_lfb_base; /* 0x3a */
+ __u8 _reserved[2]; /* 0x3e */
} __attribute__((packed));
#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
#define VIDEO_FLAGS_NOCURSOR (1 << 0) /* The video mode has no cursor set */
#define VIDEO_CAPABILITY_SKIP_QUIRKS (1 << 0)
-
+#define VIDEO_CAPABILITY_64BIT_BASE (1 << 1) /* Frame buffer base is 64-bit */
#endif /* _UAPI_SCREEN_INFO_H */