Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/riastradh-drm2]: src/sys/external/bsd/drm2/i915drm First draft of i915_g...



details:   https://anonhg.NetBSD.org/src/rev/1942a1e43e6d
branches:  riastradh-drm2
changeset: 788644:1942a1e43e6d
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Wed Mar 05 14:45:00 2014 +0000

description:
First draft of i915_gem_gtt.c for pre-Sandy Bridge (gen<6) devices.

These go through the legacy AGP cruft to get at the GTT.

diffstat:

 sys/external/bsd/drm2/i915drm/i915_gem_gtt.c |  535 +++++++++++++++++++-------
 1 files changed, 380 insertions(+), 155 deletions(-)

diffs (truncated from 640 to 300 lines):

diff -r 2f1e66134a4c -r 1942a1e43e6d sys/external/bsd/drm2/i915drm/i915_gem_gtt.c
--- a/sys/external/bsd/drm2/i915drm/i915_gem_gtt.c      Wed Mar 05 14:42:40 2014 +0000
+++ b/sys/external/bsd/drm2/i915drm/i915_gem_gtt.c      Wed Mar 05 14:45:00 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: i915_gem_gtt.c,v 1.1.2.8 2014/03/05 08:45:06 aymeric Exp $     */
+/*     $NetBSD: i915_gem_gtt.c,v 1.1.2.9 2014/03/05 14:45:00 riastradh Exp $   */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i915_gem_gtt.c,v 1.1.2.8 2014/03/05 08:45:06 aymeric Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i915_gem_gtt.c,v 1.1.2.9 2014/03/05 14:45:00 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -40,165 +40,61 @@
 
 #include <dev/pci/pcivar.h>
 
+#include <dev/pci/agpvar.h>
+#include <dev/pci/agp_i810var.h>
+
 #include <drm/drmP.h>
 
 #include "i915_drv.h"
 
+static int     i915_gem_gtt_init_scratch_page(struct intel_gtt *,
+                   bus_dma_tag_t);
+static void    i915_gem_gtt_fini_scratch_page(struct intel_gtt *,
+                   bus_dma_tag_t);
+
 static void    i915_gtt_color_adjust(struct drm_mm_node *, unsigned long,
                    unsigned long *, unsigned long *);
 static void    i915_ggtt_clear_range(struct drm_device *, unsigned, unsigned);
+
+static int     agp_gtt_init(struct drm_device *);
+static void    agp_gtt_fini(struct drm_device *);
+static void    agp_ggtt_bind_object(struct drm_i915_gem_object *,
+                   enum i915_cache_level);
+static void    agp_ggtt_clear_range(struct drm_device *, unsigned, unsigned);
+
+static int     gen6_gtt_init(struct drm_device *);
+static void    gen6_gtt_fini(struct drm_device *);
 static void    gen6_ggtt_bind_object(struct drm_i915_gem_object *,
                    enum i915_cache_level);
 static void    gen6_ggtt_clear_range(struct drm_device *, unsigned, unsigned);
 
