From patchwork Thu Jul 25 10:02:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 2833308 Return-Path: X-Original-To: patchwork-intel-gfx@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 214C9C0319 for ; Thu, 25 Jul 2013 10:06:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 76A4E20209 for ; Thu, 25 Jul 2013 10:06:31 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id B9419201F4 for ; Thu, 25 Jul 2013 10:06:29 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B6AD5E6FF4 for ; Thu, 25 Jul 2013 03:06:29 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fireflyinternet.com (s16502780.onlinehome-server.info [87.106.93.118]) by gabe.freedesktop.org (Postfix) with ESMTP id 1E2FCE6FDB for ; Thu, 25 Jul 2013 03:02:37 -0700 (PDT) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.73.22; Received: from haswell.alporthouse.com (unverified [78.156.73.22]) by fireflyinternet.com (Firefly Internet (M2)) with ESMTP id 11196388-1500048 for multiple; Thu, 25 Jul 2013 11:02:47 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Thu, 25 Jul 2013 11:02:18 +0100 Message-Id: <1374746538-3947-3-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1374746538-3947-1-git-send-email-chris@chris-wilson.co.uk> References: <1374710683-2614-1-git-send-email-jbarnes@virtuousgeek.org> <1374746538-3947-1-git-send-email-chris@chris-wilson.co.uk> X-Originating-IP: 78.156.73.22 Subject: [Intel-gfx] [PATCH 3/3] drm/i915: Lookup stolen region reserved during early PCI quirk processing X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 As we now hook into the early PCI quirk table to earmark the Intel Graphics Stolen region (inserting it into the iomem_resource) to prevent it conflicting with any later resource allocations, we can simply walk the iomem_resource tree and find it for our use. Thereby removing all of our own code to define the stolen region. Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 92 +++------------------------------- drivers/gpu/drm/i915/i915_drv.h | 3 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 15 +----- drivers/gpu/drm/i915/i915_gem_stolen.c | 70 ++++++-------------------- include/drm/intel-gtt.h | 2 +- 5 files changed, 26 insertions(+), 156 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index b8e2014..fe31280 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -343,90 +343,15 @@ static const struct aper_size_info_fixed intel_fake_agp_sizes[] = { static unsigned int intel_gtt_stolen_size(void) { - u16 gmch_ctrl; - u8 rdct; - int local = 0; - static const int ddt[4] = { 0, 16, 32, 64 }; - unsigned int stolen_size = 0; - - if (INTEL_GTT_GEN == 1) - return 0; /* no stolen mem on i81x */ - - pci_read_config_word(intel_private.bridge_dev, - I830_GMCH_CTRL, &gmch_ctrl); + struct resource *r; + unsigned int stolen_size; - if (intel_private.bridge_dev->device == PCI_DEVICE_ID_INTEL_82830_HB || - intel_private.bridge_dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I830_GMCH_GMS_STOLEN_512: - stolen_size = KB(512); - break; - case I830_GMCH_GMS_STOLEN_1024: - stolen_size = MB(1); - break; - case I830_GMCH_GMS_STOLEN_8192: - stolen_size = MB(8); - break; - case I830_GMCH_GMS_LOCAL: - rdct = readb(intel_private.registers+I830_RDRAM_CHANNEL_TYPE); - stolen_size = (I830_RDRAM_ND(rdct) + 1) * - MB(ddt[I830_RDRAM_DDT(rdct)]); - local = 1; - break; - default: - stolen_size = 0; - break; - } - } else { - switch (gmch_ctrl & I855_GMCH_GMS_MASK) { - case I855_GMCH_GMS_STOLEN_1M: - stolen_size = MB(1); - break; - case I855_GMCH_GMS_STOLEN_4M: - stolen_size = MB(4); - break; - case I855_GMCH_GMS_STOLEN_8M: - stolen_size = MB(8); - break; - case I855_GMCH_GMS_STOLEN_16M: - stolen_size = MB(16); - break; - case I855_GMCH_GMS_STOLEN_32M: - stolen_size = MB(32); - break; - case I915_GMCH_GMS_STOLEN_48M: - stolen_size = MB(48); - break; - case I915_GMCH_GMS_STOLEN_64M: - stolen_size = MB(64); - break; - case G33_GMCH_GMS_STOLEN_128M: - stolen_size = MB(128); - break; - case G33_GMCH_GMS_STOLEN_256M: - stolen_size = MB(256); - break; - case INTEL_GMCH_GMS_STOLEN_96M: - stolen_size = MB(96); - break; - case INTEL_GMCH_GMS_STOLEN_160M: - stolen_size = MB(160); - break; - case INTEL_GMCH_GMS_STOLEN_224M: - stolen_size = MB(224); - break; - case INTEL_GMCH_GMS_STOLEN_352M: - stolen_size = MB(352); - break; - default: - stolen_size = 0; - break; - } - } + r = lookup_resource_by_name(&iomem_resource, E820_STOLEN_IGFX_STRING); - if (stolen_size > 0) { - dev_info(&intel_private.bridge_dev->dev, "detected %dK %s memory\n", - stolen_size / KB(1), local ? "local" : "stolen"); + if (r) { + stolen_size = r->end - r->start + 1; + dev_info(&intel_private.bridge_dev->dev, "detected %dK stolen memory\n", + stolen_size / KB(1)); } else { dev_info(&intel_private.bridge_dev->dev, "no pre-allocated video memory detected\n"); @@ -1404,11 +1329,10 @@ int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev, } EXPORT_SYMBOL(intel_gmch_probe); -void intel_gtt_get(size_t *gtt_total, size_t *stolen_size, +void intel_gtt_get(size_t *gtt_total, phys_addr_t *mappable_base, unsigned long *mappable_end) { *gtt_total = intel_private.gtt_total_entries << PAGE_SHIFT; - *stolen_size = intel_private.stolen_size; *mappable_base = intel_private.gma_bus_addr; *mappable_end = intel_private.gtt_mappable_entries << PAGE_SHIFT; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ae36612..ec14124 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -513,7 +513,6 @@ struct i915_address_space { */ struct i915_gtt { struct i915_address_space base; - size_t stolen_size; /* Total size of stolen memory */ unsigned long mappable_end; /* End offset that we can CPU map */ struct io_mapping *mappable; /* Mapping to our CPU mappable region */ @@ -528,7 +527,7 @@ struct i915_gtt { /* global gtt ops */ int (*gtt_probe)(struct drm_device *dev, size_t *gtt_total, - size_t *stolen, phys_addr_t *mappable_base, + phys_addr_t *mappable_base, unsigned long *mappable_end); }; #define gtt_total_entries(gtt) ((gtt).base.total >> PAGE_SHIFT) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 3b639a9..1294cee 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -784,16 +784,8 @@ static inline unsigned int gen6_get_total_gtt_size(u16 snb_gmch_ctl) return snb_gmch_ctl << 20; } -static inline size_t gen6_get_stolen_size(u16 snb_gmch_ctl) -{ - snb_gmch_ctl >>= SNB_GMCH_GMS_SHIFT; - snb_gmch_ctl &= SNB_GMCH_GMS_MASK; - return snb_gmch_ctl << 25; /* 32 MB units */ -} - static int gen6_gmch_probe(struct drm_device *dev, size_t *gtt_total, - size_t *stolen, phys_addr_t *mappable_base, unsigned long *mappable_end) { @@ -820,7 +812,6 @@ static int gen6_gmch_probe(struct drm_device *dev, pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl); - *stolen = gen6_get_stolen_size(snb_gmch_ctl); *gtt_total = (gtt_size / sizeof(gen6_gtt_pte_t)) << PAGE_SHIFT; /* For Modern GENs the PTEs and register space are split in the BAR */ @@ -853,7 +844,6 @@ static void gen6_gmch_remove(struct i915_address_space *vm) static int i915_gmch_probe(struct drm_device *dev, size_t *gtt_total, - size_t *stolen, phys_addr_t *mappable_base, unsigned long *mappable_end) { @@ -866,7 +856,7 @@ static int i915_gmch_probe(struct drm_device *dev, return -EIO; } - intel_gtt_get(gtt_total, stolen, mappable_base, mappable_end); + intel_gtt_get(gtt_total, mappable_base, mappable_end); dev_priv->gtt.do_idle_maps = needs_idle_maps(dev_priv->dev); dev_priv->gtt.base.clear_range = i915_ggtt_clear_range; @@ -902,7 +892,7 @@ int i915_gem_gtt_init(struct drm_device *dev) gtt->base.pte_encode = gen6_pte_encode; } - ret = gtt->gtt_probe(dev, >t->base.total, >t->stolen_size, + ret = gtt->gtt_probe(dev, >t->base.total, >t->mappable_base, >t->mappable_end); if (ret) return ret; @@ -913,7 +903,6 @@ int i915_gem_gtt_init(struct drm_device *dev) DRM_INFO("Memory usable by graphics device = %zdM\n", gtt->base.total >> 20); DRM_DEBUG_DRIVER("GMADR size = %ldM\n", gtt->mappable_end >> 20); - DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", gtt->stolen_size >> 20); return 0; } diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index cacf769..7ae3bb9 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -28,6 +28,7 @@ #include #include +#include #include "i915_drv.h" /* @@ -42,54 +43,6 @@ * for is a boon. */ -static unsigned long i915_stolen_to_physical(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct resource *r; - u32 base; - - /* Almost universally we can find the Graphics Base of Stolen Memory - * at offset 0x5c in the igfx configuration space. On a few (desktop) - * machines this is also mirrored in the bridge device at different - * locations, or in the MCHBAR. On gen2, the layout is again slightly - * different with the Graphics Segment immediately following Top of - * Memory (or Top of Usable DRAM). Note it appears that TOUD is only - * reported by 865g, so we just use the top of memory as determined - * by the e820 probe. - * - * XXX However gen2 requires an unavailable symbol. - */ - base = 0; - if (INTEL_INFO(dev)->gen >= 3) { - /* Read Graphics Base of Stolen Memory directly */ - pci_read_config_dword(dev->pdev, 0x5c, &base); - base &= ~((1<<20) - 1); - } else { /* GEN2 */ -#if 0 - /* Stolen is immediately above Top of Memory */ - base = max_low_pfn_mapped << PAGE_SHIFT; -#endif - } - - if (base == 0) - return 0; - - /* Verify that nothing else uses this physical address. Stolen - * memory should be reserved by the BIOS and hidden from the - * kernel. So if the region is already marked as busy, something - * is seriously wrong. - */ - r = devm_request_mem_region(dev->dev, base, dev_priv->gtt.stolen_size, - "Graphics Stolen Memory"); - if (r == NULL) { - DRM_ERROR("conflict detected with stolen region: [0x%08x - 0x%08x]\n", - base, base + (uint32_t)dev_priv->gtt.stolen_size); - base = 0; - } - - return base; -} - static int i915_setup_compression(struct drm_device *dev, int size) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -188,24 +141,29 @@ void i915_gem_cleanup_stolen(struct drm_device *dev) int i915_gem_init_stolen(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + struct resource *r; int bios_reserved = 0; + size_t size; - dev_priv->mm.stolen_base = i915_stolen_to_physical(dev); - if (dev_priv->mm.stolen_base == 0) + /* Did we reserve our stolen region during early PCI quirks? */ + r = lookup_resource_by_name(&iomem_resource, E820_STOLEN_IGFX_STRING); + if (r == NULL) return 0; - DRM_DEBUG_KMS("found %zd bytes of stolen memory at %08lx\n", - dev_priv->gtt.stolen_size, dev_priv->mm.stolen_base); + size = r->end - r->start + 1; + DRM_DEBUG_KMS("found %zd bytes of stolen memory at %08qx\n", + size, r->start); + + dev_priv->mm.stolen_base = r->start; if (IS_VALLEYVIEW(dev)) bios_reserved = 1024*1024; /* top 1M on VLV/BYT */ - if (WARN_ON(bios_reserved > dev_priv->gtt.stolen_size)) + if (WARN_ON(bios_reserved > size)) return 0; /* Basic memrange allocator for stolen space */ - drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_size - - bios_reserved); + drm_mm_init(&dev_priv->mm.stolen, 0, size - bios_reserved); return 0; } @@ -219,7 +177,7 @@ i915_pages_create_for_stolen(struct drm_device *dev, struct scatterlist *sg; DRM_DEBUG_DRIVER("offset=0x%x, size=%d\n", offset, size); - BUG_ON(offset > dev_priv->gtt.stolen_size - size); + BUG_ON(offset > dev_priv->mm.stolen.head_node.size - size); /* We hide that we have no struct page backing our stolen object * by wrapping the contiguous physical allocation with a fake diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h index b08bdad..c0b5602 100644 --- a/include/drm/intel-gtt.h +++ b/include/drm/intel-gtt.h @@ -3,7 +3,7 @@ #ifndef _DRM_INTEL_GTT_H #define _DRM_INTEL_GTT_H -void intel_gtt_get(size_t *gtt_total, size_t *stolen_size, +void intel_gtt_get(size_t *gtt_total, phys_addr_t *mappable_base, unsigned long *mappable_end); int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev,