From patchwork Fri Mar 20 23:17:59 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luis R. Rodriguez" X-Patchwork-Id: 6061751 Return-Path: X-Original-To: patchwork-linux-fbdev@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 2776E9F399 for ; Fri, 20 Mar 2015 23:40:49 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 093CB20522 for ; Fri, 20 Mar 2015 23:40:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D37BA20528 for ; Fri, 20 Mar 2015 23:40:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751303AbbCTXkq (ORCPT ); Fri, 20 Mar 2015 19:40:46 -0400 Received: from mail-pa0-f53.google.com ([209.85.220.53]:34752 "EHLO mail-pa0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751164AbbCTXkp (ORCPT ); Fri, 20 Mar 2015 19:40:45 -0400 Received: by pacwe9 with SMTP id we9so123234524pac.1; Fri, 20 Mar 2015 16:40:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=jOA5Y5MFWcNMVssAon2z1sr8yH+YmFhlPPoQdcrU9wQ=; b=G+D9jcR8OUKZNtSe3/DOfUPN8f6B+mdgjblmH02QXEoGPmjmH+MCNv7l2NmcHrF3wy OPatGx1K7/QLvtu1NBO5GSjgYX1TOmrg5/PBSdfzaytOPX5QRZPM0vfytLngj7ash0QY XxHOtbqslvZ/UveyNg99JXI2VcPGlQX+zHDGwbFkORyMcMoF8FLymrDkPdka+i8rVcmQ mhNSn8Nw2J7SCtFspOyvu2PWCPqW/MN8PiMdglsPDLY3lJFMP2sFPQ1Rj2+qFP73ZBKf /moXtuj+eorhuQmN5tmc9emcSNKBGHM3joE8BvbqS05PERaYj6hw31V81vVB5U7EGNr9 NnMg== X-Received: by 10.70.138.42 with SMTP id qn10mr102222059pdb.157.1426894844735; Fri, 20 Mar 2015 16:40:44 -0700 (PDT) Received: from mcgrof@gmail.com (c-98-234-145-61.hsd1.ca.comcast.net. [98.234.145.61]) by mx.google.com with ESMTPSA id ef3sm160895pbc.26.2015.03.20.16.40.41 (version=TLSv1 cipher=RC4-SHA bits=128/128); Fri, 20 Mar 2015 16:40:43 -0700 (PDT) Received: by mcgrof@gmail.com (sSMTP sendmail emulation); Fri, 20 Mar 2015 16:38:32 -0700 From: "Luis R. Rodriguez" To: luto@amacapital.net, mingo@redhat.com, tglx@linutronix.de, hpa@zytor.com, jgross@suse.com, JBeulich@suse.com, bp@suse.de, suresh.b.siddha@intel.com, venkatesh.pallipadi@intel.com, airlied@redhat.com Cc: linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org, x86@kernel.org, xen-devel@lists.xenproject.org, "Luis R. Rodriguez" , Ingo Molnar , Linus Torvalds , Daniel Vetter , Antonino Daplas , Jean-Christophe Plagniol-Villard , Tomi Valkeinen Subject: [PATCH v1 09/47] vidoe: fbdev: atyfb: remove and fix MTRR MMIO "hole" work around Date: Fri, 20 Mar 2015 16:17:59 -0700 Message-Id: <1426893517-2511-10-git-send-email-mcgrof@do-not-panic.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1426893517-2511-1-git-send-email-mcgrof@do-not-panic.com> References: <1426893517-2511-1-git-send-email-mcgrof@do-not-panic.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=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD,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 From: "Luis R. Rodriguez" The atyfb driver uses an MTRR work around since some cards use the same PCI BAR for the framebuffer and MMIO. In such cards the last page is used for MMIO, the rest for the framebuffer, so on those cards we ioremap() the MMIO page alone, then again ioremap() the full framebuffer including the MMIO space *and* ___then___ use an MTRR with MTRR_TYPE_WRCOMB on the full PCI BAR... and finally "hole" in an MTRR_TYPE_UNCACHABLE MTRR only for MMIO. This is a terrible fucking work around, and should by no means be necessary however evidence through a large series of conversion of drivers to ioremap_wc() for the framebuffer shows that around the time MTRR started becoming popular devices did not have things lined up for easily separating the framebuffer and MMIO register access. In some cases a driver requires significant intrusive changes in order to make the split for an ioremap() for MMIO registers and another ioremap_wc() for the framebuffer, at other times a bit of careful study of the driver suffices. This example driver falls into the later category. We can replace the MTRR MTRR_TYPE_UNCACHABLE work around by using ioremap_nocache(), the length of the MMIO space should already be correct. The other part we need to correct is ensuring we ioremap() for the framebuffer only the required size. Since the ioremap() happens early on probe for PCI devices before aty_init() where we typically adjust the length and know how to do it, we can fix this by pegging the bus type as PCI on PCI probe, and finally fudging and framebuffer length just as we do on aty_init(). The last thing we do must do to remain sane is ensure we use the info->fix.smem_start and info->fix.smem_len for the framebuffer MTRR as we know that is always well adjusted. The *one* concern here would be if the MTRR is not in units of 4K __but__ we already know that in the PCI case this cannot happen, in the shared space setting the MTRR would be up to 0x7ff000 and assuming a 4K page: ; 0x7ff000 / 0x1000 2047 Also, internally when MTRR is used mtrr_add() will use mtrr_check() and that should splat a warning when the MTRR base and size are not compatible with what is expected for MTRR usage. This fix lets us nuke the MTRR_TYPE_UNCACHABLE MTRR "hole". Cc: Suresh Siddha Cc: Venkatesh Pallipadi Cc: Ingo Molnar Cc: Linus Torvalds Cc: Thomas Gleixner Cc: Juergen Gross Cc: Daniel Vetter Cc: Andy Lutomirski Cc: Dave Airlie Cc: Antonino Daplas Cc: Jean-Christophe Plagniol-Villard Cc: Tomi Valkeinen Cc: linux-fbdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Luis R. Rodriguez --- drivers/video/fbdev/aty/atyfb.h | 1 - drivers/video/fbdev/aty/atyfb_base.c | 28 ++++++---------------------- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/drivers/video/fbdev/aty/atyfb.h b/drivers/video/fbdev/aty/atyfb.h index 1f39a62..89ec439 100644 --- a/drivers/video/fbdev/aty/atyfb.h +++ b/drivers/video/fbdev/aty/atyfb.h @@ -184,7 +184,6 @@ struct atyfb_par { spinlock_t int_lock; #ifdef CONFIG_MTRR int mtrr_aper; - int mtrr_reg; #endif u32 mem_cntl; struct crtc saved_crtc; diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index 8025624..8875e56 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -2630,21 +2630,10 @@ static int aty_init(struct fb_info *info) #ifdef CONFIG_MTRR par->mtrr_aper = -1; - par->mtrr_reg = -1; if (!nomtrr) { - /* Cover the whole resource. */ - par->mtrr_aper = mtrr_add(par->res_start, par->res_size, + par->mtrr_aper = mtrr_add(info->fix.smem_start, + info->fix.smem_len, MTRR_TYPE_WRCOMB, 1); - if (par->mtrr_aper >= 0 && !par->aux_start) { - /* Make a hole for mmio. */ - par->mtrr_reg = mtrr_add(par->res_start + 0x800000 - - GUI_RESERVE, GUI_RESERVE, - MTRR_TYPE_UNCACHABLE, 1); - if (par->mtrr_reg < 0) { - mtrr_del(par->mtrr_aper, 0, 0); - par->mtrr_aper = -1; - } - } } #endif @@ -2776,10 +2765,6 @@ aty_init_exit: par->pll_ops->set_pll(info, &par->saved_pll); #ifdef CONFIG_MTRR - if (par->mtrr_reg >= 0) { - mtrr_del(par->mtrr_reg, 0, 0); - par->mtrr_reg = -1; - } if (par->mtrr_aper >= 0) { mtrr_del(par->mtrr_aper, 0, 0); par->mtrr_aper = -1; @@ -3466,7 +3451,7 @@ static int atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, } info->fix.mmio_start = raddr; - par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000); + par->ati_regbase = ioremap_nocache(info->fix.mmio_start, 0x1000); if (par->ati_regbase == NULL) return -ENOMEM; @@ -3491,6 +3476,8 @@ static int atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, info->fix.smem_start = addr; info->fix.smem_len = 0x800000; + aty_fudge_framebuffer_len(info); + info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); if (info->screen_base == NULL) { ret = -ENOMEM; @@ -3563,6 +3550,7 @@ static int atyfb_pci_probe(struct pci_dev *pdev, return -ENOMEM; } par = info->par; + par->bus_type = PCI; info->fix = atyfb_fix; info->device = &pdev->dev; par->pci_id = pdev->device; @@ -3732,10 +3720,6 @@ static void atyfb_remove(struct fb_info *info) #endif #ifdef CONFIG_MTRR - if (par->mtrr_reg >= 0) { - mtrr_del(par->mtrr_reg, 0, 0); - par->mtrr_reg = -1; - } if (par->mtrr_aper >= 0) { mtrr_del(par->mtrr_aper, 0, 0); par->mtrr_aper = -1;