From patchwork Thu Jan 23 14:14:57 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 3529231 Return-Path: X-Original-To: patchwork-linux-fbdev@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 39C14C02DC for ; Thu, 23 Jan 2014 14:18:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 497512017E for ; Thu, 23 Jan 2014 14:18:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A2F5820108 for ; Thu, 23 Jan 2014 14:18:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932167AbaAWOP7 (ORCPT ); Thu, 23 Jan 2014 09:15:59 -0500 Received: from mail-we0-f175.google.com ([74.125.82.175]:61722 "EHLO mail-we0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932160AbaAWOP4 (ORCPT ); Thu, 23 Jan 2014 09:15:56 -0500 Received: by mail-we0-f175.google.com with SMTP id p61so1194409wes.6 for ; Thu, 23 Jan 2014 06:15:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=F1sXP635vywcrjXyeXMaZPJTFC4O26mGuSgZisQZJZM=; b=LIoZ6ZqTuHRvGogzHMYWniMQ9HBvkmQ48Bv5mqHmUH7f62E0pBcvoIx0OYGpYucdVF TtlSMqKGYZW+6qfYqIO66f86ZD7jx4spqwZ3PZrE7V89Jh7YZM9327BB8xKp7UjItFfA D0MJxbmLQZ+GdmkKOuhjHM5Mks9bTi0SIKFwD1Sop+TFexVG8YsD2MfJZ4AunAM0I0kK vNLUeMbU5X3jIADp7KaF+MpO5dr3ZxoybVeSEpt4PT0MlblxkV+OoU6BZrJ6U5KLrGpV JSbFHOv2wnuUmiMeLbPw4LUdbCQpnLDd3/y+7IZMGPOMr0PazVipovsqzgV/mq53FU+0 ceUQ== X-Received: by 10.194.108.198 with SMTP id hm6mr6615267wjb.33.1390486555108; Thu, 23 Jan 2014 06:15:55 -0800 (PST) Received: from david-ub.localdomain (stgt-5f71be19.pool.mediaWays.net. [95.113.190.25]) by mx.google.com with ESMTPSA id ci4sm22667871wjc.21.2014.01.23.06.15.53 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 23 Jan 2014 06:15:54 -0800 (PST) From: David Herrmann To: dri-devel@lists.freedesktop.org Cc: Ingo Molnar , linux-fbdev@vger.kernel.org, Dave Airlie , Daniel Vetter , Tomi Valkeinen , linux-kernel@vger.kernel.org, Tom Gundersen , David Herrmann Subject: [PATCH 05/11] x86: sysfb: store apertures in simplefb platform-data Date: Thu, 23 Jan 2014 15:14:57 +0100 Message-Id: <1390486503-1504-6-git-send-email-dh.herrmann@gmail.com> X-Mailer: git-send-email 1.8.5.3 In-Reply-To: <1390486503-1504-1-git-send-email-dh.herrmann@gmail.com> References: <1390486503-1504-1-git-send-email-dh.herrmann@gmail.com> Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP To get a generic remove_conflicting_framebuffers() for firmware-framebuffers, we need to store the apertures in the platform-data of each framebuffer. So make x86-sysfb do that for simple-framebuffer devices. Unfortunately, "struct apertures_struct" contains a VLA so we cannot easily embed it. Thus, we have to use a "apert_buf" buffer with enough room for one "struct aperture". Signed-off-by: David Herrmann --- arch/x86/include/asm/sysfb.h | 6 +-- arch/x86/kernel/sysfb.c | 2 +- arch/x86/kernel/sysfb_simplefb.c | 68 ++++++++++++++++++++-------------- include/linux/platform_data/simplefb.h | 1 + 4 files changed, 44 insertions(+), 33 deletions(-) diff --git a/arch/x86/include/asm/sysfb.h b/arch/x86/include/asm/sysfb.h index 6f95b8d..4f9fda2 100644 --- a/arch/x86/include/asm/sysfb.h +++ b/arch/x86/include/asm/sysfb.h @@ -81,8 +81,7 @@ static inline void sysfb_apply_efi_quirks(void) bool parse_mode(const struct screen_info *si, struct simplefb_platform_data *mode); -int create_simplefb(const struct screen_info *si, - const struct simplefb_platform_data *mode); +int create_simplefb(const struct simplefb_platform_data *mode); #else /* CONFIG_X86_SYSFB */ @@ -92,8 +91,7 @@ static inline bool parse_mode(const struct screen_info *si, return false; } -static inline int create_simplefb(const struct screen_info *si, - const struct simplefb_platform_data *mode) +static inline int create_simplefb(const struct simplefb_platform_data *mode) { return -EINVAL; } diff --git a/arch/x86/kernel/sysfb.c b/arch/x86/kernel/sysfb.c index ba9ff26..fd07b09 100644 --- a/arch/x86/kernel/sysfb.c +++ b/arch/x86/kernel/sysfb.c @@ -117,7 +117,7 @@ static __init int sysfb_init(void) /* try to create a simple-framebuffer device */ compatible = parse_mode(si, &mode); if (compatible) { - ret = create_simplefb(si, &mode); + ret = create_simplefb(&mode); if (!ret) return 0; } diff --git a/arch/x86/kernel/sysfb_simplefb.c b/arch/x86/kernel/sysfb_simplefb.c index a760d47..9338427 100644 --- a/arch/x86/kernel/sysfb_simplefb.c +++ b/arch/x86/kernel/sysfb_simplefb.c @@ -31,9 +31,12 @@ static const struct simplefb_format formats[] = SIMPLEFB_FORMATS; __init bool parse_mode(const struct screen_info *si, struct simplefb_platform_data *mode) { + struct apertures_struct *apert = (void*)mode->apert_buf; const struct simplefb_format *f; + unsigned long len; __u8 type; unsigned int i; + u64 size; type = si->orig_video_isVGA; if (type != VIDEO_TYPE_VLFB && type != VIDEO_TYPE_EFI) @@ -41,47 +44,56 @@ __init bool parse_mode(const struct screen_info *si, for (i = 0; i < ARRAY_SIZE(formats); ++i) { f = &formats[i]; - if (si->lfb_depth == f->bits_per_pixel && - si->red_size == f->red.length && - si->red_pos == f->red.offset && - si->green_size == f->green.length && - si->green_pos == f->green.offset && - si->blue_size == f->blue.length && - si->blue_pos == f->blue.offset && - si->rsvd_size == f->transp.length && - si->rsvd_pos == f->transp.offset) { - mode->format = f->name; - mode->width = si->lfb_width; - mode->height = si->lfb_height; - mode->stride = si->lfb_linelength; - return true; + if (si->lfb_depth != f->bits_per_pixel || + si->red_size != f->red.length || + si->red_pos != f->red.offset || + si->green_size != f->green.length || + si->green_pos != f->green.offset || + si->blue_size != f->blue.length || + si->blue_pos != f->blue.offset || + si->rsvd_size != f->transp.length || + si->rsvd_pos != f->transp.offset) + continue; + + /* lfb_size is in bytes except for VLFB it's in 64kb blocks */ + size = si->lfb_size; + if (type == VIDEO_TYPE_VLFB) + size <<= 16; + + /* don't use lfb_size as it may contain the whole VMEM instead + * of only the part that is occupied by the framebuffer */ + len = si->lfb_height * (unsigned long)si->lfb_linelength; + if (len > size) { + printk(KERN_WARNING "sysfb: VRAM smaller than advertised framebuffer (%llu > %llu)\n", + (unsigned long long)len, + (unsigned long long)size); + return false; } + + mode->format = f->name; + mode->width = si->lfb_width; + mode->height = si->lfb_height; + mode->stride = si->lfb_linelength; + apert->count = 1; + apert->ranges[0].base = si->lfb_base; + apert->ranges[0].size = len; + return true; } return false; } -__init int create_simplefb(const struct screen_info *si, - const struct simplefb_platform_data *mode) +__init int create_simplefb(const struct simplefb_platform_data *mode) { + const struct apertures_struct *apert = (void*)mode->apert_buf; struct resource res; - unsigned long len; - - /* don't use lfb_size as it may contain the whole VMEM instead of only - * the part that is occupied by the framebuffer */ - len = mode->height * mode->stride; - len = PAGE_ALIGN(len); - if (len > (u64)si->lfb_size << 16) { - printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n"); - return -EINVAL; - } /* setup IORESOURCE_MEM as framebuffer memory */ memset(&res, 0, sizeof(res)); res.flags = IORESOURCE_MEM | IORESOURCE_BUSY; res.name = simplefb_resname; - res.start = si->lfb_base; - res.end = si->lfb_base + len - 1; + res.start = apert->ranges[0].base; + res.end = res.start + apert->ranges[0].size - 1; if (res.end <= res.start) return -EINVAL; diff --git a/include/linux/platform_data/simplefb.h b/include/linux/platform_data/simplefb.h index 077303c..21983cc 100644 --- a/include/linux/platform_data/simplefb.h +++ b/include/linux/platform_data/simplefb.h @@ -59,6 +59,7 @@ struct simplefb_platform_data { u32 height; u32 stride; const char *format; + u8 apert_buf[sizeof(struct apertures_struct) + sizeof(struct aperture)]; }; #endif /* __PLATFORM_DATA_SIMPLEFB_H__ */