2 * Generic System Framebuffers on x86
3 * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com>
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)
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.
18 #include <linux/err.h>
19 #include <linux/init.h>
20 #include <linux/kernel.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>
27 static const char simplefb_resname
[] = "BOOTFB";
28 static const struct simplefb_format formats
[] = SIMPLEFB_FORMATS
;
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
)
34 const struct simplefb_format
*f
;
38 type
= si
->orig_video_isVGA
;
39 if (type
!= VIDEO_TYPE_VLFB
&& type
!= VIDEO_TYPE_EFI
)
42 for (i
= 0; i
< ARRAY_SIZE(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
;
64 __init
int create_simplefb(const struct screen_info
*si
,
65 const struct simplefb_platform_data
*mode
)
67 struct platform_device
*pd
;
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
> (u64
)si
->lfb_size
<< 16) {
76 printk(KERN_WARNING
"sysfb: VRAM smaller than advertised\n");
80 /* setup IORESOURCE_MEM as framebuffer memory */
81 memset(&res
, 0, sizeof(res
));
82 res
.flags
= IORESOURCE_MEM
| IORESOURCE_BUSY
;
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
)
89 pd
= platform_device_register_resndata(NULL
, "simple-framebuffer", 0,
90 &res
, 1, mode
, sizeof(*mode
));