From patchwork Thu Jun 25 15:35:13 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Kuoppala X-Patchwork-Id: 6676201 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.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 1DBECC05AC for ; Thu, 25 Jun 2015 15:36:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E4EA5206DC for ; Thu, 25 Jun 2015 15:36:01 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 96A94206EC for ; Thu, 25 Jun 2015 15:36:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7215A7A12E; Thu, 25 Jun 2015 08:35:59 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id 3E5BF7A0D7 for ; Thu, 25 Jun 2015 08:35:55 -0700 (PDT) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP; 25 Jun 2015 08:35:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,677,1427785200"; d="scan'208";a="734577674" Received: from rosetta.fi.intel.com (HELO rosetta) ([10.237.72.104]) by fmsmga001.fm.intel.com with ESMTP; 25 Jun 2015 08:35:32 -0700 Received: by rosetta (Postfix, from userid 1000) id 8FF5E80094; Thu, 25 Jun 2015 18:35:29 +0300 (EEST) From: Mika Kuoppala To: intel-gfx@lists.freedesktop.org Date: Thu, 25 Jun 2015 18:35:13 +0300 Message-Id: <1435246520-14745-12-git-send-email-mika.kuoppala@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1435246520-14745-1-git-send-email-mika.kuoppala@intel.com> References: <1435246520-14745-1-git-send-email-mika.kuoppala@intel.com> Cc: miku@iki.fi Subject: [Intel-gfx] [PATCH 11/18] drm/i915/gtt: Make scratch page i915_page_dma compatible X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-5.6 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 Lay out scratch page structure in similar manner than other paging structures. This allows us to use the same tools for setup and teardown. Signed-off-by: Mika Kuoppala Reviewed-by: Michel Thierry --- drivers/gpu/drm/i915/i915_gem_gtt.c | 89 ++++++++++++++++++++----------------- drivers/gpu/drm/i915/i915_gem_gtt.h | 9 ++-- 2 files changed, 54 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index e85676e..0cc0cf4 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -301,11 +301,12 @@ static gen6_pte_t iris_pte_encode(dma_addr_t addr, return pte; } -static int setup_page_dma(struct drm_device *dev, struct i915_page_dma *p) +static int __setup_page_dma(struct drm_device *dev, + struct i915_page_dma *p, gfp_t flags) { struct device *device = &dev->pdev->dev; - p->page = alloc_page(GFP_KERNEL); + p->page = alloc_page(flags); if (!p->page) return -ENOMEM; @@ -320,6 +321,11 @@ static int setup_page_dma(struct drm_device *dev, struct i915_page_dma *p) return 0; } +static int setup_page_dma(struct drm_device *dev, struct i915_page_dma *p) +{ + return __setup_page_dma(dev, p, GFP_KERNEL); +} + static void cleanup_page_dma(struct drm_device *dev, struct i915_page_dma *p) { if (WARN_ON(!p->page)) @@ -391,7 +397,8 @@ static void gen8_initialize_pt(struct i915_address_space *vm, { gen8_pte_t scratch_pte; - scratch_pte = gen8_pte_encode(vm->scratch.addr, I915_CACHE_LLC, true); + scratch_pte = gen8_pte_encode(px_dma(vm->scratch_page), + I915_CACHE_LLC, true); fill_px(vm->dev, pt, scratch_pte); } @@ -519,7 +526,7 @@ static void gen8_ppgtt_clear_range(struct i915_address_space *vm, unsigned num_entries = length >> PAGE_SHIFT; unsigned last_pte, i; - scratch_pte = gen8_pte_encode(ppgtt->base.scratch.addr, + scratch_pte = gen8_pte_encode(px_dma(ppgtt->base.scratch_page), I915_CACHE_LLC, use_scratch); while (num_entries) { @@ -983,7 +990,7 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m) uint32_t pte, pde, temp; uint32_t start = ppgtt->base.start, length = ppgtt->base.total; - scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0); + scratch_pte = vm->pte_encode(px_dma(vm->scratch_page), I915_CACHE_LLC, true, 0); gen6_for_each_pde(unused, &ppgtt->pd, start, length, temp, pde) { u32 expected; @@ -1222,7 +1229,8 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm, unsigned first_pte = first_entry % GEN6_PTES; unsigned last_pte, i; - scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0); + scratch_pte = vm->pte_encode(px_dma(vm->scratch_page), + I915_CACHE_LLC, true, 0); while (num_entries) { last_pte = first_pte + num_entries; @@ -1280,9 +1288,10 @@ static void gen6_initialize_pt(struct i915_address_space *vm, { gen6_pte_t scratch_pte; - WARN_ON(vm->scratch.addr == 0); + WARN_ON(px_dma(vm->scratch_page) == 0); - scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0); + scratch_pte = vm->pte_encode(px_dma(vm->scratch_page), + I915_CACHE_LLC, true, 0); fill32_px(vm->dev, pt, scratch_pte); } @@ -1519,13 +1528,14 @@ static int __hw_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) struct drm_i915_private *dev_priv = dev->dev_private; ppgtt->base.dev = dev; - ppgtt->base.scratch = dev_priv->gtt.base.scratch; + ppgtt->base.scratch_page = dev_priv->gtt.base.scratch_page; if (INTEL_INFO(dev)->gen < 8) return gen6_ppgtt_init(ppgtt); else return gen8_ppgtt_init(ppgtt); } + int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -1842,7 +1852,7 @@ static void gen8_ggtt_clear_range(struct i915_address_space *vm, first_entry, num_entries, max_entries)) num_entries = max_entries; - scratch_pte = gen8_pte_encode(vm->scratch.addr, + scratch_pte = gen8_pte_encode(px_dma(vm->scratch_page), I915_CACHE_LLC, use_scratch); for (i = 0; i < num_entries; i++) @@ -1868,7 +1878,8 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm, first_entry, num_entries, max_entries)) num_entries = max_entries; - scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, use_scratch, 0); + scratch_pte = vm->pte_encode(px_dma(vm->scratch_page), + I915_CACHE_LLC, use_scratch, 0); for (i = 0; i < num_entries; i++) iowrite32(scratch_pte, >t_base[i]); @@ -2125,42 +2136,40 @@ void i915_global_gtt_cleanup(struct drm_device *dev) vm->cleanup(vm); } -static int setup_scratch_page(struct drm_device *dev) +static int alloc_scratch_page(struct i915_address_space *vm) { - struct drm_i915_private *dev_priv = dev->dev_private; - struct page *page; - dma_addr_t dma_addr; + struct i915_page_scratch *sp; + int ret; + + WARN_ON(vm->scratch_page); - page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); - if (page == NULL) + sp = kzalloc(sizeof(*sp), GFP_KERNEL); + if (sp == NULL) return -ENOMEM; - set_pages_uc(page, 1); -#ifdef CONFIG_INTEL_IOMMU - dma_addr = pci_map_page(dev->pdev, page, 0, PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(dev->pdev, dma_addr)) { - __free_page(page); - return -EINVAL; + ret = __setup_page_dma(vm->dev, px_base(sp), GFP_DMA32 | __GFP_ZERO); + if (ret) { + kfree(sp); + return ret; } -#else - dma_addr = page_to_phys(page); -#endif - dev_priv->gtt.base.scratch.page = page; - dev_priv->gtt.base.scratch.addr = dma_addr; + + set_pages_uc(px_page(sp), 1); + + vm->scratch_page = sp; return 0; } -static void teardown_scratch_page(struct drm_device *dev) +static void free_scratch_page(struct i915_address_space *vm) { - struct drm_i915_private *dev_priv = dev->dev_private; - struct page *page = dev_priv->gtt.base.scratch.page; + struct i915_page_scratch *sp = vm->scratch_page; - set_pages_wb(page, 1); - pci_unmap_page(dev->pdev, dev_priv->gtt.base.scratch.addr, - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - __free_page(page); + set_pages_wb(px_page(sp), 1); + + cleanup_px(vm->dev, sp); + kfree(sp); + + vm->scratch_page = NULL; } static unsigned int gen6_get_total_gtt_size(u16 snb_gmch_ctl) @@ -2268,7 +2277,7 @@ static int ggtt_probe_common(struct drm_device *dev, return -ENOMEM; } - ret = setup_scratch_page(dev); + ret = alloc_scratch_page(&dev_priv->gtt.base); if (ret) { DRM_ERROR("Scratch setup failed\n"); /* iounmap will also get called at remove, but meh */ @@ -2447,7 +2456,7 @@ static void gen6_gmch_remove(struct i915_address_space *vm) struct i915_gtt *gtt = container_of(vm, struct i915_gtt, base); iounmap(gtt->gsm); - teardown_scratch_page(vm->dev); + free_scratch_page(vm); } static int i915_gmch_probe(struct drm_device *dev, @@ -2511,13 +2520,13 @@ int i915_gem_gtt_init(struct drm_device *dev) dev_priv->gtt.base.cleanup = gen6_gmch_remove; } + gtt->base.dev = dev; + ret = gtt->gtt_probe(dev, >t->base.total, >t->stolen_size, >t->mappable_base, >t->mappable_end); if (ret) return ret; - gtt->base.dev = dev; - /* GMADR is the PCI mmio aperture into the global GTT. */ DRM_INFO("Memory usable by graphics device = %lluM\n", gtt->base.total >> 20); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index f4bcec2..216d949 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -223,6 +223,10 @@ struct i915_page_dma { #define px_page(px) (px_base(px)->page) #define px_dma(px) (px_base(px)->daddr) +struct i915_page_scratch { + struct i915_page_dma base; +}; + struct i915_page_table { struct i915_page_dma base; @@ -249,10 +253,7 @@ struct i915_address_space { u64 start; /* Start offset always 0 for dri2 */ u64 total; /* size addr space maps (ex. 2GB for ggtt) */ - struct { - dma_addr_t addr; - struct page *page; - } scratch; + struct i915_page_scratch *scratch_page; /** * List of objects currently involved in rendering.