]> Git Repo - J-linux.git/commitdiff
Merge tag 'drm-intel-next-2024-04-30' of https://anongit.freedesktop.org/git/drm...
authorDave Airlie <[email protected]>
Thu, 2 May 2024 04:30:27 +0000 (14:30 +1000)
committerDave Airlie <[email protected]>
Thu, 2 May 2024 04:30:31 +0000 (14:30 +1000)
Core DRM:
- Export drm_client_dev_unregister (Thomas Zimmermann)

Display i915:
- More initial work to make display code more independent from i915 (Jani)
- Convert i915/xe fbdev to DRM client (Thomas Zimmermann)
- VLV/CHV DPIO register cleanup (Ville)

Signed-off-by: Dave Airlie <[email protected]>
From: Rodrigo Vivi <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1  2 
drivers/gpu/drm/drm_client.c
drivers/gpu/drm/i915/gt/intel_workarounds.c
drivers/gpu/drm/i915/i915_driver.c
drivers/gpu/drm/xe/display/xe_display.c
drivers/gpu/drm/xe/xe_device.c

index 77fe217aeaf3697e12092254538340aa6fd30034,3d4f8b77d07890395b636c7b3a69db11c3dfd5d0..2803ac111bbd8ad5a069b7700832365175de76da
@@@ -172,6 -172,18 +172,18 @@@ void drm_client_release(struct drm_clie
  }
  EXPORT_SYMBOL(drm_client_release);
  
+ /**
+  * drm_client_dev_unregister - Unregister clients
+  * @dev: DRM device
+  *
+  * This function releases all clients by calling each client's
+  * &drm_client_funcs.unregister callback. The callback function
+  * is responsibe for releaseing all resources including the client
+  * itself.
+  *
+  * The helper drm_dev_unregister() calls this function. Drivers
+  * that use it don't need to call this function themselves.
+  */
  void drm_client_dev_unregister(struct drm_device *dev)
  {
        struct drm_client_dev *client, *tmp;
        }
        mutex_unlock(&dev->clientlist_mutex);
  }