-#define        SNB_GMCH_GGMS   (SNB_GMCH_GGMS_MASK << SNB_GMCH_GGMS_SHIFT)
-#define        SNB_GMCH_GMS    (SNB_GMCH_GMS_MASK << SNB_GMCH_GMS_SHIFT)
-#define        IVB_GMCH_GMS    (IVB_GMCH_GMS_MASK << IVB_GMCH_GMS_SHIFT)
-
-typedef uint32_t gtt_pte_t;
-
-#define        GEN6_PTE_VALID          __BIT(0)
-#define        GEN6_PTE_UNCACHED       __BIT(1)
-#define        HSW_PTE_UNCACHED        (0)
-#define        GEN6_PTE_CACHE_LLC      __BIT(2)
-#define        GEN6_PTE_CACHE_LLC_MLC  __BIT(3)
-
-static uint32_t
-gen6_pte_addr_encode(bus_addr_t addr)
-{
-       KASSERT(addr <= __BITS(39, 0));
-       return (addr | ((addr >> 28) & 0xff0));
-}
-
-static gtt_pte_t
-pte_encode(struct drm_device *dev, bus_addr_t addr,
-    enum i915_cache_level level)
-{
-       uint32_t flags = GEN6_PTE_VALID;
-
-       switch (level) {
-       case I915_CACHE_LLC_MLC:
-               flags |= (IS_HASWELL(dev)? GEN6_PTE_CACHE_LLC
-                   : GEN6_PTE_CACHE_LLC_MLC);
-               break;
-
-       case I915_CACHE_LLC:
-               flags |= GEN6_PTE_CACHE_LLC;
-               break;
-
-       case I915_CACHE_NONE:
-               flags |= (IS_HASWELL(dev)? HSW_PTE_UNCACHED
-                   : GEN6_PTE_UNCACHED);
-               break;
-
-       default:
-               panic("invalid i915 GTT cache level: %d", (int)level);
-               break;
-       }
-
-       return (gen6_pte_addr_encode(addr) | flags);
-}
-
 int
 i915_gem_gtt_init(struct drm_device *dev)
 {
        struct drm_i915_private *const dev_priv = dev->dev_private;
-       struct pci_attach_args *const pa = &dev->pdev->pd_pa;
        struct intel_gtt *gtt;
-       uint16_t snb_gmch_ctl, ggms, gms;
-       int nsegs;
        int ret;
 
-       if (INTEL_INFO(dev)->gen < 6) {
-               /* XXX gen<6 */
-               DRM_ERROR("device is too old for drm2 for now!\n");
-               return -ENODEV;
-       }
-
-       gtt = kmem_zalloc(sizeof(*gtt), KM_NOSLEEP);
-
-       /* XXX pci_set_dma_mask?  pci_set_consistent_dma_mask?  */
-       drm_limit_dma_space(dev, 0, 0x0000000fffffffffULL);
-
-       gtt->gma_bus_addr = dev->bus_maps[2].bm_base;
-
-       snb_gmch_ctl = pci_conf_read(pa->pa_pc, pa->pa_tag, SNB_GMCH_CTRL);
-
-       /* GMS: Graphics Mode Select.  */
-       if (INTEL_INFO(dev)->gen < 7) {
-               gms = __SHIFTOUT(snb_gmch_ctl, SNB_GMCH_GMS);
-               gtt->stolen_size = (gms << 25);
-       } else {
-               gms = __SHIFTOUT(snb_gmch_ctl, IVB_GMCH_GMS);
-               static const unsigned sizes[] = {
-                       0, 0, 0, 0, 0, 32, 48, 64, 128, 256, 96, 160, 224, 352
-               };
-               gtt->stolen_size = sizes[gms] << 20;
-       }
-
-       /* GGMS: GTT Graphics Memory Size.  */
-       ggms = __SHIFTOUT(snb_gmch_ctl, SNB_GMCH_GGMS);
-       gtt->gtt_total_entries = (ggms << 20) / sizeof(gtt_pte_t);
-
-       gtt->gtt_mappable_entries = (dev->bus_maps[2].bm_size >> PAGE_SHIFT);
-       if (((gtt->gtt_mappable_entries >> 8) < 64) ||
-           (gtt->gtt_total_entries < gtt->gtt_mappable_entries)) {
-               DRM_ERROR("unknown GMADR entries: %d\n",
-                   gtt->gtt_mappable_entries);
-               ret = -ENXIO;
-               goto fail0;
-       }
-
-       /* XXX errno NetBSD->Linux */
-       ret = -bus_dmamem_alloc(dev->dmat, PAGE_SIZE, PAGE_SIZE, 0,
-           &gtt->gtt_scratch_seg, 1, &nsegs, 0);
+       dev_priv->mm.gtt = gtt = kmem_zalloc(sizeof(*gtt), KM_SLEEP);
+       if (INTEL_INFO(dev)->gen < 6)
+               ret = agp_gtt_init(dev);
+       else
+               ret = gen6_gtt_init(dev);
        if (ret)
                goto fail0;
-       KASSERT(nsegs == 1);
 
-       /* XXX errno NetBSD->Linux */
-       ret = -bus_dmamap_create(dev->dmat, PAGE_SIZE, 1, PAGE_SIZE, 0, 0,
-           &gtt->gtt_scratch_map);
-       if (ret)
-               goto fail1;
-
-       /* XXX errno NetBSD->Linux */
-       ret = -bus_dmamap_load_raw(dev->dmat, gtt->gtt_scratch_map,
-           &gtt->gtt_scratch_seg, 1, PAGE_SIZE, BUS_DMA_NOCACHE);
-       if (ret)
-               goto fail2;
-
-       /* Linux sez:  For GEN6+ the PTEs for the ggtt live at 2MB + BAR0 */
-       if (dev->bus_maps[0].bm_size < (gtt->gtt_total_entries *
-               sizeof(gtt_pte_t))) {
-               DRM_ERROR("BAR0 too small for GTT: 0x%"PRIxMAX" < 0x%"PRIxMAX
-                   "\n",
-                   dev->bus_maps[0].bm_size,
-                   (gtt->gtt_total_entries * sizeof(gtt_pte_t)));
-               ret = -ENODEV;
-               goto fail3;
-       }
-       if (bus_space_map(dev->bst, (dev->bus_maps[0].bm_base + (2<<20)),
-               (gtt->gtt_total_entries * sizeof(gtt_pte_t)),
-               0,
-               &gtt->gtt_bsh)) {
-               DRM_ERROR("unable to map GTT\n");
-               ret = -ENODEV;
-               goto fail3;
-       }
-
+       /* Success!  */
        DRM_INFO("Memory usable by graphics device = %dM\n",
            gtt->gtt_total_entries >> 8);
        DRM_DEBUG_DRIVER("GMADR size = %dM\n", gtt->gtt_mappable_entries >> 8);
        DRM_DEBUG_DRIVER("GTT stolen size = %dM\n", gtt->stolen_size >> 20);
-
-       /* Success!  */
-       dev_priv->mm.gtt = gtt;
        return 0;
 
-fail3: bus_dmamap_unload(dev->dmat, gtt->gtt_scratch_map);
-fail2: bus_dmamap_destroy(dev->dmat, gtt->gtt_scratch_map);
-fail1: bus_dmamem_free(dev->dmat, &gtt->gtt_scratch_seg, 1);
+fail1: __unused
+       if (INTEL_INFO(dev)->gen < 6)
+               agp_gtt_fini(dev);
+       else
+               gen6_gtt_fini(dev);
 fail0: kmem_free(gtt, sizeof(*gtt));
        return ret;
 }
@@ -207,14 +103,56 @@
 i915_gem_gtt_fini(struct drm_device *dev)
 {
        struct drm_i915_private *const dev_priv = dev->dev_private;
-       struct intel_gtt *const gtt = dev_priv->mm.gtt;
+
+       if (INTEL_INFO(dev)->gen < 6)
+               agp_gtt_fini(dev);
+       else
+               gen6_gtt_fini(dev);
+       kmem_free(dev_priv->mm.gtt, sizeof(*dev_priv->mm.gtt));
+}
+
+static int
+i915_gem_gtt_init_scratch_page(struct intel_gtt *gtt, bus_dma_tag_t dmat)
+{
+       int nsegs;
+       int ret;
+
+       /* XXX errno NetBSD->Linux */
+       ret = -bus_dmamem_alloc(dmat, PAGE_SIZE, PAGE_SIZE, 0,
+           &gtt->gtt_scratch_seg, 1, &nsegs, 0);
+       if (ret)
+               goto fail0;
+       KASSERT(nsegs == 1);
 
-       bus_space_unmap(dev->bst, gtt->gtt_bsh,
-           (gtt->gtt_total_entries * sizeof(gtt_pte_t)));
-       bus_dmamap_unload(dev->dmat, gtt->gtt_scratch_map);
-       bus_dmamap_destroy(dev->dmat, gtt->gtt_scratch_map);
-       bus_dmamem_free(dev->dmat, &gtt->gtt_scratch_seg, 1);
-       kmem_free(gtt, sizeof(*gtt));
+       /* XXX errno NetBSD->Linux */
+       ret = -bus_dmamap_create(dmat, PAGE_SIZE, 1, PAGE_SIZE, 0, 0,
+           &gtt->gtt_scratch_map);
+       if (ret)
+               goto fail1;
+
+       /* XXX errno NetBSD->Linux */
+       ret = -bus_dmamap_load_raw(dmat, gtt->gtt_scratch_map,
+           &gtt->gtt_scratch_seg, 1, PAGE_SIZE, BUS_DMA_NOCACHE);
+       if (ret)
+               goto fail2;
+
+       /* Success!  */
+       return 0;
+
+fail3: __unused
+       bus_dmamap_unload(dmat, gtt->gtt_scratch_map);
+fail2: bus_dmamap_destroy(dmat, gtt->gtt_scratch_map);
+fail1: bus_dmamem_free(dmat, &gtt->gtt_scratch_seg, 1);
+fail0: return ret;
+}
+
+static void
+i915_gem_gtt_fini_scratch_page(struct intel_gtt *gtt, bus_dma_tag_t dmat)
+{
+
+       bus_dmamap_unload(dmat, gtt->gtt_scratch_map);
+       bus_dmamap_destroy(dmat, gtt->gtt_scratch_map);
+       bus_dmamem_free(dmat, &gtt->gtt_scratch_seg, 1);
 }
 
 void
@@ -329,9 +267,12 @@
 i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj,
     enum i915_cache_level cache_level)
 {
+       struct drm_device *const dev = obj->base.dev;
 
-       KASSERT(6 < INTEL_INFO(obj->base.dev)->gen); /* XXX gen<6 */
-       gen6_ggtt_bind_object(obj, cache_level);
+       if (INTEL_INFO(dev)->gen < 6)
+               agp_ggtt_bind_object(obj, cache_level);
+       else
+               gen6_ggtt_bind_object(obj, cache_level);
        obj->has_global_gtt_mapping = 1;
 }
 
@@ -345,17 +286,42 @@
        obj->has_global_gtt_mapping = 0;
 }
 
+static bool
+i915_gem_gtt_idle(struct drm_device *dev)
+{
+       struct drm_i915_private *const dev_priv = dev->dev_private;
+       const bool interruptible = dev_priv->mm.interruptible;



Home | Main Index | Thread Index | Old Index