Merge tag 'drm-intel-gt-next-2022-09-16' of git://anongit.freedesktop.org/drm/drm...
[linux-2.6-block.git] / drivers / gpu / drm / i915 / gt / intel_gt.c
index e4bac2431e41607de83512f4e6620acaa4c498d4..d0b03a928b9acaaae274907fa73e4431186470e6 100644 (file)
 #include "intel_rc6.h"
 #include "intel_renderstate.h"
 #include "intel_rps.h"
+#include "intel_sa_media.h"
 #include "intel_gt_sysfs.h"
 #include "intel_uncore.h"
 #include "shmem_utils.h"
 
-static void __intel_gt_init_early(struct intel_gt *gt)
+void intel_gt_common_init_early(struct intel_gt *gt)
 {
-       spin_lock_init(&gt->irq_lock);
+       spin_lock_init(gt->irq_lock);
 
+       INIT_LIST_HEAD(&gt->lmem_userfault_list);
+       mutex_init(&gt->lmem_userfault_lock);
        INIT_LIST_HEAD(&gt->closed_vma);
        spin_lock_init(&gt->closed_lock);
 
@@ -58,14 +61,19 @@ static void __intel_gt_init_early(struct intel_gt *gt)
 }
 
 /* Preliminary initialization of Tile 0 */
-void intel_root_gt_init_early(struct drm_i915_private *i915)
+int intel_root_gt_init_early(struct drm_i915_private *i915)
 {
        struct intel_gt *gt = to_gt(i915);
 
        gt->i915 = i915;
        gt->uncore = &i915->uncore;
+       gt->irq_lock = drmm_kzalloc(&i915->drm, sizeof(*gt->irq_lock), GFP_KERNEL);
+       if (!gt->irq_lock)
+               return -ENOMEM;
 
-       __intel_gt_init_early(gt);
+       intel_gt_common_init_early(gt);
+
+       return 0;
 }
 
 static int intel_gt_probe_lmem(struct intel_gt *gt)
@@ -781,26 +789,25 @@ static int intel_gt_tile_setup(struct intel_gt *gt, phys_addr_t phys_addr)
        int ret;
 
        if (!gt_is_root(gt)) {
-               struct intel_uncore_mmio_debug *mmio_debug;
                struct intel_uncore *uncore;
+               spinlock_t *irq_lock;
 
-               uncore = kzalloc(sizeof(*uncore), GFP_KERNEL);
+               uncore = drmm_kzalloc(&gt->i915->drm, sizeof(*uncore), GFP_KERNEL);
                if (!uncore)
                        return -ENOMEM;
 
-               mmio_debug = kzalloc(sizeof(*mmio_debug), GFP_KERNEL);
-               if (!mmio_debug) {
-                       kfree(uncore);
+               irq_lock = drmm_kzalloc(&gt->i915->drm, sizeof(*irq_lock), GFP_KERNEL);
+               if (!irq_lock)
                        return -ENOMEM;
-               }
 
                gt->uncore = uncore;
-               gt->uncore->debug = mmio_debug;
+               gt->irq_lock = irq_lock;
 
-               __intel_gt_init_early(gt);
+               intel_gt_common_init_early(gt);
        }
 
        intel_uncore_init_early(gt->uncore, gt);
+       intel_wakeref_auto_init(&gt->userfault_wakeref, gt->uncore->rpm);
 
        ret = intel_uncore_setup_mmio(gt->uncore, phys_addr);
        if (ret)
@@ -811,24 +818,14 @@ static int intel_gt_tile_setup(struct intel_gt *gt, phys_addr_t phys_addr)
        return 0;
 }
 
-static void
-intel_gt_tile_cleanup(struct intel_gt *gt)
-{
-       intel_uncore_cleanup_mmio(gt->uncore);
-
-       if (!gt_is_root(gt)) {
-               kfree(gt->uncore->debug);
-               kfree(gt->uncore);
-               kfree(gt);
-       }
-}
-
 int intel_gt_probe_all(struct drm_i915_private *i915)
 {
        struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
        struct intel_gt *gt = &i915->gt0;
+       const struct intel_gt_definition *gtdef;
        phys_addr_t phys_addr;
        unsigned int mmio_bar;
+       unsigned int i;
        int ret;
 
        mmio_bar = GRAPHICS_VER(i915) == 2 ? GEN2_GTTMMADR_BAR : GTTMMADR_BAR;
@@ -839,14 +836,74 @@ int intel_gt_probe_all(struct drm_i915_private *i915)
         * and it has been already initialized early during probe
         * in i915_driver_probe()
         */
+       gt->i915 = i915;
+       gt->name = "Primary GT";
+       gt->info.engine_mask = RUNTIME_INFO(i915)->platform_engine_mask;
+
+       drm_dbg(&i915->drm, "Setting up %s\n", gt->name);
        ret = intel_gt_tile_setup(gt, phys_addr);
        if (ret)
                return ret;
 
        i915->gt[0] = gt;
 
-       /* TODO: add more tiles */
+       if (!HAS_EXTRA_GT_LIST(i915))
+               return 0;
+
+       for (i = 1, gtdef = &INTEL_INFO(i915)->extra_gt_list[i - 1];
+            gtdef->name != NULL;
+            i++, gtdef = &INTEL_INFO(i915)->extra_gt_list[i - 1]) {
+               gt = drmm_kzalloc(&i915->drm, sizeof(*gt), GFP_KERNEL);
+               if (!gt) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+
+               gt->i915 = i915;
+               gt->name = gtdef->name;
+               gt->type = gtdef->type;
+               gt->info.engine_mask = gtdef->engine_mask;
+               gt->info.id = i;
+
+               drm_dbg(&i915->drm, "Setting up %s\n", gt->name);
+               if (GEM_WARN_ON(range_overflows_t(resource_size_t,
+                                                 gtdef->mapping_base,
+                                                 SZ_16M,
+                                                 pci_resource_len(pdev, mmio_bar)))) {
+                       ret = -ENODEV;
+                       goto err;
+               }
+
+               switch (gtdef->type) {
+               case GT_TILE:
+                       ret = intel_gt_tile_setup(gt, phys_addr + gtdef->mapping_base);
+                       break;
+
+               case GT_MEDIA:
+                       ret = intel_sa_mediagt_setup(gt, phys_addr + gtdef->mapping_base,
+                                                    gtdef->gsi_offset);
+                       break;
+
+               case GT_PRIMARY:
+                       /* Primary GT should not appear in extra GT list */
+               default:
+                       MISSING_CASE(gtdef->type);
+                       ret = -ENODEV;
+               }
+
+               if (ret)
+                       goto err;
+
+               i915->gt[i] = gt;
+       }
+
        return 0;
+
+err:
+       i915_probe_error(i915, "Failed to initialize %s! (%d)\n", gtdef->name, ret);
+       intel_gt_release_all(i915);
+
+       return ret;
 }
 
 int intel_gt_tiles_init(struct drm_i915_private *i915)
@@ -869,10 +926,8 @@ void intel_gt_release_all(struct drm_i915_private *i915)
        struct intel_gt *gt;
        unsigned int id;
 
-       for_each_gt(gt, i915, id) {
-               intel_gt_tile_cleanup(gt);
+       for_each_gt(gt, i915, id)
                i915->gt[id] = NULL;
-       }
 }
 
 void intel_gt_info_print(const struct intel_gt_info *info,