From mboxrd@z Thu Jan 1 00:00:00 1970 From: Imre Deak Subject: Re: [PATCH 23/62] drm/i915/bdw: PPGTT init & cleanup Date: Mon, 04 Nov 2013 16:58:27 +0200 Message-ID: <1383577107.18529.8.camel@intelbox> References: <1383451680-11173-1-git-send-email-benjamin.widawsky@intel.com> <1383451680-11173-24-git-send-email-benjamin.widawsky@intel.com> Reply-To: imre.deak@intel.com Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0110206808==" Return-path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTP id 3366BFA417 for ; Mon, 4 Nov 2013 06:58:30 -0800 (PST) In-Reply-To: <1383451680-11173-24-git-send-email-benjamin.widawsky@intel.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org To: Ben Widawsky Cc: Daniel Vetter , Intel GFX , Ben Widawsky List-Id: intel-gfx@lists.freedesktop.org --===============0110206808== Content-Type: multipart/signed; micalg="pgp-sha1"; protocol="application/pgp-signature"; boundary="=-gXqtWPZUkmloVlbKb0uF" --=-gXqtWPZUkmloVlbKb0uF Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sat, 2013-11-02 at 21:07 -0700, Ben Widawsky wrote: > Aside from the potential size increase of the PPGTT, the primary > difference from previous hardware is the Page Directories are no longer > carved out of the Global GTT. >=20 > Note that the PDE allocation is done as a 8MB contiguous allocation, > this needs to be eventually fixed (since driver reloading will be a > pain otherwise). Also, this will be a no-go for real PPGTT support. >=20 > v2: Move vtable initialization >=20 > v3: Resolve conflicts due to patch series reordering. >=20 > v4: Rebase on top of the address space refactoring of the PPGTT > support. Drop Imre's r-b tag for v2, too outdated by now. >=20 > Signed-off-by: Ben Widawsky (v2) > Signed-off-by: Daniel Vetter > --- > drivers/gpu/drm/i915/i915_drv.h | 19 ++++-- > drivers/gpu/drm/i915/i915_gem_gtt.c | 123 ++++++++++++++++++++++++++++++= +++++- > 2 files changed, 137 insertions(+), 5 deletions(-) >=20 > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_= drv.h > index 83d016c..97b0905 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -572,10 +572,21 @@ struct i915_gtt { > struct i915_hw_ppgtt { > struct i915_address_space base; > unsigned num_pd_entries; > - struct page **pt_pages; > - uint32_t pd_offset; > - dma_addr_t *pt_dma_addr; > - > + union { > + struct page **pt_pages; > + struct page *gen8_pt_pages; > + }; > + struct page *pd_pages; > + int num_pd_pages; > + int num_pt_pages; > + union { > + uint32_t pd_offset; > + dma_addr_t pd_dma_addr[4]; > + }; > + union { > + dma_addr_t *pt_dma_addr; > + dma_addr_t *gen8_pt_dma_addr[4]; > + }; > int (*enable)(struct drm_device *dev); > }; > =20 > diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i= 915_gem_gtt.c > index 02de12d..4a11f51 100644 > --- a/drivers/gpu/drm/i915/i915_gem_gtt.c > +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c > @@ -31,6 +31,7 @@ > #define GEN6_PPGTT_PD_ENTRIES 512 > #define I915_PPGTT_PT_ENTRIES (PAGE_SIZE / sizeof(gen6_gtt_pte_t)) > typedef uint64_t gen8_gtt_pte_t; > +typedef gen8_gtt_pte_t gen8_ppgtt_pde_t; > =20 > /* PPGTT stuff */ > #define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) > @@ -58,6 +59,9 @@ typedef uint64_t gen8_gtt_pte_t; > #define HSW_WB_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0xb) > #define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6) > =20 > +#define GEN8_PDES_PER_PAGE (PAGE_SIZE / sizeof(gen8_ppgtt_pde_t)) > +#define GEN8_LEGACY_PDPS 4 > + > #define PPAT_UNCACHED_INDEX (_PAGE_PWT | _PAGE_PCD) > #define PPAT_CACHED_PDE_INDEX 0 /* WB LLC */ > #define PPAT_CACHED_INDEX _PAGE_PAT /* WB LLCeLLC */ > @@ -177,6 +181,123 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t ad= dr, > return pte; > } > =20 > +static void gen8_ppgtt_cleanup(struct i915_address_space *vm) > +{ > + struct i915_hw_ppgtt *ppgtt =3D > + container_of(vm, struct i915_hw_ppgtt, base); > + int i, j; > + > + for (i =3D 0; i < ppgtt->num_pd_pages ; i++) { > + if (ppgtt->pd_dma_addr[i]) { > + pci_unmap_page(ppgtt->base.dev->pdev, > + ppgtt->pd_dma_addr[i], > + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); > + > + for (j =3D 0; j < GEN8_PDES_PER_PAGE; j++) { > + dma_addr_t addr =3D ppgtt->gen8_pt_dma_addr[i][j]; > + if (addr) > + pci_unmap_page(ppgtt->base.dev->pdev, > + addr, > + PAGE_SIZE, > + PCI_DMA_BIDIRECTIONAL); > + > + } > + } > + kfree(ppgtt->gen8_pt_dma_addr[i]); > + } > + > + __free_pages(ppgtt->gen8_pt_pages, get_order(ppgtt->num_pt_pages)); > + __free_pages(ppgtt->pd_pages, get_order(ppgtt->num_pd_pages)); get_order takes size not a page count. With that fixed: Reviewed-by: Imre Deak > +} > + > +/** > + * GEN8 legacy ppgtt programming is accomplished through 4 PDP registers= with a > + * net effect resembling a 2-level page table in normal x86 terms. Each = PDP > + * represents 1GB of memory > + * 4 * 512 * 512 * 4096 =3D 4GB legacy 32b address space. > + * > + * TODO: Do something with the size parameter > + **/ > +static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size) > +{ > + struct page *pt_pages; > + int i, j, ret =3D -ENOMEM; > + const int max_pdp =3D DIV_ROUND_UP(size, 1 << 30); > + const int num_pt_pages =3D GEN8_PDES_PER_PAGE * max_pdp; > + > + if (size % (1<<30)) > + DRM_INFO("Pages will be wasted unless GTT size (%llu) is divisible by = 1GB\n", size); > + > + /* FIXME: split allocation into smaller pieces. For now we only ever do > + * this once, but with full PPGTT, the multiple contiguous allocations > + * will be bad. > + */ > + ppgtt->pd_pages =3D alloc_pages(GFP_KERNEL, get_order(max_pdp << PAGE_S= HIFT)); > + if (!ppgtt->pd_pages) > + return -ENOMEM; > + > + pt_pages =3D alloc_pages(GFP_KERNEL, get_order(num_pt_pages << PAGE_SHI= FT)); > + if (!pt_pages) { > + __free_pages(ppgtt->pd_pages, get_order(max_pdp << PAGE_SHIFT)); > + return -ENOMEM; > + } > + > + ppgtt->gen8_pt_pages =3D pt_pages; > + ppgtt->num_pd_pages =3D 1 << get_order(max_pdp << PAGE_SHIFT); > + ppgtt->num_pt_pages =3D 1 << get_order(num_pt_pages << PAGE_SHIFT); > + ppgtt->num_pd_entries =3D max_pdp * GEN8_PDES_PER_PAGE; > + ppgtt->base.clear_range =3D NULL; > + ppgtt->base.insert_entries =3D NULL; > + ppgtt->base.cleanup =3D gen8_ppgtt_cleanup; > + > + BUG_ON(ppgtt->num_pd_pages > GEN8_LEGACY_PDPS); > + > + /* > + * - Create a mapping for the page directories. > + * - For each page directory: > + * allocate space for page table mappings. > + * map each page table > + */ > + for (i =3D 0; i < max_pdp; i++) { > + dma_addr_t temp; > + temp =3D pci_map_page(ppgtt->base.dev->pdev, > + &ppgtt->pd_pages[i], 0, > + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); > + if (pci_dma_mapping_error(ppgtt->base.dev->pdev, temp)) > + goto err_out; > + > + ppgtt->pd_dma_addr[i] =3D temp; > + > + ppgtt->gen8_pt_dma_addr[i] =3D kmalloc(sizeof(dma_addr_t) * GEN8_PDES_= PER_PAGE, GFP_KERNEL); > + if (!ppgtt->gen8_pt_dma_addr[i]) > + goto err_out; > + > + for (j =3D 0; j < GEN8_PDES_PER_PAGE; j++) { > + struct page *p =3D &pt_pages[i * GEN8_PDES_PER_PAGE + j]; > + temp =3D pci_map_page(ppgtt->base.dev->pdev, > + p, 0, PAGE_SIZE, > + PCI_DMA_BIDIRECTIONAL); > + > + if (pci_dma_mapping_error(ppgtt->base.dev->pdev, temp)) > + goto err_out; > + > + ppgtt->gen8_pt_dma_addr[i][j] =3D temp; > + } > + } > + > + DRM_DEBUG_DRIVER("Allocated %d pages for page directories (%d wasted)\n= ", > + ppgtt->num_pd_pages, ppgtt->num_pd_pages - max_pdp); > + DRM_DEBUG_DRIVER("Allocated %d pages for page tables (%lld wasted)\n", > + ppgtt->num_pt_pages, > + (ppgtt->num_pt_pages - num_pt_pages) + > + size % (1<<30)); > + return -ENOSYS; /* Not ready yet */ > + > +err_out: > + ppgtt->base.cleanup(&ppgtt->base); > + return ret; > +} > + > static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt) > { > struct drm_i915_private *dev_priv =3D ppgtt->base.dev->dev_private; > @@ -430,7 +551,7 @@ static int i915_gem_init_aliasing_ppgtt(struct drm_de= vice *dev) > if (INTEL_INFO(dev)->gen < 8) > ret =3D gen6_ppgtt_init(ppgtt); > else if (IS_GEN8(dev)) > - ret =3D -ENXIO; > + ret =3D gen8_ppgtt_init(ppgtt, dev_priv->gtt.base.total); > else > BUG(); > =20 --=-gXqtWPZUkmloVlbKb0uF Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQEcBAABAgAGBQJSd7YTAAoJEORIIAnNuWDFpfcH/33gzJluOOeFxl4S0KKts9Qt 5kk6DqSoyh1Mmt7Uu9JSJkUqpwP1ZFVFNakWWWYaBm8ju0dlry49IDC8GW4/7Lcx ezMy4TlAf8ZlnQz4T4JdH5zOShIMDjtL/I009cjiTt4MkAJrTtOkjisfNGeIdHYL MkSOi+Vbcx+GHrrw7dcF346rZAUWt3q9npjp9wg8vWJ5CCM1JFkEkvBXjXs7syRe PSmJLnXNoitZg+zfQLoGNAEcZDr7SAksqdy3gNN0YBiGJYoanWLpgae9yByfSUja ScSG52MzZUWQZ8oqPMZYkmz21HfZ4yxGyctDt1RwgB6bKdJTKyA5eao+CygoK/0= =3bFH -----END PGP SIGNATURE----- --=-gXqtWPZUkmloVlbKb0uF-- --===============0110206808== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx --===============0110206808==--