2019-05-29 17:18:01 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2018-01-25 04:41:20 +03:00
/*
* framebuffer - coreboot . c
*
* Memory based framebuffer accessed through coreboot table .
*
* Copyright 2012 - 2013 David Herrmann < dh . herrmann @ gmail . com >
* Copyright 2017 Google Inc .
* Copyright 2017 Samuel Holland < samuel @ sholland . org >
*/
# include <linux/device.h>
# include <linux/kernel.h>
# include <linux/mm.h>
# include <linux/module.h>
# include <linux/platform_data/simplefb.h>
# include <linux/platform_device.h>
# include "coreboot_table.h"
# define CB_TAG_FRAMEBUFFER 0x12
static const struct simplefb_format formats [ ] = SIMPLEFB_FORMATS ;
static int framebuffer_probe ( struct coreboot_device * dev )
{
int i ;
u32 length ;
struct lb_framebuffer * fb = & dev - > framebuffer ;
struct platform_device * pdev ;
struct resource res ;
struct simplefb_platform_data pdata = {
. width = fb - > x_resolution ,
. height = fb - > y_resolution ,
. stride = fb - > bytes_per_line ,
. format = NULL ,
} ;
for ( i = 0 ; i < ARRAY_SIZE ( formats ) ; + + i ) {
if ( fb - > bits_per_pixel = = formats [ i ] . bits_per_pixel & &
fb - > red_mask_pos = = formats [ i ] . red . offset & &
fb - > red_mask_size = = formats [ i ] . red . length & &
fb - > green_mask_pos = = formats [ i ] . green . offset & &
fb - > green_mask_size = = formats [ i ] . green . length & &
fb - > blue_mask_pos = = formats [ i ] . blue . offset & &
fb - > blue_mask_size = = formats [ i ] . blue . length & &
fb - > reserved_mask_pos = = formats [ i ] . transp . offset & &
fb - > reserved_mask_size = = formats [ i ] . transp . length )
pdata . format = formats [ i ] . name ;
}
if ( ! pdata . format )
return - ENODEV ;
memset ( & res , 0 , sizeof ( res ) ) ;
res . flags = IORESOURCE_MEM | IORESOURCE_BUSY ;
res . name = " Coreboot Framebuffer " ;
res . start = fb - > physical_address ;
length = PAGE_ALIGN ( fb - > y_resolution * fb - > bytes_per_line ) ;
res . end = res . start + length - 1 ;
if ( res . end < = res . start )
return - EINVAL ;
pdev = platform_device_register_resndata ( & dev - > dev ,
" simple-framebuffer " , 0 ,
& res , 1 , & pdata ,
sizeof ( pdata ) ) ;
if ( IS_ERR ( pdev ) )
pr_warn ( " coreboot: could not register framebuffer \n " ) ;
else
dev_set_drvdata ( & dev - > dev , pdev ) ;
return PTR_ERR_OR_ZERO ( pdev ) ;
}
static int framebuffer_remove ( struct coreboot_device * dev )
{
struct platform_device * pdev = dev_get_drvdata ( & dev - > dev ) ;
platform_device_unregister ( pdev ) ;
return 0 ;
}
static struct coreboot_driver framebuffer_driver = {
. probe = framebuffer_probe ,
. remove = framebuffer_remove ,
. drv = {
. name = " framebuffer " ,
} ,
. tag = CB_TAG_FRAMEBUFFER ,
} ;
2019-05-10 21:01:47 +03:00
module_coreboot_driver ( framebuffer_driver ) ;
2018-01-25 04:41:20 +03:00
MODULE_AUTHOR ( " Samuel Holland <samuel@sholland.org> " ) ;
MODULE_LICENSE ( " GPL " ) ;