+ EXPORT_SYMBOL(drm_client_dev_unregister);
  
  /**
   * drm_client_dev_hotplug - Send hotplug event to clients
@@@ -304,66 -317,6 +317,66 @@@ err_delete
        return ERR_PTR(ret);
  }
  
 +/**
 + * drm_client_buffer_vmap_local - Map DRM client buffer into address space
 + * @buffer: DRM client buffer
 + * @map_copy: Returns the mapped memory's address
 + *
 + * This function maps a client buffer into kernel address space. If the
 + * buffer is already mapped, it returns the existing mapping's address.
 + *
 + * Client buffer mappings are not ref'counted. Each call to
 + * drm_client_buffer_vmap_local() should be closely followed by a call to
 + * drm_client_buffer_vunmap_local(). See drm_client_buffer_vmap() for
 + * long-term mappings.
 + *
 + * The returned address is a copy of the internal value. In contrast to
 + * other vmap interfaces, you don't need it for the client's vunmap
 + * function. So you can modify it at will during blit and draw operations.
 + *
 + * Returns:
 + *    0 on success, or a negative errno code otherwise.
 + */
 +int drm_client_buffer_vmap_local(struct drm_client_buffer *buffer,
 +                               struct iosys_map *map_copy)
 +{
 +      struct drm_gem_object *gem = buffer->gem;
 +      struct iosys_map *map = &buffer->map;
 +      int ret;
 +
 +      drm_gem_lock(gem);
 +
 +      ret = drm_gem_vmap(gem, map);
 +      if (ret)
 +              goto err_drm_gem_vmap_unlocked;
 +      *map_copy = *map;
 +
 +      return 0;
 +
 +err_drm_gem_vmap_unlocked:
 +      drm_gem_unlock(gem);
 +      return 0;
 +}
 +EXPORT_SYMBOL(drm_client_buffer_vmap_local);
 +
 +/**
 + * drm_client_buffer_vunmap_local - Unmap DRM client buffer
 + * @buffer: DRM client buffer
 + *
 + * This function removes a client buffer's memory mapping established
 + * with drm_client_buffer_vunmap_local(). Calling this function is only
 + * required by clients that manage their buffer mappings by themselves.
 + */
 +void drm_client_buffer_vunmap_local(struct drm_client_buffer *buffer)
 +{
 +      struct drm_gem_object *gem = buffer->gem;
 +      struct iosys_map *map = &buffer->map;
 +
 +      drm_gem_vunmap(gem, map);
 +      drm_gem_unlock(gem);
 +}
 +EXPORT_SYMBOL(drm_client_buffer_vunmap_local);
 +
  /**
   * drm_client_buffer_vmap - Map DRM client buffer into address space
   * @buffer: DRM client buffer
@@@ -388,30 -341,24 +401,30 @@@ in
  drm_client_buffer_vmap(struct drm_client_buffer *buffer,
                       struct iosys_map *map_copy)
  {
 +      struct drm_gem_object *gem = buffer->gem;
        struct iosys_map *map = &buffer->map;
        int ret;
  
 -      /*
 -       * FIXME: The dependency on GEM here isn't required, we could
 -       * convert the driver handle to a dma-buf instead and use the
 -       * backend-agnostic dma-buf vmap support instead. This would
 -       * require that the handle2fd prime ioctl is reworked to pull the
 -       * fd_install step out of the driver backend hooks, to make that
 -       * final step optional for internal users.
 -       */
 -      ret = drm_gem_vmap_unlocked(buffer->gem, map);
 +      drm_gem_lock(gem);
 +
 +      ret = drm_gem_pin_locked(gem);
        if (ret)
 -              return ret;
 +              goto err_drm_gem_pin_locked;
 +      ret = drm_gem_vmap(gem, map);
 +      if (ret)
 +              goto err_drm_gem_vmap;
 +
 +      drm_gem_unlock(gem);
  
        *map_copy = *map;
  
        return 0;
 +
 +err_drm_gem_vmap:
 +      drm_gem_unpin_locked(buffer->gem);
 +err_drm_gem_pin_locked:
 +      drm_gem_unlock(gem);
 +      return ret;
  }
  EXPORT_SYMBOL(drm_client_buffer_vmap);
  
   */
  void drm_client_buffer_vunmap(struct drm_client_buffer *buffer)
  {
 +      struct drm_gem_object *gem = buffer->gem;
        struct iosys_map *map = &buffer->map;
  
 -      drm_gem_vunmap_unlocked(buffer->gem, map);
 +      drm_gem_lock(gem);
 +      drm_gem_vunmap(gem, map);
 +      drm_gem_unpin_locked(gem);
 +      drm_gem_unlock(gem);
  }
  EXPORT_SYMBOL(drm_client_buffer_vunmap);
  
index 68b6aa11bcf7db8efe0433ab39968dcc92369288,eca90b5552ae8260f77586d312f05a5e47bf7d65..40e79f0dc25701d6281b9c45014e1b3f799f4ec3
  #include "intel_engine_regs.h"
  #include "intel_gpu_commands.h"
  #include "intel_gt.h"
 +#include "intel_gt_ccs_mode.h"
  #include "intel_gt_mcr.h"
  #include "intel_gt_print.h"
  #include "intel_gt_regs.h"
  #include "intel_ring.h"
  #include "intel_workarounds.h"
  
