Received: by 10.223.176.46 with SMTP id f43csp1471276wra; Wed, 24 Jan 2018 17:42:53 -0800 (PST) X-Google-Smtp-Source: AH8x225wwkeKu55faiPHoat86vTxcxvV3E3gOqRMdRmHP4RaUE42OKCcWlcaG1ELCMVrqo64LGYz X-Received: by 10.99.38.67 with SMTP id m64mr4881919pgm.2.1516844573397; Wed, 24 Jan 2018 17:42:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516844573; cv=none; d=google.com; s=arc-20160816; b=IAvjOKcBucnWcmgZmA6uEUgsvmQzisG5nlyzff4J6Y5ZgS1k1tytW7BQPVqmoWtgVv ab/11YTypt95xoVP1d79PyXITbbBm6hgr4lf69xa+b90GzpDAiMyedO/I/pImh5WrckX sBRJBi/7XOa9AEXP0ansNn3KYbyVVF+XIMRpn1lDq9uqn1lcjFbCcxTsGm4XVxL0UydY mTo+oOQHBeUjWJ9TGYt+Z6Y1aRiH0xVLhP9/ldpFM8HHtJZOOIjXVXOvmsgSAhbWwrr4 8V6KS4ZgW21+rqt5uS9L08oNyq6mRIFFV7AZIhcTW4EwQ41ZdVBg+85XGtjaq/F2BOux cZIA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:dkim-signature :arc-authentication-results; bh=rGE1fopZ5NGKwbyQked4T6RBrtVI8wxngzybMJt1QsA=; b=RtDKSnPSTwWeVStLiI49ZMbmTvpjXb4TvNAzd3MTgTi2bCW4XWPXKgWQsybxwa1pCy LuAOR7LQqWBTmXTrER8nsSba/ZIxPSb5aL1U5KYKaGImwlLYMTifD8qm92kaayaQk89+ hGv9+d0QEopmbICVxCd6lNqLSt/Hxpu9E/7WYkXYqbZaPL+T0fBn5ooFG5vhx4RdXhNT KDLUFcmbBY7Ugg01BxnWfSLCVKHrJbl3Mkc+tdH0z+hKhC5AQ1xB/UA2m6ZpkWyh6rpu 6dHIjxyG+DWQmhC8tk4hb8cQg14Cs7PMst+IKGu5elv9VbDR1gn4QCRlo3TR0n0yXVyK 6ADw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sholland.org header.s=fm1 header.b=fuIV0vBz; dkim=pass header.i=@messagingengine.com header.s=fm1 header.b=TPyDyO+3; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w9-v6si1083274plp.93.2018.01.24.17.42.38; Wed, 24 Jan 2018 17:42:53 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@sholland.org header.s=fm1 header.b=fuIV0vBz; dkim=pass header.i=@messagingengine.com header.s=fm1 header.b=TPyDyO+3; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752681AbeAYBl4 (ORCPT + 99 others); Wed, 24 Jan 2018 20:41:56 -0500 Received: from out3-smtp.messagingengine.com ([66.111.4.27]:49831 "EHLO out3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752526AbeAYBl3 (ORCPT ); Wed, 24 Jan 2018 20:41:29 -0500 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id 4D76122717; Wed, 24 Jan 2018 20:41:29 -0500 (EST) Received: from frontend1 ([10.202.2.160]) by compute5.internal (MEProxy); Wed, 24 Jan 2018 20:41:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sholland.org; h= cc:date:from:in-reply-to:message-id:references:subject:to :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=rGE1fopZ5NGKwbyQk ed4T6RBrtVI8wxngzybMJt1QsA=; b=fuIV0vBzTjV4E/EjMTEgQb5NECccWjJ7X 9WG2bbNz7cmnJHUUZfwnDmvAf77ibJ+3D6Vkq5asOPDR6TImaRbxXQPHum8crC1i zCmdVYQIWTVAtbYDiP7uYSUtJH1Ak/K0xr4sNn2NGimxKR8JDKfsfqrvLl5Md50A OvQR9wBrXDLjPg3HIr4EHmffMmM26XbHDsIYVOTgone3ycMpoLTUqm7G+E/S/0BB oylPwUMaGBgJATkI3pqJDgLemBOaVTffAEfLHownw116f5D26uqj8QFQTjOGaIOj gWuVrRp+hDLtXOG1bRYqN26f6Kc76L4cilwEqwzbsJLyYulNAPRNw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=rGE1fopZ5NGKwbyQked4T6RBrtVI8wxngzybMJt1QsA=; b=TPyDyO+3 8o3344WkNP2LZ1QSu9CWwsXu4t5mOssAtZAd7NS8g+gBsViceXb27vxpuyRwEuBN yVfKJ5/E8wZVGZbBqN8H5hY5ahgK+uGw616zNk79WPn2JfZo4tYZPO0TMglta4C9 PoSA4ftqINIKZeUWB1HI4ooeDxOI/4D4sSe1KG/cBtumMXzj02mNukcwVCWNAcwr xQHZcebOEB068biqZLz1G2gX5a5UxALnDNvoRdXjX1q/y3c84KFA4FYcOMrORqRF 2KLgL/IvRnT8lSHCzpsurCncqgDSYvqCNLU50jmHXfKBkMcAjqjimtRzg0l2RXV1 u24if06IJtu62Q== X-ME-Sender: Received: from indium.zzz.sholland.net (unknown [99.198.199.144]) by mail.messagingengine.com (Postfix) with ESMTPA id 25B397E2E5; Wed, 24 Jan 2018 20:41:28 -0500 (EST) From: Samuel Holland To: linux-kernel@vger.kernel.org, Greg Kroah-Hartman Cc: coreboot@coreboot.org, Thierry Escande , Wei-Ning Huang , Julius Werner , Dmitry Torokhov , Guenter Roeck , Samuel Holland Subject: [PATCH 5/5] firmware: coreboot: Add coreboot framebuffer driver Date: Wed, 24 Jan 2018 19:41:20 -0600 Message-Id: <20180125014120.20851-6-samuel@sholland.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180125014120.20851-1-samuel@sholland.org> References: <20180125014120.20851-1-samuel@sholland.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Register a simplefb framebuffer when the coreboot table contains a framebuffer entry. Signed-off-by: Samuel Holland --- drivers/firmware/google/Kconfig | 8 ++ drivers/firmware/google/Makefile | 1 + drivers/firmware/google/coreboot_table.h | 22 +++++ drivers/firmware/google/framebuffer-coreboot.c | 115 +++++++++++++++++++++++++ 4 files changed, 146 insertions(+) create mode 100644 drivers/firmware/google/framebuffer-coreboot.c diff --git a/drivers/firmware/google/Kconfig b/drivers/firmware/google/Kconfig index f16b381a569c..a456a000048b 100644 --- a/drivers/firmware/google/Kconfig +++ b/drivers/firmware/google/Kconfig @@ -55,6 +55,14 @@ config GOOGLE_MEMCONSOLE_X86_LEGACY the EBDA on Google servers. If found, this log is exported to userland in the file /sys/firmware/log. +config GOOGLE_FRAMEBUFFER_COREBOOT + tristate "Coreboot Framebuffer" + depends on FB_SIMPLE + depends on GOOGLE_COREBOOT_TABLE + help + This option enables the kernel to search for a framebuffer in + the coreboot table. If found, it is registered with simplefb. + config GOOGLE_MEMCONSOLE_COREBOOT tristate "Firmware Memory Console" depends on GOOGLE_COREBOOT_TABLE diff --git a/drivers/firmware/google/Makefile b/drivers/firmware/google/Makefile index dcd3675efcfc..d0b3fba96194 100644 --- a/drivers/firmware/google/Makefile +++ b/drivers/firmware/google/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_GOOGLE_SMI) += gsmi.o obj-$(CONFIG_GOOGLE_COREBOOT_TABLE) += coreboot_table.o obj-$(CONFIG_GOOGLE_COREBOOT_TABLE_ACPI) += coreboot_table-acpi.o obj-$(CONFIG_GOOGLE_COREBOOT_TABLE_OF) += coreboot_table-of.o +obj-$(CONFIG_GOOGLE_FRAMEBUFFER_COREBOOT) += framebuffer-coreboot.o obj-$(CONFIG_GOOGLE_MEMCONSOLE) += memconsole.o obj-$(CONFIG_GOOGLE_MEMCONSOLE_COREBOOT) += memconsole-coreboot.o obj-$(CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY) += memconsole-x86-legacy.o diff --git a/drivers/firmware/google/coreboot_table.h b/drivers/firmware/google/coreboot_table.h index 26a3f3f3ac9c..8ad95a94481b 100644 --- a/drivers/firmware/google/coreboot_table.h +++ b/drivers/firmware/google/coreboot_table.h @@ -3,6 +3,7 @@ * * Internal header for coreboot table access. * + * Copyright 2014 Gerd Hoffmann * Copyright 2017 Google Inc. * Copyright 2017 Samuel Holland * @@ -46,12 +47,33 @@ struct lb_cbmem_ref { u64 cbmem_addr; }; +/* Describes framebuffer setup by coreboot */ +struct lb_framebuffer { + u32 tag; + u32 size; + + u64 physical_address; + u32 x_resolution; + u32 y_resolution; + u32 bytes_per_line; + u8 bits_per_pixel; + u8 red_mask_pos; + u8 red_mask_size; + u8 green_mask_pos; + u8 green_mask_size; + u8 blue_mask_pos; + u8 blue_mask_size; + u8 reserved_mask_pos; + u8 reserved_mask_size; +}; + /* A device, additionally with information from coreboot. */ struct coreboot_device { struct device dev; union { struct coreboot_table_entry entry; struct lb_cbmem_ref cbmem_ref; + struct lb_framebuffer framebuffer; }; }; diff --git a/drivers/firmware/google/framebuffer-coreboot.c b/drivers/firmware/google/framebuffer-coreboot.c new file mode 100644 index 000000000000..b8b49c067157 --- /dev/null +++ b/drivers/firmware/google/framebuffer-coreboot.c @@ -0,0 +1,115 @@ +/* + * framebuffer-coreboot.c + * + * Memory based framebuffer accessed through coreboot table. + * + * Copyright 2012-2013 David Herrmann + * Copyright 2017 Google Inc. + * Copyright 2017 Samuel Holland + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License v2.0 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include + +#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, +}; + +static int __init coreboot_framebuffer_init(void) +{ + return coreboot_driver_register(&framebuffer_driver); +} + +static void coreboot_framebuffer_exit(void) +{ + coreboot_driver_unregister(&framebuffer_driver); +} + +module_init(coreboot_framebuffer_init); +module_exit(coreboot_framebuffer_exit); + +MODULE_AUTHOR("Samuel Holland "); +MODULE_LICENSE("GPL"); -- 2.13.6