+ #include "display/intel_fbc_regs.h"
  /**
   * DOC: Hardware workarounds
   *
@@@ -52,8 -53,7 +54,8 @@@
   *   registers belonging to BCS, VCS or VECS should be implemented in
   *   xcs_engine_wa_init(). Workarounds for registers not belonging to a specific
   *   engine's MMIO range but that are part of of the common RCS/CCS reset domain
 - *   should be implemented in general_render_compute_wa_init().
 + *   should be implemented in general_render_compute_wa_init(). The settings
 + *   about the CCS load balancing should be added in ccs_engine_wa_mode().
   *
   * - GT workarounds: the list of these WAs is applied whenever these registers
   *   revert to their default values: on GPU reset, suspend/resume [1]_, etc.
@@@ -2700,28 -2700,6 +2702,28 @@@ add_render_compute_tuning_settings(stru
                wa_write_clr(wal, GEN8_GARBCNTL, GEN12_BUS_HASH_CTL_BIT_EXC);
  }
  
 +static void ccs_engine_wa_mode(struct intel_engine_cs *engine, struct i915_wa_list *wal)
 +{
 +      struct intel_gt *gt = engine->gt;
 +
 +      if (!IS_DG2(gt->i915))
 +              return;
 +
 +      /*
 +       * Wa_14019159160: This workaround, along with others, leads to
 +       * significant challenges in utilizing load balancing among the
 +       * CCS slices. Consequently, an architectural decision has been
 +       * made to completely disable automatic CCS load balancing.
 +       */
 +      wa_masked_en(wal, GEN12_RCU_MODE, XEHP_RCU_MODE_FIXED_SLICE_CCS_MODE);
 +
 +      /*
 +       * After having disabled automatic load balancing we need to
 +       * assign all slices to a single CCS. We will call it CCS mode 1
 +       */
 +      intel_gt_apply_ccs_mode(gt);
 +}
 +
  /*
   * The workarounds in this function apply to shared registers in
   * the general render reset domain that aren't tied to a
@@@ -2760,14 -2738,10 +2762,14 @@@ general_render_compute_wa_init(struct i
  
        if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_B0, STEP_FOREVER) ||
            IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_B0, STEP_FOREVER) ||
 -          IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 74), IP_VER(12, 74)))
 +          IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 74), IP_VER(12, 74))) {
                /* Wa_14017856879 */
                wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN3, MTL_DISABLE_FIX_FOR_EOT_FLUSH);
  
 +              /* Wa_14020495402 */
 +              wa_mcr_masked_en(wal, GEN8_ROW_CHICKEN2, XELPG_DISABLE_TDL_SVHS_GATING);
 +      }
 +
        if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||
            IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_A0, STEP_B0))
                /*
                /* Wa_14015227452:dg2,pvc */
                wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN4, XEHP_DIS_BBL_SYSPIPE);
  
 -              /* Wa_16015675438:dg2,pvc */
 -              wa_masked_en(wal, FF_SLICE_CS_CHICKEN2, GEN12_PERF_FIX_BALANCING_CFE_DISABLE);
 -
                /*
                 * Wa_16011620976:dg2_g11
                 * Wa_22015475538:dg2
@@@ -2854,10 -2831,8 +2856,10 @@@ engine_init_workarounds(struct intel_en
         * to a single RCS/CCS engine's workaround list since
         * they're reset as part of the general render domain reset.
         */
 -      if (engine->flags & I915_ENGINE_FIRST_RENDER_COMPUTE)
 +      if (engine->flags & I915_ENGINE_FIRST_RENDER_COMPUTE) {
                general_render_compute_wa_init(engine, wal);
 +              ccs_engine_wa_mode(engine, wal);
 +      }
  
        if (engine->class == COMPUTE_CLASS)
                ccs_engine_wa_init(engine, wal);
index 622a24305bc211e93fe782ac9c97881b88213d5f,6551c806e2ae0cbb78d13a3409fca6ffcd9106ad..161b21eff694310a511e518b861e9c81070982ee
@@@ -202,7 -202,7 +202,7 @@@ static void sanitize_gpu(struct drm_i91
                unsigned int i;
  
                for_each_gt(gt, i915, i)
 -                      __intel_gt_reset(gt, ALL_ENGINES);
 +                      intel_gt_reset_all_engines(gt);
        }
  }
  
@@@ -920,27 -920,6 +920,6 @@@ static int i915_driver_open(struct drm_
        return 0;
  }
  
- /**
-  * i915_driver_lastclose - clean up after all DRM clients have exited
-  * @dev: DRM device
-  *
-  * Take care of cleaning up after all DRM clients have exited.  In the
-  * mode setting case, we want to restore the kernel's initial mode (just
-  * in case the last client left us in a bad state).
-  *
-  * Additionally, in the non-mode setting case, we'll tear down the GTT
-  * and DMA structures, since the kernel won't be using them, and clea
-  * up any GEM state.
-  */
- static void i915_driver_lastclose(struct drm_device *dev)
- {
-       struct drm_i915_private *i915 = to_i915(dev);
-       intel_fbdev_restore_mode(i915);
-       vga_switcheroo_process_delayed_switch();
- }
  static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
  {
        struct drm_i915_file_private *file_priv = file->driver_priv;
@@@ -1831,7 -1810,6 +1810,6 @@@ static const struct drm_driver i915_drm
            DRIVER_SYNCOBJ_TIMELINE,
        .release = i915_driver_release,
        .open = i915_driver_open,
-       .lastclose = i915_driver_lastclose,
        .postclose = i915_driver_postclose,
        .show_fdinfo = PTR_IF(IS_ENABLED(CONFIG_PROC_FS), i915_drm_client_fdinfo),
  
index 63b27fbcdaca36baad7f7f24238ba239ca389b7f,ca5cbe1d8a03bb7703e6d66ecd74bfe029a9c6fa..0de0566e5b394a6e136f8c2afa809d4048721499
@@@ -51,14 -51,6 +51,6 @@@ bool xe_display_driver_probe_defer(stru
        return intel_display_driver_probe_defer(pdev);
  }
  
- static void xe_display_last_close(struct drm_device *dev)
- {
-       struct xe_device *xe = to_xe_device(dev);
-       if (xe->info.enable_display)
-               intel_fbdev_restore_mode(to_xe_device(dev));
- }
  /**
   * xe_display_driver_set_hooks - Add driver flags and hooks for display
   * @driver: DRM device driver
@@@ -73,7 -65,6 +65,6 @@@ void xe_display_driver_set_hooks(struc
                return;
  
        driver->driver_features |= DRIVER_MODESET | DRIVER_ATOMIC;
-       driver->lastclose = xe_display_last_close;
  }
  
  static void unset_display_features(struct xe_device *xe)
@@@ -101,14 -92,25 +92,14 @@@ static void display_destroy(struct drm_
   */
  int xe_display_create(struct xe_device *xe)
  {
 -      int err;
 -
        spin_lock_init(&xe->display.fb_tracking.lock);
  
        xe->display.hotplug.dp_wq = alloc_ordered_workqueue("xe-dp", 0);
  
        drmm_mutex_init(&xe->drm, &xe->sb_lock);
 -      drmm_mutex_init(&xe->drm, &xe->display.backlight.lock);
 -      drmm_mutex_init(&xe->drm, &xe->display.audio.mutex);
 -      drmm_mutex_init(&xe->drm, &xe->display.wm.wm_mutex);
 -      drmm_mutex_init(&xe->drm, &xe->display.pps.mutex);
 -      drmm_mutex_init(&xe->drm, &xe->display.hdcp.hdcp_mutex);
        xe->enabled_irq_mask = ~0;
  
 -      err = drmm_add_action_or_reset(&xe->drm, display_destroy, NULL);
 -      if (err)
 -              return err;
 -
 -      return 0;
 +      return drmm_add_action_or_reset(&xe->drm, display_destroy, NULL);
  }
  
  static void xe_display_fini_nommio(struct drm_device *dev, void *dummy)
@@@ -212,9 -214,7 +203,7 @@@ void xe_display_fini(struct xe_device *
        if (!xe->info.enable_display)
                return;
  
-       /* poll work can call into fbdev, hence clean that up afterwards */
        intel_hpd_poll_fini(xe);
-       intel_fbdev_fini(xe);
  
        intel_hdcp_component_fini(xe);
        intel_audio_deinit(xe);
index 55bbc8b8df159ae3667df8c82c75eaca4bad031d,9682a71b83a3ec7c907ed8813c8e79deac4814db..5ef9b50a20d01a425aa7a329c9176008fa5d0051
@@@ -9,6 -9,7 +9,7 @@@
  
  #include <drm/drm_aperture.h>
  #include <drm/drm_atomic_helper.h>
+ #include <drm/drm_client.h>
  #include <drm/drm_gem_ttm_helper.h>
  #include <drm/drm_ioctl.h>
  #include <drm/drm_managed.h>
@@@ -20,7 -21,6 +21,7 @@@
  #include "regs/xe_regs.h"
  #include "xe_bo.h"
  #include "xe_debugfs.h"
 +#include "xe_devcoredump.h"
  #include "xe_dma_buf.h"
  #include "xe_drm_client.h"
  #include "xe_drv.h"
  #include "xe_vm.h"
  #include "xe_wait_user_fence.h"
  
 -#ifdef CONFIG_LOCKDEP
 -struct lockdep_map xe_device_mem_access_lockdep_map = {
 -      .name = "xe_device_mem_access_lockdep_map"
 -};
 -#endif
 -
  static int xe_file_open(struct drm_device *dev, struct drm_file *file)
  {
        struct xe_device *xe = to_xe_device(dev);
@@@ -131,48 -137,15 +132,48 @@@ static const struct drm_ioctl_desc xe_i
                          DRM_RENDER_ALLOW),
  };
  
 +static long xe_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 +{
 +      struct drm_file *file_priv = file->private_data;
 +      struct xe_device *xe = to_xe_device(file_priv->minor->dev);
 +      long ret;
 +
 +      ret = xe_pm_runtime_get_ioctl(xe);
 +      if (ret >= 0)
 +              ret = drm_ioctl(file, cmd, arg);
 +      xe_pm_runtime_put(xe);
 +
 +      return ret;
 +}
 +
 +#ifdef CONFIG_COMPAT
 +static long xe_drm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 +{
 +      struct drm_file *file_priv = file->private_data;
 +      struct xe_device *xe = to_xe_device(file_priv->minor->dev);
 +      long ret;
 +
 +      ret = xe_pm_runtime_get_ioctl(xe);
 +      if (ret >= 0)
 +              ret = drm_compat_ioctl(file, cmd, arg);
 +      xe_pm_runtime_put(xe);
 +
 +      return ret;
 +}
 +#else
 +/* similarly to drm_compat_ioctl, let's it be assigned to .compat_ioct unconditionally */
 +#define xe_drm_compat_ioctl NULL
 +#endif
 +
  static const struct file_operations xe_driver_fops = {
        .owner = THIS_MODULE,
        .open = drm_open,
        .release = drm_release_noglobal,
 -      .unlocked_ioctl = drm_ioctl,
 +      .unlocked_ioctl = xe_drm_ioctl,
        .mmap = drm_gem_mmap,
        .poll = drm_poll,
        .read = drm_read,
 -      .compat_ioctl = drm_compat_ioctl,
 +      .compat_ioctl = xe_drm_compat_ioctl,
        .llseek = noop_llseek,
  #ifdef CONFIG_PROC_FS
        .show_fdinfo = drm_show_fdinfo,
@@@ -221,9 -194,6 +222,9 @@@ static void xe_device_destroy(struct dr
  {
        struct xe_device *xe = to_xe_device(dev);
  
 +      if (xe->preempt_fence_wq)
 +              destroy_workqueue(xe->preempt_fence_wq);
 +
        if (xe->ordered_wq)
                destroy_workqueue(xe->ordered_wq);
  
@@@ -289,15 -259,9 +290,15 @@@ struct xe_device *xe_device_create(stru
        INIT_LIST_HEAD(&xe->pinned.external_vram);
        INIT_LIST_HEAD(&xe->pinned.evicted);
  
 +      xe->preempt_fence_wq = alloc_ordered_workqueue("xe-preempt-fence-wq", 0);
        xe->ordered_wq = alloc_ordered_workqueue("xe-ordered-wq", 0);
        xe->unordered_wq = alloc_workqueue("xe-unordered-wq", 0, 0);
 -      if (!xe->ordered_wq || !xe->unordered_wq) {
 +      if (!xe->ordered_wq || !xe->unordered_wq ||
 +          !xe->preempt_fence_wq) {
 +              /*
 +               * Cleanup done in xe_device_destroy via
 +               * drmm_add_action_or_reset register above
 +               */
                drm_err(&xe->drm, "Failed to allocate xe workqueues\n");
                err = -ENOMEM;
                goto err;
@@@ -417,70 -381,8 +418,70 @@@ mask_err
        return err;
  }
  
 -/*
 - * Initialize MMIO resources that don't require any knowledge about tile count.
 +static bool verify_lmem_ready(struct xe_gt *gt)
 +{
 +      u32 val = xe_mmio_read32(gt, GU_CNTL) & LMEM_INIT;
 +
 +      return !!val;
 +}
 +
 +static int wait_for_lmem_ready(struct xe_device *xe)
 +{
 +      struct xe_gt *gt = xe_root_mmio_gt(xe);
 +      unsigned long timeout, start;
 +
 +      if (!IS_DGFX(xe))
 +              return 0;
 +
 +      if (IS_SRIOV_VF(xe))
 +              return 0;
 +
 +      if (verify_lmem_ready(gt))
 +              return 0;
 +
 +      drm_dbg(&xe->drm, "Waiting for lmem initialization\n");
 +
 +      start = jiffies;
 +      timeout = start + msecs_to_jiffies(60 * 1000); /* 60 sec! */
 +
 +      do {
 +              if (signal_pending(current))
 +                      return -EINTR;
 +
 +              /*
 +               * The boot firmware initializes local memory and
 +               * assesses its health. If memory training fails,
 +               * the punit will have been instructed to keep the GT powered
 +               * down.we won't be able to communicate with it
 +               *
 +               * If the status check is done before punit updates the register,
 +               * it can lead to the system being unusable.
 +               * use a timeout and defer the probe to prevent this.
 +               */
 +              if (time_after(jiffies, timeout)) {
 +                      drm_dbg(&xe->drm, "lmem not initialized by firmware\n");
 +                      return -EPROBE_DEFER;
 +              }
 +
 +              msleep(20);
 +
 +      } while (!verify_lmem_ready(gt));
 +
 +      drm_dbg(&xe->drm, "lmem ready after %ums",
 +              jiffies_to_msecs(jiffies - start));
 +
 +      return 0;
 +}
 +
 +/**
 + * xe_device_probe_early: Device early probe
 + * @xe: xe device instance
 + *
 + * Initialize MMIO resources that don't require any
 + * knowledge about tile count. Also initialize pcode and
 + * check vram initialization on root tile.
 + *
 + * Return: 0 on success, error code on failure
   */
  int xe_device_probe_early(struct xe_device *xe)
  {
        if (err)
                return err;
  
 -      err = xe_mmio_root_tile_init(xe);
 +      xe_sriov_probe_early(xe);
 +
 +      err = xe_pcode_probe_early(xe);
 +      if (err)
 +              return err;
 +
 +      err = wait_for_lmem_ready(xe);
        if (err)
                return err;
  
@@@ -574,15 -470,15 +575,15 @@@ int xe_device_probe(struct xe_device *x
                        return err;
        }
  
 +      err = xe_devcoredump_init(xe);
 +      if (err)
 +              return err;
        err = drmm_add_action_or_reset(&xe->drm, xe_driver_flr_fini, xe);
        if (err)
                return err;
  
 -      for_each_gt(gt, xe, id) {
 -              err = xe_pcode_probe(gt);
 -              if (err)
 -                      return err;
 -      }
 +      for_each_gt(gt, xe, id)
 +              xe_pcode_init(gt);
  
        err = xe_display_init_noirq(xe);
        if (err)
  
        xe_hwmon_register(xe);
  
 -      err = drmm_add_action_or_reset(&xe->drm, xe_device_sanitize, xe);
 -      if (err)
 -              return err;
 -
 -      return 0;
 +      return drmm_add_action_or_reset(&xe->drm, xe_device_sanitize, xe);
  
  err_fini_display:
        xe_display_driver_remove(xe);
@@@ -713,20 -613,87 +714,20 @@@ u32 xe_device_ccs_bytes(struct xe_devic
                DIV_ROUND_UP_ULL(size, NUM_BYTES_PER_CCS_BYTE(xe)) : 0;
  }
  
 -bool xe_device_mem_access_ongoing(struct xe_device *xe)
 -{
 -      if (xe_pm_read_callback_task(xe) != NULL)
 -              return true;
 -
 -      return atomic_read(&xe->mem_access.ref);
 -}
 -
 +/**
 + * xe_device_assert_mem_access - Inspect the current runtime_pm state.
 + * @xe: xe device instance
 + *
 + * To be used before any kind of memory access. It will splat a debug warning
 + * if the device is currently sleeping. But it doesn't guarantee in any way
 + * that the device is going to remain awake. Xe PM runtime get and put
 + * functions might be added to the outer bound of the memory access, while
 + * this check is intended for inner usage to splat some warning if the worst
 + * case has just happened.
 + */
  void xe_device_assert_mem_access(struct xe_device *xe)
  {
 -      XE_WARN_ON(!xe_device_mem_access_ongoing(xe));
 -}
 -
 -bool xe_device_mem_access_get_if_ongoing(struct xe_device *xe)
 -{
 -      bool active;
 -
 -      if (xe_pm_read_callback_task(xe) == current)
 -              return true;
 -
 -      active = xe_pm_runtime_get_if_active(xe);
 -      if (active) {
 -              int ref = atomic_inc_return(&xe->mem_access.ref);
 -
 -              xe_assert(xe, ref != S32_MAX);
 -      }
 -
 -      return active;
 -}
 -
 -void xe_device_mem_access_get(struct xe_device *xe)
 -{
 -      int ref;
 -
 -      /*
 -       * This looks racy, but should be fine since the pm_callback_task only
 -       * transitions from NULL -> current (and back to NULL again), during the
 -       * runtime_resume() or runtime_suspend() callbacks, for which there can
 -       * only be a single one running for our device. We only need to prevent
 -       * recursively calling the runtime_get or runtime_put from those
 -       * callbacks, as well as preventing triggering any access_ongoing
 -       * asserts.
 -       */
 -      if (xe_pm_read_callback_task(xe) == current)
 -              return;
 -
 -      /*
 -       * Since the resume here is synchronous it can be quite easy to deadlock
 -       * if we are not careful. Also in practice it might be quite timing
 -       * sensitive to ever see the 0 -> 1 transition with the callers locks
 -       * held, so deadlocks might exist but are hard for lockdep to ever see.
 -       * With this in mind, help lockdep learn about the potentially scary
 -       * stuff that can happen inside the runtime_resume callback by acquiring
 -       * a dummy lock (it doesn't protect anything and gets compiled out on
 -       * non-debug builds).  Lockdep then only needs to see the
 -       * mem_access_lockdep_map -> runtime_resume callback once, and then can
 -       * hopefully validate all the (callers_locks) -> mem_access_lockdep_map.
 -       * For example if the (callers_locks) are ever grabbed in the
 -       * runtime_resume callback, lockdep should give us a nice splat.
 -       */
 -      lock_map_acquire(&xe_device_mem_access_lockdep_map);
 -      lock_map_release(&xe_device_mem_access_lockdep_map);
 -
 -      xe_pm_runtime_get(xe);
 -      ref = atomic_inc_return(&xe->mem_access.ref);
 -
 -      xe_assert(xe, ref != S32_MAX);
 -
 -}
 -
 -void xe_device_mem_access_put(struct xe_device *xe)
 -{
 -      int ref;
 -
 -      if (xe_pm_read_callback_task(xe) == current)
 -              return;
 -
 -      ref = atomic_dec_return(&xe->mem_access.ref);
 -      xe_pm_runtime_put(xe);
 -
 -      xe_assert(xe, ref >= 0);
 +      xe_assert(xe, !xe_pm_runtime_suspended(xe));
  }
  
  void xe_device_snapshot_print(struct xe_device *xe, struct drm_printer *p)
This page took 0.092792 seconds and 4 git commands to generate.