]> Git Repo - linux.git/commitdiff
Backmerge i915 security patches from commit 'ea0b163b13ff' into drm-next
authorDave Airlie <[email protected]>
Thu, 14 Nov 2019 01:06:01 +0000 (11:06 +1000)
committerDave Airlie <[email protected]>
Thu, 14 Nov 2019 01:09:06 +0000 (11:09 +1000)
This backmerges the branch that ended up in Linus' tree. It removes
all the changes for the rc6 patches from Linus' tree in favour of
a patch that is based on a large refactor that occured.

Otherwise it all looks good.

Signed-off-by: Dave Airlie <[email protected]>
1  2 
drivers/gpu/drm/i915/gem/i915_gem_context.c
drivers/gpu/drm/i915/gem/i915_gem_context_types.h
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
drivers/gpu/drm/i915/gt/intel_engine_types.h
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_getparam.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_pm.c

index de6e55af82cf71a49edf2f4b9538d207e6cb2e5d,e41fd94ae5a9d98c76bc84fe3de471408316ef54..138c8e33d26b4ce34f9b647720c2a1fb5e47337d
  
  #include <drm/i915_drm.h>
  
 -#include "gt/intel_lrc_reg.h"
 +#include "gt/intel_engine_heartbeat.h"
  #include "gt/intel_engine_user.h"
 +#include "gt/intel_lrc_reg.h"
 +#include "gt/intel_ring.h"
  
  #include "i915_gem_context.h"
  #include "i915_globals.h"
@@@ -169,6 -167,97 +169,6 @@@ lookup_user_engine(struct i915_gem_cont
        return i915_gem_context_get_engine(ctx, idx);
  }
  
 -static inline int new_hw_id(struct drm_i915_private *i915, gfp_t gfp)
 -{
 -      unsigned int max;
 -
 -      lockdep_assert_held(&i915->contexts.mutex);
 -
 -      if (INTEL_GEN(i915) >= 12)
 -              max = GEN12_MAX_CONTEXT_HW_ID;
 -      else if (INTEL_GEN(i915) >= 11)
 -              max = GEN11_MAX_CONTEXT_HW_ID;
 -      else if (USES_GUC_SUBMISSION(i915))
 -              /*
 -               * When using GuC in proxy submission, GuC consumes the
 -               * highest bit in the context id to indicate proxy submission.
 -               */
 -              max = MAX_GUC_CONTEXT_HW_ID;
 -      else
 -              max = MAX_CONTEXT_HW_ID;
 -
 -      return ida_simple_get(&i915->contexts.hw_ida, 0, max, gfp);
 -}
 -
 -static int steal_hw_id(struct drm_i915_private *i915)
 -{
 -      struct i915_gem_context *ctx, *cn;
 -      LIST_HEAD(pinned);
 -      int id = -ENOSPC;
 -
 -      lockdep_assert_held(&i915->contexts.mutex);
 -
 -      list_for_each_entry_safe(ctx, cn,
 -                               &i915->contexts.hw_id_list, hw_id_link) {
 -              if (atomic_read(&ctx->hw_id_pin_count)) {
 -                      list_move_tail(&ctx->hw_id_link, &pinned);
 -                      continue;
 -              }
 -
 -              GEM_BUG_ON(!ctx->hw_id); /* perma-pinned kernel context */
 -              list_del_init(&ctx->hw_id_link);
 -              id = ctx->hw_id;
 -              break;
 -      }
 -
 -      /*
 -       * Remember how far we got up on the last repossesion scan, so the
 -       * list is kept in a "least recently scanned" order.
 -       */
 -      list_splice_tail(&pinned, &i915->contexts.hw_id_list);
 -      return id;
 -}
 -
 -static int assign_hw_id(struct drm_i915_private *i915, unsigned int *out)
 -{
 -      int ret;
 -
 -      lockdep_assert_held(&i915->contexts.mutex);
 -
 -      /*
 -       * We prefer to steal/stall ourselves and our users over that of the
 -       * entire system. That may be a little unfair to our users, and
 -       * even hurt high priority clients. The choice is whether to oomkill
 -       * something else, or steal a context id.
 -       */
 -      ret = new_hw_id(i915, GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
 -      if (unlikely(ret < 0)) {
 -              ret = steal_hw_id(i915);
 -              if (ret < 0) /* once again for the correct errno code */
 -                      ret = new_hw_id(i915, GFP_KERNEL);
 -              if (ret < 0)
 -                      return ret;
 -      }
 -
 -      *out = ret;
 -      return 0;
 -}
 -
 -static void release_hw_id(struct i915_gem_context *ctx)
 -{
 -      struct drm_i915_private *i915 = ctx->i915;
 -
 -      if (list_empty(&ctx->hw_id_link))
 -              return;
 -
 -      mutex_lock(&i915->contexts.mutex);
 -      if (!list_empty(&ctx->hw_id_link)) {
 -              ida_simple_remove(&i915->contexts.hw_ida, ctx->hw_id);
 -              list_del_init(&ctx->hw_id_link);
 -      }
 -      mutex_unlock(&i915->contexts.mutex);
 -}
 -
  static void __free_engines(struct i915_gem_engines *e, unsigned int count)
  {
        while (count--) {
@@@ -205,239 -294,103 +205,241 @@@ static struct i915_gem_engines *default
        for_each_engine(engine, gt, id) {
                struct intel_context *ce;
  
 +              if (engine->legacy_idx == INVALID_ENGINE)
 +                      continue;
 +
 +              GEM_BUG_ON(engine->legacy_idx >= I915_NUM_ENGINES);
 +              GEM_BUG_ON(e->engines[engine->legacy_idx]);
 +
                ce = intel_context_create(ctx, engine);
                if (IS_ERR(ce)) {
 -                      __free_engines(e, id);
 +                      __free_engines(e, e->num_engines + 1);
                        return ERR_CAST(ce);
                }
  
 -              e->engines[id] = ce;
 -              e->num_engines = id + 1;
 +              e->engines[engine->legacy_idx] = ce;
 +              e->num_engines = max(e->num_engines, engine->legacy_idx);
        }
 +      e->num_engines++;
  
        return e;
  }
  
  static void i915_gem_context_free(struct i915_gem_context *ctx)
  {
 -      lockdep_assert_held(&ctx->i915->drm.struct_mutex);
        GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
  
 -      release_hw_id(ctx);
 -      if (ctx->vm)
 -              i915_vm_put(ctx->vm);
 +      spin_lock(&ctx->i915->gem.contexts.lock);
 +      list_del(&ctx->link);
 +      spin_unlock(&ctx->i915->gem.contexts.lock);
  
        free_engines(rcu_access_pointer(ctx->engines));
        mutex_destroy(&ctx->engines_mutex);
  
+       kfree(ctx->jump_whitelist);
        if (ctx->timeline)
                intel_timeline_put(ctx->timeline);
  
        kfree(ctx->name);
        put_pid(ctx->pid);
  
 -      list_del(&ctx->link);
        mutex_destroy(&ctx->mutex);
  
        kfree_rcu(ctx, rcu);
  }
  
 -static void contexts_free(struct drm_i915_private *i915)
 +static void contexts_free_all(struct llist_node *list)
  {
 -      struct llist_node *freed = llist_del_all(&i915->contexts.free_list);
        struct i915_gem_context *ctx, *cn;
  
 -      lockdep_assert_held(&i915->drm.struct_mutex);
 -
 -      llist_for_each_entry_safe(ctx, cn, freed, free_link)
 +      llist_for_each_entry_safe(ctx, cn, list, free_link)
                i915_gem_context_free(ctx);
  }
  
 -static void contexts_free_first(struct drm_i915_private *i915)
 +static void contexts_flush_free(struct i915_gem_contexts *gc)
  {
 -      struct i915_gem_context *ctx;
 -      struct llist_node *freed;
 -
 -      lockdep_assert_held(&i915->drm.struct_mutex);
 -
 -      freed = llist_del_first(&i915->contexts.free_list);
 -      if (!freed)
 -              return;
 -
 -      ctx = container_of(freed, typeof(*ctx), free_link);
 -      i915_gem_context_free(ctx);
 +      contexts_free_all(llist_del_all(&gc->free_list));
  }
  
  static void contexts_free_worker(struct work_struct *work)
  {
 -      struct drm_i915_private *i915 =
 -              container_of(work, typeof(*i915), contexts.free_work);
 +      struct i915_gem_contexts *gc =
 +              container_of(work, typeof(*gc), free_work);
  
 -      mutex_lock(&i915->drm.struct_mutex);
 -      contexts_free(i915);
 -      mutex_unlock(&i915->drm.struct_mutex);
 +      contexts_flush_free(gc);
  }
  
  void i915_gem_context_release(struct kref *ref)
  {
        struct i915_gem_context *ctx = container_of(ref, typeof(*ctx), ref);
 -      struct drm_i915_private *i915 = ctx->i915;
 +      struct i915_gem_contexts *gc = &ctx->i915->gem.contexts;
  
        trace_i915_context_free(ctx);
 -      if (llist_add(&ctx->free_link, &i915->contexts.free_list))
 -              queue_work(i915->wq, &i915->contexts.free_work);
 +      if (llist_add(&ctx->free_link, &gc->free_list))
 +              schedule_work(&gc->free_work);
  }
  
 -static void context_close(struct i915_gem_context *ctx)
 +static inline struct i915_gem_engines *
 +__context_engines_static(const struct i915_gem_context *ctx)
  {
 -      mutex_lock(&ctx->mutex);
 +      return rcu_dereference_protected(ctx->engines, true);
 +}
  
 -      i915_gem_context_set_closed(ctx);
 -      ctx->file_priv = ERR_PTR(-EBADF);
 +static bool __reset_engine(struct intel_engine_cs *engine)
 +{
 +      struct intel_gt *gt = engine->gt;
 +      bool success = false;
 +
 +      if (!intel_has_reset_engine(gt))
 +              return false;
 +
 +      if (!test_and_set_bit(I915_RESET_ENGINE + engine->id,
 +                            &gt->reset.flags)) {
 +              success = intel_engine_reset(engine, NULL) == 0;
 +              clear_and_wake_up_bit(I915_RESET_ENGINE + engine->id,
 +                                    &gt->reset.flags);
 +      }
 +
 +      return success;
 +}
 +
 +static void __reset_context(struct i915_gem_context *ctx,
 +                          struct intel_engine_cs *engine)
 +{
 +      intel_gt_handle_error(engine->gt, engine->mask, 0,
 +                            "context closure in %s", ctx->name);
 +}
 +
 +static bool __cancel_engine(struct intel_engine_cs *engine)
 +{
 +      /*
 +       * Send a "high priority pulse" down the engine to cause the
 +       * current request to be momentarily preempted. (If it fails to
 +       * be preempted, it will be reset). As we have marked our context
 +       * as banned, any incomplete request, including any running, will
 +       * be skipped following the preemption.
 +       *
 +       * If there is no hangchecking (one of the reasons why we try to
 +       * cancel the context) and no forced preemption, there may be no
 +       * means by which we reset the GPU and evict the persistent hog.
 +       * Ergo if we are unable to inject a preemptive pulse that can
 +       * kill the banned context, we fallback to doing a local reset
 +       * instead.
 +       */
 +      if (IS_ACTIVE(CONFIG_DRM_I915_PREEMPT_TIMEOUT) &&
 +          !intel_engine_pulse(engine))
 +              return true;
 +
 +      /* If we are unable to send a pulse, try resetting this engine. */
 +      return __reset_engine(engine);
 +}
 +
 +static struct intel_engine_cs *__active_engine(struct i915_request *rq)
 +{
 +      struct intel_engine_cs *engine, *locked;
 +
 +      /*
 +       * Serialise with __i915_request_submit() so that it sees
 +       * is-banned?, or we know the request is already inflight.
 +       */
 +      locked = READ_ONCE(rq->engine);
 +      spin_lock_irq(&locked->active.lock);
 +      while (unlikely(locked != (engine = READ_ONCE(rq->engine)))) {
 +              spin_unlock(&locked->active.lock);
 +              spin_lock(&engine->active.lock);
 +              locked = engine;
 +      }
 +
 +      engine = NULL;
 +      if (i915_request_is_active(rq) && !rq->fence.error)
 +              engine = rq->engine;
 +
 +      spin_unlock_irq(&locked->active.lock);
 +
 +      return engine;
 +}
 +
 +static struct intel_engine_cs *active_engine(struct intel_context *ce)
 +{
 +      struct intel_engine_cs *engine = NULL;
 +      struct i915_request *rq;
 +
 +      if (!ce->timeline)
 +              return NULL;
 +
 +      rcu_read_lock();
 +      list_for_each_entry_reverse(rq, &ce->timeline->requests, link) {
 +              if (i915_request_completed(rq))
 +                      break;
 +
 +              /* Check with the backend if the request is inflight */
 +              engine = __active_engine(rq);
 +              if (engine)
 +                      break;
 +      }
 +      rcu_read_unlock();
 +
 +      return engine;
 +}
 +
 +static void kill_context(struct i915_gem_context *ctx)
 +{
 +      struct i915_gem_engines_iter it;
 +      struct intel_context *ce;
 +
 +      /*
 +       * If we are already banned, it was due to a guilty request causing
 +       * a reset and the entire context being evicted from the GPU.
 +       */
 +      if (i915_gem_context_is_banned(ctx))
 +              return;
 +
 +      i915_gem_context_set_banned(ctx);
  
        /*
 -       * This context will never again be assinged to HW, so we can
 -       * reuse its ID for the next context.
 +       * Map the user's engine back to the actual engines; one virtual
 +       * engine will be mapped to multiple engines, and using ctx->engine[]
 +       * the same engine may be have multiple instances in the user's map.
 +       * However, we only care about pending requests, so only include
 +       * engines on which there are incomplete requests.
         */
 -      release_hw_id(ctx);
 +      for_each_gem_engine(ce, __context_engines_static(ctx), it) {
 +              struct intel_engine_cs *engine;
 +
 +              /*
 +               * Check the current active state of this context; if we
 +               * are currently executing on the GPU we need to evict
 +               * ourselves. On the other hand, if we haven't yet been
 +               * submitted to the GPU or if everything is complete,
 +               * we have nothing to do.
 +               */
 +              engine = active_engine(ce);
 +
 +              /* First attempt to gracefully cancel the context */
 +              if (engine && !__cancel_engine(engine))
 +                      /*
 +                       * If we are unable to send a preemptive pulse to bump
 +                       * the context from the GPU, we have to resort to a full
 +                       * reset. We hope the collateral damage is worth it.
 +                       */
 +                      __reset_context(ctx, engine);
 +      }
 +}
 +
 +static void context_close(struct i915_gem_context *ctx)
 +{
 +      struct i915_address_space *vm;
 +
 +      i915_gem_context_set_closed(ctx);
 +
 +      mutex_lock(&ctx->mutex);
 +
 +      vm = i915_gem_context_vm(ctx);
 +      if (vm)
 +              i915_vm_close(vm);
 +
 +      ctx->file_priv = ERR_PTR(-EBADF);
  
        /*
         * The LUT uses the VMA as a backpointer to unref the object,
        lut_close(ctx);
  
        mutex_unlock(&ctx->mutex);
 +
 +      /*
 +       * If the user has disabled hangchecking, we can not be sure that
 +       * the batches will ever complete after the context is closed,
 +       * keeping the context and all resources pinned forever. So in this
 +       * case we opt to forcibly kill off all remaining requests on
 +       * context close.
 +       */
 +      if (!i915_gem_context_is_persistent(ctx) ||
 +          !i915_modparams.enable_hangcheck)
 +              kill_context(ctx);
 +
        i915_gem_context_put(ctx);
  }
  
 +static int __context_set_persistence(struct i915_gem_context *ctx, bool state)
 +{
 +      if (i915_gem_context_is_persistent(ctx) == state)
 +              return 0;
 +
 +      if (state) {
 +              /*
 +               * Only contexts that are short-lived [that will expire or be
 +               * reset] are allowed to survive past termination. We require
 +               * hangcheck to ensure that the persistent requests are healthy.
 +               */
 +              if (!i915_modparams.enable_hangcheck)
 +                      return -EINVAL;
 +
 +              i915_gem_context_set_persistence(ctx);
 +      } else {
 +              /* To cancel a context we use "preempt-to-idle" */
 +              if (!(ctx->i915->caps.scheduler & I915_SCHEDULER_CAP_PREEMPTION))
 +                      return -ENODEV;
 +
 +              i915_gem_context_clear_persistence(ctx);
 +      }
 +
 +      return 0;
 +}
 +
  static struct i915_gem_context *
  __create_context(struct drm_i915_private *i915)
  {
                return ERR_PTR(-ENOMEM);
  
        kref_init(&ctx->ref);
 -      list_add_tail(&ctx->link, &i915->contexts.list);
        ctx->i915 = i915;
        ctx->sched.priority = I915_USER_PRIORITY(I915_PRIORITY_NORMAL);
        mutex_init(&ctx->mutex);
        RCU_INIT_POINTER(ctx->engines, e);
  
        INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
 -      INIT_LIST_HEAD(&ctx->hw_id_link);
  
        /* NB: Mark all slices as needing a remap so that when the context first
         * loads it will restore whatever remap state already exists. If there
  
        i915_gem_context_set_bannable(ctx);
        i915_gem_context_set_recoverable(ctx);
 +      __context_set_persistence(ctx, true /* cgroup hook? */);
  
        for (i = 0; i < ARRAY_SIZE(ctx->hang_timestamp); i++)
                ctx->hang_timestamp[i] = jiffies - CONTEXT_FAST_HANG_JIFFIES;
  
+       ctx->jump_whitelist = NULL;
+       ctx->jump_whitelist_cmds = 0;
 +      spin_lock(&i915->gem.contexts.lock);
 +      list_add_tail(&ctx->link, &i915->gem.contexts.list);
 +      spin_unlock(&i915->gem.contexts.lock);
 +
        return ctx;
  
  err_free:
@@@ -560,11 -475,11 +565,11 @@@ static void __apply_ppgtt(struct intel_
  static struct i915_address_space *
  __set_ppgtt(struct i915_gem_context *ctx, struct i915_address_space *vm)
  {
 -      struct i915_address_space *old = ctx->vm;
 +      struct i915_address_space *old = i915_gem_context_vm(ctx);
  
        GEM_BUG_ON(old && i915_vm_is_4lvl(vm) != i915_vm_is_4lvl(old));
  
 -      ctx->vm = i915_vm_get(vm);
 +      rcu_assign_pointer(ctx->vm, i915_vm_open(vm));
        context_apply_all(ctx, __apply_ppgtt, vm);
  
        return old;
  static void __assign_ppgtt(struct i915_gem_context *ctx,
                           struct i915_address_space *vm)
  {
 -      if (vm == ctx->vm)
 +      if (vm == rcu_access_pointer(ctx->vm))
                return;
  
        vm = __set_ppgtt(ctx, vm);
        if (vm)
 -              i915_vm_put(vm);
 +              i915_vm_close(vm);
  }
  
  static void __set_timeline(struct intel_timeline **dst,
@@@ -605,25 -520,27 +610,25 @@@ static void __assign_timeline(struct i9
  }
  
  static struct i915_gem_context *
 -i915_gem_create_context(struct drm_i915_private *dev_priv, unsigned int flags)
 +i915_gem_create_context(struct drm_i915_private *i915, unsigned int flags)
  {
        struct i915_gem_context *ctx;
  
 -      lockdep_assert_held(&dev_priv->drm.struct_mutex);
 -
        if (flags & I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE &&
 -          !HAS_EXECLISTS(dev_priv))
 +          !HAS_EXECLISTS(i915))
                return ERR_PTR(-EINVAL);
  
 -      /* Reap the most stale context */
 -      contexts_free_first(dev_priv);
 +      /* Reap the stale contexts */
 +      contexts_flush_free(&i915->gem.contexts);
  
 -      ctx = __create_context(dev_priv);
 +      ctx = __create_context(i915);
        if (IS_ERR(ctx))
                return ctx;
  
 -      if (HAS_FULL_PPGTT(dev_priv)) {
 +      if (HAS_FULL_PPGTT(i915)) {
                struct i915_ppgtt *ppgtt;
  
 -              ppgtt = i915_ppgtt_create(dev_priv);
 +              ppgtt = i915_ppgtt_create(i915);
                if (IS_ERR(ppgtt)) {
                        DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n",
                                         PTR_ERR(ppgtt));
                        return ERR_CAST(ppgtt);
                }
  
 +              mutex_lock(&ctx->mutex);
                __assign_ppgtt(ctx, &ppgtt->vm);
 +              mutex_unlock(&ctx->mutex);
 +
                i915_vm_put(&ppgtt->vm);
        }
  
        if (flags & I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE) {
                struct intel_timeline *timeline;
  
 -              timeline = intel_timeline_create(&dev_priv->gt, NULL);
 +              timeline = intel_timeline_create(&i915->gt, NULL);
                if (IS_ERR(timeline)) {
                        context_close(ctx);
                        return ERR_CAST(timeline);
@@@ -673,13 -587,19 +678,13 @@@ struct i915_gem_context 
  i915_gem_context_create_kernel(struct drm_i915_private *i915, int prio)
  {
        struct i915_gem_context *ctx;
 -      int err;
  
        ctx = i915_gem_create_context(i915, 0);
        if (IS_ERR(ctx))
                return ctx;
  
 -      err = i915_gem_context_pin_hw_id(ctx);
 -      if (err) {
 -              destroy_kernel_context(&ctx);
 -              return ERR_PTR(err);
 -      }
 -
        i915_gem_context_clear_bannable(ctx);
 +      i915_gem_context_set_persistence(ctx);
        ctx->sched.priority = I915_USER_PRIORITY(prio);
  
        GEM_BUG_ON(!i915_gem_context_is_kernel(ctx));
        return ctx;
  }
  
 -static void init_contexts(struct drm_i915_private *i915)
 +static void init_contexts(struct i915_gem_contexts *gc)
  {
 -      mutex_init(&i915->contexts.mutex);
 -      INIT_LIST_HEAD(&i915->contexts.list);
 -
 -      /* Using the simple ida interface, the max is limited by sizeof(int) */
 -      BUILD_BUG_ON(MAX_CONTEXT_HW_ID > INT_MAX);
 -      BUILD_BUG_ON(GEN11_MAX_CONTEXT_HW_ID > INT_MAX);
 -      ida_init(&i915->contexts.hw_ida);
 -      INIT_LIST_HEAD(&i915->contexts.hw_id_list);
 +      spin_lock_init(&gc->lock);
 +      INIT_LIST_HEAD(&gc->list);
  
 -      INIT_WORK(&i915->contexts.free_work, contexts_free_worker);
 -      init_llist_head(&i915->contexts.free_list);
 +      INIT_WORK(&gc->free_work, contexts_free_worker);
 +      init_llist_head(&gc->free_list);
  }
  
 -int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
 +int i915_gem_init_contexts(struct drm_i915_private *i915)
  {
        struct i915_gem_context *ctx;
  
        /* Reassure ourselves we are only called once */
 -      GEM_BUG_ON(dev_priv->kernel_context);
 +      GEM_BUG_ON(i915->kernel_context);
  
 -      init_contexts(dev_priv);
 +      init_contexts(&i915->gem.contexts);
  
        /* lowest priority; idle task */
 -      ctx = i915_gem_context_create_kernel(dev_priv, I915_PRIORITY_MIN);
 +      ctx = i915_gem_context_create_kernel(i915, I915_PRIORITY_MIN);
        if (IS_ERR(ctx)) {
                DRM_ERROR("Failed to create default global context\n");
                return PTR_ERR(ctx);
        }
 -      /*
 -       * For easy recognisablity, we want the kernel context to be 0 and then
 -       * all user contexts will have non-zero hw_id. Kernel contexts are
 -       * permanently pinned, so that we never suffer a stall and can
 -       * use them from any allocation context (e.g. for evicting other
 -       * contexts and from inside the shrinker).
 -       */
 -      GEM_BUG_ON(ctx->hw_id);
 -      GEM_BUG_ON(!atomic_read(&ctx->hw_id_pin_count));
 -      dev_priv->kernel_context = ctx;
 +      i915->kernel_context = ctx;
  
        DRM_DEBUG_DRIVER("%s context support initialized\n",
 -                       DRIVER_CAPS(dev_priv)->has_logical_contexts ?
 +                       DRIVER_CAPS(i915)->has_logical_contexts ?
                         "logical" : "fake");
        return 0;
  }
  
 -void i915_gem_contexts_fini(struct drm_i915_private *i915)
 +void i915_gem_driver_release__contexts(struct drm_i915_private *i915)
  {
 -      lockdep_assert_held(&i915->drm.struct_mutex);
 -
        destroy_kernel_context(&i915->kernel_context);
 -
 -      /* Must free all deferred contexts (via flush_workqueue) first */
 -      GEM_BUG_ON(!list_empty(&i915->contexts.hw_id_list));
 -      ida_destroy(&i915->contexts.hw_ida);
  }
  
  static int context_idr_cleanup(int id, void *p, void *data)
@@@ -739,16 -680,11 +744,16 @@@ static int vm_idr_cleanup(int id, void 
  static int gem_context_register(struct i915_gem_context *ctx,
                                struct drm_i915_file_private *fpriv)
  {
 +      struct i915_address_space *vm;
        int ret;
  
        ctx->file_priv = fpriv;
 -      if (ctx->vm)
 -              ctx->vm->file = fpriv;
 +
 +      mutex_lock(&ctx->mutex);
 +      vm = i915_gem_context_vm(ctx);
 +      if (vm)
 +              WRITE_ONCE(vm->file, fpriv); /* XXX */
 +      mutex_unlock(&ctx->mutex);
  
        ctx->pid = get_task_pid(current, PIDTYPE_PID);
        ctx->name = kasprintf(GFP_KERNEL, "%s[%d]",
@@@ -785,7 -721,9 +790,7 @@@ int i915_gem_context_open(struct drm_i9
        idr_init(&file_priv->context_idr);
        idr_init_base(&file_priv->vm_idr, 1);
  
 -      mutex_lock(&i915->drm.struct_mutex);
        ctx = i915_gem_create_context(i915, 0);
 -      mutex_unlock(&i915->drm.struct_mutex);
        if (IS_ERR(ctx)) {
                err = PTR_ERR(ctx);
                goto err;
@@@ -813,7 -751,6 +818,7 @@@ err
  void i915_gem_context_close(struct drm_file *file)
  {
        struct drm_i915_file_private *file_priv = file->driver_priv;
 +      struct drm_i915_private *i915 = file_priv->dev_priv;
  
        idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL);
        idr_destroy(&file_priv->context_idr);
        idr_for_each(&file_priv->vm_idr, vm_idr_cleanup, NULL);
        idr_destroy(&file_priv->vm_idr);
        mutex_destroy(&file_priv->vm_idr_lock);
 +
 +      contexts_flush_free(&i915->gem.contexts);
  }
  
  int i915_gem_vm_create_ioctl(struct drm_device *dev, void *data,
@@@ -916,7 -851,6 +921,7 @@@ struct context_barrier_task 
        void *data;
  };
  
 +__i915_active_call
  static void cb_retire(struct i915_active *base)
  {
        struct context_barrier_task *cb = container_of(base, typeof(*cb), base);
@@@ -936,18 -870,20 +941,18 @@@ static int context_barrier_task(struct 
                                void (*task)(void *data),
                                void *data)
  {
 -      struct drm_i915_private *i915 = ctx->i915;
        struct context_barrier_task *cb;
        struct i915_gem_engines_iter it;
        struct intel_context *ce;
        int err = 0;
  
 -      lockdep_assert_held(&i915->drm.struct_mutex);
        GEM_BUG_ON(!task);
  
        cb = kmalloc(sizeof(*cb), GFP_KERNEL);
        if (!cb)
                return -ENOMEM;
  
 -      i915_active_init(i915, &cb->base, NULL, cb_retire);
 +      i915_active_init(&cb->base, NULL, cb_retire);
        err = i915_active_acquire(&cb->base);
        if (err) {
                kfree(cb);
                if (emit)
                        err = emit(rq, data);
                if (err == 0)
 -                      err = i915_active_ref(&cb->base, rq->timeline, rq);
 +                      err = i915_active_add_request(&cb->base, rq);
  
                i915_request_add(rq);
                if (err)
@@@ -1002,12 -938,16 +1007,12 @@@ static int get_ppgtt(struct drm_i915_fi
        struct i915_address_space *vm;
        int ret;
  
 -      if (!ctx->vm)
 +      if (!rcu_access_pointer(ctx->vm))
                return -ENODEV;
  
 -      /* XXX rcu acquire? */
 -      ret = mutex_lock_interruptible(&ctx->i915->drm.struct_mutex);
 -      if (ret)
 -              return ret;
 -
 +      rcu_read_lock();
        vm = i915_vm_get(ctx->vm);
 -      mutex_unlock(&ctx->i915->drm.struct_mutex);
 +      rcu_read_unlock();
  
        ret = mutex_lock_interruptible(&file_priv->vm_idr_lock);
        if (ret)
        if (ret < 0)
                goto err_unlock;
  
 -      i915_vm_get(vm);
 +      i915_vm_open(vm);
  
        args->size = 0;
        args->value = ret;
@@@ -1038,7 -978,7 +1043,7 @@@ static void set_ppgtt_barrier(void *dat
        if (INTEL_GEN(old->i915) < 8)
                gen6_ppgtt_unpin_all(i915_vm_to_ppgtt(old));
  
 -      i915_vm_put(old);
 +      i915_vm_close(old);
  }
  
  static int emit_ppgtt_update(struct i915_request *rq, void *data)
                intel_ring_advance(rq, cs);
        } else if (HAS_LOGICAL_RING_CONTEXTS(engine->i915)) {
                struct i915_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
 +              int err;
 +
 +              /* Magic required to prevent forcewake errors! */
 +              err = engine->emit_flush(rq, EMIT_INVALIDATE);
 +              if (err)
 +                      return err;
  
                cs = intel_ring_begin(rq, 4 * GEN8_3LVL_PDPES + 2);
                if (IS_ERR(cs))
                        return PTR_ERR(cs);
  
 -              *cs++ = MI_LOAD_REGISTER_IMM(2 * GEN8_3LVL_PDPES);
 +              *cs++ = MI_LOAD_REGISTER_IMM(2 * GEN8_3LVL_PDPES) | MI_LRI_FORCE_POSTED;
                for (i = GEN8_3LVL_PDPES; i--; ) {
                        const dma_addr_t pd_daddr = i915_page_dir_dma_addr(ppgtt, i);
  
@@@ -1116,34 -1050,34 +1121,34 @@@ static int set_ppgtt(struct drm_i915_fi
        if (args->size)
                return -EINVAL;
  
 -      if (!ctx->vm)
 +      if (!rcu_access_pointer(ctx->vm))
                return -ENODEV;
  
        if (upper_32_bits(args->value))
                return -ENOENT;
  
 -      err = mutex_lock_interruptible(&file_priv->vm_idr_lock);
 -      if (err)
 -              return err;
 -
 +      rcu_read_lock();
        vm = idr_find(&file_priv->vm_idr, args->value);
 -      if (vm)
 -              i915_vm_get(vm);
 -      mutex_unlock(&file_priv->vm_idr_lock);
 +      if (vm && !kref_get_unless_zero(&vm->ref))
 +              vm = NULL;
 +      rcu_read_unlock();
        if (!vm)
                return -ENOENT;
  
 -      err = mutex_lock_interruptible(&ctx->i915->drm.struct_mutex);
 +      err = mutex_lock_interruptible(&ctx->mutex);
        if (err)
                goto out;
  
 -      if (vm == ctx->vm)
 +      if (i915_gem_context_is_closed(ctx)) {
 +              err = -ENOENT;
 +              goto out;
 +      }
 +
 +      if (vm == rcu_access_pointer(ctx->vm))
                goto unlock;
  
        /* Teardown the existing obj:vma cache, it will have to be rebuilt. */
 -      mutex_lock(&ctx->mutex);
        lut_close(ctx);
 -      mutex_unlock(&ctx->mutex);
  
        old = __set_ppgtt(ctx, vm);
  
                                   set_ppgtt_barrier,
                                   old);
        if (err) {
 -              i915_vm_put(__set_ppgtt(ctx, old));
 -              i915_vm_put(old);
 +              i915_vm_close(__set_ppgtt(ctx, old));
 +              i915_vm_close(old);
        }
  
  unlock:
 -      mutex_unlock(&ctx->i915->drm.struct_mutex);
 -
 +      mutex_unlock(&ctx->mutex);
  out:
        i915_vm_put(vm);
        return err;
@@@ -1182,7 -1117,7 +1187,7 @@@ static int gen8_emit_rpcs_config(struc
  
        offset = i915_ggtt_offset(ce->state) +
                 LRC_STATE_PN * PAGE_SIZE +
 -               (CTX_R_PWR_CLK_STATE + 1) * 4;
 +               CTX_R_PWR_CLK_STATE * 4;
  
        *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
        *cs++ = lower_32_bits(offset);
@@@ -1225,7 -1160,8 +1230,7 @@@ gen8_modify_rpcs(struct intel_context *
  }
  
  static int
 -__intel_context_reconfigure_sseu(struct intel_context *ce,
 -                               struct intel_sseu sseu)
 +intel_context_reconfigure_sseu(struct intel_context *ce, struct intel_sseu sseu)
  {
        int ret;
  
@@@ -1248,6 -1184,23 +1253,6 @@@ unlock
        return ret;
  }
  
 -static int
 -intel_context_reconfigure_sseu(struct intel_context *ce, struct intel_sseu sseu)
 -{
 -      struct drm_i915_private *i915 = ce->engine->i915;
 -      int ret;
 -
 -      ret = mutex_lock_interruptible(&i915->drm.struct_mutex);
 -      if (ret)
 -              return ret;
 -
 -      ret = __intel_context_reconfigure_sseu(ce, sseu);
 -
 -      mutex_unlock(&i915->drm.struct_mutex);
 -
 -      return ret;
 -}
 -
  static int
  user_to_context_sseu(struct drm_i915_private *i915,
                     const struct drm_i915_gem_context_param_sseu *user,
@@@ -1790,16 -1743,6 +1795,16 @@@ err_free
        return err;
  }
  
 +static int
 +set_persistence(struct i915_gem_context *ctx,
 +              const struct drm_i915_gem_context_param *args)
 +{
 +      if (args->size)
 +              return -EINVAL;
 +
 +      return __context_set_persistence(ctx, args->value);
 +}
 +
  static int ctx_setparam(struct drm_i915_file_private *fpriv,
                        struct i915_gem_context *ctx,
                        struct drm_i915_gem_context_param *args)
                ret = set_engines(ctx, args);
                break;
  
 +      case I915_CONTEXT_PARAM_PERSISTENCE:
 +              ret = set_persistence(ctx, args);
 +              break;
 +
        case I915_CONTEXT_PARAM_BAN_PERIOD:
        default:
                ret = -EINVAL;
@@@ -2033,11 -1972,10 +2038,11 @@@ static int clone_vm(struct i915_gem_con
                    struct i915_gem_context *src)
  {
        struct i915_address_space *vm;
 +      int err = 0;
  
        rcu_read_lock();
        do {
 -              vm = READ_ONCE(src->vm);
 +              vm = rcu_dereference(src->vm);
                if (!vm)
                        break;
  
                 * it cannot be reallocated elsewhere.
                 */
  
 -              if (vm == READ_ONCE(src->vm))
 +              if (vm == rcu_access_pointer(src->vm))
                        break;
  
                i915_vm_put(vm);
        rcu_read_unlock();
  
        if (vm) {
 -              __assign_ppgtt(dst, vm);
 +              if (!mutex_lock_interruptible(&dst->mutex)) {
 +                      __assign_ppgtt(dst, vm);
 +                      mutex_unlock(&dst->mutex);
 +              } else {
 +                      err = -EINTR;
 +              }
                i915_vm_put(vm);
        }
  
 -      return 0;
 +      return err;
  }
  
  static int create_clone(struct i915_user_extension __user *ext, void *data)
@@@ -2166,7 -2099,12 +2171,7 @@@ int i915_gem_context_create_ioctl(struc
                return -EIO;
        }
  
 -      ret = i915_mutex_lock_interruptible(dev);
 -      if (ret)
 -              return ret;
 -
        ext_data.ctx = i915_gem_create_context(i915, args->flags);
 -      mutex_unlock(&dev->struct_mutex);
        if (IS_ERR(ext_data.ctx))
                return PTR_ERR(ext_data.ctx);
  
@@@ -2293,12 -2231,12 +2298,12 @@@ int i915_gem_context_getparam_ioctl(str
  
        case I915_CONTEXT_PARAM_GTT_SIZE:
                args->size = 0;
 -              if (ctx->vm)
 -                      args->value = ctx->vm->total;
 -              else if (to_i915(dev)->ggtt.alias)
 -                      args->value = to_i915(dev)->ggtt.alias->vm.total;
 +              rcu_read_lock();
 +              if (rcu_access_pointer(ctx->vm))
 +                      args->value = rcu_dereference(ctx->vm)->total;
                else
                        args->value = to_i915(dev)->ggtt.vm.total;
 +              rcu_read_unlock();
                break;
  
        case I915_CONTEXT_PARAM_NO_ERROR_CAPTURE:
                ret = get_engines(ctx, args);
                break;
  
 +      case I915_CONTEXT_PARAM_PERSISTENCE:
 +              args->size = 0;
 +              args->value = i915_gem_context_is_persistent(ctx);
 +              break;
 +
        case I915_CONTEXT_PARAM_BAN_PERIOD:
        default:
                ret = -EINVAL;
@@@ -2369,7 -2302,7 +2374,7 @@@ int i915_gem_context_setparam_ioctl(str
  int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
                                       void *data, struct drm_file *file)
  {
 -      struct drm_i915_private *dev_priv = to_i915(dev);
 +      struct drm_i915_private *i915 = to_i915(dev);
        struct drm_i915_reset_stats *args = data;
        struct i915_gem_context *ctx;
        int ret;
         */
  
        if (capable(CAP_SYS_ADMIN))
 -              args->reset_count = i915_reset_count(&dev_priv->gpu_error);
 +              args->reset_count = i915_reset_count(&i915->gpu_error);
        else
                args->reset_count = 0;
  
@@@ -2404,6 -2337,33 +2409,6 @@@ out
        return ret;
  }
  
 -int __i915_gem_context_pin_hw_id(struct i915_gem_context *ctx)
 -{
 -      struct drm_i915_private *i915 = ctx->i915;
 -      int err = 0;
 -
 -      mutex_lock(&i915->contexts.mutex);
 -
 -      GEM_BUG_ON(i915_gem_context_is_closed(ctx));
 -
 -      if (list_empty(&ctx->hw_id_link)) {
 -              GEM_BUG_ON(atomic_read(&ctx->hw_id_pin_count));
 -
 -              err = assign_hw_id(i915, &ctx->hw_id);
 -              if (err)
 -                      goto out_unlock;
 -
 -              list_add_tail(&ctx->hw_id_link, &i915->contexts.hw_id_list);
 -      }
 -
 -      GEM_BUG_ON(atomic_read(&ctx->hw_id_pin_count) == ~0u);
 -      atomic_inc(&ctx->hw_id_pin_count);
 -
 -out_unlock:
 -      mutex_unlock(&i915->contexts.mutex);
 -      return err;
 -}
 -
  /* GEM context-engines iterator: for_each_gem_engine() */
  struct intel_context *
  i915_gem_engines_iter_next(struct i915_gem_engines_iter *it)
index 861d7d92fe9f6fced21ba89cdc73d42b6053c5a6,00537b9d7006b54038519fac98faa703793532fd..3870dd5daaa099bc372b11b51a46b4db630e1e20
@@@ -88,7 -88,7 +88,7 @@@ struct i915_gem_context 
         * In other modes, this is a NULL pointer with the expectation that
         * the caller uses the shared global GTT.
         */
 -      struct i915_address_space *vm;
 +      struct i915_address_space __rcu *vm;
  
        /**
         * @pid: process id of creator
  #define UCONTEXT_NO_ERROR_CAPTURE     1
  #define UCONTEXT_BANNABLE             2
  #define UCONTEXT_RECOVERABLE          3
 +#define UCONTEXT_PERSISTENCE          4
  
        /**
         * @flags: small set of booleans
  #define CONTEXT_CLOSED                        1
  #define CONTEXT_FORCE_SINGLE_SUBMISSION       2
  #define CONTEXT_USER_ENGINES          3
 -
 -      /**
 -       * @hw_id: - unique identifier for the context
 -       *
 -       * The hardware needs to uniquely identify the context for a few
 -       * functions like fault reporting, PASID, scheduling. The
 -       * &drm_i915_private.context_hw_ida is used to assign a unqiue
 -       * id for the lifetime of the context.
 -       *
 -       * @hw_id_pin_count: - number of times this context had been pinned
 -       * for use (should be, at most, once per engine).
 -       *
 -       * @hw_id_link: - all contexts with an assigned id are tracked
 -       * for possible repossession.
 -       */
 -      unsigned int hw_id;
 -      atomic_t hw_id_pin_count;
 -      struct list_head hw_id_link;
 +#define CONTEXT_NOPREEMPT             4
  
        struct mutex mutex;
  
         * per vm, which may be one per context or shared with the global GTT)
         */
        struct radix_tree_root handles_vma;
+       /** jump_whitelist: Bit array for tracking cmds during cmdparsing
+        *  Guarded by struct_mutex
+        */
+       unsigned long *jump_whitelist;
+       /** jump_whitelist_cmds: No of cmd slots available */
+       u32 jump_whitelist_cmds;
  };
  
  #endif /* __I915_GEM_CONTEXT_TYPES_H__ */
index e4f5c269150ab26789a0d30814e9aa48bee9db92,e635e1e5f4d308eb903c85f0710dcfd13c316418..f0998f1225af15a16bd8384dcf4df903c958c638
@@@ -19,7 -19,6 +19,7 @@@
  #include "gt/intel_engine_pool.h"
  #include "gt/intel_gt.h"
  #include "gt/intel_gt_pm.h"
 +#include "gt/intel_ring.h"
  
  #include "i915_drv.h"
  #include "i915_gem_clflush.h"
@@@ -253,7 -252,6 +253,7 @@@ struct i915_execbuffer 
                bool has_fence : 1;
                bool needs_unfenced : 1;
  
 +              struct intel_context *ce;
                struct i915_request *rq;
                u32 *rq_cmd;
                unsigned int rq_size;
@@@ -298,7 -296,9 +298,9 @@@ static inline u64 gen8_noncanonical_add
  
  static inline bool eb_use_cmdparser(const struct i915_execbuffer *eb)
  {
-       return intel_engine_needs_cmd_parser(eb->engine) && eb->batch_len;
+       return intel_engine_requires_cmd_parser(eb->engine) ||
+               (intel_engine_using_cmd_parser(eb->engine) &&
+                eb->args->batch_len);
  }
  
  static int eb_create(struct i915_execbuffer *eb)
@@@ -699,9 -699,7 +701,9 @@@ static int eb_reserve(struct i915_execb
  
                case 1:
                        /* Too fragmented, unbind everything and retry */
 +                      mutex_lock(&eb->context->vm->mutex);
                        err = i915_gem_evict_vm(eb->context->vm);
 +                      mutex_unlock(&eb->context->vm->mutex);
                        if (err)
                                return err;
                        break;
@@@ -729,7 -727,7 +731,7 @@@ static int eb_select_context(struct i91
                return -ENOENT;
  
        eb->gem_context = ctx;
 -      if (ctx->vm)
 +      if (rcu_access_pointer(ctx->vm))
                eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
  
        eb->context_flags = 0;
@@@ -884,9 -882,6 +886,9 @@@ static void eb_destroy(const struct i91
  {
        GEM_BUG_ON(eb->reloc_cache.rq);
  
 +      if (eb->reloc_cache.ce)
 +              intel_context_put(eb->reloc_cache.ce);
 +
        if (eb->lut_size > 0)
                kfree(eb->buckets);
  }
@@@ -909,8 -904,7 +911,8 @@@ static void reloc_cache_init(struct rel
        cache->use_64bit_reloc = HAS_64BIT_RELOC(i915);
        cache->has_fence = cache->gen < 4;
        cache->needs_unfenced = INTEL_INFO(i915)->unfenced_needs_alignment;
 -      cache->node.allocated = false;
 +      cache->node.flags = 0;
 +      cache->ce = NULL;
        cache->rq = NULL;
        cache->rq_size = 0;
  }
@@@ -971,13 -965,11 +973,13 @@@ static void reloc_cache_reset(struct re
                intel_gt_flush_ggtt_writes(ggtt->vm.gt);
                io_mapping_unmap_atomic((void __iomem *)vaddr);
  
 -              if (cache->node.allocated) {
 +              if (drm_mm_node_allocated(&cache->node)) {
                        ggtt->vm.clear_range(&ggtt->vm,
                                             cache->node.start,
                                             cache->node.size);
 +                      mutex_lock(&ggtt->vm.mutex);
                        drm_mm_remove_node(&cache->node);
 +                      mutex_unlock(&ggtt->vm.mutex);
                } else {
                        i915_vma_unpin((struct i915_vma *)cache->node.mm);
                }
@@@ -1052,13 -1044,11 +1054,13 @@@ static void *reloc_iomap(struct drm_i91
                                               PIN_NOEVICT);
                if (IS_ERR(vma)) {
                        memset(&cache->node, 0, sizeof(cache->node));
 +                      mutex_lock(&ggtt->vm.mutex);
                        err = drm_mm_insert_node_in_range
                                (&ggtt->vm.mm, &cache->node,
                                 PAGE_SIZE, 0, I915_COLOR_UNEVICTABLE,
                                 0, ggtt->mappable_end,
                                 DRM_MM_INSERT_LOW);
 +                      mutex_unlock(&ggtt->vm.mutex);
                        if (err) /* no inactive aperture space, use cpu reloc */
                                return NULL;
                } else {
        }
  
        offset = cache->node.start;
 -      if (cache->node.allocated) {
 +      if (drm_mm_node_allocated(&cache->node)) {
                ggtt->vm.insert_page(&ggtt->vm,
                                     i915_gem_object_get_dma_address(obj, page),
                                     offset, I915_CACHE_NONE, 0);
@@@ -1157,7 -1147,7 +1159,7 @@@ static int __reloc_gpu_alloc(struct i91
        u32 *cmd;
        int err;
  
 -      pool = intel_engine_pool_get(&eb->engine->pool, PAGE_SIZE);
 +      pool = intel_engine_get_pool(eb->engine, PAGE_SIZE);
        if (IS_ERR(pool))
                return PTR_ERR(pool);
  
        if (err)
                goto err_unmap;
  
 -      rq = i915_request_create(eb->context);
 +      rq = intel_context_create_request(cache->ce);
        if (IS_ERR(rq)) {
                err = PTR_ERR(rq);
                goto err_unpin;
@@@ -1251,29 -1241,6 +1253,29 @@@ static u32 *reloc_gpu(struct i915_execb
                if (!intel_engine_can_store_dword(eb->engine))
                        return ERR_PTR(-ENODEV);
  
 +              if (!cache->ce) {
 +                      struct intel_context *ce;
 +
 +                      /*
 +                       * The CS pre-parser can pre-fetch commands across
 +                       * memory sync points and starting gen12 it is able to
 +                       * pre-fetch across BB_START and BB_END boundaries
 +                       * (within the same context). We therefore use a
 +                       * separate context gen12+ to guarantee that the reloc
 +                       * writes land before the parser gets to the target
 +                       * memory location.
 +                       */
 +                      if (cache->gen >= 12)
 +                              ce = intel_context_create(eb->context->gem_context,
 +                                                        eb->engine);
 +                      else
 +                              ce = intel_context_get(eb->context);
 +                      if (IS_ERR(ce))
 +                              return ERR_CAST(ce);
 +
 +                      cache->ce = ce;
 +              }
 +
                err = __reloc_gpu_alloc(eb, vma, len);
                if (unlikely(err))
                        return ERR_PTR(err);
@@@ -1423,7 -1390,7 +1425,7 @@@ eb_relocate_entry(struct i915_execbuffe
                if (reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION &&
                    IS_GEN(eb->i915, 6)) {
                        err = i915_vma_bind(target, target->obj->cache_level,
 -                                          PIN_GLOBAL);
 +                                          PIN_GLOBAL, NULL);
                        if (WARN_ONCE(err,
                                      "Unexpected failure to bind target VMA!"))
                                return err;
@@@ -1990,40 -1957,94 +1992,94 @@@ static int i915_reset_gen7_sol_offsets(
        return 0;
  }
  
- static struct i915_vma *eb_parse(struct i915_execbuffer *eb, bool is_master)
+ static struct i915_vma *
+ shadow_batch_pin(struct i915_execbuffer *eb, struct drm_i915_gem_object *obj)
+ {
+       struct drm_i915_private *dev_priv = eb->i915;
+       struct i915_vma * const vma = *eb->vma;
+       struct i915_address_space *vm;
+       u64 flags;
+       /*
+        * PPGTT backed shadow buffers must be mapped RO, to prevent
+        * post-scan tampering
+        */
+       if (CMDPARSER_USES_GGTT(dev_priv)) {
+               flags = PIN_GLOBAL;
+               vm = &dev_priv->ggtt.vm;
+       } else if (vma->vm->has_read_only) {
+               flags = PIN_USER;
+               vm = vma->vm;
+               i915_gem_object_set_readonly(obj);
+       } else {
+               DRM_DEBUG("Cannot prevent post-scan tampering without RO capable vm\n");
+               return ERR_PTR(-EINVAL);
+       }
+       return i915_gem_object_pin(obj, vm, NULL, 0, 0, flags);
+ }
+ static struct i915_vma *eb_parse(struct i915_execbuffer *eb)
  {
        struct intel_engine_pool_node *pool;
        struct i915_vma *vma;
+       u64 batch_start;
+       u64 shadow_batch_start;
        int err;
  
 -      pool = intel_engine_pool_get(&eb->engine->pool, eb->batch_len);
 +      pool = intel_engine_get_pool(eb->engine, eb->batch_len);
        if (IS_ERR(pool))
                return ERR_CAST(pool);
  
-       err = intel_engine_cmd_parser(eb->engine,
+       vma = shadow_batch_pin(eb, pool->obj);
+       if (IS_ERR(vma))
+               goto err;
+       batch_start = gen8_canonical_addr(eb->batch->node.start) +
+                     eb->batch_start_offset;
+       shadow_batch_start = gen8_canonical_addr(vma->node.start);
+       err = intel_engine_cmd_parser(eb->gem_context,
+                                     eb->engine,
                                      eb->batch->obj,
-                                     pool->obj,
+                                     batch_start,
                                      eb->batch_start_offset,
                                      eb->batch_len,
-                                     is_master);
+                                     pool->obj,
+                                     shadow_batch_start);
        if (err) {
-               if (err == -EACCES) /* unhandled chained batch */
+               i915_vma_unpin(vma);
+               /*
+                * Unsafe GGTT-backed buffers can still be submitted safely
+                * as non-secure.
+                * For PPGTT backing however, we have no choice but to forcibly
+                * reject unsafe buffers
+                */
+               if (CMDPARSER_USES_GGTT(eb->i915) && (err == -EACCES))
+                       /* Execute original buffer non-secure */
                        vma = NULL;
                else
                        vma = ERR_PTR(err);
                goto err;
        }
  
-       vma = i915_gem_object_ggtt_pin(pool->obj, NULL, 0, 0, 0);
-       if (IS_ERR(vma))
-               goto err;
        eb->vma[eb->buffer_count] = i915_vma_get(vma);
        eb->flags[eb->buffer_count] =
                __EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_REF;
        vma->exec_flags = &eb->flags[eb->buffer_count];
        eb->buffer_count++;
  
+       eb->batch_start_offset = 0;
+       eb->batch = vma;
+       if (CMDPARSER_USES_GGTT(eb->i915))
+               eb->batch_flags |= I915_DISPATCH_SECURE;
+       /* eb->batch_len unchanged */
        vma->private = pool;
        return vma;
  
@@@ -2078,9 -2099,6 +2134,9 @@@ static int eb_submit(struct i915_execbu
        if (err)
                return err;
  
 +      if (i915_gem_context_nopreempt(eb->gem_context))
 +              eb->request->flags |= I915_REQUEST_NOPREEMPT;
 +
        return 0;
  }
  
@@@ -2150,6 -2168,35 +2206,6 @@@ static struct i915_request *eb_throttle
        return i915_request_get(rq);
  }
  
 -static int
 -__eb_pin_context(struct i915_execbuffer *eb, struct intel_context *ce)
 -{
 -      int err;
 -
 -      if (likely(atomic_inc_not_zero(&ce->pin_count)))
 -              return 0;
 -
 -      err = mutex_lock_interruptible(&eb->i915->drm.struct_mutex);
 -      if (err)
 -              return err;
 -
 -      err = __intel_context_do_pin(ce);
 -      mutex_unlock(&eb->i915->drm.struct_mutex);
 -
 -      return err;
 -}
 -
 -static void
 -__eb_unpin_context(struct i915_execbuffer *eb, struct intel_context *ce)
 -{
 -      if (likely(atomic_add_unless(&ce->pin_count, -1, 1)))
 -              return;
 -
 -      mutex_lock(&eb->i915->drm.struct_mutex);
 -      intel_context_unpin(ce);
 -      mutex_unlock(&eb->i915->drm.struct_mutex);
 -}
 -
  static int __eb_pin_engine(struct i915_execbuffer *eb, struct intel_context *ce)
  {
        struct intel_timeline *tl;
         * GGTT space, so do this first before we reserve a seqno for
         * ourselves.
         */
 -      err = __eb_pin_context(eb, ce);
 +      err = intel_context_pin(ce);
        if (err)
                return err;
  
@@@ -2213,7 -2260,7 +2269,7 @@@ err_exit
        intel_context_exit(ce);
        intel_context_timeline_unlock(tl);
  err_unpin:
 -      __eb_unpin_context(eb, ce);
 +      intel_context_unpin(ce);
        return err;
  }
  
@@@ -2226,7 -2273,7 +2282,7 @@@ static void eb_unpin_engine(struct i915
        intel_context_exit(ce);
        mutex_unlock(&tl->mutex);
  
 -      __eb_unpin_context(eb, ce);
 +      intel_context_unpin(ce);
  }
  
  static unsigned int
@@@ -2430,6 -2477,7 +2486,7 @@@ i915_gem_do_execbuffer(struct drm_devic
                       struct drm_i915_gem_exec_object2 *exec,
                       struct drm_syncobj **fences)
  {
+       struct drm_i915_private *i915 = to_i915(dev);
        struct i915_execbuffer eb;
        struct dma_fence *in_fence = NULL;
        struct dma_fence *exec_fence = NULL;
        BUILD_BUG_ON(__EXEC_OBJECT_INTERNAL_FLAGS &
                     ~__EXEC_OBJECT_UNKNOWN_FLAGS);
  
-       eb.i915 = to_i915(dev);
+       eb.i915 = i915;
        eb.file = file;
        eb.args = args;
        if (DBG_FORCE_RELOC || !(args->flags & I915_EXEC_NO_RELOC))
  
        eb.batch_flags = 0;
        if (args->flags & I915_EXEC_SECURE) {
+               if (INTEL_GEN(i915) >= 11)
+                       return -ENODEV;
+               /* Return -EPERM to trigger fallback code on old binaries. */
+               if (!HAS_SECURE_BATCHES(i915))
+                       return -EPERM;
                if (!drm_is_current_master(file) || !capable(CAP_SYS_ADMIN))
-                   return -EPERM;
+                       return -EPERM;
  
                eb.batch_flags |= I915_DISPATCH_SECURE;
        }
                goto err_vma;
        }
  
+       if (eb.batch_len == 0)
+               eb.batch_len = eb.batch->size - eb.batch_start_offset;
        if (eb_use_cmdparser(&eb)) {
                struct i915_vma *vma;
  
-               vma = eb_parse(&eb, drm_is_current_master(file));
+               vma = eb_parse(&eb);
                if (IS_ERR(vma)) {
                        err = PTR_ERR(vma);
                        goto err_vma;
                }
-               if (vma) {
-                       /*
-                        * Batch parsed and accepted:
-                        *
-                        * Set the DISPATCH_SECURE bit to remove the NON_SECURE
-                        * bit from MI_BATCH_BUFFER_START commands issued in
-                        * the dispatch_execbuffer implementations. We
-                        * specifically don't want that set on batches the
-                        * command parser has accepted.
-                        */
-                       eb.batch_flags |= I915_DISPATCH_SECURE;
-                       eb.batch_start_offset = 0;
-                       eb.batch = vma;
-               }
        }
  
-       if (eb.batch_len == 0)
-               eb.batch_len = eb.batch->size - eb.batch_start_offset;
        /*
         * snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure
         * batch" bit. Hence we need to pin secure batches into the global gtt.
index c5d1047a4bc5f482356ba5f87bc4ebf33d0c0d87,9dd8c299cb2dbb61989d81d6d233979d25192766..758f0e8ec6723dd8f0a89d987e9e0eb248f4e259
@@@ -15,7 -15,6 +15,7 @@@
  #include <linux/rbtree.h>
  #include <linux/timer.h>
  #include <linux/types.h>
 +#include <linux/workqueue.h>
  
  #include "i915_gem.h"
  #include "i915_pmu.h"
@@@ -59,7 -58,6 +59,7 @@@ struct i915_gem_context
  struct i915_request;
  struct i915_sched_attr;
  struct intel_gt;
 +struct intel_ring;
  struct intel_uncore;
  
  typedef u8 intel_engine_mask_t;
@@@ -78,6 -76,40 +78,6 @@@ struct intel_instdone 
        u32 row[I915_MAX_SLICES][I915_MAX_SUBSLICES];
  };
  
 -struct intel_engine_hangcheck {
 -      u64 acthd;
 -      u32 last_ring;
 -      u32 last_head;
 -      unsigned long action_timestamp;
 -      struct intel_instdone instdone;
 -};
 -
 -struct intel_ring {
 -      struct kref ref;
 -      struct i915_vma *vma;
 -      void *vaddr;
 -
 -      /*
 -       * As we have two types of rings, one global to the engine used
 -       * by ringbuffer submission and those that are exclusive to a
 -       * context used by execlists, we have to play safe and allow
 -       * atomic updates to the pin_count. However, the actual pinning
 -       * of the context is either done during initialisation for
 -       * ringbuffer submission or serialised as part of the context
 -       * pinning for execlists, and so we do not need a mutex ourselves
 -       * to serialise intel_ring_pin/intel_ring_unpin.
 -       */
 -      atomic_t pin_count;
 -
 -      u32 head;
 -      u32 tail;
 -      u32 emit;
 -
 -      u32 space;
 -      u32 size;
 -      u32 effective_size;
 -};
 -
  /*
   * we use a single page to load ctx workarounds so all of these
   * values are referred in terms of dwords
@@@ -116,7 -148,6 +116,7 @@@ enum intel_engine_id 
        VECS1,
  #define _VECS(n) (VECS0 + (n))
        I915_NUM_ENGINES
 +#define INVALID_ENGINE ((enum intel_engine_id)-1)
  };
  
  struct st_preempt_hang {
@@@ -142,11 -173,6 +142,11 @@@ struct intel_engine_execlists 
         */
        struct timer_list timer;
  
 +      /**
 +       * @preempt: reset the current context if it fails to give way
 +       */
 +      struct timer_list preempt;
 +
        /**
         * @default_priolist: priority list for I915_PRIORITY_NORMAL
         */
@@@ -277,12 -303,10 +277,12 @@@ struct intel_engine_cs 
        u8 uabi_class;
        u8 uabi_instance;
  
 +      u32 uabi_capabilities;
        u32 context_size;
        u32 mmio_base;
  
 -      u32 uabi_capabilities;
 +      unsigned int context_tag;
 +#define NUM_CONTEXT_TAG roundup_pow_of_two(2 * EXECLIST_MAX_PORTS)
  
        struct rb_node uabi_node;
  
  
        intel_engine_mask_t saturated; /* submitting semaphores too late? */
  
 +      struct {
 +              struct delayed_work work;
 +              struct i915_request *systole;
 +      } heartbeat;
 +
        unsigned long serial;
  
        unsigned long wakeref_serial;
        /* status_notifier: list of callbacks for context-switch changes */
        struct atomic_notifier_head context_status_notifier;
  
- #define I915_ENGINE_NEEDS_CMD_PARSER BIT(0)
 -      struct intel_engine_hangcheck hangcheck;
 -
+ #define I915_ENGINE_USING_CMD_PARSER BIT(0)
  #define I915_ENGINE_SUPPORTS_STATS   BIT(1)
  #define I915_ENGINE_HAS_PREEMPTION   BIT(2)
  #define I915_ENGINE_HAS_SEMAPHORES   BIT(3)
  #define I915_ENGINE_NEEDS_BREADCRUMB_TASKLET BIT(4)
  #define I915_ENGINE_IS_VIRTUAL       BIT(5)
 +#define I915_ENGINE_HAS_RELATIVE_MMIO BIT(6)
+ #define I915_ENGINE_REQUIRES_CMD_PARSER BIT(7)
        unsigned int flags;
  
        /*
                 */
                ktime_t total;
        } stats;
 +
 +      struct {
 +              unsigned long heartbeat_interval_ms;
 +              unsigned long preempt_timeout_ms;
 +              unsigned long stop_timeout_ms;
 +              unsigned long timeslice_duration_ms;
 +      } props;
  };
  
  static inline bool
- intel_engine_needs_cmd_parser(const struct intel_engine_cs *engine)
+ intel_engine_using_cmd_parser(const struct intel_engine_cs *engine)
  {
-       return engine->flags & I915_ENGINE_NEEDS_CMD_PARSER;
+       return engine->flags & I915_ENGINE_USING_CMD_PARSER;
+ }
+ static inline bool
+ intel_engine_requires_cmd_parser(const struct intel_engine_cs *engine)
+ {
+       return engine->flags & I915_ENGINE_REQUIRES_CMD_PARSER;
  }
  
  static inline bool
@@@ -563,24 -583,20 +570,24 @@@ intel_engine_is_virtual(const struct in
        return engine->flags & I915_ENGINE_IS_VIRTUAL;
  }
  
 -#define instdone_slice_mask(dev_priv__) \
 -      (IS_GEN(dev_priv__, 7) ? \
 -       1 : RUNTIME_INFO(dev_priv__)->sseu.slice_mask)
 +static inline bool
 +intel_engine_has_relative_mmio(const struct intel_engine_cs * const engine)
 +{
 +      return engine->flags & I915_ENGINE_HAS_RELATIVE_MMIO;
 +}
  
 -#define instdone_subslice_mask(dev_priv__) \
 -      (IS_GEN(dev_priv__, 7) ? \
 -       1 : RUNTIME_INFO(dev_priv__)->sseu.subslice_mask[0])
 +#define instdone_has_slice(dev_priv___, sseu___, slice___) \
 +      ((IS_GEN(dev_priv___, 7) ? 1 : ((sseu___)->slice_mask)) & BIT(slice___))
  
 -#define for_each_instdone_slice_subslice(dev_priv__, slice__, subslice__) \
 -      for ((slice__) = 0, (subslice__) = 0; \
 -           (slice__) < I915_MAX_SLICES; \
 -           (subslice__) = ((subslice__) + 1) < I915_MAX_SUBSLICES ? (subslice__) + 1 : 0, \
 -             (slice__) += ((subslice__) == 0)) \
 -              for_each_if((BIT(slice__) & instdone_slice_mask(dev_priv__)) && \
 -                          (BIT(subslice__) & instdone_subslice_mask(dev_priv__)))
 +#define instdone_has_subslice(dev_priv__, sseu__, slice__, subslice__) \
 +      (IS_GEN(dev_priv__, 7) ? (1 & BIT(subslice__)) : \
 +       intel_sseu_has_subslice(sseu__, 0, subslice__))
  
 +#define for_each_instdone_slice_subslice(dev_priv_, sseu_, slice_, subslice_) \
 +      for ((slice_) = 0, (subslice_) = 0; (slice_) < I915_MAX_SLICES; \
 +           (subslice_) = ((subslice_) + 1) % I915_MAX_SUBSLICES, \
 +           (slice_) += ((subslice_) == 0)) \
 +              for_each_if((instdone_has_slice(dev_priv_, sseu_, slice_)) && \
 +                          (instdone_has_subslice(dev_priv_, sseu_, slice_, \
 +                                                  subslice_)))
  #endif /* __INTEL_ENGINE_TYPES_H__ */
index 7765bd450797a240b270bda4b64d52bee037ca63,89b6112bd66b04a32a641407eb574d86006d257e..632cc12326044dcd6fc3f75f330a51dc2ed5cd8b
@@@ -67,7 -67,6 +67,7 @@@
  #include "display/intel_display.h"
  #include "display/intel_display_power.h"
  #include "display/intel_dpll_mgr.h"
 +#include "display/intel_dsb.h"
  #include "display/intel_frontbuffer.h"
  #include "display/intel_gmbus.h"
  #include "display/intel_opregion.h"
@@@ -85,7 -84,6 +85,7 @@@
  #include "intel_device_info.h"
  #include "intel_pch.h"
  #include "intel_runtime_pm.h"
 +#include "intel_memory_region.h"
  #include "intel_uncore.h"
  #include "intel_wakeref.h"
  #include "intel_wopcm.h"
  #include "i915_gem_fence_reg.h"
  #include "i915_gem_gtt.h"
  #include "i915_gpu_error.h"
 +#include "i915_perf_types.h"
  #include "i915_request.h"
  #include "i915_scheduler.h"
  #include "gt/intel_timeline.h"
  #include "i915_vma.h"
  #include "i915_irq.h"
  
 +#include "intel_region_lmem.h"
 +
  #include "intel_gvt.h"
  
  /* General customization:
  
  #define DRIVER_NAME           "i915"
  #define DRIVER_DESC           "Intel Graphics"
 -#define DRIVER_DATE           "20190822"
 -#define DRIVER_TIMESTAMP      1566477988
 +#define DRIVER_DATE           "20191101"
 +#define DRIVER_TIMESTAMP      1572604873
  
  struct drm_i915_gem_object;
  
@@@ -190,11 -185,7 +190,11 @@@ struct i915_mmu_object
  
  struct drm_i915_file_private {
        struct drm_i915_private *dev_priv;
 -      struct drm_file *file;
 +
 +      union {
 +              struct drm_file *file;
 +              struct rcu_head rcu;
 +      };
  
        struct {
                spinlock_t lock;
@@@ -281,7 -272,6 +281,7 @@@ struct drm_i915_display_funcs 
        int (*compute_global_watermarks)(struct intel_atomic_state *state);
        void (*update_wm)(struct intel_crtc *crtc);
        int (*modeset_calc_cdclk)(struct intel_atomic_state *state);
 +      u8 (*calc_voltage_level)(int cdclk);
        /* Returns the active state of the crtc, and if the crtc is active,
         * fills out the pipe-config with the hw state. */
        bool (*get_pipe_config)(struct intel_crtc *,
                            struct intel_atomic_state *old_state);
        void (*crtc_disable)(struct intel_crtc_state *old_crtc_state,
                             struct intel_atomic_state *old_state);
 -      void (*update_crtcs)(struct intel_atomic_state *state);
 +      void (*commit_modeset_enables)(struct intel_atomic_state *state);
 +      void (*commit_modeset_disables)(struct intel_atomic_state *state);
        void (*audio_codec_enable)(struct intel_encoder *encoder,
                                   const struct intel_crtc_state *crtc_state,
                                   const struct drm_connector_state *conn_state);
@@@ -342,7 -331,6 +342,7 @@@ struct intel_csr 
        i915_reg_t mmioaddr[20];
        u32 mmiodata[20];
        u32 dc_state;
 +      u32 target_dc_state;
        u32 allowed_dc_mask;
        intel_wakeref_t wakeref;
  };
@@@ -491,7 -479,6 +491,7 @@@ struct i915_psr 
        bool enabled;
        struct intel_dp *dp;
        enum pipe pipe;
 +      enum transcoder transcoder;
        bool active;
        struct work_struct work;
        unsigned busy_frontbuffer_bits;
        bool sink_not_reliable;
        bool irq_aux_error;
        u16 su_x_granularity;
 +      bool dc3co_enabled;
 +      u32 dc3co_exit_delay;
 +      struct delayed_work idle_work;
  };
  
  #define QUIRK_LVDS_SSC_DISABLE (1<<1)
@@@ -545,6 -529,108 +545,6 @@@ struct i915_suspend_saved_registers 
  
  struct vlv_s0ix_state;
  
 -struct intel_rps_ei {
 -      ktime_t ktime;
 -      u32 render_c0;
 -      u32 media_c0;
 -};
 -
 -struct intel_rps {
 -      struct mutex lock; /* protects enabling and the worker */
 -
 -      /*
 -       * work, interrupts_enabled and pm_iir are protected by
 -       * dev_priv->irq_lock
 -       */
 -      struct work_struct work;
 -      bool interrupts_enabled;
 -      u32 pm_iir;
 -
 -      /* PM interrupt bits that should never be masked */
 -      u32 pm_intrmsk_mbz;
 -
 -      /* Frequencies are stored in potentially platform dependent multiples.
 -       * In other words, *_freq needs to be multiplied by X to be interesting.
 -       * Soft limits are those which are used for the dynamic reclocking done
 -       * by the driver (raise frequencies under heavy loads, and lower for
 -       * lighter loads). Hard limits are those imposed by the hardware.
 -       *
 -       * A distinction is made for overclocking, which is never enabled by
 -       * default, and is considered to be above the hard limit if it's
 -       * possible at all.
 -       */
 -      u8 cur_freq;            /* Current frequency (cached, may not == HW) */
 -      u8 min_freq_softlimit;  /* Minimum frequency permitted by the driver */
 -      u8 max_freq_softlimit;  /* Max frequency permitted by the driver */
 -      u8 max_freq;            /* Maximum frequency, RP0 if not overclocking */
 -      u8 min_freq;            /* AKA RPn. Minimum frequency */
 -      u8 boost_freq;          /* Frequency to request when wait boosting */
 -      u8 idle_freq;           /* Frequency to request when we are idle */
 -      u8 efficient_freq;      /* AKA RPe. Pre-determined balanced frequency */
 -      u8 rp1_freq;            /* "less than" RP0 power/freqency */
 -      u8 rp0_freq;            /* Non-overclocked max frequency. */
 -      u16 gpll_ref_freq;      /* vlv/chv GPLL reference frequency */
 -
 -      int last_adj;
 -
 -      struct {
 -              struct mutex mutex;
 -
 -              enum { LOW_POWER, BETWEEN, HIGH_POWER } mode;
 -              unsigned int interactive;
 -
 -              u8 up_threshold; /* Current %busy required to uplock */
 -              u8 down_threshold; /* Current %busy required to downclock */
 -      } power;
 -
 -      bool enabled;
 -      atomic_t num_waiters;
 -      atomic_t boosts;
 -
 -      /* manual wa residency calculations */
 -      struct intel_rps_ei ei;
 -};
 -
 -struct intel_rc6 {
 -      bool enabled;
 -      bool ctx_corrupted;
 -      intel_wakeref_t ctx_corrupted_wakeref;
 -      u64 prev_hw_residency[4];
 -      u64 cur_residency[4];
 -};
 -
 -struct intel_llc_pstate {
 -      bool enabled;
 -};
 -
 -struct intel_gen6_power_mgmt {
 -      struct intel_rps rps;
 -      struct intel_rc6 rc6;
 -      struct intel_llc_pstate llc_pstate;
 -};
 -
 -/* defined intel_pm.c */
 -extern spinlock_t mchdev_lock;
 -
 -struct intel_ilk_power_mgmt {
 -      u8 cur_delay;
 -      u8 min_delay;
 -      u8 max_delay;
 -      u8 fmax;
 -      u8 fstart;
 -
 -      u64 last_count1;
 -      unsigned long last_time1;
 -      unsigned long chipset_power;
 -      u64 last_count2;
 -      u64 last_time2;
 -      unsigned long gfx_power;
 -      u8 corr;
 -
 -      int c_m;
 -      int r_t;
 -};
 -
  #define MAX_L3_SLICES 2
  struct intel_l3_parity {
        u32 *remap_info[MAX_L3_SLICES];
@@@ -593,8 -679,6 +593,8 @@@ struct i915_gem_mm 
         */
        struct vfsmount *gemfs;
  
 +      struct intel_memory_region *regions[INTEL_REGION_UNKNOWN];
 +
        struct notifier_block oom_notifier;
        struct notifier_block vmap_notifier;
        struct shrinker shrinker;
         */
        struct workqueue_struct *userptr_wq;
  
 -      /** Bit 6 swizzling required for X tiling */
 -      u32 bit_6_swizzle_x;
 -      /** Bit 6 swizzling required for Y tiling */
 -      u32 bit_6_swizzle_y;
 -
        /* shrinker accounting, also useful for userland debugging */
        u64 shrink_memory;
        u32 shrink_count;
@@@ -886,6 -975,305 +886,6 @@@ struct intel_wm_config 
        bool sprites_scaled;
  };
  
 -struct i915_oa_format {
 -      u32 format;
 -      int size;
 -};
 -
 -struct i915_oa_reg {
 -      i915_reg_t addr;
 -      u32 value;
 -};
 -
 -struct i915_oa_config {
 -      char uuid[UUID_STRING_LEN + 1];
 -      int id;
 -
 -      const struct i915_oa_reg *mux_regs;
 -      u32 mux_regs_len;
 -      const struct i915_oa_reg *b_counter_regs;
 -      u32 b_counter_regs_len;
 -      const struct i915_oa_reg *flex_regs;
 -      u32 flex_regs_len;
 -
 -      struct attribute_group sysfs_metric;
 -      struct attribute *attrs[2];
 -      struct device_attribute sysfs_metric_id;
 -
 -      atomic_t ref_count;
 -};
 -
 -struct i915_perf_stream;
 -
 -/**
 - * struct i915_perf_stream_ops - the OPs to support a specific stream type
 - */
 -struct i915_perf_stream_ops {
 -      /**
 -       * @enable: Enables the collection of HW samples, either in response to
 -       * `I915_PERF_IOCTL_ENABLE` or implicitly called when stream is opened
 -       * without `I915_PERF_FLAG_DISABLED`.
 -       */
 -      void (*enable)(struct i915_perf_stream *stream);
 -
 -      /**
 -       * @disable: Disables the collection of HW samples, either in response
 -       * to `I915_PERF_IOCTL_DISABLE` or implicitly called before destroying
 -       * the stream.
 -       */
 -      void (*disable)(struct i915_perf_stream *stream);
 -
 -      /**
 -       * @poll_wait: Call poll_wait, passing a wait queue that will be woken
 -       * once there is something ready to read() for the stream
 -       */
 -      void (*poll_wait)(struct i915_perf_stream *stream,
 -                        struct file *file,
 -                        poll_table *wait);
 -
 -      /**
 -       * @wait_unlocked: For handling a blocking read, wait until there is
 -       * something to ready to read() for the stream. E.g. wait on the same
 -       * wait queue that would be passed to poll_wait().
 -       */
 -      int (*wait_unlocked)(struct i915_perf_stream *stream);
 -
 -      /**
 -       * @read: Copy buffered metrics as records to userspace
 -       * **buf**: the userspace, destination buffer
 -       * **count**: the number of bytes to copy, requested by userspace
 -       * **offset**: zero at the start of the read, updated as the read
 -       * proceeds, it represents how many bytes have been copied so far and
 -       * the buffer offset for copying the next record.
 -       *
 -       * Copy as many buffered i915 perf samples and records for this stream
 -       * to userspace as will fit in the given buffer.
 -       *
 -       * Only write complete records; returning -%ENOSPC if there isn't room
 -       * for a complete record.
 -       *
 -       * Return any error condition that results in a short read such as
 -       * -%ENOSPC or -%EFAULT, even though these may be squashed before
 -       * returning to userspace.
 -       */
 -      int (*read)(struct i915_perf_stream *stream,
 -                  char __user *buf,
 -                  size_t count,
 -                  size_t *offset);
 -
 -      /**
 -       * @destroy: Cleanup any stream specific resources.
 -       *
 -       * The stream will always be disabled before this is called.
 -       */
 -      void (*destroy)(struct i915_perf_stream *stream);
 -};
 -
 -/**
 - * struct i915_perf_stream - state for a single open stream FD
 - */
 -struct i915_perf_stream {
 -      /**
 -       * @dev_priv: i915 drm device
 -       */
 -      struct drm_i915_private *dev_priv;
 -
 -      /**
 -       * @link: Links the stream into ``&drm_i915_private->streams``
 -       */
 -      struct list_head link;
 -
 -      /**
 -       * @wakeref: As we keep the device awake while the perf stream is
 -       * active, we track our runtime pm reference for later release.
 -       */
 -      intel_wakeref_t wakeref;
 -
 -      /**
 -       * @sample_flags: Flags representing the `DRM_I915_PERF_PROP_SAMPLE_*`
 -       * properties given when opening a stream, representing the contents
 -       * of a single sample as read() by userspace.
 -       */
 -      u32 sample_flags;
 -
 -      /**
 -       * @sample_size: Considering the configured contents of a sample
 -       * combined with the required header size, this is the total size
 -       * of a single sample record.
 -       */
 -      int sample_size;
 -
 -      /**
 -       * @ctx: %NULL if measuring system-wide across all contexts or a
 -       * specific context that is being monitored.
 -       */
 -      struct i915_gem_context *ctx;
 -
 -      /**
 -       * @enabled: Whether the stream is currently enabled, considering
 -       * whether the stream was opened in a disabled state and based
 -       * on `I915_PERF_IOCTL_ENABLE` and `I915_PERF_IOCTL_DISABLE` calls.
 -       */
 -      bool enabled;
 -
 -      /**
 -       * @ops: The callbacks providing the implementation of this specific
 -       * type of configured stream.
 -       */
 -      const struct i915_perf_stream_ops *ops;
 -
 -      /**
 -       * @oa_config: The OA configuration used by the stream.
 -       */
 -      struct i915_oa_config *oa_config;
 -
 -      /**
 -       * The OA context specific information.
 -       */
 -      struct intel_context *pinned_ctx;
 -      u32 specific_ctx_id;
 -      u32 specific_ctx_id_mask;
 -
 -      struct hrtimer poll_check_timer;
 -      wait_queue_head_t poll_wq;
 -      bool pollin;
 -
 -      bool periodic;
 -      int period_exponent;
 -
 -      /**
 -       * State of the OA buffer.
 -       */
 -      struct {
 -              struct i915_vma *vma;
 -              u8 *vaddr;
 -              u32 last_ctx_id;
 -              int format;
 -              int format_size;
 -              int size_exponent;
 -
 -              /**
 -               * Locks reads and writes to all head/tail state
 -               *
 -               * Consider: the head and tail pointer state needs to be read
 -               * consistently from a hrtimer callback (atomic context) and
 -               * read() fop (user context) with tail pointer updates happening
 -               * in atomic context and head updates in user context and the
 -               * (unlikely) possibility of read() errors needing to reset all
 -               * head/tail state.
 -               *
 -               * Note: Contention/performance aren't currently a significant
 -               * concern here considering the relatively low frequency of
 -               * hrtimer callbacks (5ms period) and that reads typically only
 -               * happen in response to a hrtimer event and likely complete
 -               * before the next callback.
 -               *
 -               * Note: This lock is not held *while* reading and copying data
 -               * to userspace so the value of head observed in htrimer
 -               * callbacks won't represent any partial consumption of data.
 -               */
 -              spinlock_t ptr_lock;
 -
 -              /**
 -               * One 'aging' tail pointer and one 'aged' tail pointer ready to
 -               * used for reading.
 -               *
 -               * Initial values of 0xffffffff are invalid and imply that an
 -               * update is required (and should be ignored by an attempted
 -               * read)
 -               */
 -              struct {
 -                      u32 offset;
 -              } tails[2];
 -
 -              /**
 -               * Index for the aged tail ready to read() data up to.
 -               */
 -              unsigned int aged_tail_idx;
 -
 -              /**
 -               * A monotonic timestamp for when the current aging tail pointer
 -               * was read; used to determine when it is old enough to trust.
 -               */
 -              u64 aging_timestamp;
 -
 -              /**
 -               * Although we can always read back the head pointer register,
 -               * we prefer to avoid trusting the HW state, just to avoid any
 -               * risk that some hardware condition could * somehow bump the
 -               * head pointer unpredictably and cause us to forward the wrong
 -               * OA buffer data to userspace.
 -               */
 -              u32 head;
 -      } oa_buffer;
 -};
 -
 -/**
 - * struct i915_oa_ops - Gen specific implementation of an OA unit stream
 - */
 -struct i915_oa_ops {
 -      /**
 -       * @is_valid_b_counter_reg: Validates register's address for
 -       * programming boolean counters for a particular platform.
 -       */
 -      bool (*is_valid_b_counter_reg)(struct drm_i915_private *dev_priv,
 -                                     u32 addr);
 -
 -      /**
 -       * @is_valid_mux_reg: Validates register's address for programming mux
 -       * for a particular platform.
 -       */
 -      bool (*is_valid_mux_reg)(struct drm_i915_private *dev_priv, u32 addr);
 -
 -      /**
 -       * @is_valid_flex_reg: Validates register's address for programming
 -       * flex EU filtering for a particular platform.
 -       */
 -      bool (*is_valid_flex_reg)(struct drm_i915_private *dev_priv, u32 addr);
 -
 -      /**
 -       * @enable_metric_set: Selects and applies any MUX configuration to set
 -       * up the Boolean and Custom (B/C) counters that are part of the
 -       * counter reports being sampled. May apply system constraints such as
 -       * disabling EU clock gating as required.
 -       */
 -      int (*enable_metric_set)(struct i915_perf_stream *stream);
 -
 -      /**
 -       * @disable_metric_set: Remove system constraints associated with using
 -       * the OA unit.
 -       */
 -      void (*disable_metric_set)(struct i915_perf_stream *stream);
 -
 -      /**
 -       * @oa_enable: Enable periodic sampling
 -       */
 -      void (*oa_enable)(struct i915_perf_stream *stream);
 -
 -      /**
 -       * @oa_disable: Disable periodic sampling
 -       */
 -      void (*oa_disable)(struct i915_perf_stream *stream);
 -
 -      /**
 -       * @read: Copy data from the circular OA buffer into a given userspace
 -       * buffer.
 -       */
 -      int (*read)(struct i915_perf_stream *stream,
 -                  char __user *buf,
 -                  size_t count,
 -                  size_t *offset);
 -
 -      /**
 -       * @oa_hw_tail_read: read the OA tail pointer register
 -       *
 -       * In particular this enables us to share all the fiddly code for
 -       * handling the OA unit tail pointer race that affects multiple
 -       * generations.
 -       */
 -      u32 (*oa_hw_tail_read)(struct i915_perf_stream *stream);
 -};
 -
  struct intel_cdclk_state {
        unsigned int cdclk, vco, ref, bypass;
        u8 voltage_level;
@@@ -945,11 -1333,11 +945,11 @@@ struct drm_i915_private 
         */
        u32 gpio_mmio_base;
  
 +      u32 hsw_psr_mmio_adjust;
 +
        /* MMIO base address for MIPI regs */
        u32 mipi_mmio_base;
  
 -      u32 psr_mmio_base;
 -
        u32 pps_mmio_base;
  
        wait_queue_head_t gmbus_wait_queue;
                u32 irq_mask;
                u32 de_irq_mask[I915_MAX_PIPES];
        };
 -      u32 pm_rps_events;
        u32 pipestat_irq_mask[I915_MAX_PIPES];
  
        struct i915_hotplug hotplug;
        unsigned int fdi_pll_freq;
        unsigned int czclk_freq;
  
 +      /*
 +       * For reading holding any crtc lock is sufficient,
 +       * for writing must hold all of them.
 +       */
        struct {
                /*
                 * The current logical cdclk state.
                 * See intel_atomic_state.cdclk.logical
 -               *
 -               * For reading holding any crtc lock is sufficient,
 -               * for writing must hold all of them.
                 */
                struct intel_cdclk_state logical;
                /*
                /* The current hardware cdclk state */
                struct intel_cdclk_state hw;
  
 +              /* cdclk, divider, and ratio table from bspec */
 +              const struct intel_cdclk_vals *table;
 +
                int force_min_cdclk;
        } cdclk;
  
  
        /* ordered wq for modesets */
        struct workqueue_struct *modeset_wq;
 +      /* unbound hipri wq for page flips/plane updates */
 +      struct workqueue_struct *flip_wq;
  
        /* Display functions */
        struct drm_i915_display_funcs display;
         */
        struct mutex dpll_lock;
  
 -      unsigned int active_crtcs;
 +      /*
 +       * For reading active_pipes, min_cdclk, min_voltage_level holding
 +       * any crtc lock is sufficient, for writing must hold all of them.
 +       */
 +      u8 active_pipes;
        /* minimum acceptable cdclk for each pipe */
        int min_cdclk[I915_MAX_PIPES];
        /* minimum acceptable voltage level for each pipe */
         */
        u32 edram_size_mb;
  
 -      /* gen6+ GT PM state */
 -      struct intel_gen6_power_mgmt gt_pm;
 -
 -      /* ilk-only ips/rps state. Everything in here is protected by the global
 -       * mchdev_lock in intel_pm.c */
 -      struct intel_ilk_power_mgmt ips;
 -
        struct i915_power_domains power_domains;
  
        struct i915_psr psr;
         */
        struct mutex av_mutex;
        int audio_power_refcount;
 -
 -      struct {
 -              struct mutex mutex;
 -              struct list_head list;
 -              struct llist_head free_list;
 -              struct work_struct free_work;
 -
 -              /* The hw wants to have a stable context identifier for the
 -               * lifetime of the context (for OA, PASID, faults, etc).
 -               * This is limited in execlists to 21 bits.
 -               */
 -              struct ida hw_ida;
 -#define MAX_CONTEXT_HW_ID (1<<21) /* exclusive */
 -#define MAX_GUC_CONTEXT_HW_ID (1 << 20) /* exclusive */
 -#define GEN11_MAX_CONTEXT_HW_ID (1<<11) /* exclusive */
 -/* in Gen12 ID 0x7FF is reserved to indicate idle */
 -#define GEN12_MAX_CONTEXT_HW_ID       (GEN11_MAX_CONTEXT_HW_ID - 1)
 -              struct list_head hw_id_list;
 -      } contexts;
 +      u32 audio_freq_cntrl;
  
        u32 fdi_rx_config;
  
                I915_SAGV_NOT_CONTROLLED
        } sagv_status;
  
 +      u32 sagv_block_time_us;
 +
        struct {
                /*
                 * Raw watermark latency values:
  
        struct intel_runtime_pm runtime_pm;
  
 -      struct {
 -              bool initialized;
 -
 -              struct kobject *metrics_kobj;
 -              struct ctl_table_header *sysctl_header;
 -
 -              /*
 -               * Lock associated with adding/modifying/removing OA configs
 -               * in dev_priv->perf.metrics_idr.
 -               */
 -              struct mutex metrics_lock;
 -
 -              /*
 -               * List of dynamic configurations, you need to hold
 -               * dev_priv->perf.metrics_lock to access it.
 -               */
 -              struct idr metrics_idr;
 -
 -              /*
 -               * Lock associated with anything below within this structure
 -               * except exclusive_stream.
 -               */
 -              struct mutex lock;
 -              struct list_head streams;
 -
 -              /*
 -               * The stream currently using the OA unit. If accessed
 -               * outside a syscall associated to its file
 -               * descriptor, you need to hold
 -               * dev_priv->drm.struct_mutex.
 -               */
 -              struct i915_perf_stream *exclusive_stream;
 -
 -              /**
 -               * For rate limiting any notifications of spurious
 -               * invalid OA reports
 -               */
 -              struct ratelimit_state spurious_report_rs;
 -
 -              struct i915_oa_config test_config;
 -
 -              u32 gen7_latched_oastatus1;
 -              u32 ctx_oactxctrl_offset;
 -              u32 ctx_flexeu0_offset;
 -
 -              /**
 -               * The RPT_ID/reason field for Gen8+ includes a bit
 -               * to determine if the CTX ID in the report is valid
 -               * but the specific bit differs between Gen 8 and 9
 -               */
 -              u32 gen8_valid_ctx_bit;
 -
 -              struct i915_oa_ops ops;
 -              const struct i915_oa_format *oa_formats;
 -      } perf;
 +      struct i915_perf perf;
  
        /* Abstract the submission mechanism (legacy ringbuffer or execlists) away */
        struct intel_gt gt;
        struct {
                struct notifier_block pm_notifier;
  
 -              /**
 -               * We leave the user IRQ off as much as possible,
 -               * but this means that requests will finish and never
 -               * be retired once the system goes idle. Set a timer to
 -               * fire periodically while the ring is running. When it
 -               * fires, go retire requests.
 -               */
 -              struct delayed_work retire_work;
 -
 -              /**
 -               * When we detect an idle GPU, we want to turn on
 -               * powersaving features. So once we see that there
 -               * are no more requests outstanding and no more
 -               * arrive within a small period of time, we fire
 -               * off the idle_work.
 -               */
 -              struct work_struct idle_work;
 +              struct i915_gem_contexts {
 +                      spinlock_t lock; /* locks list */
 +                      struct list_head list;
 +
 +                      struct llist_head free_list;
 +                      struct work_struct free_work;
 +              } contexts;
        } gem;
  
        u8 pch_ssc_use;
  
 -      /* For i945gm vblank irq vs. C3 workaround */
 -      struct {
 -              struct work_struct work;
 -              struct pm_qos_request pm_qos;
 -              u8 c3_disable_latency;
 -              u8 enabled;
 -      } i945gm_vblank;
 +      /* For i915gm/i945gm vblank irq workaround */
 +      u8 vblank_enabled;
  
        /* perform PHY state sanity checks? */
        bool chv_phy_assert[2];
@@@ -1325,10 -1796,10 +1325,10 @@@ static inline struct drm_i915_private *
                for_each_if ((engine__) = (dev_priv__)->engine[(id__)])
  
  /* Iterator over subset of engines selected by mask */
 -#define for_each_engine_masked(engine__, dev_priv__, mask__, tmp__) \
 -      for ((tmp__) = (mask__) & INTEL_INFO(dev_priv__)->engine_mask; \
 +#define for_each_engine_masked(engine__, gt__, mask__, tmp__) \
 +      for ((tmp__) = (mask__) & INTEL_INFO((gt__)->i915)->engine_mask; \
             (tmp__) ? \
 -           ((engine__) = (dev_priv__)->engine[__mask_next_bit(tmp__)]), 1 : \
 +           ((engine__) = (gt__)->engine[__mask_next_bit(tmp__)]), 1 : \
             0;)
  
  #define rb_to_uabi_engine(rb) \
        (BUILD_BUG_ON_ZERO(!__builtin_constant_p(n)) + \
         INTEL_INFO(dev_priv)->gen == (n))
  
 +#define HAS_DSB(dev_priv)     (INTEL_INFO(dev_priv)->display.has_dsb)
 +
  /*
   * Return true if revision is in range [since,until] inclusive.
   *
@@@ -1457,7 -1926,6 +1457,7 @@@ IS_SUBPLATFORM(const struct drm_i915_pr
  }
  
  #define IS_MOBILE(dev_priv)   (INTEL_INFO(dev_priv)->is_mobile)
 +#define IS_DGFX(dev_priv)   (INTEL_INFO(dev_priv)->is_dgfx)
  
  #define IS_I830(dev_priv)     IS_PLATFORM(dev_priv, INTEL_I830)
  #define IS_I845G(dev_priv)    IS_PLATFORM(dev_priv, INTEL_I845G)
  #define IS_ICL_REVID(p, since, until) \
        (IS_ICELAKE(p) && IS_REVID(p, since, until))
  
 +#define TGL_REVID_A0          0x0
 +
 +#define IS_TGL_REVID(p, since, until) \
 +      (IS_TIGERLAKE(p) && IS_REVID(p, since, until))
 +
  #define IS_LP(dev_priv)       (INTEL_INFO(dev_priv)->is_lp)
  #define IS_GEN9_LP(dev_priv)  (IS_GEN(dev_priv, 9) && IS_LP(dev_priv))
  #define IS_GEN9_BC(dev_priv)  (IS_GEN(dev_priv, 9) && !IS_LP(dev_priv))
  #define VEBOX_MASK(dev_priv) \
        ENGINE_INSTANCES_MASK(dev_priv, VECS0, I915_MAX_VECS)
  
+ /*
+  * The Gen7 cmdparser copies the scanned buffer to the ggtt for execution
+  * All later gens can run the final buffer from the ppgtt
+  */
+ #define CMDPARSER_USES_GGTT(dev_priv) IS_GEN(dev_priv, 7)
  #define HAS_LLC(dev_priv)     (INTEL_INFO(dev_priv)->has_llc)
  #define HAS_SNOOP(dev_priv)   (INTEL_INFO(dev_priv)->has_snoop)
  #define HAS_EDRAM(dev_priv)   ((dev_priv)->edram_size_mb)
+ #define HAS_SECURE_BATCHES(dev_priv) (INTEL_GEN(dev_priv) < 6)
  #define HAS_WT(dev_priv)      ((IS_HASWELL(dev_priv) || \
                                 IS_BROADWELL(dev_priv)) && HAS_EDRAM(dev_priv))
  
  
  #define HAS_IPC(dev_priv)              (INTEL_INFO(dev_priv)->display.has_ipc)
  
 +#define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i))
 +#define HAS_LMEM(i915) HAS_REGION(i915, REGION_LMEM)
 +
  #define HAS_GT_UC(dev_priv)   (INTEL_INFO(dev_priv)->has_gt_uc)
  
  /* Having GuC is not the same as using GuC */
  #define GT_FREQUENCY_MULTIPLIER 50
  #define GEN9_FREQ_SCALER 3
  
 -#define HAS_DISPLAY(dev_priv) (INTEL_INFO(dev_priv)->num_pipes > 0)
 +#define INTEL_NUM_PIPES(dev_priv) (hweight8(INTEL_INFO(dev_priv)->pipe_mask))
 +
 +#define HAS_DISPLAY(dev_priv) (INTEL_INFO(dev_priv)->pipe_mask != 0)
 +
 +/* Only valid when HAS_DISPLAY() is true */
 +#define INTEL_DISPLAY_ENABLED(dev_priv) (WARN_ON(!HAS_DISPLAY(dev_priv)), !i915_modparams.disable_display)
  
  static inline bool intel_vtd_active(void)
  {
@@@ -1760,9 -2222,7 +1767,9 @@@ extern const struct dev_pm_ops i915_pm_
  int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
  void i915_driver_remove(struct drm_i915_private *i915);
  
 -void intel_engine_init_hangcheck(struct intel_engine_cs *engine);
 +int i915_resume_switcheroo(struct drm_i915_private *i915);
 +int i915_suspend_switcheroo(struct drm_i915_private *i915, pm_message_t state);
 +
  int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool on);
  
  static inline bool intel_gvt_active(struct drm_i915_private *dev_priv)
@@@ -1781,13 -2241,12 +1788,13 @@@ int i915_getparam_ioctl(struct drm_devi
  /* i915_gem.c */
  int i915_gem_init_userptr(struct drm_i915_private *dev_priv);
  void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv);
 -void i915_gem_sanitize(struct drm_i915_private *i915);
 -int i915_gem_init_early(struct drm_i915_private *dev_priv);
 +void i915_gem_init_early(struct drm_i915_private *dev_priv);
  void i915_gem_cleanup_early(struct drm_i915_private *dev_priv);
  int i915_gem_freeze(struct drm_i915_private *dev_priv);
  int i915_gem_freeze_late(struct drm_i915_private *dev_priv);
  
 +struct intel_memory_region *i915_gem_shmem_setup(struct drm_i915_private *i915);
 +
  static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
  {
        /*
@@@ -1836,6 -2295,14 +1843,14 @@@ int i915_gem_object_unbind(struct drm_i
                           unsigned long flags);
  #define I915_GEM_OBJECT_UNBIND_ACTIVE BIT(0)
  
+ struct i915_vma * __must_check
+ i915_gem_object_pin(struct drm_i915_gem_object *obj,
+                   struct i915_address_space *vm,
+                   const struct i915_ggtt_view *view,
+                   u64 size,
+                   u64 alignment,
+                   u64 flags);
  void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv);
  
  static inline int __must_check
@@@ -1864,11 -2331,15 +1879,11 @@@ static inline u32 i915_reset_engine_cou
        return atomic_read(&error->reset_engine_count[engine->uabi_class]);
  }
  
 -void i915_gem_init_mmio(struct drm_i915_private *i915);
  int __must_check i915_gem_init(struct drm_i915_private *dev_priv);
 -int __must_check i915_gem_init_hw(struct drm_i915_private *dev_priv);
  void i915_gem_driver_register(struct drm_i915_private *i915);
  void i915_gem_driver_unregister(struct drm_i915_private *i915);
  void i915_gem_driver_remove(struct drm_i915_private *dev_priv);
  void i915_gem_driver_release(struct drm_i915_private *dev_priv);
 -int i915_gem_wait_for_idle(struct drm_i915_private *dev_priv,
 -                         unsigned int flags, long timeout);
  void i915_gem_suspend(struct drm_i915_private *dev_priv);
  void i915_gem_suspend_late(struct drm_i915_private *dev_priv);
  void i915_gem_resume(struct drm_i915_private *dev_priv);
@@@ -1908,7 -2379,7 +1923,7 @@@ i915_gem_context_lookup(struct drm_i915
  /* i915_gem_evict.c */
  int __must_check i915_gem_evict_something(struct i915_address_space *vm,
                                          u64 min_size, u64 alignment,
 -                                        unsigned cache_level,
 +                                        unsigned long color,
                                          u64 start, u64 end,
                                          unsigned flags);
  int __must_check i915_gem_evict_for_node(struct i915_address_space *vm,
@@@ -1924,9 -2395,9 +1939,9 @@@ i915_gem_object_create_internal(struct 
  /* i915_gem_tiling.c */
  static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
  {
 -      struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
 +      struct drm_i915_private *i915 = to_i915(obj->base.dev);
  
 -      return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&
 +      return i915->ggtt.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&
                i915_gem_object_is_tiled(obj);
  }
  
@@@ -1941,12 -2412,14 +1956,14 @@@ const char *i915_cache_level_str(struc
  int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv);
  void intel_engine_init_cmd_parser(struct intel_engine_cs *engine);
  void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine);
- int intel_engine_cmd_parser(struct intel_engine_cs *engine,
+ int intel_engine_cmd_parser(struct i915_gem_context *cxt,
+                           struct intel_engine_cs *engine,
                            struct drm_i915_gem_object *batch_obj,
-                           struct drm_i915_gem_object *shadow_batch_obj,
+                           u64 user_batch_start,
                            u32 batch_start_offset,
                            u32 batch_len,
-                           bool is_master);
+                           struct drm_i915_gem_object *shadow_batch_obj,
+                           u64 shadow_batch_start);
  
  /* intel_device_info.c */
  static inline struct intel_device_info *
index ac23322fb3826378ed9c45c899c0c7f99b84d47f,98305d987ac14b366ccad231752e7ed4e1be4577..b9eb6b3149b711cea3a4a1673c5ae6bcf7c7bc23
  #include "gem/i915_gem_context.h"
  #include "gem/i915_gem_ioctls.h"
  #include "gem/i915_gem_pm.h"
 -#include "gem/i915_gemfs.h"
  #include "gt/intel_engine_user.h"
  #include "gt/intel_gt.h"
  #include "gt/intel_gt_pm.h"
 +#include "gt/intel_gt_requests.h"
  #include "gt/intel_mocs.h"
  #include "gt/intel_reset.h"
  #include "gt/intel_renderstate.h"
 +#include "gt/intel_rps.h"
  #include "gt/intel_workarounds.h"
  
  #include "i915_drv.h"
  #include "intel_pm.h"
  
  static int
 -insert_mappable_node(struct i915_ggtt *ggtt,
 -                     struct drm_mm_node *node, u32 size)
 +insert_mappable_node(struct i915_ggtt *ggtt, struct drm_mm_node *node, u32 size)
  {
 +      int err;
 +
 +      err = mutex_lock_interruptible(&ggtt->vm.mutex);
 +      if (err)
 +              return err;
 +
        memset(node, 0, sizeof(*node));
 -      return drm_mm_insert_node_in_range(&ggtt->vm.mm, node,
 -                                         size, 0, I915_COLOR_UNEVICTABLE,
 -                                         0, ggtt->mappable_end,
 -                                         DRM_MM_INSERT_LOW);
 +      err = drm_mm_insert_node_in_range(&ggtt->vm.mm, node,
 +                                        size, 0, I915_COLOR_UNEVICTABLE,
 +                                        0, ggtt->mappable_end,
 +                                        DRM_MM_INSERT_LOW);
 +
 +      mutex_unlock(&ggtt->vm.mutex);
 +
 +      return err;
  }
  
  static void
 -remove_mappable_node(struct drm_mm_node *node)
 +remove_mappable_node(struct i915_ggtt *ggtt, struct drm_mm_node *node)
  {
 +      mutex_lock(&ggtt->vm.mutex);
        drm_mm_remove_node(node);
 +      mutex_unlock(&ggtt->vm.mutex);
  }
  
  int
@@@ -99,8 -87,7 +99,8 @@@ i915_gem_get_aperture_ioctl(struct drm_
        struct i915_vma *vma;
        u64 pinned;
  
 -      mutex_lock(&ggtt->vm.mutex);
 +      if (mutex_lock_interruptible(&ggtt->vm.mutex))
 +              return -EINTR;
  
        pinned = ggtt->vm.reserved;
        list_for_each_entry(vma, &ggtt->vm.bound_list, vm_link)
@@@ -122,24 -109,20 +122,24 @@@ int i915_gem_object_unbind(struct drm_i
        LIST_HEAD(still_in_list);
        int ret = 0;
  
 -      lockdep_assert_held(&obj->base.dev->struct_mutex);
 -
        spin_lock(&obj->vma.lock);
        while (!ret && (vma = list_first_entry_or_null(&obj->vma.list,
                                                       struct i915_vma,
                                                       obj_link))) {
 +              struct i915_address_space *vm = vma->vm;
 +
 +              ret = -EBUSY;
 +              if (!i915_vm_tryopen(vm))
 +                      break;
 +
                list_move_tail(&vma->obj_link, &still_in_list);
                spin_unlock(&obj->vma.lock);
  
 -              ret = -EBUSY;
                if (flags & I915_GEM_OBJECT_UNBIND_ACTIVE ||
                    !i915_vma_is_active(vma))
                        ret = i915_vma_unbind(vma);
  
 +              i915_vm_close(vm);
                spin_lock(&obj->vma.lock);
        }
        list_splice(&still_in_list, &obj->vma.list);
@@@ -355,6 -338,10 +355,6 @@@ i915_gem_gtt_pread(struct drm_i915_gem_
        u64 remain, offset;
        int ret;
  
 -      ret = mutex_lock_interruptible(&i915->drm.struct_mutex);
 -      if (ret)
 -              return ret;
 -
        wakeref = intel_runtime_pm_get(&i915->runtime_pm);
        vma = ERR_PTR(-ENODEV);
        if (!i915_gem_object_is_tiled(obj))
                                               PIN_NOEVICT);
        if (!IS_ERR(vma)) {
                node.start = i915_ggtt_offset(vma);
 -              node.allocated = false;
 +              node.flags = 0;
        } else {
                ret = insert_mappable_node(ggtt, &node, PAGE_SIZE);
                if (ret)
 -                      goto out_unlock;
 -              GEM_BUG_ON(!node.allocated);
 +                      goto out_rpm;
 +              GEM_BUG_ON(!drm_mm_node_allocated(&node));
        }
  
 -      mutex_unlock(&i915->drm.struct_mutex);
 -
        ret = i915_gem_object_lock_interruptible(obj);
        if (ret)
                goto out_unpin;
                unsigned page_offset = offset_in_page(offset);
                unsigned page_length = PAGE_SIZE - page_offset;
                page_length = remain < page_length ? remain : page_length;
 -              if (node.allocated) {
 +              if (drm_mm_node_allocated(&node)) {
                        ggtt->vm.insert_page(&ggtt->vm,
                                             i915_gem_object_get_dma_address(obj, offset >> PAGE_SHIFT),
                                             node.start, I915_CACHE_NONE, 0);
  
        i915_gem_object_unlock_fence(obj, fence);
  out_unpin:
 -      mutex_lock(&i915->drm.struct_mutex);
 -      if (node.allocated) {
 +      if (drm_mm_node_allocated(&node)) {
                ggtt->vm.clear_range(&ggtt->vm, node.start, node.size);
 -              remove_mappable_node(&node);
 +              remove_mappable_node(ggtt, &node);
        } else {
                i915_vma_unpin(vma);
        }
 -out_unlock:
 +out_rpm:
        intel_runtime_pm_put(&i915->runtime_pm, wakeref);
 -      mutex_unlock(&i915->drm.struct_mutex);
 -
        return ret;
  }
  
@@@ -539,6 -531,10 +539,6 @@@ i915_gem_gtt_pwrite_fast(struct drm_i91
        void __user *user_data;
        int ret;
  
 -      ret = mutex_lock_interruptible(&i915->drm.struct_mutex);
 -      if (ret)
 -              return ret;
 -
        if (i915_gem_object_has_struct_page(obj)) {
                /*
                 * Avoid waking the device up if we can fallback, as
                 * using the cache bypass of indirect GGTT access.
                 */
                wakeref = intel_runtime_pm_get_if_in_use(rpm);
 -              if (!wakeref) {
 -                      ret = -EFAULT;
 -                      goto out_unlock;
 -              }
 +              if (!wakeref)
 +                      return -EFAULT;
        } else {
                /* No backing pages, no fallback, we must force GGTT access */
                wakeref = intel_runtime_pm_get(rpm);
                                               PIN_NOEVICT);
        if (!IS_ERR(vma)) {
                node.start = i915_ggtt_offset(vma);
 -              node.allocated = false;
 +              node.flags = 0;
        } else {
                ret = insert_mappable_node(ggtt, &node, PAGE_SIZE);
                if (ret)
                        goto out_rpm;
 -              GEM_BUG_ON(!node.allocated);
 +              GEM_BUG_ON(!drm_mm_node_allocated(&node));
        }
  
 -      mutex_unlock(&i915->drm.struct_mutex);
 -
        ret = i915_gem_object_lock_interruptible(obj);
        if (ret)
                goto out_unpin;
                unsigned int page_offset = offset_in_page(offset);
                unsigned int page_length = PAGE_SIZE - page_offset;
                page_length = remain < page_length ? remain : page_length;
 -              if (node.allocated) {
 +              if (drm_mm_node_allocated(&node)) {
                        /* flush the write before we modify the GGTT */
                        intel_gt_flush_ggtt_writes(ggtt->vm.gt);
                        ggtt->vm.insert_page(&ggtt->vm,
  
        i915_gem_object_unlock_fence(obj, fence);
  out_unpin:
 -      mutex_lock(&i915->drm.struct_mutex);
        intel_gt_flush_ggtt_writes(ggtt->vm.gt);
 -      if (node.allocated) {
 +      if (drm_mm_node_allocated(&node)) {
                ggtt->vm.clear_range(&ggtt->vm, node.start, node.size);
 -              remove_mappable_node(&node);
 +              remove_mappable_node(ggtt, &node);
        } else {
                i915_vma_unpin(vma);
        }
  out_rpm:
        intel_runtime_pm_put(rpm, wakeref);
 -out_unlock:
 -      mutex_unlock(&i915->drm.struct_mutex);
        return ret;
  }
  
@@@ -884,6 -887,74 +884,6 @@@ void i915_gem_runtime_suspend(struct dr
        }
  }
  
 -static long
 -wait_for_timelines(struct drm_i915_private *i915,
 -                 unsigned int wait, long timeout)
 -{
 -      struct intel_gt_timelines *timelines = &i915->gt.timelines;
 -      struct intel_timeline *tl;
 -      unsigned long flags;
 -
 -      spin_lock_irqsave(&timelines->lock, flags);
 -      list_for_each_entry(tl, &timelines->active_list, link) {
 -              struct i915_request *rq;
 -
 -              rq = i915_active_request_get_unlocked(&tl->last_request);
 -              if (!rq)
 -                      continue;
 -
 -              spin_unlock_irqrestore(&timelines->lock, flags);
 -
 -              /*
 -               * "Race-to-idle".
 -               *
 -               * Switching to the kernel context is often used a synchronous
 -               * step prior to idling, e.g. in suspend for flushing all
 -               * current operations to memory before sleeping. These we
 -               * want to complete as quickly as possible to avoid prolonged
 -               * stalls, so allow the gpu to boost to maximum clocks.
 -               */
 -              if (wait & I915_WAIT_FOR_IDLE_BOOST)
 -                      gen6_rps_boost(rq);
 -
 -              timeout = i915_request_wait(rq, wait, timeout);
 -              i915_request_put(rq);
 -              if (timeout < 0)
 -                      return timeout;
 -
 -              /* restart after reacquiring the lock */
 -              spin_lock_irqsave(&timelines->lock, flags);
 -              tl = list_entry(&timelines->active_list, typeof(*tl), link);
 -      }
 -      spin_unlock_irqrestore(&timelines->lock, flags);
 -
 -      return timeout;
 -}
 -
 -int i915_gem_wait_for_idle(struct drm_i915_private *i915,
 -                         unsigned int flags, long timeout)
 -{
 -      /* If the device is asleep, we have no requests outstanding */
 -      if (!intel_gt_pm_is_awake(&i915->gt))
 -              return 0;
 -
 -      GEM_TRACE("flags=%x (%s), timeout=%ld%s\n",
 -                flags, flags & I915_WAIT_LOCKED ? "locked" : "unlocked",
 -                timeout, timeout == MAX_SCHEDULE_TIMEOUT ? " (forever)" : "");
 -
 -      timeout = wait_for_timelines(i915, flags, timeout);
 -      if (timeout < 0)
 -              return timeout;
 -
 -      if (flags & I915_WAIT_LOCKED) {
 -              lockdep_assert_held(&i915->drm.struct_mutex);
 -
 -              i915_retire_requests(i915);
 -      }
 -
 -      return 0;
 -}
 -
  struct i915_vma *
  i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
                         const struct i915_ggtt_view *view,
  {
        struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
        struct i915_address_space *vm = &dev_priv->ggtt.vm;
+       return i915_gem_object_pin(obj, vm, view, size, alignment,
+                                  flags | PIN_GLOBAL);
+ }
+ struct i915_vma *
+ i915_gem_object_pin(struct drm_i915_gem_object *obj,
+                   struct i915_address_space *vm,
+                   const struct i915_ggtt_view *view,
+                   u64 size,
+                   u64 alignment,
+                   u64 flags)
+ {
+       struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
        struct i915_vma *vma;
        int ret;
  
 -      lockdep_assert_held(&obj->base.dev->struct_mutex);
 -
        if (i915_gem_object_never_bind_ggtt(obj))
                return ERR_PTR(-ENODEV);
  
                                return ERR_PTR(-ENOSPC);
                }
  
 -              WARN(i915_vma_is_pinned(vma),
 -                   "bo is already pinned in ggtt with incorrect alignment:"
 -                   " offset=%08x, req.alignment=%llx,"
 -                   " req.map_and_fenceable=%d, vma->map_and_fenceable=%d\n",
 -                   i915_ggtt_offset(vma), alignment,
 -                   !!(flags & PIN_MAPPABLE),
 -                   i915_vma_is_map_and_fenceable(vma));
                ret = i915_vma_unbind(vma);
                if (ret)
                        return ERR_PTR(ret);
                        return ERR_PTR(ret);
        }
  
-       ret = i915_vma_pin(vma, size, alignment, flags | PIN_GLOBAL);
+       ret = i915_vma_pin(vma, size, alignment, flags);
        if (ret)
                return ERR_PTR(ret);
  
        return err;
  }
  
 -void i915_gem_sanitize(struct drm_i915_private *i915)
 -{
 -      intel_wakeref_t wakeref;
 -
 -      GEM_TRACE("\n");
 -
 -      wakeref = intel_runtime_pm_get(&i915->runtime_pm);
 -      intel_uncore_forcewake_get(&i915->uncore, FORCEWAKE_ALL);
 -
 -      /*
 -       * As we have just resumed the machine and woken the device up from
 -       * deep PCI sleep (presumably D3_cold), assume the HW has been reset
 -       * back to defaults, recovering from whatever wedged state we left it
 -       * in and so worth trying to use the device once more.
 -       */
 -      if (intel_gt_is_wedged(&i915->gt))
 -              intel_gt_unset_wedged(&i915->gt);
 -
 -      /*
 -       * If we inherit context state from the BIOS or earlier occupants
 -       * of the GPU, the GPU may be in an inconsistent state when we
 -       * try to take over. The only way to remove the earlier state
 -       * is by resetting. However, resetting on earlier gen is tricky as
 -       * it may impact the display and we are uncertain about the stability
 -       * of the reset, so this could be applied to even earlier gen.
 -       */
 -      intel_gt_sanitize(&i915->gt, false);
 -
 -      intel_uncore_forcewake_put(&i915->uncore, FORCEWAKE_ALL);
 -      intel_runtime_pm_put(&i915->runtime_pm, wakeref);
 -}
 -
 -static void init_unused_ring(struct intel_gt *gt, u32 base)
 -{
 -      struct intel_uncore *uncore = gt->uncore;
 -
 -      intel_uncore_write(uncore, RING_CTL(base), 0);
 -      intel_uncore_write(uncore, RING_HEAD(base), 0);
 -      intel_uncore_write(uncore, RING_TAIL(base), 0);
 -      intel_uncore_write(uncore, RING_START(base), 0);
 -}
 -
 -static void init_unused_rings(struct intel_gt *gt)
 -{
 -      struct drm_i915_private *i915 = gt->i915;
 -
 -      if (IS_I830(i915)) {
 -              init_unused_ring(gt, PRB1_BASE);
 -              init_unused_ring(gt, SRB0_BASE);
 -              init_unused_ring(gt, SRB1_BASE);
 -              init_unused_ring(gt, SRB2_BASE);
 -              init_unused_ring(gt, SRB3_BASE);
 -      } else if (IS_GEN(i915, 2)) {
 -              init_unused_ring(gt, SRB0_BASE);
 -              init_unused_ring(gt, SRB1_BASE);
 -      } else if (IS_GEN(i915, 3)) {
 -              init_unused_ring(gt, PRB1_BASE);
 -              init_unused_ring(gt, PRB2_BASE);
 -      }
 -}
 -
 -int i915_gem_init_hw(struct drm_i915_private *i915)
 -{
 -      struct intel_uncore *uncore = &i915->uncore;
 -      struct intel_gt *gt = &i915->gt;
 -      int ret;
 -
 -      BUG_ON(!i915->kernel_context);
 -      ret = intel_gt_terminally_wedged(gt);
 -      if (ret)
 -              return ret;
 -
 -      gt->last_init_time = ktime_get();
 -
 -      /* Double layer security blanket, see i915_gem_init() */
 -      intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
 -
 -      if (HAS_EDRAM(i915) && INTEL_GEN(i915) < 9)
 -              intel_uncore_rmw(uncore, HSW_IDICR, 0, IDIHASHMSK(0xf));
 -
 -      if (IS_HASWELL(i915))
 -              intel_uncore_write(uncore,
 -                                 MI_PREDICATE_RESULT_2,
 -                                 IS_HSW_GT3(i915) ?
 -                                 LOWER_SLICE_ENABLED : LOWER_SLICE_DISABLED);
 -
 -      /* Apply the GT workarounds... */
 -      intel_gt_apply_workarounds(gt);
 -      /* ...and determine whether they are sticking. */
 -      intel_gt_verify_workarounds(gt, "init");
 -
 -      intel_gt_init_swizzling(gt);
 -
 -      /*
 -       * At least 830 can leave some of the unused rings
 -       * "active" (ie. head != tail) after resume which
 -       * will prevent c3 entry. Makes sure all unused rings
 -       * are totally idle.
 -       */
 -      init_unused_rings(gt);
 -
 -      ret = i915_ppgtt_init_hw(gt);
 -      if (ret) {
 -              DRM_ERROR("Enabling PPGTT failed (%d)\n", ret);
 -              goto out;
 -      }
 -
 -      /* We can't enable contexts until all firmware is loaded */
 -      ret = intel_uc_init_hw(&gt->uc);
 -      if (ret) {
 -              i915_probe_error(i915, "Enabling uc failed (%d)\n", ret);
 -              goto out;
 -      }
 -
 -      intel_mocs_init(gt);
 -
 -out:
 -      intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL);
 -      return ret;
 -}
 -
 -static int __intel_engines_record_defaults(struct drm_i915_private *i915)
 +static int __intel_engines_record_defaults(struct intel_gt *gt)
  {
        struct i915_request *requests[I915_NUM_ENGINES] = {};
        struct intel_engine_cs *engine;
         * from the same default HW values.
         */
  
 -      for_each_engine(engine, i915, id) {
 +      for_each_engine(engine, gt, id) {
                struct intel_context *ce;
                struct i915_request *rq;
  
                GEM_BUG_ON(!engine->kernel_context);
                engine->serial++; /* force the kernel context switch */
  
 -              ce = intel_context_create(i915->kernel_context, engine);
 +              ce = intel_context_create(engine->kernel_context->gem_context,
 +                                        engine);
                if (IS_ERR(ce)) {
                        err = PTR_ERR(ce);
                        goto out;
                if (err)
                        goto err_rq;
  
 -              /*
 -               * Failing to program the MOCS is non-fatal.The system will not
 -               * run at peak performance. So warn the user and carry on.
 -               */
 -              err = intel_mocs_emit(rq);
 -              if (err)
 -                      dev_notice(i915->drm.dev,
 -                                 "Failed to program MOCS registers; expect performance issues.\n");
 -
                err = intel_renderstate_emit(rq);
                if (err)
                        goto err_rq;
@@@ -1093,7 -1316,7 +1107,7 @@@ err_rq
        }
  
        /* Flush the default context image to memory, and enable powersaving. */
 -      if (!i915_gem_load_power_context(i915)) {
 +      if (intel_gt_wait_for_idle(gt, I915_GEM_IDLE_TIMEOUT) == -ETIME) {
                err = -EIO;
                goto out;
        }
@@@ -1152,7 -1375,7 +1166,7 @@@ out
         * this is by declaring ourselves wedged.
         */
        if (err)
 -              intel_gt_set_wedged(&i915->gt);
 +              intel_gt_set_wedged(gt);
  
        for (id = 0; id < ARRAY_SIZE(requests); id++) {
                struct intel_context *ce;
        return err;
  }
  
 -static int
 -i915_gem_init_scratch(struct drm_i915_private *i915, unsigned int size)
 -{
 -      return intel_gt_init_scratch(&i915->gt, size);
 -}
 -
 -static void i915_gem_fini_scratch(struct drm_i915_private *i915)
 -{
 -      intel_gt_fini_scratch(&i915->gt);
 -}
 -
 -static int intel_engines_verify_workarounds(struct drm_i915_private *i915)
 +static int intel_engines_verify_workarounds(struct intel_gt *gt)
  {
        struct intel_engine_cs *engine;
        enum intel_engine_id id;
        if (!IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM))
                return 0;
  
 -      for_each_engine(engine, i915, id) {
 +      for_each_engine(engine, gt, id) {
                if (intel_engine_verify_workarounds(engine, "load"))
                        err = -EIO;
        }
@@@ -1210,6 -1444,7 +1224,6 @@@ int i915_gem_init(struct drm_i915_priva
         * we hold the forcewake during initialisation these problems
         * just magically go away.
         */
 -      mutex_lock(&dev_priv->drm.struct_mutex);
        intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
  
        ret = i915_init_ggtt(dev_priv);
                goto err_unlock;
        }
  
 -      ret = i915_gem_init_scratch(dev_priv,
 -                                  IS_GEN(dev_priv, 2) ? SZ_256K : PAGE_SIZE);
 -      if (ret) {
 -              GEM_BUG_ON(ret == -EIO);
 -              goto err_ggtt;
 -      }
 +      intel_gt_init(&dev_priv->gt);
  
 -      ret = intel_engines_setup(dev_priv);
 +      ret = intel_engines_setup(&dev_priv->gt);
        if (ret) {
                GEM_BUG_ON(ret == -EIO);
                goto err_unlock;
        }
  
 -      ret = i915_gem_contexts_init(dev_priv);
 +      ret = i915_gem_init_contexts(dev_priv);
        if (ret) {
                GEM_BUG_ON(ret == -EIO);
                goto err_scratch;
        }
  
 -      ret = intel_engines_init(dev_priv);
 +      ret = intel_engines_init(&dev_priv->gt);
        if (ret) {
                GEM_BUG_ON(ret == -EIO);
                goto err_context;
        }
  
 -      intel_init_gt_powersave(dev_priv);
 -
        intel_uc_init(&dev_priv->gt.uc);
  
 -      ret = i915_gem_init_hw(dev_priv);
 +      ret = intel_gt_init_hw(&dev_priv->gt);
        if (ret)
                goto err_uc_init;
  
         */
        intel_init_clock_gating(dev_priv);
  
 -      ret = intel_engines_verify_workarounds(dev_priv);
 +      ret = intel_engines_verify_workarounds(&dev_priv->gt);
        if (ret)
                goto err_gt;
  
 -      ret = __intel_engines_record_defaults(dev_priv);
 +      ret = __intel_engines_record_defaults(&dev_priv->gt);
        if (ret)
                goto err_gt;
  
 -      ret = i915_inject_load_error(dev_priv, -ENODEV);
 +      ret = i915_inject_probe_error(dev_priv, -ENODEV);
        if (ret)
                goto err_gt;
  
 -      ret = i915_inject_load_error(dev_priv, -EIO);
 +      ret = i915_inject_probe_error(dev_priv, -EIO);
        if (ret)
                goto err_gt;
  
        intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 -      mutex_unlock(&dev_priv->drm.struct_mutex);
  
        return 0;
  
         * driver doesn't explode during runtime.
         */
  err_gt:
 -      mutex_unlock(&dev_priv->drm.struct_mutex);
 -
 -      intel_gt_set_wedged(&dev_priv->gt);
 +      intel_gt_set_wedged_on_init(&dev_priv->gt);
        i915_gem_suspend(dev_priv);
        i915_gem_suspend_late(dev_priv);
  
        i915_gem_drain_workqueue(dev_priv);
 -
 -      mutex_lock(&dev_priv->drm.struct_mutex);
  err_init_hw:
        intel_uc_fini_hw(&dev_priv->gt.uc);
  err_uc_init:
        if (ret != -EIO) {
                intel_uc_fini(&dev_priv->gt.uc);
 -              intel_cleanup_gt_powersave(dev_priv);
 -              intel_engines_cleanup(dev_priv);
 +              intel_engines_cleanup(&dev_priv->gt);
        }
  err_context:
        if (ret != -EIO)
 -              i915_gem_contexts_fini(dev_priv);
 +              i915_gem_driver_release__contexts(dev_priv);
  err_scratch:
 -      i915_gem_fini_scratch(dev_priv);
 -err_ggtt:
 +      intel_gt_driver_release(&dev_priv->gt);
  err_unlock:
        intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 -      mutex_unlock(&dev_priv->drm.struct_mutex);
  
        if (ret != -EIO) {
                intel_uc_cleanup_firmwares(&dev_priv->gt.uc);
        }
  
        if (ret == -EIO) {
 -              mutex_lock(&dev_priv->drm.struct_mutex);
 -
                /*
                 * Allow engines or uC initialisation to fail by marking the GPU
                 * as wedged. But we only want to do this when the GPU is angry,
                /* Minimal basic recovery for KMS */
                ret = i915_ggtt_enable_hw(dev_priv);
                i915_gem_restore_gtt_mappings(dev_priv);
 -              i915_gem_restore_fences(dev_priv);
 +              i915_gem_restore_fences(&dev_priv->ggtt);
                intel_init_clock_gating(dev_priv);
 -
 -              mutex_unlock(&dev_priv->drm.struct_mutex);
        }
  
        i915_gem_drain_freed_objects(dev_priv);
@@@ -1350,35 -1604,48 +1364,35 @@@ void i915_gem_driver_unregister(struct 
  
  void i915_gem_driver_remove(struct drm_i915_private *dev_priv)
  {
 -      GEM_BUG_ON(dev_priv->gt.awake);
 -
        intel_wakeref_auto_fini(&dev_priv->ggtt.userfault_wakeref);
  
        i915_gem_suspend_late(dev_priv);
 -      intel_disable_gt_powersave(dev_priv);
 +      intel_gt_driver_remove(&dev_priv->gt);
  
        /* Flush any outstanding unpin_work. */
        i915_gem_drain_workqueue(dev_priv);
  
 -      mutex_lock(&dev_priv->drm.struct_mutex);
        intel_uc_fini_hw(&dev_priv->gt.uc);
        intel_uc_fini(&dev_priv->gt.uc);
 -      mutex_unlock(&dev_priv->drm.struct_mutex);
  
        i915_gem_drain_freed_objects(dev_priv);
  }
  
  void i915_gem_driver_release(struct drm_i915_private *dev_priv)
  {
 -      mutex_lock(&dev_priv->drm.struct_mutex);
 -      intel_engines_cleanup(dev_priv);
 -      i915_gem_contexts_fini(dev_priv);
 -      i915_gem_fini_scratch(dev_priv);
 -      mutex_unlock(&dev_priv->drm.struct_mutex);
 +      intel_engines_cleanup(&dev_priv->gt);
 +      i915_gem_driver_release__contexts(dev_priv);
 +      intel_gt_driver_release(&dev_priv->gt);
  
        intel_wa_list_free(&dev_priv->gt_wa_list);
  
 -      intel_cleanup_gt_powersave(dev_priv);
 -
        intel_uc_cleanup_firmwares(&dev_priv->gt.uc);
        i915_gem_cleanup_userptr(dev_priv);
        intel_timelines_fini(dev_priv);
  
        i915_gem_drain_freed_objects(dev_priv);
  
 -      WARN_ON(!list_empty(&dev_priv->contexts.list));
 -}
 -
 -void i915_gem_init_mmio(struct drm_i915_private *i915)
 -{
 -      i915_gem_sanitize(i915);
 +      WARN_ON(!list_empty(&dev_priv->gem.contexts.list));
  }
  
  static void i915_gem_init__mm(struct drm_i915_private *i915)
        i915_gem_init__objects(i915);
  }
  
 -int i915_gem_init_early(struct drm_i915_private *dev_priv)
 +void i915_gem_init_early(struct drm_i915_private *dev_priv)
  {
 -      int err;
 -
        i915_gem_init__mm(dev_priv);
 -      i915_gem_init__pm(dev_priv);
  
        spin_lock_init(&dev_priv->fb_tracking.lock);
 -
 -      err = i915_gemfs_init(dev_priv);
 -      if (err)
 -              DRM_NOTE("Unable to create a private tmpfs mount, hugepage support will be disabled(%d).\n", err);
 -
 -      return 0;
  }
  
  void i915_gem_cleanup_early(struct drm_i915_private *dev_priv)
        GEM_BUG_ON(!llist_empty(&dev_priv->mm.free_list));
        GEM_BUG_ON(atomic_read(&dev_priv->mm.free_count));
        WARN_ON(dev_priv->mm.shrink_count);
 -
 -      i915_gemfs_fini(dev_priv);
  }
  
  int i915_gem_freeze(struct drm_i915_private *dev_priv)
index ad33fbe90a286f7555ebf058ce0b86990b1959fb,9f1517af5b7f49d4b5e13277296f7bc86fb0dd7e..cf8a8c3ef047f66ee7628bcd056806f8499d4b5e
@@@ -5,7 -5,6 +5,7 @@@
  #include "gt/intel_engine_user.h"
  
  #include "i915_drv.h"
 +#include "i915_perf.h"
  
  int i915_getparam_ioctl(struct drm_device *dev, void *data,
                        struct drm_file *file_priv)
@@@ -63,7 -62,7 +63,7 @@@
                value = !!(i915->caps.scheduler & I915_SCHEDULER_CAP_SEMAPHORES);
                break;
        case I915_PARAM_HAS_SECURE_BATCHES:
-               value = capable(CAP_SYS_ADMIN);
+               value = HAS_SECURE_BATCHES(i915) && capable(CAP_SYS_ADMIN);
                break;
        case I915_PARAM_CMD_PARSER_VERSION:
                value = i915_cmd_parser_get_version(i915);
@@@ -80,8 -79,8 +80,8 @@@
                break;
        case I915_PARAM_HAS_GPU_RESET:
                value = i915_modparams.enable_hangcheck &&
 -                      intel_has_gpu_reset(i915);
 -              if (value && intel_has_reset_engine(i915))
 +                      intel_has_gpu_reset(&i915->gt);
 +              if (value && intel_has_reset_engine(&i915->gt))
                        value = 2;
                break;
        case I915_PARAM_HAS_RESOURCE_STREAMER:
        case I915_PARAM_MMAP_GTT_COHERENT:
                value = INTEL_INFO(i915)->has_coherent_ggtt;
                break;
 +      case I915_PARAM_PERF_REVISION:
 +              value = i915_perf_ioctl_version();
 +              break;
        default:
                DRM_DEBUG("Unknown parameter %d\n", param->param);
                return -EINVAL;
index ae306dab57fadcaece8fd7f6fdbd3fc1947598d5,f8ee9aba3955c54c89b2932ddc61bb524ae9c0c1..445dacbdc0e9efef7e31359f8f0a641f2750e367
@@@ -413,9 -413,6 +413,9 @@@ static inline bool i915_mmio_reg_valid(
  #define GEN11_VECS_SFC_USAGE(engine)          _MMIO((engine)->mmio_base + 0x2014)
  #define   GEN11_VECS_SFC_USAGE_BIT            (1 << 0)
  
 +#define GEN12_SFC_DONE(n)             _MMIO(0x1cc00 + (n) * 0x100)
 +#define GEN12_SFC_DONE_MAX            4
 +
  #define RING_PP_DIR_BASE(base)                _MMIO((base) + 0x228)
  #define RING_PP_DIR_BASE_READ(base)   _MMIO((base) + 0x518)
  #define RING_PP_DIR_DCLV(base)                _MMIO((base) + 0x220)
  #define MI_PREDICATE_SRC0_UDW _MMIO(0x2400 + 4)
  #define MI_PREDICATE_SRC1     _MMIO(0x2408)
  #define MI_PREDICATE_SRC1_UDW _MMIO(0x2408 + 4)
 -
 +#define MI_PREDICATE_DATA       _MMIO(0x2410)
 +#define MI_PREDICATE_RESULT     _MMIO(0x2418)
 +#define MI_PREDICATE_RESULT_1   _MMIO(0x241c)
  #define MI_PREDICATE_RESULT_2 _MMIO(0x2214)
  #define  LOWER_SLICE_ENABLED  (1 << 0)
  #define  LOWER_SLICE_DISABLED (0 << 0)
   */
  #define BCS_SWCTRL _MMIO(0x22200)
  
+ /* There are 16 GPR registers */
+ #define BCS_GPR(n)    _MMIO(0x22600 + (n) * 8)
+ #define BCS_GPR_UDW(n)        _MMIO(0x22600 + (n) * 8 + 4)
  #define GPGPU_THREADS_DISPATCHED        _MMIO(0x2290)
  #define GPGPU_THREADS_DISPATCHED_UDW  _MMIO(0x2290 + 4)
  #define HS_INVOCATION_COUNT             _MMIO(0x2300)
  #define OABUFFER_SIZE_8M    (6 << 3)
  #define OABUFFER_SIZE_16M   (7 << 3)
  
 +/* Gen12 OAR unit */
 +#define GEN12_OAR_OACONTROL _MMIO(0x2960)
 +#define  GEN12_OAR_OACONTROL_COUNTER_FORMAT_SHIFT 1
 +#define  GEN12_OAR_OACONTROL_COUNTER_ENABLE       (1 << 0)
 +
 +#define GEN12_OACTXCONTROL _MMIO(0x2360)
 +#define GEN12_OAR_OASTATUS _MMIO(0x2968)
 +
 +/* Gen12 OAG unit */
 +#define GEN12_OAG_OAHEADPTR _MMIO(0xdb00)
 +#define  GEN12_OAG_OAHEADPTR_MASK 0xffffffc0
 +#define GEN12_OAG_OATAILPTR _MMIO(0xdb04)
 +#define  GEN12_OAG_OATAILPTR_MASK 0xffffffc0
 +
 +#define GEN12_OAG_OABUFFER  _MMIO(0xdb08)
 +#define  GEN12_OAG_OABUFFER_BUFFER_SIZE_MASK  (0x7)
 +#define  GEN12_OAG_OABUFFER_BUFFER_SIZE_SHIFT (3)
 +#define  GEN12_OAG_OABUFFER_MEMORY_SELECT     (1 << 0) /* 0: PPGTT, 1: GGTT */
 +
 +#define GEN12_OAG_OAGLBCTXCTRL _MMIO(0x2b28)
 +#define  GEN12_OAG_OAGLBCTXCTRL_TIMER_PERIOD_SHIFT 2
 +#define  GEN12_OAG_OAGLBCTXCTRL_TIMER_ENABLE       (1 << 1)
 +#define  GEN12_OAG_OAGLBCTXCTRL_COUNTER_RESUME     (1 << 0)
 +
 +#define GEN12_OAG_OACONTROL _MMIO(0xdaf4)
 +#define  GEN12_OAG_OACONTROL_OA_COUNTER_FORMAT_SHIFT 2
 +#define  GEN12_OAG_OACONTROL_OA_COUNTER_ENABLE       (1 << 0)
 +
 +#define GEN12_OAG_OA_DEBUG _MMIO(0xdaf8)
 +#define  GEN12_OAG_OA_DEBUG_INCLUDE_CLK_RATIO          (1 << 6)
 +#define  GEN12_OAG_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS  (1 << 5)
 +#define  GEN12_OAG_OA_DEBUG_DISABLE_GO_1_0_REPORTS     (1 << 2)
 +#define  GEN12_OAG_OA_DEBUG_DISABLE_CTX_SWITCH_REPORTS (1 << 1)
 +
 +#define GEN12_OAG_OASTATUS _MMIO(0xdafc)
 +#define  GEN12_OAG_OASTATUS_COUNTER_OVERFLOW (1 << 2)
 +#define  GEN12_OAG_OASTATUS_BUFFER_OVERFLOW  (1 << 1)
 +#define  GEN12_OAG_OASTATUS_REPORT_LOST      (1 << 0)
 +
  /*
   * Flexible, Aggregate EU Counter Registers.
   * Note: these aren't contiguous
  #define OAREPORTTRIG8_NOA_SELECT_6_SHIFT    24
  #define OAREPORTTRIG8_NOA_SELECT_7_SHIFT    28
  
 +/* Same layout as OASTARTTRIGX */
 +#define GEN12_OAG_OASTARTTRIG1 _MMIO(0xd900)
 +#define GEN12_OAG_OASTARTTRIG2 _MMIO(0xd904)
 +#define GEN12_OAG_OASTARTTRIG3 _MMIO(0xd908)
 +#define GEN12_OAG_OASTARTTRIG4 _MMIO(0xd90c)
 +#define GEN12_OAG_OASTARTTRIG5 _MMIO(0xd910)
 +#define GEN12_OAG_OASTARTTRIG6 _MMIO(0xd914)
 +#define GEN12_OAG_OASTARTTRIG7 _MMIO(0xd918)
 +#define GEN12_OAG_OASTARTTRIG8 _MMIO(0xd91c)
 +
 +/* Same layout as OAREPORTTRIGX */
 +#define GEN12_OAG_OAREPORTTRIG1 _MMIO(0xd920)
 +#define GEN12_OAG_OAREPORTTRIG2 _MMIO(0xd924)
 +#define GEN12_OAG_OAREPORTTRIG3 _MMIO(0xd928)
 +#define GEN12_OAG_OAREPORTTRIG4 _MMIO(0xd92c)
 +#define GEN12_OAG_OAREPORTTRIG5 _MMIO(0xd930)
 +#define GEN12_OAG_OAREPORTTRIG6 _MMIO(0xd934)
 +#define GEN12_OAG_OAREPORTTRIG7 _MMIO(0xd938)
 +#define GEN12_OAG_OAREPORTTRIG8 _MMIO(0xd93c)
 +
  /* CECX_0 */
  #define OACEC_COMPARE_LESS_OR_EQUAL   6
  #define OACEC_COMPARE_NOT_EQUAL               5
  #define OACEC_SELECT_PREV     (1 << 19)
  #define OACEC_SELECT_BOOLEAN  (2 << 19)
  
 +/* 11-bit array 0: pass-through, 1: negated */
 +#define GEN12_OASCEC_NEGATE_MASK  0x7ff
 +#define GEN12_OASCEC_NEGATE_SHIFT 21
 +
  /* CECX_1 */
  #define OACEC_MASK_MASK                   0xffff
  #define OACEC_CONSIDERATIONS_MASK   0xffff
  #define OACEC7_0 _MMIO(0x27a8)
  #define OACEC7_1 _MMIO(0x27ac)
  
 +/* Same layout as CECX_Y */
 +#define GEN12_OAG_CEC0_0 _MMIO(0xd940)
 +#define GEN12_OAG_CEC0_1 _MMIO(0xd944)
 +#define GEN12_OAG_CEC1_0 _MMIO(0xd948)
 +#define GEN12_OAG_CEC1_1 _MMIO(0xd94c)
 +#define GEN12_OAG_CEC2_0 _MMIO(0xd950)
 +#define GEN12_OAG_CEC2_1 _MMIO(0xd954)
 +#define GEN12_OAG_CEC3_0 _MMIO(0xd958)
 +#define GEN12_OAG_CEC3_1 _MMIO(0xd95c)
 +#define GEN12_OAG_CEC4_0 _MMIO(0xd960)
 +#define GEN12_OAG_CEC4_1 _MMIO(0xd964)
 +#define GEN12_OAG_CEC5_0 _MMIO(0xd968)
 +#define GEN12_OAG_CEC5_1 _MMIO(0xd96c)
 +#define GEN12_OAG_CEC6_0 _MMIO(0xd970)
 +#define GEN12_OAG_CEC6_1 _MMIO(0xd974)
 +#define GEN12_OAG_CEC7_0 _MMIO(0xd978)
 +#define GEN12_OAG_CEC7_1 _MMIO(0xd97c)
 +
 +/* Same layout as CECX_Y + negate 11-bit array */
 +#define GEN12_OAG_SCEC0_0 _MMIO(0xdc00)
 +#define GEN12_OAG_SCEC0_1 _MMIO(0xdc04)
 +#define GEN12_OAG_SCEC1_0 _MMIO(0xdc08)
 +#define GEN12_OAG_SCEC1_1 _MMIO(0xdc0c)
 +#define GEN12_OAG_SCEC2_0 _MMIO(0xdc10)
 +#define GEN12_OAG_SCEC2_1 _MMIO(0xdc14)
 +#define GEN12_OAG_SCEC3_0 _MMIO(0xdc18)
 +#define GEN12_OAG_SCEC3_1 _MMIO(0xdc1c)
 +#define GEN12_OAG_SCEC4_0 _MMIO(0xdc20)
 +#define GEN12_OAG_SCEC4_1 _MMIO(0xdc24)
 +#define GEN12_OAG_SCEC5_0 _MMIO(0xdc28)
 +#define GEN12_OAG_SCEC5_1 _MMIO(0xdc2c)
 +#define GEN12_OAG_SCEC6_0 _MMIO(0xdc30)
 +#define GEN12_OAG_SCEC6_1 _MMIO(0xdc34)
 +#define GEN12_OAG_SCEC7_0 _MMIO(0xdc38)
 +#define GEN12_OAG_SCEC7_1 _MMIO(0xdc3c)
 +
  /* OA perf counters */
  #define OA_PERFCNT1_LO      _MMIO(0x91B8)
  #define OA_PERFCNT1_HI      _MMIO(0x91BC)
  #define MICRO_BP3_COUNT_STATUS23      _MMIO(0x9838)
  #define MICRO_BP_FIRED_ARMED          _MMIO(0x983C)
  
 +#define GEN12_OAA_DBG_REG _MMIO(0xdc44)
 +#define GEN12_OAG_OA_PESS _MMIO(0x2b2c)
 +#define GEN12_OAG_SPCTR_CNF _MMIO(0xdc40)
 +
  #define GDT_CHICKEN_BITS    _MMIO(0x9840)
  #define   GT_NOA_ENABLE           0x00000080
  
  #define ICL_DPHY_CHKN(port)                   _MMIO(_ICL_COMBOPHY(port) + _ICL_DPHY_CHKN_REG)
  #define   ICL_DPHY_CHKN_AFE_OVER_PPI_STRAP    REG_BIT(7)
  
 -#define MG_PHY_PORT_LN(ln, port, ln0p1, ln0p2, ln1p1) \
 -      _MMIO(_PORT((port) - PORT_C, ln0p1, ln0p2) + (ln) * ((ln1p1) - (ln0p1)))
 +#define MG_PHY_PORT_LN(ln, tc_port, ln0p1, ln0p2, ln1p1) \
 +      _MMIO(_PORT(tc_port, ln0p1, ln0p2) + (ln) * ((ln1p1) - (ln0p1)))
  
  #define MG_TX_LINK_PARAMS_TX1LN0_PORT1                0x16812C
  #define MG_TX_LINK_PARAMS_TX1LN1_PORT1                0x16852C
  #define MG_TX_LINK_PARAMS_TX1LN1_PORT3                0x16A52C
  #define MG_TX_LINK_PARAMS_TX1LN0_PORT4                0x16B12C
  #define MG_TX_LINK_PARAMS_TX1LN1_PORT4                0x16B52C
 -#define MG_TX1_LINK_PARAMS(ln, port) \
 -      MG_PHY_PORT_LN(ln, port, MG_TX_LINK_PARAMS_TX1LN0_PORT1, \
 -                               MG_TX_LINK_PARAMS_TX1LN0_PORT2, \
 -                               MG_TX_LINK_PARAMS_TX1LN1_PORT1)
 +#define MG_TX1_LINK_PARAMS(ln, tc_port) \
 +      MG_PHY_PORT_LN(ln, tc_port, MG_TX_LINK_PARAMS_TX1LN0_PORT1, \
 +                                  MG_TX_LINK_PARAMS_TX1LN0_PORT2, \
 +                                  MG_TX_LINK_PARAMS_TX1LN1_PORT1)
  
  #define MG_TX_LINK_PARAMS_TX2LN0_PORT1                0x1680AC
  #define MG_TX_LINK_PARAMS_TX2LN1_PORT1                0x1684AC
  #define MG_TX_LINK_PARAMS_TX2LN1_PORT3                0x16A4AC
  #define MG_TX_LINK_PARAMS_TX2LN0_PORT4                0x16B0AC
  #define MG_TX_LINK_PARAMS_TX2LN1_PORT4                0x16B4AC
 -#define MG_TX2_LINK_PARAMS(ln, port) \
 -      MG_PHY_PORT_LN(ln, port, MG_TX_LINK_PARAMS_TX2LN0_PORT1, \
 -                               MG_TX_LINK_PARAMS_TX2LN0_PORT2, \
 -                               MG_TX_LINK_PARAMS_TX2LN1_PORT1)
 +#define MG_TX2_LINK_PARAMS(ln, tc_port) \
 +      MG_PHY_PORT_LN(ln, tc_port, MG_TX_LINK_PARAMS_TX2LN0_PORT1, \
 +                                  MG_TX_LINK_PARAMS_TX2LN0_PORT2, \
 +                                  MG_TX_LINK_PARAMS_TX2LN1_PORT1)
  #define   CRI_USE_FS32                        (1 << 5)
  
  #define MG_TX_PISO_READLOAD_TX1LN0_PORT1              0x16814C
  #define MG_TX_PISO_READLOAD_TX1LN1_PORT3              0x16A54C
  #define MG_TX_PISO_READLOAD_TX1LN0_PORT4              0x16B14C
  #define MG_TX_PISO_READLOAD_TX1LN1_PORT4              0x16B54C
 -#define MG_TX1_PISO_READLOAD(ln, port) \
 -      MG_PHY_PORT_LN(ln, port, MG_TX_PISO_READLOAD_TX1LN0_PORT1, \
 -                               MG_TX_PISO_READLOAD_TX1LN0_PORT2, \
 -                               MG_TX_PISO_READLOAD_TX1LN1_PORT1)
 +#define MG_TX1_PISO_READLOAD(ln, tc_port) \
 +      MG_PHY_PORT_LN(ln, tc_port, MG_TX_PISO_READLOAD_TX1LN0_PORT1, \
 +                                  MG_TX_PISO_READLOAD_TX1LN0_PORT2, \
 +                                  MG_TX_PISO_READLOAD_TX1LN1_PORT1)
  
  #define MG_TX_PISO_READLOAD_TX2LN0_PORT1              0x1680CC
  #define MG_TX_PISO_READLOAD_TX2LN1_PORT1              0x1684CC
  #define MG_TX_PISO_READLOAD_TX2LN1_PORT3              0x16A4CC
  #define MG_TX_PISO_READLOAD_TX2LN0_PORT4              0x16B0CC
  #define MG_TX_PISO_READLOAD_TX2LN1_PORT4              0x16B4CC
 -#define MG_TX2_PISO_READLOAD(ln, port) \
 -      MG_PHY_PORT_LN(ln, port, MG_TX_PISO_READLOAD_TX2LN0_PORT1, \
 -                               MG_TX_PISO_READLOAD_TX2LN0_PORT2, \
 -                               MG_TX_PISO_READLOAD_TX2LN1_PORT1)
 +#define MG_TX2_PISO_READLOAD(ln, tc_port) \
 +      MG_PHY_PORT_LN(ln, tc_port, MG_TX_PISO_READLOAD_TX2LN0_PORT1, \
 +                                  MG_TX_PISO_READLOAD_TX2LN0_PORT2, \
 +                                  MG_TX_PISO_READLOAD_TX2LN1_PORT1)
  #define   CRI_CALCINIT                                        (1 << 1)
  
  #define MG_TX_SWINGCTRL_TX1LN0_PORT1          0x168148
  #define MG_TX_SWINGCTRL_TX1LN1_PORT3          0x16A548
  #define MG_TX_SWINGCTRL_TX1LN0_PORT4          0x16B148
  #define MG_TX_SWINGCTRL_TX1LN1_PORT4          0x16B548
 -#define MG_TX1_SWINGCTRL(ln, port) \
 -      MG_PHY_PORT_LN(ln, port, MG_TX_SWINGCTRL_TX1LN0_PORT1, \
 -                               MG_TX_SWINGCTRL_TX1LN0_PORT2, \
 -                               MG_TX_SWINGCTRL_TX1LN1_PORT1)
 +#define MG_TX1_SWINGCTRL(ln, tc_port) \
 +      MG_PHY_PORT_LN(ln, tc_port, MG_TX_SWINGCTRL_TX1LN0_PORT1, \
 +                                  MG_TX_SWINGCTRL_TX1LN0_PORT2, \
 +                                  MG_TX_SWINGCTRL_TX1LN1_PORT1)
  
  #define MG_TX_SWINGCTRL_TX2LN0_PORT1          0x1680C8
  #define MG_TX_SWINGCTRL_TX2LN1_PORT1          0x1684C8
  #define MG_TX_SWINGCTRL_TX2LN1_PORT3          0x16A4C8
  #define MG_TX_SWINGCTRL_TX2LN0_PORT4          0x16B0C8
  #define MG_TX_SWINGCTRL_TX2LN1_PORT4          0x16B4C8
 -#define MG_TX2_SWINGCTRL(ln, port) \
 -      MG_PHY_PORT_LN(ln, port, MG_TX_SWINGCTRL_TX2LN0_PORT1, \
 -                               MG_TX_SWINGCTRL_TX2LN0_PORT2, \
 -                               MG_TX_SWINGCTRL_TX2LN1_PORT1)
 +#define MG_TX2_SWINGCTRL(ln, tc_port) \
 +      MG_PHY_PORT_LN(ln, tc_port, MG_TX_SWINGCTRL_TX2LN0_PORT1, \
 +                                  MG_TX_SWINGCTRL_TX2LN0_PORT2, \
 +                                  MG_TX_SWINGCTRL_TX2LN1_PORT1)
  #define   CRI_TXDEEMPH_OVERRIDE_17_12(x)              ((x) << 0)
  #define   CRI_TXDEEMPH_OVERRIDE_17_12_MASK            (0x3F << 0)
  
  #define MG_TX_DRVCTRL_TX1LN1_TXPORT3                  0x16A544
  #define MG_TX_DRVCTRL_TX1LN0_TXPORT4                  0x16B144
  #define MG_TX_DRVCTRL_TX1LN1_TXPORT4                  0x16B544
 -#define MG_TX1_DRVCTRL(ln, port) \
 -      MG_PHY_PORT_LN(ln, port, MG_TX_DRVCTRL_TX1LN0_TXPORT1, \
 -                               MG_TX_DRVCTRL_TX1LN0_TXPORT2, \
 -                               MG_TX_DRVCTRL_TX1LN1_TXPORT1)
 +#define MG_TX1_DRVCTRL(ln, tc_port) \
 +      MG_PHY_PORT_LN(ln, tc_port, MG_TX_DRVCTRL_TX1LN0_TXPORT1, \
 +                                  MG_TX_DRVCTRL_TX1LN0_TXPORT2, \
 +                                  MG_TX_DRVCTRL_TX1LN1_TXPORT1)
  
  #define MG_TX_DRVCTRL_TX2LN0_PORT1                    0x1680C4
  #define MG_TX_DRVCTRL_TX2LN1_PORT1                    0x1684C4
  #define MG_TX_DRVCTRL_TX2LN1_PORT3                    0x16A4C4
  #define MG_TX_DRVCTRL_TX2LN0_PORT4                    0x16B0C4
  #define MG_TX_DRVCTRL_TX2LN1_PORT4                    0x16B4C4
 -#define MG_TX2_DRVCTRL(ln, port) \
 -      MG_PHY_PORT_LN(ln, port, MG_TX_DRVCTRL_TX2LN0_PORT1, \
 -                               MG_TX_DRVCTRL_TX2LN0_PORT2, \
 -                               MG_TX_DRVCTRL_TX2LN1_PORT1)
 +#define MG_TX2_DRVCTRL(ln, tc_port) \
 +      MG_PHY_PORT_LN(ln, tc_port, MG_TX_DRVCTRL_TX2LN0_PORT1, \
 +                                  MG_TX_DRVCTRL_TX2LN0_PORT2, \
 +                                  MG_TX_DRVCTRL_TX2LN1_PORT1)
  #define   CRI_TXDEEMPH_OVERRIDE_11_6(x)                       ((x) << 24)
  #define   CRI_TXDEEMPH_OVERRIDE_11_6_MASK             (0x3F << 24)
  #define   CRI_TXDEEMPH_OVERRIDE_EN                    (1 << 22)
  #define MG_CLKHUB_LN1_PORT3                   0x16A79C
  #define MG_CLKHUB_LN0_PORT4                   0x16B39C
  #define MG_CLKHUB_LN1_PORT4                   0x16B79C
 -#define MG_CLKHUB(ln, port) \
 -      MG_PHY_PORT_LN(ln, port, MG_CLKHUB_LN0_PORT1, \
 -                               MG_CLKHUB_LN0_PORT2, \
 -                               MG_CLKHUB_LN1_PORT1)
 +#define MG_CLKHUB(ln, tc_port) \
 +      MG_PHY_PORT_LN(ln, tc_port, MG_CLKHUB_LN0_PORT1, \
 +                                  MG_CLKHUB_LN0_PORT2, \
 +                                  MG_CLKHUB_LN1_PORT1)
  #define   CFG_LOW_RATE_LKREN_EN                               (1 << 11)
  
  #define MG_TX_DCC_TX1LN0_PORT1                        0x168110
  #define MG_TX_DCC_TX1LN1_PORT3                        0x16A510
  #define MG_TX_DCC_TX1LN0_PORT4                        0x16B110
  #define MG_TX_DCC_TX1LN1_PORT4                        0x16B510
 -#define MG_TX1_DCC(ln, port) \
 -      MG_PHY_PORT_LN(ln, port, MG_TX_DCC_TX1LN0_PORT1, \
 -                               MG_TX_DCC_TX1LN0_PORT2, \
 -                               MG_TX_DCC_TX1LN1_PORT1)
 +#define MG_TX1_DCC(ln, tc_port) \
 +      MG_PHY_PORT_LN(ln, tc_port, MG_TX_DCC_TX1LN0_PORT1, \
 +                                  MG_TX_DCC_TX1LN0_PORT2, \
 +                                  MG_TX_DCC_TX1LN1_PORT1)
  #define MG_TX_DCC_TX2LN0_PORT1                        0x168090
  #define MG_TX_DCC_TX2LN1_PORT1                        0x168490
  #define MG_TX_DCC_TX2LN0_PORT2                        0x169090
  #define MG_TX_DCC_TX2LN1_PORT3                        0x16A490
  #define MG_TX_DCC_TX2LN0_PORT4                        0x16B090
  #define MG_TX_DCC_TX2LN1_PORT4                        0x16B490
 -#define MG_TX2_DCC(ln, port) \
 -      MG_PHY_PORT_LN(ln, port, MG_TX_DCC_TX2LN0_PORT1, \
 -                               MG_TX_DCC_TX2LN0_PORT2, \
 -                               MG_TX_DCC_TX2LN1_PORT1)
 +#define MG_TX2_DCC(ln, tc_port) \
 +      MG_PHY_PORT_LN(ln, tc_port, MG_TX_DCC_TX2LN0_PORT1, \
 +                                  MG_TX_DCC_TX2LN0_PORT2, \
 +                                  MG_TX_DCC_TX2LN1_PORT1)
  #define   CFG_AMI_CK_DIV_OVERRIDE_VAL(x)      ((x) << 25)
  #define   CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK    (0x3 << 25)
  #define   CFG_AMI_CK_DIV_OVERRIDE_EN          (1 << 24)
  #define MG_DP_MODE_LN1_ACU_PORT3                      0x16A7A0
  #define MG_DP_MODE_LN0_ACU_PORT4                      0x16B3A0
  #define MG_DP_MODE_LN1_ACU_PORT4                      0x16B7A0
 -#define MG_DP_MODE(ln, port)  \
 -      MG_PHY_PORT_LN(ln, port, MG_DP_MODE_LN0_ACU_PORT1, \
 -                               MG_DP_MODE_LN0_ACU_PORT2, \
 -                               MG_DP_MODE_LN1_ACU_PORT1)
 +#define MG_DP_MODE(ln, tc_port)       \
 +      MG_PHY_PORT_LN(ln, tc_port, MG_DP_MODE_LN0_ACU_PORT1, \
 +                                  MG_DP_MODE_LN0_ACU_PORT2, \
 +                                  MG_DP_MODE_LN1_ACU_PORT1)
  #define   MG_DP_MODE_CFG_DP_X2_MODE                   (1 << 7)
  #define   MG_DP_MODE_CFG_DP_X1_MODE                   (1 << 6)
  #define   MG_DP_MODE_CFG_TR2PWR_GATING                        (1 << 5)
  #define _MMIO_FIA(fia, off)           _MMIO(_FIA(fia) + (off))
  
  /* ICL PHY DFLEX registers */
 -#define PORT_TX_DFLEXDPMLE1(fia)      _MMIO_FIA((fia),  0x008C0)
 -#define   DFLEXDPMLE1_DPMLETC_MASK(tc_port)   (0xf << (4 * (tc_port)))
 -#define   DFLEXDPMLE1_DPMLETC_ML0(tc_port)    (1 << (4 * (tc_port)))
 -#define   DFLEXDPMLE1_DPMLETC_ML1_0(tc_port)  (3 << (4 * (tc_port)))
 -#define   DFLEXDPMLE1_DPMLETC_ML3(tc_port)    (8 << (4 * (tc_port)))
 -#define   DFLEXDPMLE1_DPMLETC_ML3_2(tc_port)  (12 << (4 * (tc_port)))
 -#define   DFLEXDPMLE1_DPMLETC_ML3_0(tc_port)  (15 << (4 * (tc_port)))
 +#define PORT_TX_DFLEXDPMLE1(fia)              _MMIO_FIA((fia),  0x008C0)
 +#define   DFLEXDPMLE1_DPMLETC_MASK(idx)               (0xf << (4 * (idx)))
 +#define   DFLEXDPMLE1_DPMLETC_ML0(idx)                (1 << (4 * (idx)))
 +#define   DFLEXDPMLE1_DPMLETC_ML1_0(idx)      (3 << (4 * (idx)))
 +#define   DFLEXDPMLE1_DPMLETC_ML3(idx)                (8 << (4 * (idx)))
 +#define   DFLEXDPMLE1_DPMLETC_ML3_2(idx)      (12 << (4 * (idx)))
 +#define   DFLEXDPMLE1_DPMLETC_ML3_0(idx)      (15 << (4 * (idx)))
  
  /* BXT PHY Ref registers */
  #define _PORT_REF_DW3_A                       0x16218C
  #define   RING_FAULT_FAULT_TYPE(x) (((x) >> 1) & 0x3)
  #define   RING_FAULT_VALID    (1 << 0)
  #define DONE_REG              _MMIO(0x40b0)
 +#define GEN12_GAM_DONE                _MMIO(0xcf68)
  #define GEN8_PRIVATE_PAT_LO   _MMIO(0x40e0)
  #define GEN8_PRIVATE_PAT_HI   _MMIO(0x40e0 + 4)
  #define GEN10_PAT_INDEX(index)        _MMIO(0x40e0 + (index) * 4)
  #define   RING_WAIT           (1 << 11) /* gen3+, PRBx_CTL */
  #define   RING_WAIT_SEMAPHORE (1 << 10) /* gen6+ */
  
 +/* There are 16 64-bit CS General Purpose Registers per-engine on Gen8+ */
 +#define GEN8_RING_CS_GPR(base, n)     _MMIO((base) + 0x600 + (n) * 8)
 +#define GEN8_RING_CS_GPR_UDW(base, n) _MMIO((base) + 0x600 + (n) * 8 + 4)
 +
  #define RING_FORCE_TO_NONPRIV(base, i) _MMIO(((base) + 0x4D0) + (i) * 4)
 +#define   RING_FORCE_TO_NONPRIV_ADDRESS_MASK  REG_GENMASK(25, 2)
  #define   RING_FORCE_TO_NONPRIV_ACCESS_RW     (0 << 28)    /* CFL+ & Gen11+ */
  #define   RING_FORCE_TO_NONPRIV_ACCESS_RD     (1 << 28)
  #define   RING_FORCE_TO_NONPRIV_ACCESS_WR     (2 << 28)
  #define   FAULT_VA_HIGH_BITS          (0xf << 0)
  #define   FAULT_GTT_SEL                       (1 << 4)
  
 +#define GEN12_AUX_ERR_DBG             _MMIO(0x43f4)
 +
  #define FPGA_DBG              _MMIO(0x42300)
  #define   FPGA_DBG_RM_NOCLAIM (1 << 31)
  
  #define VLV_GU_CTL0   _MMIO(VLV_DISPLAY_BASE + 0x2030)
  #define VLV_GU_CTL1   _MMIO(VLV_DISPLAY_BASE + 0x2034)
  #define SCPD0         _MMIO(0x209c) /* 915+ only */
 +#define  CSTATE_RENDER_CLOCK_GATE_DISABLE     (1 << 5)
  #define GEN2_IER      _MMIO(0x20a0)
  #define GEN2_IIR      _MMIO(0x20a4)
  #define GEN2_IMR      _MMIO(0x20a8)
  
  #define GEN6_RC_SLEEP_PSMI_CONTROL    _MMIO(0x2050)
  #define   GEN6_PSMI_SLEEP_MSG_DISABLE (1 << 0)
 +#define   GEN12_WAIT_FOR_EVENT_POWER_DOWN_DISABLE REG_BIT(7)
  #define   GEN8_RC_SEMA_IDLE_MSG_DISABLE       (1 << 12)
  #define   GEN8_FF_DOP_CLOCK_GATE_DISABLE      (1 << 10)
  
  
  #define GEN11_GT_SUBSLICE_DISABLE _MMIO(0x913C)
  
 +#define GEN12_GT_DSS_ENABLE _MMIO(0x913C)
 +
  #define GEN6_BSD_SLEEP_PSMI_CONTROL   _MMIO(0x12050)
  #define   GEN6_BSD_SLEEP_MSG_DISABLE  (1 << 0)
  #define   GEN6_BSD_SLEEP_FLUSH_DISABLE        (1 << 2)
  #define _PALETTE_A            0xa000
  #define _PALETTE_B            0xa800
  #define _CHV_PALETTE_C                0xc000
 +#define PALETTE_RED_MASK        REG_GENMASK(23, 16)
 +#define PALETTE_GREEN_MASK      REG_GENMASK(15, 8)
 +#define PALETTE_BLUE_MASK       REG_GENMASK(7, 0)
  #define PALETTE(pipe, i)      _MMIO(DISPLAY_MMIO_BASE(dev_priv) + \
                                      _PICK((pipe), _PALETTE_A,         \
                                            _PALETTE_B, _CHV_PALETTE_C) + \
@@@ -4163,15 -4044,10 +4167,15 @@@ enum 
  #define  SARBUNIT_CLKGATE_DIS         (1 << 5)
  #define  RCCUNIT_CLKGATE_DIS          (1 << 7)
  #define  MSCUNIT_CLKGATE_DIS          (1 << 10)
 +#define  L3_CLKGATE_DIS                       REG_BIT(16)
 +#define  L3_CR2X_CLKGATE_DIS          REG_BIT(17)
  
  #define SUBSLICE_UNIT_LEVEL_CLKGATE   _MMIO(0x9524)
  #define  GWUNIT_CLKGATE_DIS           (1 << 16)
  
 +#define SUBSLICE_UNIT_LEVEL_CLKGATE2  _MMIO(0x9528)
 +#define  CPSSUNIT_CLKGATE_DIS         REG_BIT(9)
 +
  #define UNSLICE_UNIT_LEVEL_CLKGATE    _MMIO(0x9434)
  #define  VFUNIT_CLKGATE_DIS           (1 << 20)
  
  #define _VTOTAL_A     0x6000c
  #define _VBLANK_A     0x60010
  #define _VSYNC_A      0x60014
 +#define _EXITLINE_A   0x60018
  #define _PIPEASRC     0x6001c
  #define _BCLRPAT_A    0x60020
  #define _VSYNCSHIFT_A 0x60028
  #define PIPESRC(trans)                _MMIO_TRANS2(trans, _PIPEASRC)
  #define PIPE_MULT(trans)      _MMIO_TRANS2(trans, _PIPE_MULT_A)
  
 -/* HSW+ eDP PSR registers */
 -#define HSW_EDP_PSR_BASE      0x64800
 -#define BDW_EDP_PSR_BASE      0x6f800
 -#define EDP_PSR_CTL                           _MMIO(dev_priv->psr_mmio_base + 0)
 +#define EXITLINE(trans)               _MMIO_TRANS2(trans, _EXITLINE_A)
 +#define   EXITLINE_ENABLE     REG_BIT(31)
 +#define   EXITLINE_MASK               REG_GENMASK(12, 0)
 +#define   EXITLINE_SHIFT      0
 +
 +/*
 + * HSW+ eDP PSR registers
 + *
 + * HSW PSR registers are relative to DDIA(_DDI_BUF_CTL_A + 0x800) with just one
 + * instance of it
 + */
 +#define _HSW_EDP_PSR_BASE                     0x64800
 +#define _SRD_CTL_A                            0x60800
 +#define _SRD_CTL_EDP                          0x6f800
 +#define _PSR_ADJ(tran, reg)                   (_TRANS2(tran, reg) - dev_priv->hsw_psr_mmio_adjust)
 +#define EDP_PSR_CTL(tran)                     _MMIO(_PSR_ADJ(tran, _SRD_CTL_A))
  #define   EDP_PSR_ENABLE                      (1 << 31)
  #define   BDW_PSR_SINGLE_FRAME                        (1 << 30)
  #define   EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK (1 << 29) /* SW can't modify */
  #define   EDP_PSR_TP1_TIME_0us                        (3 << 4)
  #define   EDP_PSR_IDLE_FRAME_SHIFT            0
  
 -/* Bspec claims those aren't shifted but stay at 0x64800 */
 +/*
 + * Until TGL, IMR/IIR are fixed at 0x648xx. On TGL+ those registers are relative
 + * to transcoder and bits defined for each one as if using no shift (i.e. as if
 + * it was for TRANSCODER_EDP)
 + */
  #define EDP_PSR_IMR                           _MMIO(0x64834)
  #define EDP_PSR_IIR                           _MMIO(0x64838)
 -#define   EDP_PSR_ERROR(shift)                        (1 << ((shift) + 2))
 -#define   EDP_PSR_POST_EXIT(shift)            (1 << ((shift) + 1))
 -#define   EDP_PSR_PRE_ENTRY(shift)            (1 << (shift))
 -#define   EDP_PSR_TRANSCODER_C_SHIFT          24
 -#define   EDP_PSR_TRANSCODER_B_SHIFT          16
 -#define   EDP_PSR_TRANSCODER_A_SHIFT          8
 -#define   EDP_PSR_TRANSCODER_EDP_SHIFT                0
 -
 -#define EDP_PSR_AUX_CTL                               _MMIO(dev_priv->psr_mmio_base + 0x10)
 +#define _PSR_IMR_A                            0x60814
 +#define _PSR_IIR_A                            0x60818
 +#define TRANS_PSR_IMR(tran)                   _MMIO_TRANS2(tran, _PSR_IMR_A)
 +#define TRANS_PSR_IIR(tran)                   _MMIO_TRANS2(tran, _PSR_IIR_A)
 +#define   _EDP_PSR_TRANS_SHIFT(trans)         ((trans) == TRANSCODER_EDP ? \
 +                                               0 : ((trans) - TRANSCODER_A + 1) * 8)
 +#define   EDP_PSR_TRANS_MASK(trans)           (0x7 << _EDP_PSR_TRANS_SHIFT(trans))
 +#define   EDP_PSR_ERROR(trans)                        (0x4 << _EDP_PSR_TRANS_SHIFT(trans))
 +#define   EDP_PSR_POST_EXIT(trans)            (0x2 << _EDP_PSR_TRANS_SHIFT(trans))
 +#define   EDP_PSR_PRE_ENTRY(trans)            (0x1 << _EDP_PSR_TRANS_SHIFT(trans))
 +
 +#define _SRD_AUX_CTL_A                                0x60810
 +#define _SRD_AUX_CTL_EDP                      0x6f810
 +#define EDP_PSR_AUX_CTL(tran)                 _MMIO(_PSR_ADJ(tran, _SRD_AUX_CTL_A))
  #define   EDP_PSR_AUX_CTL_TIME_OUT_MASK               (3 << 26)
  #define   EDP_PSR_AUX_CTL_MESSAGE_SIZE_MASK   (0x1f << 20)
  #define   EDP_PSR_AUX_CTL_PRECHARGE_2US_MASK  (0xf << 16)
  #define   EDP_PSR_AUX_CTL_ERROR_INTERRUPT     (1 << 11)
  #define   EDP_PSR_AUX_CTL_BIT_CLOCK_2X_MASK   (0x7ff)
  
 -#define EDP_PSR_AUX_DATA(i)                   _MMIO(dev_priv->psr_mmio_base + 0x14 + (i) * 4) /* 5 registers */
 +#define _SRD_AUX_DATA_A                               0x60814
 +#define _SRD_AUX_DATA_EDP                     0x6f814
 +#define EDP_PSR_AUX_DATA(tran, i)             _MMIO(_PSR_ADJ(tran, _SRD_AUX_DATA_A) + (i) + 4) /* 5 registers */
  
 -#define EDP_PSR_STATUS                                _MMIO(dev_priv->psr_mmio_base + 0x40)
 +#define _SRD_STATUS_A                         0x60840
 +#define _SRD_STATUS_EDP                               0x6f840
 +#define EDP_PSR_STATUS(tran)                  _MMIO(_PSR_ADJ(tran, _SRD_STATUS_A))
  #define   EDP_PSR_STATUS_STATE_MASK           (7 << 29)
  #define   EDP_PSR_STATUS_STATE_SHIFT          29
  #define   EDP_PSR_STATUS_STATE_IDLE           (0 << 29)
  #define   EDP_PSR_STATUS_SENDING_TP1          (1 << 4)
  #define   EDP_PSR_STATUS_IDLE_MASK            0xf
  
 -#define EDP_PSR_PERF_CNT              _MMIO(dev_priv->psr_mmio_base + 0x44)
 +#define _SRD_PERF_CNT_A                       0x60844
 +#define _SRD_PERF_CNT_EDP             0x6f844
 +#define EDP_PSR_PERF_CNT(tran)                _MMIO(_PSR_ADJ(tran, _SRD_PERF_CNT_A))
  #define   EDP_PSR_PERF_CNT_MASK               0xffffff
  
 -#define EDP_PSR_DEBUG                         _MMIO(dev_priv->psr_mmio_base + 0x60) /* PSR_MASK on SKL+ */
 +/* PSR_MASK on SKL+ */
 +#define _SRD_DEBUG_A                          0x60860
 +#define _SRD_DEBUG_EDP                                0x6f860
 +#define EDP_PSR_DEBUG(tran)                   _MMIO(_PSR_ADJ(tran, _SRD_DEBUG_A))
  #define   EDP_PSR_DEBUG_MASK_MAX_SLEEP         (1 << 28)
  #define   EDP_PSR_DEBUG_MASK_LPSP              (1 << 27)
  #define   EDP_PSR_DEBUG_MASK_MEMUP             (1 << 26)
  #define   EDP_PSR_DEBUG_MASK_DISP_REG_WRITE    (1 << 16) /* Reserved in ICL+ */
  #define   EDP_PSR_DEBUG_EXIT_ON_PIXEL_UNDERRUN (1 << 15) /* SKL+ */
  
 -#define EDP_PSR2_CTL                  _MMIO(0x6f900)
 +#define _PSR2_CTL_A                   0x60900
 +#define _PSR2_CTL_EDP                 0x6f900
 +#define EDP_PSR2_CTL(tran)            _MMIO_TRANS2(tran, _PSR2_CTL_A)
  #define   EDP_PSR2_ENABLE             (1 << 31)
  #define   EDP_SU_TRACK_ENABLE         (1 << 30)
  #define   EDP_Y_COORDINATE_VALID      (1 << 26) /* GLK and CNL+ */
  #define _PSR_EVENT_TRANS_B                    0x61848
  #define _PSR_EVENT_TRANS_C                    0x62848
  #define _PSR_EVENT_TRANS_D                    0x63848
 -#define _PSR_EVENT_TRANS_EDP                  0x6F848
 -#define PSR_EVENT(trans)                      _MMIO_TRANS2(trans, _PSR_EVENT_TRANS_A)
 +#define _PSR_EVENT_TRANS_EDP                  0x6f848
 +#define PSR_EVENT(tran)                               _MMIO_TRANS2(tran, _PSR_EVENT_TRANS_A)
  #define  PSR_EVENT_PSR2_WD_TIMER_EXPIRE               (1 << 17)
  #define  PSR_EVENT_PSR2_DISABLED              (1 << 16)
  #define  PSR_EVENT_SU_DIRTY_FIFO_UNDERRUN     (1 << 15)
  #define  PSR_EVENT_LPSP_MODE_EXIT             (1 << 1)
  #define  PSR_EVENT_PSR_DISABLE                        (1 << 0)
  
 -#define EDP_PSR2_STATUS                       _MMIO(0x6f940)
 +#define _PSR2_STATUS_A                        0x60940
 +#define _PSR2_STATUS_EDP              0x6f940
 +#define EDP_PSR2_STATUS(tran)         _MMIO_TRANS2(tran, _PSR2_STATUS_A)
  #define EDP_PSR2_STATUS_STATE_MASK     (0xf << 28)
  #define EDP_PSR2_STATUS_STATE_SHIFT    28
  
 -#define _PSR2_SU_STATUS_0             0x6F914
 -#define _PSR2_SU_STATUS_1             0x6F918
 -#define _PSR2_SU_STATUS_2             0x6F91C
 -#define _PSR2_SU_STATUS(index)                _MMIO(_PICK_EVEN((index), _PSR2_SU_STATUS_0, _PSR2_SU_STATUS_1))
 -#define PSR2_SU_STATUS(frame)         (_PSR2_SU_STATUS((frame) / 3))
 +#define _PSR2_SU_STATUS_A             0x60914
 +#define _PSR2_SU_STATUS_EDP           0x6f914
 +#define _PSR2_SU_STATUS(tran, index)  _MMIO(_TRANS2(tran, _PSR2_SU_STATUS_A) + (index) * 4)
 +#define PSR2_SU_STATUS(tran, frame)   (_PSR2_SU_STATUS(tran, (frame) / 3))
  #define PSR2_SU_STATUS_SHIFT(frame)   (((frame) % 3) * 10)
  #define PSR2_SU_STATUS_MASK(frame)    (0x3ff << PSR2_SU_STATUS_SHIFT(frame))
  #define PSR2_SU_STATUS_FRAMES         8
   * (Haswell and newer) to see which VIDEO_DIP_DATA byte corresponds to each byte
   * of the infoframe structure specified by CEA-861. */
  #define   VIDEO_DIP_DATA_SIZE 32
 +#define   VIDEO_DIP_GMP_DATA_SIZE     36
  #define   VIDEO_DIP_VSC_DATA_SIZE     36
  #define   VIDEO_DIP_PPS_DATA_SIZE     132
  #define VIDEO_DIP_CTL         _MMIO(0x61170)
   */
  #define _DPA_AUX_CH_CTL               (DISPLAY_MMIO_BASE(dev_priv) + 0x64010)
  #define _DPA_AUX_CH_DATA1     (DISPLAY_MMIO_BASE(dev_priv) + 0x64014)
 -#define _DPA_AUX_CH_DATA2     (DISPLAY_MMIO_BASE(dev_priv) + 0x64018)
 -#define _DPA_AUX_CH_DATA3     (DISPLAY_MMIO_BASE(dev_priv) + 0x6401c)
 -#define _DPA_AUX_CH_DATA4     (DISPLAY_MMIO_BASE(dev_priv) + 0x64020)
 -#define _DPA_AUX_CH_DATA5     (DISPLAY_MMIO_BASE(dev_priv) + 0x64024)
  
  #define _DPB_AUX_CH_CTL               (DISPLAY_MMIO_BASE(dev_priv) + 0x64110)
  #define _DPB_AUX_CH_DATA1     (DISPLAY_MMIO_BASE(dev_priv) + 0x64114)
 -#define _DPB_AUX_CH_DATA2     (DISPLAY_MMIO_BASE(dev_priv) + 0x64118)
 -#define _DPB_AUX_CH_DATA3     (DISPLAY_MMIO_BASE(dev_priv) + 0x6411c)
 -#define _DPB_AUX_CH_DATA4     (DISPLAY_MMIO_BASE(dev_priv) + 0x64120)
 -#define _DPB_AUX_CH_DATA5     (DISPLAY_MMIO_BASE(dev_priv) + 0x64124)
 -
 -#define _DPC_AUX_CH_CTL               (DISPLAY_MMIO_BASE(dev_priv) + 0x64210)
 -#define _DPC_AUX_CH_DATA1     (DISPLAY_MMIO_BASE(dev_priv) + 0x64214)
 -#define _DPC_AUX_CH_DATA2     (DISPLAY_MMIO_BASE(dev_priv) + 0x64218)
 -#define _DPC_AUX_CH_DATA3     (DISPLAY_MMIO_BASE(dev_priv) + 0x6421c)
 -#define _DPC_AUX_CH_DATA4     (DISPLAY_MMIO_BASE(dev_priv) + 0x64220)
 -#define _DPC_AUX_CH_DATA5     (DISPLAY_MMIO_BASE(dev_priv) + 0x64224)
 -
 -#define _DPD_AUX_CH_CTL               (DISPLAY_MMIO_BASE(dev_priv) + 0x64310)
 -#define _DPD_AUX_CH_DATA1     (DISPLAY_MMIO_BASE(dev_priv) + 0x64314)
 -#define _DPD_AUX_CH_DATA2     (DISPLAY_MMIO_BASE(dev_priv) + 0x64318)
 -#define _DPD_AUX_CH_DATA3     (DISPLAY_MMIO_BASE(dev_priv) + 0x6431c)
 -#define _DPD_AUX_CH_DATA4     (DISPLAY_MMIO_BASE(dev_priv) + 0x64320)
 -#define _DPD_AUX_CH_DATA5     (DISPLAY_MMIO_BASE(dev_priv) + 0x64324)
 -
 -#define _DPE_AUX_CH_CTL               (DISPLAY_MMIO_BASE(dev_priv) + 0x64410)
 -#define _DPE_AUX_CH_DATA1     (DISPLAY_MMIO_BASE(dev_priv) + 0x64414)
 -#define _DPE_AUX_CH_DATA2     (DISPLAY_MMIO_BASE(dev_priv) + 0x64418)
 -#define _DPE_AUX_CH_DATA3     (DISPLAY_MMIO_BASE(dev_priv) + 0x6441c)
 -#define _DPE_AUX_CH_DATA4     (DISPLAY_MMIO_BASE(dev_priv) + 0x64420)
 -#define _DPE_AUX_CH_DATA5     (DISPLAY_MMIO_BASE(dev_priv) + 0x64424)
 -
 -#define _DPF_AUX_CH_CTL               (DISPLAY_MMIO_BASE(dev_priv) + 0x64510)
 -#define _DPF_AUX_CH_DATA1     (DISPLAY_MMIO_BASE(dev_priv) + 0x64514)
 -#define _DPF_AUX_CH_DATA2     (DISPLAY_MMIO_BASE(dev_priv) + 0x64518)
 -#define _DPF_AUX_CH_DATA3     (DISPLAY_MMIO_BASE(dev_priv) + 0x6451c)
 -#define _DPF_AUX_CH_DATA4     (DISPLAY_MMIO_BASE(dev_priv) + 0x64520)
 -#define _DPF_AUX_CH_DATA5     (DISPLAY_MMIO_BASE(dev_priv) + 0x64524)
  
  #define DP_AUX_CH_CTL(aux_ch) _MMIO_PORT(aux_ch, _DPA_AUX_CH_CTL, _DPB_AUX_CH_CTL)
  #define DP_AUX_CH_DATA(aux_ch, i)     _MMIO(_PORT(aux_ch, _DPA_AUX_CH_DATA1, _DPB_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
  #define   PIPECONF_CXSR_DOWNCLOCK     (1 << 16)
  #define   PIPECONF_EDP_RR_MODE_SWITCH_VLV     (1 << 14)
  #define   PIPECONF_COLOR_RANGE_SELECT (1 << 13)
 +#define   PIPECONF_OUTPUT_COLORSPACE_MASK     (3 << 11) /* ilk-ivb */
 +#define   PIPECONF_OUTPUT_COLORSPACE_RGB      (0 << 11) /* ilk-ivb */
 +#define   PIPECONF_OUTPUT_COLORSPACE_YUV601   (1 << 11) /* ilk-ivb */
 +#define   PIPECONF_OUTPUT_COLORSPACE_YUV709   (2 << 11) /* ilk-ivb */
 +#define   PIPECONF_OUTPUT_COLORSPACE_YUV_HSW  (1 << 11) /* hsw only */
  #define   PIPECONF_BPC_MASK   (0x7 << 5)
  #define   PIPECONF_8BPC               (0 << 5)
  #define   PIPECONF_10BPC      (1 << 5)
  
  #define  _PIPEAGCMAX           0x70010
  #define  _PIPEBGCMAX           0x71010
 +#define PIPEGCMAX_RGB_MASK     REG_GENMASK(15, 0)
  #define PIPEGCMAX(pipe, i)     _MMIO_PIPE2(pipe, _PIPEAGCMAX + (i) * 4)
  
  #define _PIPE_MISC_A                  0x70030
  #define _PIPE_MISC_B                  0x71030
 -#define   PIPEMISC_YUV420_ENABLE      (1 << 27)
 -#define   PIPEMISC_YUV420_MODE_FULL_BLEND (1 << 26)
 +#define   PIPEMISC_YUV420_ENABLE      (1 << 27) /* glk+ */
 +#define   PIPEMISC_YUV420_MODE_FULL_BLEND (1 << 26) /* glk+ */
  #define   PIPEMISC_HDR_MODE_PRECISION (1 << 23) /* icl+ */
  #define   PIPEMISC_OUTPUT_COLORSPACE_YUV  (1 << 11)
  #define   PIPEMISC_DITHER_BPC_MASK    (7 << 5)
  #define CHV_CURSOR_C_OFFSET 0x700e0
  #define IVB_CURSOR_B_OFFSET 0x71080
  #define IVB_CURSOR_C_OFFSET 0x72080
 +#define TGL_CURSOR_D_OFFSET 0x73080
  
  /* Display A control */
  #define _DSPACNTR                             0x70180
  /* legacy palette */
  #define _LGC_PALETTE_A           0x4a000
  #define _LGC_PALETTE_B           0x4a800
 +#define LGC_PALETTE_RED_MASK     REG_GENMASK(23, 16)
 +#define LGC_PALETTE_GREEN_MASK   REG_GENMASK(15, 8)
 +#define LGC_PALETTE_BLUE_MASK    REG_GENMASK(7, 0)
  #define LGC_PALETTE(pipe, i) _MMIO(_PIPE(pipe, _LGC_PALETTE_A, _LGC_PALETTE_B) + (i) * 4)
  
  /* ilk/snb precision palette */
  #define _PREC_PALETTE_A           0x4b000
  #define _PREC_PALETTE_B           0x4c000
 +#define   PREC_PALETTE_RED_MASK   REG_GENMASK(29, 20)
 +#define   PREC_PALETTE_GREEN_MASK REG_GENMASK(19, 10)
 +#define   PREC_PALETTE_BLUE_MASK  REG_GENMASK(9, 0)
  #define PREC_PALETTE(pipe, i) _MMIO(_PIPE(pipe, _PREC_PALETTE_A, _PREC_PALETTE_B) + (i) * 4)
  
  #define  _PREC_PIPEAGCMAX              0x4d000
  #define TGL_DMC_DEBUG_DC5_COUNT       _MMIO(0x101084)
  #define TGL_DMC_DEBUG_DC6_COUNT       _MMIO(0x101088)
  
 +#define DMC_DEBUG3            _MMIO(0x101090)
 +
+ /* Display Internal Timeout Register */
+ #define RM_TIMEOUT            _MMIO(0x42060)
+ #define  MMIO_TIMEOUT_US(us)  ((us) << 0)
  /* interrupts */
  #define DE_MASTER_IRQ_CONTROL   (1 << 31)
  #define DE_SPRITEB_FLIP_DONE    (1 << 29)
  #define  GEN8_PIPE_VSYNC              (1 << 1)
  #define  GEN8_PIPE_VBLANK             (1 << 0)
  #define  GEN9_PIPE_CURSOR_FAULT               (1 << 11)
 +#define  GEN11_PIPE_PLANE7_FAULT      (1 << 22)
 +#define  GEN11_PIPE_PLANE6_FAULT      (1 << 21)
 +#define  GEN11_PIPE_PLANE5_FAULT      (1 << 20)
  #define  GEN9_PIPE_PLANE4_FAULT               (1 << 10)
  #define  GEN9_PIPE_PLANE3_FAULT               (1 << 9)
  #define  GEN9_PIPE_PLANE2_FAULT               (1 << 8)
         GEN9_PIPE_PLANE3_FAULT | \
         GEN9_PIPE_PLANE2_FAULT | \
         GEN9_PIPE_PLANE1_FAULT)
 +#define GEN11_DE_PIPE_IRQ_FAULT_ERRORS \
 +      (GEN9_DE_PIPE_IRQ_FAULT_ERRORS | \
 +       GEN11_PIPE_PLANE7_FAULT | \
 +       GEN11_PIPE_PLANE6_FAULT | \
 +       GEN11_PIPE_PLANE5_FAULT)
  
  #define GEN8_DE_PORT_ISR _MMIO(0x44440)
  #define GEN8_DE_PORT_IMR _MMIO(0x44444)
  #define  GEN8_PORT_DP_A_HOTPLUG               (1 << 3)
  #define  BXT_DE_PORT_GMBUS            (1 << 1)
  #define  GEN8_AUX_CHANNEL_A           (1 << 0)
 +#define  TGL_DE_PORT_AUX_USBC6                (1 << 13)
 +#define  TGL_DE_PORT_AUX_USBC5                (1 << 12)
 +#define  TGL_DE_PORT_AUX_USBC4                (1 << 11)
 +#define  TGL_DE_PORT_AUX_USBC3                (1 << 10)
 +#define  TGL_DE_PORT_AUX_USBC2                (1 << 9)
 +#define  TGL_DE_PORT_AUX_USBC1                (1 << 8)
  #define  TGL_DE_PORT_AUX_DDIC         (1 << 2)
  #define  TGL_DE_PORT_AUX_DDIB         (1 << 1)
  #define  TGL_DE_PORT_AUX_DDIA         (1 << 0)
  #define  BDW_DPRS_MASK_VBLANK_SRD     (1 << 0)
  #define CHICKEN_PIPESL_1(pipe) _MMIO_PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B)
  
 -#define CHICKEN_TRANS_A               _MMIO(0x420c0)
 -#define CHICKEN_TRANS_B               _MMIO(0x420c4)
 -#define CHICKEN_TRANS_C               _MMIO(0x420c8)
 -#define CHICKEN_TRANS_EDP     _MMIO(0x420cc)
 +#define _CHICKEN_TRANS_A      0x420c0
 +#define _CHICKEN_TRANS_B      0x420c4
 +#define _CHICKEN_TRANS_C      0x420c8
 +#define _CHICKEN_TRANS_EDP    0x420cc
 +#define _CHICKEN_TRANS_D      0x420d8
 +#define CHICKEN_TRANS(trans)  _MMIO(_PICK((trans), \
 +                                          [TRANSCODER_EDP] = _CHICKEN_TRANS_EDP, \
 +                                          [TRANSCODER_A] = _CHICKEN_TRANS_A, \
 +                                          [TRANSCODER_B] = _CHICKEN_TRANS_B, \
 +                                          [TRANSCODER_C] = _CHICKEN_TRANS_C, \
 +                                          [TRANSCODER_D] = _CHICKEN_TRANS_D))
  #define  VSC_DATA_SEL_SOFTWARE_CONTROL        (1 << 25) /* GLK and CNL+ */
  #define  DDI_TRAINING_OVERRIDE_ENABLE (1 << 19)
  #define  DDI_TRAINING_OVERRIDE_VALUE  (1 << 18)
  #define   CNL_DDI_CLOCK_REG_ACCESS_ON (1 << 7)
  
  #define SKL_DFSM                      _MMIO(0x51000)
 -#define SKL_DFSM_CDCLK_LIMIT_MASK     (3 << 23)
 -#define SKL_DFSM_CDCLK_LIMIT_675      (0 << 23)
 -#define SKL_DFSM_CDCLK_LIMIT_540      (1 << 23)
 -#define SKL_DFSM_CDCLK_LIMIT_450      (2 << 23)
 -#define SKL_DFSM_CDCLK_LIMIT_337_5    (3 << 23)
 -#define SKL_DFSM_PIPE_A_DISABLE               (1 << 30)
 -#define SKL_DFSM_PIPE_B_DISABLE               (1 << 21)
 -#define SKL_DFSM_PIPE_C_DISABLE               (1 << 28)
 -#define TGL_DFSM_PIPE_D_DISABLE               (1 << 22)
 +#define   SKL_DFSM_DISPLAY_PM_DISABLE (1 << 27)
 +#define   SKL_DFSM_DISPLAY_HDCP_DISABLE       (1 << 25)
 +#define   SKL_DFSM_CDCLK_LIMIT_MASK   (3 << 23)
 +#define   SKL_DFSM_CDCLK_LIMIT_675    (0 << 23)
 +#define   SKL_DFSM_CDCLK_LIMIT_540    (1 << 23)
 +#define   SKL_DFSM_CDCLK_LIMIT_450    (2 << 23)
 +#define   SKL_DFSM_CDCLK_LIMIT_337_5  (3 << 23)
 +#define   ICL_DFSM_DMC_DISABLE                (1 << 23)
 +#define   SKL_DFSM_PIPE_A_DISABLE     (1 << 30)
 +#define   SKL_DFSM_PIPE_B_DISABLE     (1 << 21)
 +#define   SKL_DFSM_PIPE_C_DISABLE     (1 << 28)
 +#define   TGL_DFSM_PIPE_D_DISABLE     (1 << 22)
 +#define   CNL_DFSM_DISPLAY_DSC_DISABLE        (1 << 7)
  
  #define SKL_DSSM                              _MMIO(0x51004)
  #define CNL_DSSM_CDCLK_PLL_REFCLK_24MHz               (1 << 31)
  #define  GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE  (1 << 10)
  
  #define GEN9_CS_DEBUG_MODE1           _MMIO(0x20ec)
 +#define   FF_DOP_CLOCK_GATE_DISABLE   REG_BIT(1)
  #define GEN9_CTX_PREEMPT_REG          _MMIO(0x2248)
 +#define   GEN12_DISABLE_POSH_BUSY_FF_DOP_CG REG_BIT(11)
 +
  #define GEN8_CS_CHICKEN1              _MMIO(0x2580)
  #define GEN9_PREEMPT_3D_OBJECT_LEVEL          (1 << 0)
  #define GEN9_PREEMPT_GPGPU_LEVEL(hi, lo)      (((hi) << 2) | ((lo) << 1))
  
  #define GEN11_COMMON_SLICE_CHICKEN3           _MMIO(0x7304)
    #define GEN11_BLEND_EMB_FIX_DISABLE_IN_RCC  (1 << 11)
 +  #define GEN12_DISABLE_CPS_AWARE_COLOR_PIPE  (1 << 9)
  
  #define HIZ_CHICKEN                                   _MMIO(0x7018)
  # define CHV_HZ_8X8_MODE_IN_1X                                (1 << 15)
                                 SDE_FDI_RXA_CPT)
  
  /* south display engine interrupt: ICP/TGP */
 -#define SDE_TC6_HOTPLUG_TGP           (1 << 29)
 -#define SDE_TC5_HOTPLUG_TGP           (1 << 28)
 -#define SDE_TC4_HOTPLUG_ICP           (1 << 27)
 -#define SDE_TC3_HOTPLUG_ICP           (1 << 26)
 -#define SDE_TC2_HOTPLUG_ICP           (1 << 25)
 -#define SDE_TC1_HOTPLUG_ICP           (1 << 24)
  #define SDE_GMBUS_ICP                 (1 << 23)
 -#define SDE_DDIC_HOTPLUG_TGP          (1 << 18)
 -#define SDE_DDIB_HOTPLUG_ICP          (1 << 17)
 -#define SDE_DDIA_HOTPLUG_ICP          (1 << 16)
  #define SDE_TC_HOTPLUG_ICP(tc_port)   (1 << ((tc_port) + 24))
  #define SDE_DDI_HOTPLUG_ICP(port)     (1 << ((port) + 16))
 -#define SDE_DDI_MASK_ICP              (SDE_DDIB_HOTPLUG_ICP | \
 -                                       SDE_DDIA_HOTPLUG_ICP)
 -#define SDE_TC_MASK_ICP                       (SDE_TC4_HOTPLUG_ICP |  \
 -                                       SDE_TC3_HOTPLUG_ICP |  \
 -                                       SDE_TC2_HOTPLUG_ICP |  \
 -                                       SDE_TC1_HOTPLUG_ICP)
 -#define SDE_DDI_MASK_TGP              (SDE_DDIC_HOTPLUG_TGP | \
 -                                       SDE_DDI_MASK_ICP)
 -#define SDE_TC_MASK_TGP                       (SDE_TC6_HOTPLUG_TGP |  \
 -                                       SDE_TC5_HOTPLUG_TGP |  \
 -                                       SDE_TC_MASK_ICP)
 +#define SDE_DDI_MASK_ICP              (SDE_DDI_HOTPLUG_ICP(PORT_B) | \
 +                                       SDE_DDI_HOTPLUG_ICP(PORT_A))
 +#define SDE_TC_MASK_ICP                       (SDE_TC_HOTPLUG_ICP(PORT_TC4) | \
 +                                       SDE_TC_HOTPLUG_ICP(PORT_TC3) | \
 +                                       SDE_TC_HOTPLUG_ICP(PORT_TC2) | \
 +                                       SDE_TC_HOTPLUG_ICP(PORT_TC1))
 +#define SDE_DDI_MASK_TGP              (SDE_DDI_HOTPLUG_ICP(PORT_C) | \
 +                                       SDE_DDI_HOTPLUG_ICP(PORT_B) | \
 +                                       SDE_DDI_HOTPLUG_ICP(PORT_A))
 +#define SDE_TC_MASK_TGP                       (SDE_TC_HOTPLUG_ICP(PORT_TC6) | \
 +                                       SDE_TC_HOTPLUG_ICP(PORT_TC5) | \
 +                                       SDE_TC_HOTPLUG_ICP(PORT_TC4) | \
 +                                       SDE_TC_HOTPLUG_ICP(PORT_TC3) | \
 +                                       SDE_TC_HOTPLUG_ICP(PORT_TC2) | \
 +                                       SDE_TC_HOTPLUG_ICP(PORT_TC1))
  
  #define SDEISR  _MMIO(0xc4000)
  #define SDEIMR  _MMIO(0xc4004)
   * SHOTPLUG_CTL_DDI and SHOTPLUG_CTL_TC.
   */
  
 -#define SHOTPLUG_CTL_DDI                      _MMIO(0xc4030)
 -#define   TGP_DDIC_HPD_ENABLE                 (1 << 11)
 -#define   TGP_DDIC_HPD_STATUS_MASK            (3 << 8)
 -#define   TGP_DDIC_HPD_NO_DETECT              (0 << 8)
 -#define   TGP_DDIC_HPD_SHORT_DETECT           (1 << 8)
 -#define   TGP_DDIC_HPD_LONG_DETECT            (2 << 8)
 -#define   TGP_DDIC_HPD_SHORT_LONG_DETECT      (3 << 8)
 -#define   ICP_DDIB_HPD_ENABLE                 (1 << 7)
 -#define   ICP_DDIB_HPD_STATUS_MASK            (3 << 4)
 -#define   ICP_DDIB_HPD_NO_DETECT              (0 << 4)
 -#define   ICP_DDIB_HPD_SHORT_DETECT           (1 << 4)
 -#define   ICP_DDIB_HPD_LONG_DETECT            (2 << 4)
 -#define   ICP_DDIB_HPD_SHORT_LONG_DETECT      (3 << 4)
 -#define   ICP_DDIA_HPD_ENABLE                 (1 << 3)
 -#define   ICP_DDIA_HPD_OP_DRIVE_1             (1 << 2)
 -#define   ICP_DDIA_HPD_STATUS_MASK            (3 << 0)
 -#define   ICP_DDIA_HPD_NO_DETECT              (0 << 0)
 -#define   ICP_DDIA_HPD_SHORT_DETECT           (1 << 0)
 -#define   ICP_DDIA_HPD_LONG_DETECT            (2 << 0)
 -#define   ICP_DDIA_HPD_SHORT_LONG_DETECT      (3 << 0)
 +#define SHOTPLUG_CTL_DDI                              _MMIO(0xc4030)
 +#define   SHOTPLUG_CTL_DDI_HPD_ENABLE(port)           (0x8 << (4 * (port)))
 +#define   SHOTPLUG_CTL_DDI_HPD_STATUS_MASK(port)      (0x3 << (4 * (port)))
 +#define   SHOTPLUG_CTL_DDI_HPD_NO_DETECT(port)                (0x0 << (4 * (port)))
 +#define   SHOTPLUG_CTL_DDI_HPD_SHORT_DETECT(port)     (0x1 << (4 * (port)))
 +#define   SHOTPLUG_CTL_DDI_HPD_LONG_DETECT(port)      (0x2 << (4 * (port)))
 +#define   SHOTPLUG_CTL_DDI_HPD_SHORT_LONG_DETECT(port)        (0x3 << (4 * (port)))
  
  #define SHOTPLUG_CTL_TC                               _MMIO(0xc4034)
  #define   ICP_TC_HPD_ENABLE(tc_port)          (8 << (tc_port) * 4)
  #define   ICP_TC_HPD_LONG_DETECT(tc_port)     (2 << (tc_port) * 4)
  #define   ICP_TC_HPD_SHORT_DETECT(tc_port)    (1 << (tc_port) * 4)
  
 -#define ICP_DDI_HPD_ENABLE_MASK               (ICP_DDIB_HPD_ENABLE |  \
 -                                       ICP_DDIA_HPD_ENABLE)
 +#define ICP_DDI_HPD_ENABLE_MASK               (SHOTPLUG_CTL_DDI_HPD_ENABLE(PORT_B) | \
 +                                       SHOTPLUG_CTL_DDI_HPD_ENABLE(PORT_A))
  #define ICP_TC_HPD_ENABLE_MASK                (ICP_TC_HPD_ENABLE(PORT_TC4) | \
                                         ICP_TC_HPD_ENABLE(PORT_TC3) | \
                                         ICP_TC_HPD_ENABLE(PORT_TC2) | \
                                         ICP_TC_HPD_ENABLE(PORT_TC1))
 -#define TGP_DDI_HPD_ENABLE_MASK               (TGP_DDIC_HPD_ENABLE |  \
 -                                       ICP_DDI_HPD_ENABLE_MASK)
 +#define TGP_DDI_HPD_ENABLE_MASK               (SHOTPLUG_CTL_DDI_HPD_ENABLE(PORT_C) | \
 +                                       SHOTPLUG_CTL_DDI_HPD_ENABLE(PORT_B) | \
 +                                       SHOTPLUG_CTL_DDI_HPD_ENABLE(PORT_A))
  #define TGP_TC_HPD_ENABLE_MASK                (ICP_TC_HPD_ENABLE(PORT_TC6) | \
                                         ICP_TC_HPD_ENABLE(PORT_TC5) | \
                                         ICP_TC_HPD_ENABLE_MASK)
  #define   GEN9_PWRGT_MEDIA_STATUS_MASK                (1 << 0)
  #define   GEN9_PWRGT_RENDER_STATUS_MASK               (1 << 1)
  
 +#define POWERGATE_ENABLE                      _MMIO(0xa210)
 +#define    VDN_HCP_POWERGATE_ENABLE(n)                BIT(((n) * 2) + 3)
 +#define    VDN_MFX_POWERGATE_ENABLE(n)                BIT(((n) * 2) + 4)
 +
  #define  GTFIFODBG                            _MMIO(0x120000)
  #define    GT_FIFO_SBDEDICATE_FREE_ENTRY_CHV  (0x1f << 20)
  #define    GT_FIFO_FREE_ENTRIES_CHV           (0x7f << 13)
  #define     GEN9_SAGV_DISABLE                 0x0
  #define     GEN9_SAGV_IS_DISABLED             0x1
  #define     GEN9_SAGV_ENABLE                  0x3
 +#define GEN12_PCODE_READ_SAGV_BLOCK_TIME_US   0x23
  #define GEN6_PCODE_DATA                               _MMIO(0x138128)
  #define   GEN6_PCODE_FREQ_IA_RATIO_SHIFT      8
  #define   GEN6_PCODE_FREQ_RING_RATIO_SHIFT    16
  #define HSW_AUD_CHICKENBIT                    _MMIO(0x65f10)
  #define   SKL_AUD_CODEC_WAKE_SIGNAL           (1 << 15)
  
 +#define AUD_FREQ_CNTRL                        _MMIO(0x65900)
 +#define AUD_PIN_BUF_CTL               _MMIO(0x48414)
 +#define   AUD_PIN_BUF_ENABLE          REG_BIT(31)
 +
  /*
   * HSW - ICL power wells
   *
@@@ -9421,20 -9266,12 +9429,20 @@@ enum skl_power_gate 
  
  /* HDCP Repeater Registers */
  #define HDCP_REP_CTL                  _MMIO(0x66d00)
 +#define  HDCP_TRANSA_REP_PRESENT      BIT(31)
 +#define  HDCP_TRANSB_REP_PRESENT      BIT(30)
 +#define  HDCP_TRANSC_REP_PRESENT      BIT(29)
 +#define  HDCP_TRANSD_REP_PRESENT      BIT(28)
  #define  HDCP_DDIB_REP_PRESENT                BIT(30)
  #define  HDCP_DDIA_REP_PRESENT                BIT(29)
  #define  HDCP_DDIC_REP_PRESENT                BIT(28)
  #define  HDCP_DDID_REP_PRESENT                BIT(27)
  #define  HDCP_DDIF_REP_PRESENT                BIT(26)
  #define  HDCP_DDIE_REP_PRESENT                BIT(25)
 +#define  HDCP_TRANSA_SHA1_M0          (1 << 20)
 +#define  HDCP_TRANSB_SHA1_M0          (2 << 20)
 +#define  HDCP_TRANSC_SHA1_M0          (3 << 20)
 +#define  HDCP_TRANSD_SHA1_M0          (4 << 20)
  #define  HDCP_DDIB_SHA1_M0            (1 << 20)
  #define  HDCP_DDIA_SHA1_M0            (2 << 20)
  #define  HDCP_DDIC_SHA1_M0            (3 << 20)
                                          _PORTE_HDCP_AUTHENC, \
                                          _PORTF_HDCP_AUTHENC) + (x))
  #define PORT_HDCP_CONF(port)          _PORT_HDCP_AUTHENC(port, 0x0)
 +#define _TRANSA_HDCP_CONF             0x66400
 +#define _TRANSB_HDCP_CONF             0x66500
 +#define TRANS_HDCP_CONF(trans)                _MMIO_TRANS(trans, _TRANSA_HDCP_CONF, \
 +                                                  _TRANSB_HDCP_CONF)
 +#define HDCP_CONF(dev_priv, trans, port) \
 +                                      (INTEL_GEN(dev_priv) >= 12 ? \
 +                                       TRANS_HDCP_CONF(trans) : \
 +                                       PORT_HDCP_CONF(port))
 +
  #define  HDCP_CONF_CAPTURE_AN         BIT(0)
  #define  HDCP_CONF_AUTH_AND_ENC               (BIT(1) | BIT(0))
  #define PORT_HDCP_ANINIT(port)                _PORT_HDCP_AUTHENC(port, 0x4)
 +#define _TRANSA_HDCP_ANINIT           0x66404
 +#define _TRANSB_HDCP_ANINIT           0x66504
 +#define TRANS_HDCP_ANINIT(trans)      _MMIO_TRANS(trans, \
 +                                                  _TRANSA_HDCP_ANINIT, \
 +                                                  _TRANSB_HDCP_ANINIT)
 +#define HDCP_ANINIT(dev_priv, trans, port) \
 +                                      (INTEL_GEN(dev_priv) >= 12 ? \
 +                                       TRANS_HDCP_ANINIT(trans) : \
 +                                       PORT_HDCP_ANINIT(port))
 +
  #define PORT_HDCP_ANLO(port)          _PORT_HDCP_AUTHENC(port, 0x8)
 +#define _TRANSA_HDCP_ANLO             0x66408
 +#define _TRANSB_HDCP_ANLO             0x66508
 +#define TRANS_HDCP_ANLO(trans)                _MMIO_TRANS(trans, _TRANSA_HDCP_ANLO, \
 +                                                  _TRANSB_HDCP_ANLO)
 +#define HDCP_ANLO(dev_priv, trans, port) \
 +                                      (INTEL_GEN(dev_priv) >= 12 ? \
 +                                       TRANS_HDCP_ANLO(trans) : \
 +                                       PORT_HDCP_ANLO(port))
 +
  #define PORT_HDCP_ANHI(port)          _PORT_HDCP_AUTHENC(port, 0xC)
 +#define _TRANSA_HDCP_ANHI             0x6640C
 +#define _TRANSB_HDCP_ANHI             0x6650C
 +#define TRANS_HDCP_ANHI(trans)                _MMIO_TRANS(trans, _TRANSA_HDCP_ANHI, \
 +                                                  _TRANSB_HDCP_ANHI)
 +#define HDCP_ANHI(dev_priv, trans, port) \
 +                                      (INTEL_GEN(dev_priv) >= 12 ? \
 +                                       TRANS_HDCP_ANHI(trans) : \
 +                                       PORT_HDCP_ANHI(port))
 +
  #define PORT_HDCP_BKSVLO(port)                _PORT_HDCP_AUTHENC(port, 0x10)
 +#define _TRANSA_HDCP_BKSVLO           0x66410
 +#define _TRANSB_HDCP_BKSVLO           0x66510
 +#define TRANS_HDCP_BKSVLO(trans)      _MMIO_TRANS(trans, \
 +                                                  _TRANSA_HDCP_BKSVLO, \
 +                                                  _TRANSB_HDCP_BKSVLO)
 +#define HDCP_BKSVLO(dev_priv, trans, port) \
 +                                      (INTEL_GEN(dev_priv) >= 12 ? \
 +                                       TRANS_HDCP_BKSVLO(trans) : \
 +                                       PORT_HDCP_BKSVLO(port))
 +
  #define PORT_HDCP_BKSVHI(port)                _PORT_HDCP_AUTHENC(port, 0x14)
 +#define _TRANSA_HDCP_BKSVHI           0x66414
 +#define _TRANSB_HDCP_BKSVHI           0x66514
 +#define TRANS_HDCP_BKSVHI(trans)      _MMIO_TRANS(trans, \
 +                                                  _TRANSA_HDCP_BKSVHI, \
 +                                                  _TRANSB_HDCP_BKSVHI)
 +#define HDCP_BKSVHI(dev_priv, trans, port) \
 +                                      (INTEL_GEN(dev_priv) >= 12 ? \
 +                                       TRANS_HDCP_BKSVHI(trans) : \
 +                                       PORT_HDCP_BKSVHI(port))
 +
  #define PORT_HDCP_RPRIME(port)                _PORT_HDCP_AUTHENC(port, 0x18)
 +#define _TRANSA_HDCP_RPRIME           0x66418
 +#define _TRANSB_HDCP_RPRIME           0x66518
 +#define TRANS_HDCP_RPRIME(trans)      _MMIO_TRANS(trans, \
 +                                                  _TRANSA_HDCP_RPRIME, \
 +                                                  _TRANSB_HDCP_RPRIME)
 +#define HDCP_RPRIME(dev_priv, trans, port) \
 +                                      (INTEL_GEN(dev_priv) >= 12 ? \
 +                                       TRANS_HDCP_RPRIME(trans) : \
 +                                       PORT_HDCP_RPRIME(port))
 +
  #define PORT_HDCP_STATUS(port)                _PORT_HDCP_AUTHENC(port, 0x1C)
 +#define _TRANSA_HDCP_STATUS           0x6641C
 +#define _TRANSB_HDCP_STATUS           0x6651C
 +#define TRANS_HDCP_STATUS(trans)      _MMIO_TRANS(trans, \
 +                                                  _TRANSA_HDCP_STATUS, \
 +                                                  _TRANSB_HDCP_STATUS)
 +#define HDCP_STATUS(dev_priv, trans, port) \
 +                                      (INTEL_GEN(dev_priv) >= 12 ? \
 +                                       TRANS_HDCP_STATUS(trans) : \
 +                                       PORT_HDCP_STATUS(port))
 +
  #define  HDCP_STATUS_STREAM_A_ENC     BIT(31)
  #define  HDCP_STATUS_STREAM_B_ENC     BIT(30)
  #define  HDCP_STATUS_STREAM_C_ENC     BIT(29)
                                          _PORTD_HDCP2_BASE, \
                                          _PORTE_HDCP2_BASE, \
                                          _PORTF_HDCP2_BASE) + (x))
 -
 -#define HDCP2_AUTH_DDI(port)          _PORT_HDCP2_BASE(port, 0x98)
 +#define PORT_HDCP2_AUTH(port)         _PORT_HDCP2_BASE(port, 0x98)
 +#define _TRANSA_HDCP2_AUTH            0x66498
 +#define _TRANSB_HDCP2_AUTH            0x66598
 +#define TRANS_HDCP2_AUTH(trans)               _MMIO_TRANS(trans, _TRANSA_HDCP2_AUTH, \
 +                                                  _TRANSB_HDCP2_AUTH)
  #define   AUTH_LINK_AUTHENTICATED     BIT(31)
  #define   AUTH_LINK_TYPE              BIT(30)
  #define   AUTH_FORCE_CLR_INPUTCTR     BIT(19)
  #define   AUTH_CLR_KEYS                       BIT(18)
 -
 -#define HDCP2_CTL_DDI(port)           _PORT_HDCP2_BASE(port, 0xB0)
 +#define HDCP2_AUTH(dev_priv, trans, port) \
 +                                      (INTEL_GEN(dev_priv) >= 12 ? \
 +                                       TRANS_HDCP2_AUTH(trans) : \
 +                                       PORT_HDCP2_AUTH(port))
 +
 +#define PORT_HDCP2_CTL(port)          _PORT_HDCP2_BASE(port, 0xB0)
 +#define _TRANSA_HDCP2_CTL             0x664B0
 +#define _TRANSB_HDCP2_CTL             0x665B0
 +#define TRANS_HDCP2_CTL(trans)                _MMIO_TRANS(trans, _TRANSA_HDCP2_CTL, \
 +                                                  _TRANSB_HDCP2_CTL)
  #define   CTL_LINK_ENCRYPTION_REQ     BIT(31)
 -
 -#define HDCP2_STATUS_DDI(port)                _PORT_HDCP2_BASE(port, 0xB4)
 -#define   STREAM_ENCRYPTION_STATUS_A  BIT(31)
 -#define   STREAM_ENCRYPTION_STATUS_B  BIT(30)
 -#define   STREAM_ENCRYPTION_STATUS_C  BIT(29)
 +#define HDCP2_CTL(dev_priv, trans, port) \
 +                                      (INTEL_GEN(dev_priv) >= 12 ? \
 +                                       TRANS_HDCP2_CTL(trans) : \
 +                                       PORT_HDCP2_CTL(port))
 +
 +#define PORT_HDCP2_STATUS(port)               _PORT_HDCP2_BASE(port, 0xB4)
 +#define _TRANSA_HDCP2_STATUS          0x664B4
 +#define _TRANSB_HDCP2_STATUS          0x665B4
 +#define TRANS_HDCP2_STATUS(trans)     _MMIO_TRANS(trans, \
 +                                                  _TRANSA_HDCP2_STATUS, \
 +                                                  _TRANSB_HDCP2_STATUS)
  #define   LINK_TYPE_STATUS            BIT(22)
  #define   LINK_AUTH_STATUS            BIT(21)
  #define   LINK_ENCRYPTION_STATUS      BIT(20)
 +#define HDCP2_STATUS(dev_priv, trans, port) \
 +                                      (INTEL_GEN(dev_priv) >= 12 ? \
 +                                       TRANS_HDCP2_STATUS(trans) : \
 +                                       PORT_HDCP2_STATUS(port))
  
  /* Per-pipe DDI Function Control */
  #define _TRANS_DDI_FUNC_CTL_A         0x60400
  #define  TRANS_DDI_EDP_INPUT_A_ONOFF  (4 << 12)
  #define  TRANS_DDI_EDP_INPUT_B_ONOFF  (5 << 12)
  #define  TRANS_DDI_EDP_INPUT_C_ONOFF  (6 << 12)
 +#define  TRANS_DDI_MST_TRANSPORT_SELECT_MASK  REG_GENMASK(12, 10)
 +#define  TRANS_DDI_MST_TRANSPORT_SELECT(trans)        \
 +      REG_FIELD_PREP(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, trans)
  #define  TRANS_DDI_HDCP_SIGNALLING    (1 << 9)
  #define  TRANS_DDI_DP_VC_PAYLOAD_ALLOC        (1 << 8)
  #define  TRANS_DDI_HDMI_SCRAMBLER_CTS_ENABLE (1 << 7)
  /* DisplayPort Transport Control */
  #define _DP_TP_CTL_A                  0x64040
  #define _DP_TP_CTL_B                  0x64140
 +#define _TGL_DP_TP_CTL_A              0x60540
  #define DP_TP_CTL(port) _MMIO_PORT(port, _DP_TP_CTL_A, _DP_TP_CTL_B)
 +#define TGL_DP_TP_CTL(tran) _MMIO_TRANS2((tran), _TGL_DP_TP_CTL_A)
  #define  DP_TP_CTL_ENABLE                     (1 << 31)
  #define  DP_TP_CTL_FEC_ENABLE                 (1 << 30)
  #define  DP_TP_CTL_MODE_SST                   (0 << 27)
  /* DisplayPort Transport Status */
  #define _DP_TP_STATUS_A                       0x64044
  #define _DP_TP_STATUS_B                       0x64144
 +#define _TGL_DP_TP_STATUS_A           0x60544
  #define DP_TP_STATUS(port) _MMIO_PORT(port, _DP_TP_STATUS_A, _DP_TP_STATUS_B)
 +#define TGL_DP_TP_STATUS(tran) _MMIO_TRANS2((tran), _TGL_DP_TP_STATUS_A)
  #define  DP_TP_STATUS_FEC_ENABLE_LIVE         (1 << 28)
  #define  DP_TP_STATUS_IDLE_DONE                       (1 << 25)
  #define  DP_TP_STATUS_ACT_SENT                        (1 << 24)
  #define _TRANSC_MSA_MISC              0x62410
  #define _TRANS_EDP_MSA_MISC           0x6f410
  #define TRANS_MSA_MISC(tran) _MMIO_TRANS2(tran, _TRANSA_MSA_MISC)
 -
 -#define  TRANS_MSA_SYNC_CLK           (1 << 0)
 -#define  TRANS_MSA_SAMPLING_444               (2 << 1)
 -#define  TRANS_MSA_CLRSP_YCBCR                (2 << 3)
 -#define  TRANS_MSA_6_BPC              (0 << 5)
 -#define  TRANS_MSA_8_BPC              (1 << 5)
 -#define  TRANS_MSA_10_BPC             (2 << 5)
 -#define  TRANS_MSA_12_BPC             (3 << 5)
 -#define  TRANS_MSA_16_BPC             (4 << 5)
 -#define  TRANS_MSA_CEA_RANGE          (1 << 3)
 -#define  TRANS_MSA_USE_VSC_SDP                (1 << 14)
 +/* See DP_MSA_MISC_* for the bit definitions */
  
  /* LCPLL Control */
  #define LCPLL_CTL                     _MMIO(0x130040)
  #define  BXT_CDCLK_CD2X_PIPE(pipe)    ((pipe) << 20)
  #define  CDCLK_DIVMUX_CD_OVERRIDE     (1 << 19)
  #define  BXT_CDCLK_CD2X_PIPE_NONE     BXT_CDCLK_CD2X_PIPE(3)
 +#define  ICL_CDCLK_CD2X_PIPE(pipe)    (_PICK(pipe, 0, 2, 6) << 19)
  #define  ICL_CDCLK_CD2X_PIPE_NONE     (7 << 19)
 +#define  TGL_CDCLK_CD2X_PIPE(pipe)    BXT_CDCLK_CD2X_PIPE(pipe)
 +#define  TGL_CDCLK_CD2X_PIPE_NONE     ICL_CDCLK_CD2X_PIPE_NONE
  #define  BXT_CDCLK_SSA_PRECHARGE_ENABLE       (1 << 16)
  #define  CDCLK_FREQ_DECIMAL_MASK      (0x7ff)
  
                                                   _TGL_DPLL1_CFGCR1, \
                                                   _TGL_TBTPLL_CFGCR1)
  
 +#define _DKL_PHY1_BASE                        0x168000
 +#define _DKL_PHY2_BASE                        0x169000
 +#define _DKL_PHY3_BASE                        0x16A000
 +#define _DKL_PHY4_BASE                        0x16B000
 +#define _DKL_PHY5_BASE                        0x16C000
 +#define _DKL_PHY6_BASE                        0x16D000
 +
 +/* DEKEL PHY MMIO Address = Phy base + (internal address & ~index_mask) */
 +#define _DKL_PLL_DIV0                 0x200
 +#define   DKL_PLL_DIV0_INTEG_COEFF(x) ((x) << 16)
 +#define   DKL_PLL_DIV0_INTEG_COEFF_MASK       (0x1F << 16)
 +#define   DKL_PLL_DIV0_PROP_COEFF(x)  ((x) << 12)
 +#define   DKL_PLL_DIV0_PROP_COEFF_MASK        (0xF << 12)
 +#define   DKL_PLL_DIV0_FBPREDIV_SHIFT   (8)
 +#define   DKL_PLL_DIV0_FBPREDIV(x)    ((x) << DKL_PLL_DIV0_FBPREDIV_SHIFT)
 +#define   DKL_PLL_DIV0_FBPREDIV_MASK  (0xF << DKL_PLL_DIV0_FBPREDIV_SHIFT)
 +#define   DKL_PLL_DIV0_FBDIV_INT(x)   ((x) << 0)
 +#define   DKL_PLL_DIV0_FBDIV_INT_MASK (0xFF << 0)
 +#define DKL_PLL_DIV0(tc_port)         _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \
 +                                                  _DKL_PHY2_BASE) + \
 +                                                  _DKL_PLL_DIV0)
 +
 +#define _DKL_PLL_DIV1                         0x204
 +#define   DKL_PLL_DIV1_IREF_TRIM(x)           ((x) << 16)
 +#define   DKL_PLL_DIV1_IREF_TRIM_MASK         (0x1F << 16)
 +#define   DKL_PLL_DIV1_TDC_TARGET_CNT(x)      ((x) << 0)
 +#define   DKL_PLL_DIV1_TDC_TARGET_CNT_MASK    (0xFF << 0)
 +#define DKL_PLL_DIV1(tc_port)         _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \
 +                                                  _DKL_PHY2_BASE) + \
 +                                                  _DKL_PLL_DIV1)
 +
 +#define _DKL_PLL_SSC                          0x210
 +#define   DKL_PLL_SSC_IREF_NDIV_RATIO(x)      ((x) << 29)
 +#define   DKL_PLL_SSC_IREF_NDIV_RATIO_MASK    (0x7 << 29)
 +#define   DKL_PLL_SSC_STEP_LEN(x)             ((x) << 16)
 +#define   DKL_PLL_SSC_STEP_LEN_MASK           (0xFF << 16)
 +#define   DKL_PLL_SSC_STEP_NUM(x)             ((x) << 11)
 +#define   DKL_PLL_SSC_STEP_NUM_MASK           (0x7 << 11)
 +#define   DKL_PLL_SSC_EN                      (1 << 9)
 +#define DKL_PLL_SSC(tc_port)          _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \
 +                                                  _DKL_PHY2_BASE) + \
 +                                                  _DKL_PLL_SSC)
 +
 +#define _DKL_PLL_BIAS                 0x214
 +#define   DKL_PLL_BIAS_FRAC_EN_H      (1 << 30)
 +#define   DKL_PLL_BIAS_FBDIV_SHIFT    (8)
 +#define   DKL_PLL_BIAS_FBDIV_FRAC(x)  ((x) << DKL_PLL_BIAS_FBDIV_SHIFT)
 +#define   DKL_PLL_BIAS_FBDIV_FRAC_MASK        (0x3FFFFF << DKL_PLL_BIAS_FBDIV_SHIFT)
 +#define DKL_PLL_BIAS(tc_port)         _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \
 +                                                  _DKL_PHY2_BASE) + \
 +                                                  _DKL_PLL_BIAS)
 +
 +#define _DKL_PLL_TDC_COLDST_BIAS              0x218
 +#define   DKL_PLL_TDC_SSC_STEP_SIZE(x)                ((x) << 8)
 +#define   DKL_PLL_TDC_SSC_STEP_SIZE_MASK      (0xFF << 8)
 +#define   DKL_PLL_TDC_FEED_FWD_GAIN(x)                ((x) << 0)
 +#define   DKL_PLL_TDC_FEED_FWD_GAIN_MASK      (0xFF << 0)
 +#define DKL_PLL_TDC_COLDST_BIAS(tc_port) _MMIO(_PORT(tc_port, \
 +                                                   _DKL_PHY1_BASE, \
 +                                                   _DKL_PHY2_BASE) + \
 +                                                   _DKL_PLL_TDC_COLDST_BIAS)
 +
 +#define _DKL_REFCLKIN_CTL             0x12C
 +/* Bits are the same as MG_REFCLKIN_CTL */
 +#define DKL_REFCLKIN_CTL(tc_port)     _MMIO(_PORT(tc_port, \
 +                                                  _DKL_PHY1_BASE, \
 +                                                  _DKL_PHY2_BASE) + \
 +                                            _DKL_REFCLKIN_CTL)
 +
 +#define _DKL_CLKTOP2_HSCLKCTL         0xD4
 +/* Bits are the same as MG_CLKTOP2_HSCLKCTL */
 +#define DKL_CLKTOP2_HSCLKCTL(tc_port) _MMIO(_PORT(tc_port, \
 +                                                  _DKL_PHY1_BASE, \
 +                                                  _DKL_PHY2_BASE) + \
 +                                            _DKL_CLKTOP2_HSCLKCTL)
 +
 +#define _DKL_CLKTOP2_CORECLKCTL1              0xD8
 +/* Bits are the same as MG_CLKTOP2_CORECLKCTL1 */
 +#define DKL_CLKTOP2_CORECLKCTL1(tc_port)      _MMIO(_PORT(tc_port, \
 +                                                          _DKL_PHY1_BASE, \
 +                                                          _DKL_PHY2_BASE) + \
 +                                                    _DKL_CLKTOP2_CORECLKCTL1)
 +
 +#define _DKL_TX_DPCNTL0                               0x2C0
 +#define  DKL_TX_PRESHOOT_COEFF(x)                     ((x) << 13)
 +#define  DKL_TX_PRESHOOT_COEFF_MASK                   (0x1f << 13)
 +#define  DKL_TX_DE_EMPHASIS_COEFF(x)          ((x) << 8)
 +#define  DKL_TX_DE_EMPAHSIS_COEFF_MASK                (0x1f << 8)
 +#define  DKL_TX_VSWING_CONTROL(x)                     ((x) << 0)
 +#define  DKL_TX_VSWING_CONTROL_MASK                   (0x7 << 0)
 +#define DKL_TX_DPCNTL0(tc_port) _MMIO(_PORT(tc_port, \
 +                                                   _DKL_PHY1_BASE, \
 +                                                   _DKL_PHY2_BASE) + \
 +                                                   _DKL_TX_DPCNTL0)
 +
 +#define _DKL_TX_DPCNTL1                               0x2C4
 +/* Bits are the same as DKL_TX_DPCNTRL0 */
 +#define DKL_TX_DPCNTL1(tc_port) _MMIO(_PORT(tc_port, \
 +                                                   _DKL_PHY1_BASE, \
 +                                                   _DKL_PHY2_BASE) + \
 +                                                   _DKL_TX_DPCNTL1)
 +
 +#define _DKL_TX_DPCNTL2                               0x2C8
 +#define  DKL_TX_DP20BITMODE                           (1 << 2)
 +#define DKL_TX_DPCNTL2(tc_port) _MMIO(_PORT(tc_port, \
 +                                                   _DKL_PHY1_BASE, \
 +                                                   _DKL_PHY2_BASE) + \
 +                                                   _DKL_TX_DPCNTL2)
 +
 +#define _DKL_TX_FW_CALIB                              0x2F8
 +#define  DKL_TX_CFG_DISABLE_WAIT_INIT                 (1 << 7)
 +#define DKL_TX_FW_CALIB(tc_port) _MMIO(_PORT(tc_port, \
 +                                                   _DKL_PHY1_BASE, \
 +                                                   _DKL_PHY2_BASE) + \
 +                                                   _DKL_TX_FW_CALIB)
 +
 +#define _DKL_TX_PMD_LANE_SUS                          0xD00
 +#define DKL_TX_PMD_LANE_SUS(tc_port) _MMIO(_PORT(tc_port, \
 +                                                        _DKL_PHY1_BASE, \
 +                                                        _DKL_PHY2_BASE) + \
 +                                                        _DKL_TX_PMD_LANE_SUS)
 +
 +#define _DKL_TX_DW17                                  0xDC4
 +#define DKL_TX_DW17(tc_port) _MMIO(_PORT(tc_port, \
 +                                                   _DKL_PHY1_BASE, \
 +                                                   _DKL_PHY2_BASE) + \
 +                                                   _DKL_TX_DW17)
 +
 +#define _DKL_TX_DW18                                  0xDC8
 +#define DKL_TX_DW18(tc_port) _MMIO(_PORT(tc_port, \
 +                                                   _DKL_PHY1_BASE, \
 +                                                   _DKL_PHY2_BASE) + \
 +                                                   _DKL_TX_DW18)
 +
 +#define _DKL_DP_MODE                                  0xA0
 +#define DKL_DP_MODE(tc_port) _MMIO(_PORT(tc_port, \
 +                                                   _DKL_PHY1_BASE, \
 +                                                   _DKL_PHY2_BASE) + \
 +                                                   _DKL_DP_MODE)
 +
 +#define _DKL_CMN_UC_DW27                      0x36C
 +#define  DKL_CMN_UC_DW27_UC_HEALTH            (0x1 << 15)
 +#define DKL_CMN_UC_DW_27(tc_port)             _MMIO(_PORT(tc_port, \
 +                                                          _DKL_PHY1_BASE, \
 +                                                          _DKL_PHY2_BASE) + \
 +                                                          _DKL_CMN_UC_DW27)
 +
 +/*
 + * Each Dekel PHY is addressed through a 4KB aperture. Each PHY has more than
 + * 4KB of register space, so a separate index is programmed in HIP_INDEX_REG0
 + * or HIP_INDEX_REG1, based on the port number, to set the upper 2 address
 + * bits that point the 4KB window into the full PHY register space.
 + */
 +#define _HIP_INDEX_REG0                       0x1010A0
 +#define _HIP_INDEX_REG1                       0x1010A4
 +#define HIP_INDEX_REG(tc_port)                _MMIO((tc_port) < 4 ? _HIP_INDEX_REG0 \
 +                                            : _HIP_INDEX_REG1)
 +#define _HIP_INDEX_SHIFT(tc_port)     (8 * ((tc_port) % 4))
 +#define HIP_INDEX_VAL(tc_port, val)   ((val) << _HIP_INDEX_SHIFT(tc_port))
 +
  /* BXT display engine PLL */
  #define BXT_DE_PLL_CTL                        _MMIO(0x6d000)
  #define   BXT_DE_PLL_RATIO(x)         (x)     /* {60,65,100} * 19.2MHz */
  /* GEN9 DC */
  #define DC_STATE_EN                   _MMIO(0x45504)
  #define  DC_STATE_DISABLE             0
 +#define  DC_STATE_EN_DC3CO            REG_BIT(30)
 +#define  DC_STATE_DC3CO_STATUS                REG_BIT(29)
  #define  DC_STATE_EN_UPTO_DC5         (1 << 0)
  #define  DC_STATE_EN_DC9              (1 << 3)
  #define  DC_STATE_EN_UPTO_DC6         (2 << 0)
  #define _PIPE_A_CSC_COEFF_BV  0x49024
  
  #define _PIPE_A_CSC_MODE      0x49028
 -#define  ICL_CSC_ENABLE                       (1 << 31)
 -#define  ICL_OUTPUT_CSC_ENABLE                (1 << 30)
 -#define  CSC_BLACK_SCREEN_OFFSET      (1 << 2)
 -#define  CSC_POSITION_BEFORE_GAMMA    (1 << 1)
 -#define  CSC_MODE_YUV_TO_RGB          (1 << 0)
 +#define  ICL_CSC_ENABLE                       (1 << 31) /* icl+ */
 +#define  ICL_OUTPUT_CSC_ENABLE                (1 << 30) /* icl+ */
 +#define  CSC_BLACK_SCREEN_OFFSET      (1 << 2) /* ilk/snb */
 +#define  CSC_POSITION_BEFORE_GAMMA    (1 << 1) /* pre-glk */
 +#define  CSC_MODE_YUV_TO_RGB          (1 << 0) /* ilk/snb */
  
  #define _PIPE_A_CSC_PREOFF_HI 0x49030
  #define _PIPE_A_CSC_PREOFF_ME 0x49034
  #define _PAL_PREC_GC_MAX_A    0x4A410
  #define _PAL_PREC_GC_MAX_B    0x4AC10
  #define _PAL_PREC_GC_MAX_C    0x4B410
 +#define   PREC_PAL_DATA_RED_MASK      REG_GENMASK(29, 20)
 +#define   PREC_PAL_DATA_GREEN_MASK    REG_GENMASK(19, 10)
 +#define   PREC_PAL_DATA_BLUE_MASK     REG_GENMASK(9, 0)
  #define _PAL_PREC_EXT_GC_MAX_A        0x4A420
  #define _PAL_PREC_EXT_GC_MAX_B        0x4AC20
  #define _PAL_PREC_EXT_GC_MAX_C        0x4B420
  #define   CGM_PIPE_MODE_GAMMA (1 << 2)
  #define   CGM_PIPE_MODE_CSC   (1 << 1)
  #define   CGM_PIPE_MODE_DEGAMMA       (1 << 0)
 +#define   CGM_PIPE_GAMMA_RED_MASK   REG_GENMASK(9, 0)
 +#define   CGM_PIPE_GAMMA_GREEN_MASK REG_GENMASK(25, 16)
 +#define   CGM_PIPE_GAMMA_BLUE_MASK  REG_GENMASK(9, 0)
  
  #define _CGM_PIPE_B_CSC_COEFF01       (VLV_DISPLAY_BASE + 0x69900)
  #define _CGM_PIPE_B_CSC_COEFF23       (VLV_DISPLAY_BASE + 0x69904)
  
  #define PORT_TX_DFLEXDPSP(fia)                        _MMIO_FIA((fia), 0x008A0)
  #define   MODULAR_FIA_MASK                    (1 << 4)
 -#define   TC_LIVE_STATE_TBT(tc_port)          (1 << ((tc_port) * 8 + 6))
 -#define   TC_LIVE_STATE_TC(tc_port)           (1 << ((tc_port) * 8 + 5))
 -#define   DP_LANE_ASSIGNMENT_SHIFT(tc_port)   ((tc_port) * 8)
 -#define   DP_LANE_ASSIGNMENT_MASK(tc_port)    (0xf << ((tc_port) * 8))
 -#define   DP_LANE_ASSIGNMENT(tc_port, x)      ((x) << ((tc_port) * 8))
 +#define   TC_LIVE_STATE_TBT(idx)              (1 << ((idx) * 8 + 6))
 +#define   TC_LIVE_STATE_TC(idx)                       (1 << ((idx) * 8 + 5))
 +#define   DP_LANE_ASSIGNMENT_SHIFT(idx)               ((idx) * 8)
 +#define   DP_LANE_ASSIGNMENT_MASK(idx)                (0xf << ((idx) * 8))
 +#define   DP_LANE_ASSIGNMENT(idx, x)          ((x) << ((idx) * 8))
  
  #define PORT_TX_DFLEXDPPMS(fia)                       _MMIO_FIA((fia), 0x00890)
 -#define   DP_PHY_MODE_STATUS_COMPLETED(tc_port)               (1 << (tc_port))
 +#define   DP_PHY_MODE_STATUS_COMPLETED(idx)   (1 << (idx))
  
  #define PORT_TX_DFLEXDPCSSS(fia)              _MMIO_FIA((fia), 0x00894)
 -#define   DP_PHY_MODE_STATUS_NOT_SAFE(tc_port)                (1 << (tc_port))
 +#define   DP_PHY_MODE_STATUS_NOT_SAFE(idx)    (1 << (idx))
 +
 +#define PORT_TX_DFLEXPA1(fia)                 _MMIO_FIA((fia), 0x00880)
 +#define   DP_PIN_ASSIGNMENT_SHIFT(idx)                ((idx) * 4)
 +#define   DP_PIN_ASSIGNMENT_MASK(idx)         (0xf << ((idx) * 4))
 +#define   DP_PIN_ASSIGNMENT(idx, x)           ((x) << ((idx) * 4))
 +
 +/* This register controls the Display State Buffer (DSB) engines. */
 +#define _DSBSL_INSTANCE_BASE          0x70B00
 +#define DSBSL_INSTANCE(pipe, id)      (_DSBSL_INSTANCE_BASE + \
 +                                       (pipe) * 0x1000 + (id) * 100)
 +#define DSB_HEAD(pipe, id)            _MMIO(DSBSL_INSTANCE(pipe, id) + 0x0)
 +#define DSB_TAIL(pipe, id)            _MMIO(DSBSL_INSTANCE(pipe, id) + 0x4)
 +#define DSB_CTRL(pipe, id)            _MMIO(DSBSL_INSTANCE(pipe, id) + 0x8)
 +#define   DSB_ENABLE                  (1 << 31)
 +#define   DSB_STATUS                  (1 << 0)
  
  #endif /* _I915_REG_H_ */
index 5d2b460d3ee5d9dc67a4bd7b478f501a57281d91,2efe1d12d5a91160f2dfe70422ad7e82d007b507..809bff955b5acecf0c28a4f71ccf50a1d414c7e9
@@@ -25,6 -25,7 +25,6 @@@
   *
   */
  
 -#include <linux/cpufreq.h>
  #include <linux/module.h>
  #include <linux/pm_runtime.h>
  
@@@ -37,8 -38,6 +37,8 @@@
  #include "display/intel_fbc.h"
  #include "display/intel_sprite.h"
  
 +#include "gt/intel_llc.h"
 +
  #include "i915_drv.h"
  #include "i915_irq.h"
  #include "i915_trace.h"
  #include "intel_sideband.h"
  #include "../../../platform/x86/intel_ips.h"
  
 -/**
 - * DOC: RC6
 - *
 - * RC6 is a special power stage which allows the GPU to enter an very
 - * low-voltage mode when idle, using down to 0V while at this stage.  This
 - * stage is entered automatically when the GPU is idle when RC6 support is
 - * enabled, and as soon as new workload arises GPU wakes up automatically as well.
 - *
 - * There are different RC6 modes available in Intel GPU, which differentiate
 - * among each other with the latency required to enter and leave RC6 and
 - * voltage consumed by the GPU in different states.
 - *
 - * The combination of the following flags define which states GPU is allowed
 - * to enter, while RC6 is the normal RC6 state, RC6p is the deep RC6, and
 - * RC6pp is deepest RC6. Their support by hardware varies according to the
 - * GPU, BIOS, chipset and platform. RC6 is usually the safest one and the one
 - * which brings the most power savings; deeper states save more power, but
 - * require higher latency to switch to and wake up.
 - */
 -
  static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
  {
        if (HAS_LLC(dev_priv)) {
@@@ -107,6 -126,14 +107,14 @@@ static void bxt_init_clock_gating(struc
         */
        I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) |
                   PWM1_GATING_DIS | PWM2_GATING_DIS);
+       /*
+        * Lower the display internal timeout.
+        * This is needed to avoid any hard hangs when DSI port PLL
+        * is off and a MMIO access is attempted by any privilege
+        * application, using batch buffers or any other means.
+        */
+       I915_WRITE(RM_TIMEOUT, MMIO_TIMEOUT_US(950));
  }
  
  static void glk_init_clock_gating(struct drm_i915_private *dev_priv)
@@@ -197,6 -224,8 +205,6 @@@ static void i915_ironlake_get_mem_freq(
                break;
        }
  
 -      dev_priv->ips.r_t = dev_priv->mem_freq;
 -
        switch (csipll & 0x3ff) {
        case 0x00c:
                dev_priv->fsb_freq = 3200;
                dev_priv->fsb_freq = 0;
                break;
        }
 -
 -      if (dev_priv->fsb_freq == 3200) {
 -              dev_priv->ips.c_m = 0;
 -      } else if (dev_priv->fsb_freq > 3200 && dev_priv->fsb_freq <= 4800) {
 -              dev_priv->ips.c_m = 1;
 -      } else {
 -              dev_priv->ips.c_m = 2;
 -      }
  }
  
  static const struct cxsr_latency cxsr_latency_table[] = {
@@@ -1108,7 -1145,10 +1116,7 @@@ static u16 g4x_compute_wm(const struct 
        clock = adjusted_mode->crtc_clock;
        htotal = adjusted_mode->crtc_htotal;
  
 -      if (plane->id == PLANE_CURSOR)
 -              width = plane_state->base.crtc_w;
 -      else
 -              width = drm_rect_width(&plane_state->base.dst);
 +      width = drm_rect_width(&plane_state->base.dst);
  
        if (plane->id == PLANE_CURSOR) {
                wm = intel_wm_method2(clock, htotal, width, cpp, latency);
@@@ -1295,8 -1335,8 +1303,8 @@@ static int g4x_compute_pipe_wm(struct i
        struct intel_atomic_state *state =
                to_intel_atomic_state(crtc_state->base.state);
        struct g4x_wm_state *wm_state = &crtc_state->wm.g4x.optimal;
 -      int num_active_planes = hweight32(crtc_state->active_planes &
 -                                        ~BIT(PLANE_CURSOR));
 +      int num_active_planes = hweight8(crtc_state->active_planes &
 +                                       ~BIT(PLANE_CURSOR));
        const struct g4x_pipe_wm *raw;
        const struct intel_plane_state *old_plane_state;
        const struct intel_plane_state *new_plane_state;
@@@ -1458,7 -1498,7 +1466,7 @@@ static void g4x_merge_wm(struct drm_i91
                         struct g4x_wm_values *wm)
  {
        struct intel_crtc *crtc;
 -      int num_active_crtcs = 0;
 +      int num_active_pipes = 0;
  
        wm->cxsr = true;
        wm->hpll_en = true;
                if (!wm_state->fbc_en)
                        wm->fbc_en = false;
  
 -              num_active_crtcs++;
 +              num_active_pipes++;
        }
  
 -      if (num_active_crtcs != 1) {
 +      if (num_active_pipes != 1) {
                wm->cxsr = false;
                wm->hpll_en = false;
                wm->fbc_en = false;
@@@ -1627,7 -1667,7 +1635,7 @@@ static int vlv_compute_fifo(struct inte
                &crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM2];
        struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state;
        unsigned int active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
 -      int num_active_planes = hweight32(active_planes);
 +      int num_active_planes = hweight8(active_planes);
        const int fifo_size = 511;
        int fifo_extra, fifo_left = fifo_size;
        int sprite0_fifo_extra = 0;
@@@ -1816,8 -1856,8 +1824,8 @@@ static int vlv_compute_pipe_wm(struct i
        struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal;
        const struct vlv_fifo_state *fifo_state =
                &crtc_state->wm.vlv.fifo_state;
 -      int num_active_planes = hweight32(crtc_state->active_planes &
 -                                        ~BIT(PLANE_CURSOR));
 +      int num_active_planes = hweight8(crtc_state->active_planes &
 +                                       ~BIT(PLANE_CURSOR));
        bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->base);
        const struct intel_plane_state *old_plane_state;
        const struct intel_plane_state *new_plane_state;
  
        for (level = 0; level < wm_state->num_levels; level++) {
                const struct g4x_pipe_wm *raw = &crtc_state->wm.vlv.raw[level];
 -              const int sr_fifo_size = INTEL_INFO(dev_priv)->num_pipes * 512 - 1;
 +              const int sr_fifo_size = INTEL_NUM_PIPES(dev_priv) * 512 - 1;
  
                if (!vlv_raw_crtc_wm_is_valid(crtc_state, level))
                        break;
@@@ -2066,7 -2106,7 +2074,7 @@@ static void vlv_merge_wm(struct drm_i91
                         struct vlv_wm_values *wm)
  {
        struct intel_crtc *crtc;
 -      int num_active_crtcs = 0;
 +      int num_active_pipes = 0;
  
        wm->level = dev_priv->wm.max_level;
        wm->cxsr = true;
                if (!wm_state->cxsr)
                        wm->cxsr = false;
  
 -              num_active_crtcs++;
 +              num_active_pipes++;
                wm->level = min_t(int, wm->level, wm_state->num_levels - 1);
        }
  
 -      if (num_active_crtcs != 1)
 +      if (num_active_pipes != 1)
                wm->cxsr = false;
  
 -      if (num_active_crtcs > 1)
 +      if (num_active_pipes > 1)
                wm->level = VLV_WM_LEVEL_PM2;
  
        for_each_intel_crtc(&dev_priv->drm, crtc) {
@@@ -2537,8 -2577,7 +2545,8 @@@ static u32 ilk_compute_cur_wm(const str
  
        return ilk_wm_method2(crtc_state->pixel_rate,
                              crtc_state->base.adjusted_mode.crtc_htotal,
 -                            plane_state->base.crtc_w, cpp, mem_value);
 +                            drm_rect_width(&plane_state->base.dst),
 +                            cpp, mem_value);
  }
  
  /* Only for WM_LP. */
@@@ -2617,7 -2656,7 +2625,7 @@@ static unsigned int ilk_plane_wm_max(co
  
        /* HSW allows LP1+ watermarks even with multiple pipes */
        if (level == 0 || config->num_pipes_active > 1) {
 -              fifo_size /= INTEL_INFO(dev_priv)->num_pipes;
 +              fifo_size /= INTEL_NUM_PIPES(dev_priv);
  
                /*
                 * For some reason the non self refresh
@@@ -3078,8 -3117,8 +3086,8 @@@ static int ilk_compute_pipe_wm(struct i
        struct intel_pipe_wm *pipe_wm;
        struct drm_device *dev = state->dev;
        const struct drm_i915_private *dev_priv = to_i915(dev);
 -      struct drm_plane *plane;
 -      const struct drm_plane_state *plane_state;
 +      struct intel_plane *plane;
 +      const struct intel_plane_state *plane_state;
        const struct intel_plane_state *pristate = NULL;
        const struct intel_plane_state *sprstate = NULL;
        const struct intel_plane_state *curstate = NULL;
  
        pipe_wm = &crtc_state->wm.ilk.optimal;
  
 -      drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, &crtc_state->base) {
 -              const struct intel_plane_state *ps = to_intel_plane_state(plane_state);
 -
 -              if (plane->type == DRM_PLANE_TYPE_PRIMARY)
 -                      pristate = ps;
 -              else if (plane->type == DRM_PLANE_TYPE_OVERLAY)
 -                      sprstate = ps;
 -              else if (plane->type == DRM_PLANE_TYPE_CURSOR)
 -                      curstate = ps;
 +      intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
 +              if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
 +                      pristate = plane_state;
 +              else if (plane->base.type == DRM_PLANE_TYPE_OVERLAY)
 +                      sprstate = plane_state;
 +              else if (plane->base.type == DRM_PLANE_TYPE_CURSOR)
 +                      curstate = plane_state;
        }
  
        pipe_wm->pipe_enabled = crtc_state->base.active;
@@@ -3621,47 -3662,10 +3629,47 @@@ static bool skl_needs_memory_bw_wa(stru
  static bool
  intel_has_sagv(struct drm_i915_private *dev_priv)
  {
 +      /* HACK! */
 +      if (IS_GEN(dev_priv, 12))
 +              return false;
 +
        return (IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) &&
                dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED;
  }
  
 +static void
 +skl_setup_sagv_block_time(struct drm_i915_private *dev_priv)
 +{
 +      if (INTEL_GEN(dev_priv) >= 12) {
 +              u32 val = 0;
 +              int ret;
 +
 +              ret = sandybridge_pcode_read(dev_priv,
 +                                           GEN12_PCODE_READ_SAGV_BLOCK_TIME_US,
 +                                           &val, NULL);
 +              if (!ret) {
 +                      dev_priv->sagv_block_time_us = val;
 +                      return;
 +              }
 +
 +              DRM_DEBUG_DRIVER("Couldn't read SAGV block time!\n");
 +      } else if (IS_GEN(dev_priv, 11)) {
 +              dev_priv->sagv_block_time_us = 10;
 +              return;
 +      } else if (IS_GEN(dev_priv, 10)) {
 +              dev_priv->sagv_block_time_us = 20;
 +              return;
 +      } else if (IS_GEN(dev_priv, 9)) {
 +              dev_priv->sagv_block_time_us = 30;
 +              return;
 +      } else {
 +              MISSING_CASE(INTEL_GEN(dev_priv));
 +      }
 +
 +      /* Default to an unusable block time */
 +      dev_priv->sagv_block_time_us = -1;
 +}
 +
  /*
   * SAGV dynamically adjusts the system agent voltage and clock frequencies
   * depending on power and performance requirements. The display engine access
@@@ -3750,25 -3754,33 +3758,25 @@@ bool intel_can_enable_sagv(struct intel
        struct intel_crtc_state *crtc_state;
        enum pipe pipe;
        int level, latency;
 -      int sagv_block_time_us;
  
        if (!intel_has_sagv(dev_priv))
                return false;
  
 -      if (IS_GEN(dev_priv, 9))
 -              sagv_block_time_us = 30;
 -      else if (IS_GEN(dev_priv, 10))
 -              sagv_block_time_us = 20;
 -      else
 -              sagv_block_time_us = 10;
 -
        /*
         * If there are no active CRTCs, no additional checks need be performed
         */
 -      if (hweight32(state->active_crtcs) == 0)
 +      if (hweight8(state->active_pipes) == 0)
                return true;
  
        /*
         * SKL+ workaround: bspec recommends we disable SAGV when we have
         * more then one pipe enabled
         */
 -      if (hweight32(state->active_crtcs) > 1)
 +      if (hweight8(state->active_pipes) > 1)
                return false;
  
        /* Since we're now guaranteed to only have one active CRTC... */
 -      pipe = ffs(state->active_crtcs) - 1;
 +      pipe = ffs(state->active_pipes) - 1;
        crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
        crtc_state = to_intel_crtc_state(crtc->base.state);
  
                 * incur memory latencies higher than sagv_block_time_us we
                 * can't enable SAGV.
                 */
 -              if (latency < sagv_block_time_us)
 +              if (latency < dev_priv->sagv_block_time_us)
                        return false;
        }
  
@@@ -3863,14 -3875,14 +3871,14 @@@ skl_ddb_get_pipe_allocation_limits(stru
        if (WARN_ON(!state) || !crtc_state->base.active) {
                alloc->start = 0;
                alloc->end = 0;
 -              *num_active = hweight32(dev_priv->active_crtcs);
 +              *num_active = hweight8(dev_priv->active_pipes);
                return;
        }
  
        if (intel_state->active_pipe_changes)
 -              *num_active = hweight32(intel_state->active_crtcs);
 +              *num_active = hweight8(intel_state->active_pipes);
        else
 -              *num_active = hweight32(dev_priv->active_crtcs);
 +              *num_active = hweight8(dev_priv->active_pipes);
  
        ddb_size = intel_get_ddb_size(dev_priv, crtc_state, total_data_rate,
                                      *num_active, ddb);
@@@ -4001,8 -4013,7 +4009,8 @@@ skl_ddb_get_hw_plane_state(struct drm_i
                val = I915_READ(PLANE_BUF_CFG(pipe, plane_id));
                val2 = I915_READ(PLANE_NV12_BUF_CFG(pipe, plane_id));
  
 -              if (is_planar_yuv_format(fourcc))
 +              if (fourcc &&
 +                  drm_format_info_is_yuv_semiplanar(drm_format_info(fourcc)))
                        swap(val, val2);
  
                skl_ddb_entry_init_from_hw(dev_priv, ddb_y, val);
@@@ -4060,6 -4071,7 +4068,6 @@@ static uint_fixed_16_16_
  skl_plane_downscale_amount(const struct intel_crtc_state *crtc_state,
                           const struct intel_plane_state *plane_state)
  {
 -      struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
        u32 src_w, src_h, dst_w, dst_h;
        uint_fixed_16_16_t fp_w_ratio, fp_h_ratio;
        uint_fixed_16_16_t downscale_h, downscale_w;
        if (WARN_ON(!intel_wm_plane_visible(crtc_state, plane_state)))
                return u32_to_fixed16(0);
  
 -      /* n.b., src is 16.16 fixed point, dst is whole integer */
 -      if (plane->id == PLANE_CURSOR) {
 -              /*
 -               * Cursors only support 0/180 degree rotation,
 -               * hence no need to account for rotation here.
 -               */
 -              src_w = plane_state->base.src_w >> 16;
 -              src_h = plane_state->base.src_h >> 16;
 -              dst_w = plane_state->base.crtc_w;
 -              dst_h = plane_state->base.crtc_h;
 -      } else {
 -              /*
 -               * Src coordinates are already rotated by 270 degrees for
 -               * the 90/270 degree plane rotation cases (to match the
 -               * GTT mapping), hence no need to account for rotation here.
 -               */
 -              src_w = drm_rect_width(&plane_state->base.src) >> 16;
 -              src_h = drm_rect_height(&plane_state->base.src) >> 16;
 -              dst_w = drm_rect_width(&plane_state->base.dst);
 -              dst_h = drm_rect_height(&plane_state->base.dst);
 -      }
 +      /*
 +       * Src coordinates are already rotated by 270 degrees for
 +       * the 90/270 degree plane rotation cases (to match the
 +       * GTT mapping), hence no need to account for rotation here.
 +       *
 +       * n.b., src is 16.16 fixed point, dst is whole integer.
 +       */
 +      src_w = drm_rect_width(&plane_state->base.src) >> 16;
 +      src_h = drm_rect_height(&plane_state->base.src) >> 16;
 +      dst_w = drm_rect_width(&plane_state->base.dst);
 +      dst_h = drm_rect_height(&plane_state->base.dst);
  
        fp_w_ratio = div_fixed16(src_w, dst_w);
        fp_h_ratio = div_fixed16(src_h, dst_h);
        return mul_fixed16(downscale_w, downscale_h);
  }
  
 -static uint_fixed_16_16_t
 -skl_pipe_downscale_amount(const struct intel_crtc_state *crtc_state)
 -{
 -      uint_fixed_16_16_t pipe_downscale = u32_to_fixed16(1);
 -
 -      if (!crtc_state->base.enable)
 -              return pipe_downscale;
 -
 -      if (crtc_state->pch_pfit.enabled) {
 -              u32 src_w, src_h, dst_w, dst_h;
 -              u32 pfit_size = crtc_state->pch_pfit.size;
 -              uint_fixed_16_16_t fp_w_ratio, fp_h_ratio;
 -              uint_fixed_16_16_t downscale_h, downscale_w;
 -
 -              src_w = crtc_state->pipe_src_w;
 -              src_h = crtc_state->pipe_src_h;
 -              dst_w = pfit_size >> 16;
 -              dst_h = pfit_size & 0xffff;
 -
 -              if (!dst_w || !dst_h)
 -                      return pipe_downscale;
 -
 -              fp_w_ratio = div_fixed16(src_w, dst_w);
 -              fp_h_ratio = div_fixed16(src_h, dst_h);
 -              downscale_w = max_fixed16(fp_w_ratio, u32_to_fixed16(1));
 -              downscale_h = max_fixed16(fp_h_ratio, u32_to_fixed16(1));
 -
 -              pipe_downscale = mul_fixed16(downscale_w, downscale_h);
 -      }
 -
 -      return pipe_downscale;
 -}
 -
 -int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 -                                struct intel_crtc_state *crtc_state)
 -{
 -      struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
 -      struct drm_atomic_state *state = crtc_state->base.state;
 -      struct drm_plane *plane;
 -      const struct drm_plane_state *drm_plane_state;
 -      int crtc_clock, dotclk;
 -      u32 pipe_max_pixel_rate;
 -      uint_fixed_16_16_t pipe_downscale;
 -      uint_fixed_16_16_t max_downscale = u32_to_fixed16(1);
 -
 -      if (!crtc_state->base.enable)
 -              return 0;
 -
 -      drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->base) {
 -              uint_fixed_16_16_t plane_downscale;
 -              uint_fixed_16_16_t fp_9_div_8 = div_fixed16(9, 8);
 -              int bpp;
 -              const struct intel_plane_state *plane_state =
 -                      to_intel_plane_state(drm_plane_state);
 -
 -              if (!intel_wm_plane_visible(crtc_state, plane_state))
 -                      continue;
 -
 -              if (WARN_ON(!plane_state->base.fb))
 -                      return -EINVAL;
 -
 -              plane_downscale = skl_plane_downscale_amount(crtc_state, plane_state);
 -              bpp = plane_state->base.fb->format->cpp[0] * 8;
 -              if (bpp == 64)
 -                      plane_downscale = mul_fixed16(plane_downscale,
 -                                                    fp_9_div_8);
 -
 -              max_downscale = max_fixed16(plane_downscale, max_downscale);
 -      }
 -      pipe_downscale = skl_pipe_downscale_amount(crtc_state);
 -
 -      pipe_downscale = mul_fixed16(pipe_downscale, max_downscale);
 -
 -      crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
 -      dotclk = to_intel_atomic_state(state)->cdclk.logical.cdclk;
 -
 -      if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10)
 -              dotclk *= 2;
 -
 -      pipe_max_pixel_rate = div_round_up_u32_fixed16(dotclk, pipe_downscale);
 -
 -      if (pipe_max_pixel_rate < crtc_clock) {
 -              DRM_DEBUG_KMS("Max supported pixel clock with scaling exceeded\n");
 -              return -EINVAL;
 -      }
 -
 -      return 0;
 -}
 -
  static u64
  skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
                             const struct intel_plane_state *plane_state,
 -                           const int plane)
 +                           int color_plane)
  {
 -      struct intel_plane *intel_plane = to_intel_plane(plane_state->base.plane);
 +      struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 +      const struct drm_framebuffer *fb = plane_state->base.fb;
        u32 data_rate;
        u32 width = 0, height = 0;
 -      struct drm_framebuffer *fb;
 -      u32 format;
        uint_fixed_16_16_t down_scale_amount;
        u64 rate;
  
        if (!plane_state->base.visible)
                return 0;
  
 -      fb = plane_state->base.fb;
 -      format = fb->format->format;
 -
 -      if (intel_plane->id == PLANE_CURSOR)
 +      if (plane->id == PLANE_CURSOR)
                return 0;
 -      if (plane == 1 && !is_planar_yuv_format(format))
 +
 +      if (color_plane == 1 &&
 +          !drm_format_info_is_yuv_semiplanar(fb->format))
                return 0;
  
        /*
        height = drm_rect_height(&plane_state->base.src) >> 16;
  
        /* UV plane does 1/2 pixel sub-sampling */
 -      if (plane == 1 && is_planar_yuv_format(format)) {
 +      if (color_plane == 1) {
                width /= 2;
                height /= 2;
        }
  
        rate = mul_round_up_u32_fixed16(data_rate, down_scale_amount);
  
 -      rate *= fb->format->cpp[plane];
 +      rate *= fb->format->cpp[color_plane];
        return rate;
  }
  
@@@ -4139,16 -4252,18 +4147,16 @@@ skl_get_total_relative_data_rate(struc
                                 u64 *uv_plane_data_rate)
  {
        struct drm_atomic_state *state = crtc_state->base.state;
 -      struct drm_plane *plane;
 -      const struct drm_plane_state *drm_plane_state;
 +      struct intel_plane *plane;
 +      const struct intel_plane_state *plane_state;
        u64 total_data_rate = 0;
  
        if (WARN_ON(!state))
                return 0;
  
        /* Calculate and cache data rate for each plane */
 -      drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->base) {
 -              enum plane_id plane_id = to_intel_plane(plane)->id;
 -              const struct intel_plane_state *plane_state =
 -                      to_intel_plane_state(drm_plane_state);
 +      intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
 +              enum plane_id plane_id = plane->id;
                u64 rate;
  
                /* packed/y */
@@@ -4169,19 -4284,21 +4177,19 @@@ static u6
  icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
                                 u64 *plane_data_rate)
  {
 -      struct drm_plane *plane;
 -      const struct drm_plane_state *drm_plane_state;
 +      struct intel_plane *plane;
 +      const struct intel_plane_state *plane_state;
        u64 total_data_rate = 0;
  
        if (WARN_ON(!crtc_state->base.state))
                return 0;
  
        /* Calculate and cache data rate for each plane */
 -      drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->base) {
 -              const struct intel_plane_state *plane_state =
 -                      to_intel_plane_state(drm_plane_state);
 -              enum plane_id plane_id = to_intel_plane(plane)->id;
 +      intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
 +              enum plane_id plane_id = plane->id;
                u64 rate;
  
 -              if (!plane_state->linked_plane) {
 +              if (!plane_state->planar_linked_plane) {
                        rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
                        plane_data_rate[plane_id] = rate;
                        total_data_rate += rate;
  
                        /*
                         * The slave plane might not iterate in
 -                       * drm_atomic_crtc_state_for_each_plane_state(),
 +                       * intel_atomic_crtc_state_for_each_plane_state(),
                         * and needs the master plane state which may be
                         * NULL if we try get_new_plane_state(), so we
                         * always calculate from the master.
                         */
 -                      if (plane_state->slave)
 +                      if (plane_state->planar_slave)
                                continue;
  
                        /* Y plane rate is calculated on the slave */
                        rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
 -                      y_plane_id = plane_state->linked_plane->id;
 +                      y_plane_id = plane_state->planar_linked_plane->id;
                        plane_data_rate[y_plane_id] = rate;
                        total_data_rate += rate;
  
@@@ -4530,7 -4647,7 +4538,7 @@@ skl_compute_wm_params(const struct inte
        u32 interm_pbpl;
  
        /* only planar format has two planes */
 -      if (color_plane == 1 && !is_planar_yuv_format(format->format)) {
 +      if (color_plane == 1 && !drm_format_info_is_yuv_semiplanar(format)) {
                DRM_DEBUG_KMS("Non planar format have single plane\n");
                return -EINVAL;
        }
        wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED;
        wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
                         modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
 -      wp->is_planar = is_planar_yuv_format(format->format);
 +      wp->is_planar = drm_format_info_is_yuv_semiplanar(format);
  
        wp->width = width;
        if (color_plane == 1 && wp->is_planar)
@@@ -4614,15 -4731,20 +4622,15 @@@ skl_compute_plane_wm_params(const struc
                            const struct intel_plane_state *plane_state,
                            struct skl_wm_params *wp, int color_plane)
  {
 -      struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
        const struct drm_framebuffer *fb = plane_state->base.fb;
        int width;
  
 -      if (plane->id == PLANE_CURSOR) {
 -              width = plane_state->base.crtc_w;
 -      } else {
 -              /*
 -               * Src coordinates are already rotated by 270 degrees for
 -               * the 90/270 degree plane rotation cases (to match the
 -               * GTT mapping), hence no need to account for rotation here.
 -               */
 -              width = drm_rect_width(&plane_state->base.src) >> 16;
 -      }
 +      /*
 +       * Src coordinates are already rotated by 270 degrees for
 +       * the 90/270 degree plane rotation cases (to match the
 +       * GTT mapping), hence no need to account for rotation here.
 +       */
 +      width = drm_rect_width(&plane_state->base.src) >> 16;
  
        return skl_compute_wm_params(crtc_state, width,
                                     fb->format, fb->modifier,
@@@ -4934,12 -5056,12 +4942,12 @@@ static int icl_build_plane_wm(struct in
        int ret;
  
        /* Watermarks calculated in master */
 -      if (plane_state->slave)
 +      if (plane_state->planar_slave)
                return 0;
  
 -      if (plane_state->linked_plane) {
 +      if (plane_state->planar_linked_plane) {
                const struct drm_framebuffer *fb = plane_state->base.fb;
 -              enum plane_id y_plane_id = plane_state->linked_plane->id;
 +              enum plane_id y_plane_id = plane_state->planar_linked_plane->id;
  
                WARN_ON(!intel_wm_plane_visible(crtc_state, plane_state));
                WARN_ON(!fb->format->is_yuv ||
@@@ -4968,8 -5090,8 +4976,8 @@@ static int skl_build_pipe_wm(struct int
  {
        struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
        struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
 -      struct drm_plane *plane;
 -      const struct drm_plane_state *drm_plane_state;
 +      struct intel_plane *plane;
 +      const struct intel_plane_state *plane_state;
        int ret;
  
        /*
         */
        memset(pipe_wm->planes, 0, sizeof(pipe_wm->planes));
  
 -      drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state,
 -                                                 &crtc_state->base) {
 -              const struct intel_plane_state *plane_state =
 -                      to_intel_plane_state(drm_plane_state);
 +      intel_atomic_crtc_state_for_each_plane_state(plane, plane_state,
 +                                                   crtc_state) {
  
                if (INTEL_GEN(dev_priv) >= 11)
                        ret = icl_build_plane_wm(crtc_state, plane_state);
@@@ -5139,6 -5263,19 +5147,6 @@@ bool skl_ddb_allocation_overlaps(const 
        return false;
  }
  
 -static u32
 -pipes_modified(struct intel_atomic_state *state)
 -{
 -      struct intel_crtc *crtc;
 -      struct intel_crtc_state *crtc_state;
 -      u32 i, ret = 0;
 -
 -      for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i)
 -              ret |= drm_crtc_mask(&crtc->base);
 -
 -      return ret;
 -}
 -
  static int
  skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state,
                            struct intel_crtc_state *new_crtc_state)
@@@ -5314,27 -5451,36 +5322,27 @@@ skl_print_wm_changes(struct intel_atomi
        }
  }
  
 -static int
 -skl_ddb_add_affected_pipes(struct intel_atomic_state *state, bool *changed)
 +static int intel_add_all_pipes(struct intel_atomic_state *state)
  {
 -      struct drm_device *dev = state->base.dev;
 -      const struct drm_i915_private *dev_priv = to_i915(dev);
 +      struct drm_i915_private *dev_priv = to_i915(state->base.dev);
        struct intel_crtc *crtc;
 -      struct intel_crtc_state *crtc_state;
 -      u32 realloc_pipes = pipes_modified(state);
 -      int ret, i;
  
 -      /*
 -       * When we distrust bios wm we always need to recompute to set the
 -       * expected DDB allocations for each CRTC.
 -       */
 -      if (dev_priv->wm.distrust_bios_wm)
 -              (*changed) = true;
 +      for_each_intel_crtc(&dev_priv->drm, crtc) {
 +              struct intel_crtc_state *crtc_state;
  
 -      /*
 -       * If this transaction isn't actually touching any CRTC's, don't
 -       * bother with watermark calculation.  Note that if we pass this
 -       * test, we're guaranteed to hold at least one CRTC state mutex,
 -       * which means we can safely use values like dev_priv->active_crtcs
 -       * since any racing commits that want to update them would need to
 -       * hold _all_ CRTC state mutexes.
 -       */
 -      for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i)
 -              (*changed) = true;
 +              crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
 +              if (IS_ERR(crtc_state))
 +                      return PTR_ERR(crtc_state);
 +      }
  
 -      if (!*changed)
 -              return 0;
 +      return 0;
 +}
 +
 +static int
 +skl_ddb_add_affected_pipes(struct intel_atomic_state *state)
 +{
 +      struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 +      int ret;
  
        /*
         * If this is our first atomic update following hardware readout,
         * ensure a full DDB recompute.
         */
        if (dev_priv->wm.distrust_bios_wm) {
 -              ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
 +              ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex,
                                       state->base.acquire_ctx);
                if (ret)
                        return ret;
                state->active_pipe_changes = ~0;
  
                /*
 -               * We usually only initialize state->active_crtcs if we
 +               * We usually only initialize state->active_pipes if we
                 * we're doing a modeset; make sure this field is always
                 * initialized during the sanitization process that happens
                 * on the first commit too.
                 */
                if (!state->modeset)
 -                      state->active_crtcs = dev_priv->active_crtcs;
 +                      state->active_pipes = dev_priv->active_pipes;
        }
  
        /*
         * to grab the lock on *all* CRTC's.
         */
        if (state->active_pipe_changes || state->modeset) {
 -              realloc_pipes = ~0;
                state->wm_results.dirty_pipes = ~0;
 -      }
  
 -      /*
 -       * We're not recomputing for the pipes not included in the commit, so
 -       * make sure we start with the current state.
 -       */
 -      for_each_intel_crtc_mask(dev, crtc, realloc_pipes) {
 -              crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
 -              if (IS_ERR(crtc_state))
 -                      return PTR_ERR(crtc_state);
 +              ret = intel_add_all_pipes(state);
 +              if (ret)
 +                      return ret;
        }
  
        return 0;
@@@ -5451,13 -5604,14 +5459,13 @@@ skl_compute_wm(struct intel_atomic_stat
        struct intel_crtc_state *new_crtc_state;
        struct intel_crtc_state *old_crtc_state;
        struct skl_ddb_values *results = &state->wm_results;
 -      bool changed = false;
        int ret, i;
  
        /* Clear all dirty flags */
        results->dirty_pipes = 0;
  
 -      ret = skl_ddb_add_affected_pipes(state, &changed);
 -      if (ret || !changed)
 +      ret = skl_ddb_add_affected_pipes(state);
 +      if (ret)
                return ret;
  
        /*
                if (!skl_pipe_wm_equals(crtc,
                                        &old_crtc_state->wm.skl.optimal,
                                        &new_crtc_state->wm.skl.optimal))
 -                      results->dirty_pipes |= drm_crtc_mask(&crtc->base);
 +                      results->dirty_pipes |= BIT(crtc->pipe);
        }
  
        ret = skl_compute_ddb(state);
@@@ -5499,7 -5653,7 +5507,7 @@@ static void skl_atomic_update_crtc_wm(s
        struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
        enum pipe pipe = crtc->pipe;
  
 -      if (!(state->wm_results.dirty_pipes & drm_crtc_mask(&crtc->base)))
 +      if ((state->wm_results.dirty_pipes & BIT(crtc->pipe)) == 0)
                return;
  
        I915_WRITE(PIPE_WM_LINETIME(pipe), pipe_wm->linetime);
  static void skl_initial_wm(struct intel_atomic_state *state,
                           struct intel_crtc_state *crtc_state)
  {
 -      struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
 -      struct drm_device *dev = intel_crtc->base.dev;
 -      struct drm_i915_private *dev_priv = to_i915(dev);
 +      struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 +      struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        struct skl_ddb_values *results = &state->wm_results;
  
 -      if ((results->dirty_pipes & drm_crtc_mask(&intel_crtc->base)) == 0)
 +      if ((results->dirty_pipes & BIT(crtc->pipe)) == 0)
                return;
  
        mutex_lock(&dev_priv->wm.wm_mutex);
@@@ -5661,10 -5816,10 +5669,10 @@@ void skl_wm_get_hw_state(struct drm_i91
                skl_pipe_wm_get_hw_state(crtc, &crtc_state->wm.skl.optimal);
  
                if (crtc->active)
 -                      hw->dirty_pipes |= drm_crtc_mask(&crtc->base);
 +                      hw->dirty_pipes |= BIT(crtc->pipe);
        }
  
 -      if (dev_priv->active_crtcs) {
 +      if (dev_priv->active_pipes) {
                /* Fully recompute DDB on first atomic commit */
                dev_priv->wm.distrust_bios_wm = true;
        }
@@@ -6242,105 -6397,2587 +6250,105 @@@ void intel_init_ipc(struct drm_i915_pri
        intel_enable_ipc(dev_priv);
  }
  
 -/*
 - * Lock protecting IPS related data structures
 - */
 -DEFINE_SPINLOCK(mchdev_lock);
 +static void ibx_init_clock_gating(struct drm_i915_private *dev_priv)
 +{
 +      /*
 +       * On Ibex Peak and Cougar Point, we need to disable clock
 +       * gating for the panel power sequencer or it will fail to
 +       * start up when no ports are active.
 +       */
 +      I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
 +}
  
 -bool ironlake_set_drps(struct drm_i915_private *i915, u8 val)
 +static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv)
  {
 -      struct intel_uncore *uncore = &i915->uncore;
 -      u16 rgvswctl;
 +      enum pipe pipe;
  
 -      lockdep_assert_held(&mchdev_lock);
 +      for_each_pipe(dev_priv, pipe) {
 +              I915_WRITE(DSPCNTR(pipe),
 +                         I915_READ(DSPCNTR(pipe)) |
 +                         DISPPLANE_TRICKLE_FEED_DISABLE);
  
 -      rgvswctl = intel_uncore_read16(uncore, MEMSWCTL);
 -      if (rgvswctl & MEMCTL_CMD_STS) {
 -              DRM_DEBUG("gpu busy, RCS change rejected\n");
 -              return false; /* still busy with another command */
 +              I915_WRITE(DSPSURF(pipe), I915_READ(DSPSURF(pipe)));
 +              POSTING_READ(DSPSURF(pipe));
        }
 -
 -      rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) |
 -              (val << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM;
 -      intel_uncore_write16(uncore, MEMSWCTL, rgvswctl);
 -      intel_uncore_posting_read16(uncore, MEMSWCTL);
 -
 -      rgvswctl |= MEMCTL_CMD_STS;
 -      intel_uncore_write16(uncore, MEMSWCTL, rgvswctl);
 -
 -      return true;
  }
  
 -static void ironlake_enable_drps(struct drm_i915_private *dev_priv)
 +static void ilk_init_clock_gating(struct drm_i915_private *dev_priv)
  {
 -      struct intel_uncore *uncore = &dev_priv->uncore;
 -      u32 rgvmodectl;
 -      u8 fmax, fmin, fstart, vstart;
 -
 -      spin_lock_irq(&mchdev_lock);
 -
 -      rgvmodectl = intel_uncore_read(uncore, MEMMODECTL);
 -
 -      /* Enable temp reporting */
 -      intel_uncore_write16(uncore, PMMISC, I915_READ(PMMISC) | MCPPCE_EN);
 -      intel_uncore_write16(uncore, TSC1, I915_READ(TSC1) | TSE);
 -
 -      /* 100ms RC evaluation intervals */
 -      intel_uncore_write(uncore, RCUPEI, 100000);
 -      intel_uncore_write(uncore, RCDNEI, 100000);
 -
 -      /* Set max/min thresholds to 90ms and 80ms respectively */
 -      intel_uncore_write(uncore, RCBMAXAVG, 90000);
 -      intel_uncore_write(uncore, RCBMINAVG, 80000);
 -
 -      intel_uncore_write(uncore, MEMIHYST, 1);
 -
 -      /* Set up min, max, and cur for interrupt handling */
 -      fmax = (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT;
 -      fmin = (rgvmodectl & MEMMODE_FMIN_MASK);
 -      fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >>
 -              MEMMODE_FSTART_SHIFT;
 -
 -      vstart = (intel_uncore_read(uncore, PXVFREQ(fstart)) &
 -                PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT;
 -
 -      dev_priv->ips.fmax = fmax; /* IPS callback will increase this */
 -      dev_priv->ips.fstart = fstart;
 +      u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE;
  
 -      dev_priv->ips.max_delay = fstart;
 -      dev_priv->ips.min_delay = fmin;
 -      dev_priv->ips.cur_delay = fstart;
 +      /*
 +       * Required for FBC
 +       * WaFbcDisableDpfcClockGating:ilk
 +       */
 +      dspclk_gate |= ILK_DPFCRUNIT_CLOCK_GATE_DISABLE |
 +                 ILK_DPFCUNIT_CLOCK_GATE_DISABLE |
 +                 ILK_DPFDUNIT_CLOCK_GATE_ENABLE;
  
 -      DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n",
 -                       fmax, fmin, fstart);
 +      I915_WRITE(PCH_3DCGDIS0,
 +                 MARIUNIT_CLOCK_GATE_DISABLE |
 +                 SVSMUNIT_CLOCK_GATE_DISABLE);
 +      I915_WRITE(PCH_3DCGDIS1,
 +                 VFMUNIT_CLOCK_GATE_DISABLE);
  
 -      intel_uncore_write(uncore,
 -                         MEMINTREN,
 -                         MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN);
 +      /*
 +       * According to the spec the following bits should be set in
 +       * order to enable memory self-refresh
 +       * The bit 22/21 of 0x42004
 +       * The bit 5 of 0x42020
 +       * The bit 15 of 0x45000
 +       */
 +      I915_WRITE(ILK_DISPLAY_CHICKEN2,
 +                 (I915_READ(ILK_DISPLAY_CHICKEN2) |
 +                  ILK_DPARB_GATE | ILK_VSDPFD_FULL));
 +      dspclk_gate |= ILK_DPARBUNIT_CLOCK_GATE_ENABLE;
 +      I915_WRITE(DISP_ARB_CTL,
 +                 (I915_READ(DISP_ARB_CTL) |
 +                  DISP_FBC_WM_DIS));
  
        /*
 -       * Interrupts will be enabled in ironlake_irq_postinstall
 +       * Based on the document from hardware guys the following bits
 +       * should be set unconditionally in order to enable FBC.
 +       * The bit 22 of 0x42000
 +       * The bit 22 of 0x42004
 +       * The bit 7,8,9 of 0x42020.
         */
 +      if (IS_IRONLAKE_M(dev_priv)) {
 +              /* WaFbcAsynchFlipDisableFbcQueue:ilk */
 +              I915_WRITE(ILK_DISPLAY_CHICKEN1,
 +                         I915_READ(ILK_DISPLAY_CHICKEN1) |
 +                         ILK_FBCQ_DIS);
 +              I915_WRITE(ILK_DISPLAY_CHICKEN2,
 +                         I915_READ(ILK_DISPLAY_CHICKEN2) |
 +                         ILK_DPARB_GATE);
 +      }
  
 -      intel_uncore_write(uncore, VIDSTART, vstart);
 -      intel_uncore_posting_read(uncore, VIDSTART);
 +      I915_WRITE(ILK_DSPCLK_GATE_D, dspclk_gate);
  
 -      rgvmodectl |= MEMMODE_SWMODE_EN;
 -      intel_uncore_write(uncore, MEMMODECTL, rgvmodectl);
 +      I915_WRITE(ILK_DISPLAY_CHICKEN2,
 +                 I915_READ(ILK_DISPLAY_CHICKEN2) |
 +                 ILK_ELPIN_409_SELECT);
 +      I915_WRITE(_3D_CHICKEN2,
 +                 _3D_CHICKEN2_WM_READ_PIPELINED << 16 |
 +                 _3D_CHICKEN2_WM_READ_PIPELINED);
  
 -      if (wait_for_atomic((intel_uncore_read(uncore, MEMSWCTL) &
 -                           MEMCTL_CMD_STS) == 0, 10))
 -              DRM_ERROR("stuck trying to change perf mode\n");
 -      mdelay(1);
 +      /* WaDisableRenderCachePipelinedFlush:ilk */
 +      I915_WRITE(CACHE_MODE_0,
 +                 _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE));
  
 -      ironlake_set_drps(dev_priv, fstart);
 +      /* WaDisable_RenderCache_OperationalFlush:ilk */
 +      I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
  
 -      dev_priv->ips.last_count1 =
 -              intel_uncore_read(uncore, DMIEC) +
 -              intel_uncore_read(uncore, DDREC) +
 -              intel_uncore_read(uncore, CSIEC);
 -      dev_priv->ips.last_time1 = jiffies_to_msecs(jiffies);
 -      dev_priv->ips.last_count2 = intel_uncore_read(uncore, GFXEC);
 -      dev_priv->ips.last_time2 = ktime_get_raw_ns();
 +      g4x_disable_trickle_feed(dev_priv);
  
 -      spin_unlock_irq(&mchdev_lock);
 +      ibx_init_clock_gating(dev_priv);
  }
  
 -static void ironlake_disable_drps(struct drm_i915_private *i915)
 +static void cpt_init_clock_gating(struct drm_i915_private *dev_priv)
  {
 -      struct intel_uncore *uncore = &i915->uncore;
 -      u16 rgvswctl;
 -
 -      spin_lock_irq(&mchdev_lock);
 -
 -      rgvswctl = intel_uncore_read16(uncore, MEMSWCTL);
 -
 -      /* Ack interrupts, disable EFC interrupt */
 -      intel_uncore_write(uncore,
 -                         MEMINTREN,
 -                         intel_uncore_read(uncore, MEMINTREN) &
 -                         ~MEMINT_EVAL_CHG_EN);
 -      intel_uncore_write(uncore, MEMINTRSTS, MEMINT_EVAL_CHG);
 -      intel_uncore_write(uncore,
 -                         DEIER,
 -                         intel_uncore_read(uncore, DEIER) & ~DE_PCU_EVENT);
 -      intel_uncore_write(uncore, DEIIR, DE_PCU_EVENT);
 -      intel_uncore_write(uncore,
 -                         DEIMR,
 -                         intel_uncore_read(uncore, DEIMR) | DE_PCU_EVENT);
 -
 -      /* Go back to the starting frequency */
 -      ironlake_set_drps(i915, i915->ips.fstart);
 -      mdelay(1);
 -      rgvswctl |= MEMCTL_CMD_STS;
 -      intel_uncore_write(uncore, MEMSWCTL, rgvswctl);
 -      mdelay(1);
 -
 -      spin_unlock_irq(&mchdev_lock);
 -}
 -
 -/* There's a funny hw issue where the hw returns all 0 when reading from
 - * GEN6_RP_INTERRUPT_LIMITS. Hence we always need to compute the desired value
 - * ourselves, instead of doing a rmw cycle (which might result in us clearing
 - * all limits and the gpu stuck at whatever frequency it is at atm).
 - */
 -static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -      u32 limits;
 -
 -      /* Only set the down limit when we've reached the lowest level to avoid
 -       * getting more interrupts, otherwise leave this clear. This prevents a
 -       * race in the hw when coming out of rc6: There's a tiny window where
 -       * the hw runs at the minimal clock before selecting the desired
 -       * frequency, if the down threshold expires in that window we will not
 -       * receive a down interrupt. */
 -      if (INTEL_GEN(dev_priv) >= 9) {
 -              limits = (rps->max_freq_softlimit) << 23;
 -              if (val <= rps->min_freq_softlimit)
 -                      limits |= (rps->min_freq_softlimit) << 14;
 -      } else {
 -              limits = rps->max_freq_softlimit << 24;
 -              if (val <= rps->min_freq_softlimit)
 -                      limits |= rps->min_freq_softlimit << 16;
 -      }
 -
 -      return limits;
 -}
 -
 -static void rps_set_power(struct drm_i915_private *dev_priv, int new_power)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -      u32 threshold_up = 0, threshold_down = 0; /* in % */
 -      u32 ei_up = 0, ei_down = 0;
 -
 -      lockdep_assert_held(&rps->power.mutex);
 -
 -      if (new_power == rps->power.mode)
 -              return;
 -
 -      /* Note the units here are not exactly 1us, but 1280ns. */
 -      switch (new_power) {
 -      case LOW_POWER:
 -              /* Upclock if more than 95% busy over 16ms */
 -              ei_up = 16000;
 -              threshold_up = 95;
 -
 -              /* Downclock if less than 85% busy over 32ms */
 -              ei_down = 32000;
 -              threshold_down = 85;
 -              break;
 -
 -      case BETWEEN:
 -              /* Upclock if more than 90% busy over 13ms */
 -              ei_up = 13000;
 -              threshold_up = 90;
 -
 -              /* Downclock if less than 75% busy over 32ms */
 -              ei_down = 32000;
 -              threshold_down = 75;
 -              break;
 -
 -      case HIGH_POWER:
 -              /* Upclock if more than 85% busy over 10ms */
 -              ei_up = 10000;
 -              threshold_up = 85;
 -
 -              /* Downclock if less than 60% busy over 32ms */
 -              ei_down = 32000;
 -              threshold_down = 60;
 -              break;
 -      }
 -
 -      /* When byt can survive without system hang with dynamic
 -       * sw freq adjustments, this restriction can be lifted.
 -       */
 -      if (IS_VALLEYVIEW(dev_priv))
 -              goto skip_hw_write;
 -
 -      I915_WRITE(GEN6_RP_UP_EI,
 -                 GT_INTERVAL_FROM_US(dev_priv, ei_up));
 -      I915_WRITE(GEN6_RP_UP_THRESHOLD,
 -                 GT_INTERVAL_FROM_US(dev_priv,
 -                                     ei_up * threshold_up / 100));
 -
 -      I915_WRITE(GEN6_RP_DOWN_EI,
 -                 GT_INTERVAL_FROM_US(dev_priv, ei_down));
 -      I915_WRITE(GEN6_RP_DOWN_THRESHOLD,
 -                 GT_INTERVAL_FROM_US(dev_priv,
 -                                     ei_down * threshold_down / 100));
 -
 -      I915_WRITE(GEN6_RP_CONTROL,
 -                 (INTEL_GEN(dev_priv) > 9 ? 0 : GEN6_RP_MEDIA_TURBO) |
 -                 GEN6_RP_MEDIA_HW_NORMAL_MODE |
 -                 GEN6_RP_MEDIA_IS_GFX |
 -                 GEN6_RP_ENABLE |
 -                 GEN6_RP_UP_BUSY_AVG |
 -                 GEN6_RP_DOWN_IDLE_AVG);
 -
 -skip_hw_write:
 -      rps->power.mode = new_power;
 -      rps->power.up_threshold = threshold_up;
 -      rps->power.down_threshold = threshold_down;
 -}
 -
 -static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -      int new_power;
 -
 -      new_power = rps->power.mode;
 -      switch (rps->power.mode) {
 -      case LOW_POWER:
 -              if (val > rps->efficient_freq + 1 &&
 -                  val > rps->cur_freq)
 -                      new_power = BETWEEN;
 -              break;
 -
 -      case BETWEEN:
 -              if (val <= rps->efficient_freq &&
 -                  val < rps->cur_freq)
 -                      new_power = LOW_POWER;
 -              else if (val >= rps->rp0_freq &&
 -                       val > rps->cur_freq)
 -                      new_power = HIGH_POWER;
 -              break;
 -
 -      case HIGH_POWER:
 -              if (val < (rps->rp1_freq + rps->rp0_freq) >> 1 &&
 -                  val < rps->cur_freq)
 -                      new_power = BETWEEN;
 -              break;
 -      }
 -      /* Max/min bins are special */
 -      if (val <= rps->min_freq_softlimit)
 -              new_power = LOW_POWER;
 -      if (val >= rps->max_freq_softlimit)
 -              new_power = HIGH_POWER;
 -
 -      mutex_lock(&rps->power.mutex);
 -      if (rps->power.interactive)
 -              new_power = HIGH_POWER;
 -      rps_set_power(dev_priv, new_power);
 -      mutex_unlock(&rps->power.mutex);
 -}
 -
 -void intel_rps_mark_interactive(struct drm_i915_private *i915, bool interactive)
 -{
 -      struct intel_rps *rps = &i915->gt_pm.rps;
 -
 -      if (INTEL_GEN(i915) < 6)
 -              return;
 -
 -      mutex_lock(&rps->power.mutex);
 -      if (interactive) {
 -              if (!rps->power.interactive++ && READ_ONCE(i915->gt.awake))
 -                      rps_set_power(i915, HIGH_POWER);
 -      } else {
 -              GEM_BUG_ON(!rps->power.interactive);
 -              rps->power.interactive--;
 -      }
 -      mutex_unlock(&rps->power.mutex);
 -}
 -
 -static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -      u32 mask = 0;
 -
 -      /* We use UP_EI_EXPIRED interupts for both up/down in manual mode */
 -      if (val > rps->min_freq_softlimit)
 -              mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT;
 -      if (val < rps->max_freq_softlimit)
 -              mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD;
 -
 -      mask &= dev_priv->pm_rps_events;
 -
 -      return gen6_sanitize_rps_pm_mask(dev_priv, ~mask);
 -}
 -
 -/* gen6_set_rps is called to update the frequency request, but should also be
 - * called when the range (min_delay and max_delay) is modified so that we can
 - * update the GEN6_RP_INTERRUPT_LIMITS register accordingly. */
 -static int gen6_set_rps(struct drm_i915_private *dev_priv, u8 val)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -
 -      /* min/max delay may still have been modified so be sure to
 -       * write the limits value.
 -       */
 -      if (val != rps->cur_freq) {
 -              gen6_set_rps_thresholds(dev_priv, val);
 -
 -              if (INTEL_GEN(dev_priv) >= 9)
 -                      I915_WRITE(GEN6_RPNSWREQ,
 -                                 GEN9_FREQUENCY(val));
 -              else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
 -                      I915_WRITE(GEN6_RPNSWREQ,
 -                                 HSW_FREQUENCY(val));
 -              else
 -                      I915_WRITE(GEN6_RPNSWREQ,
 -                                 GEN6_FREQUENCY(val) |
 -                                 GEN6_OFFSET(0) |
 -                                 GEN6_AGGRESSIVE_TURBO);
 -      }
 -
 -      /* Make sure we continue to get interrupts
 -       * until we hit the minimum or maximum frequencies.
 -       */
 -      I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, intel_rps_limits(dev_priv, val));
 -      I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val));
 -
 -      rps->cur_freq = val;
 -      trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val));
 -
 -      return 0;
 -}
 -
 -static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val)
 -{
 -      int err;
 -
 -      if (WARN_ONCE(IS_CHERRYVIEW(dev_priv) && (val & 1),
 -                    "Odd GPU freq value\n"))
 -              val &= ~1;
 -
 -      I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val));
 -
 -      if (val != dev_priv->gt_pm.rps.cur_freq) {
 -              vlv_punit_get(dev_priv);
 -              err = vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val);
 -              vlv_punit_put(dev_priv);
 -              if (err)
 -                      return err;
 -
 -              gen6_set_rps_thresholds(dev_priv, val);
 -      }
 -
 -      dev_priv->gt_pm.rps.cur_freq = val;
 -      trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val));
 -
 -      return 0;
 -}
 -
 -/* vlv_set_rps_idle: Set the frequency to idle, if Gfx clocks are down
 - *
 - * * If Gfx is Idle, then
 - * 1. Forcewake Media well.
 - * 2. Request idle freq.
 - * 3. Release Forcewake of Media well.
 -*/
 -static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -      u32 val = rps->idle_freq;
 -      int err;
 -
 -      if (rps->cur_freq <= val)
 -              return;
 -
 -      /* The punit delays the write of the frequency and voltage until it
 -       * determines the GPU is awake. During normal usage we don't want to
 -       * waste power changing the frequency if the GPU is sleeping (rc6).
 -       * However, the GPU and driver is now idle and we do not want to delay
 -       * switching to minimum voltage (reducing power whilst idle) as we do
 -       * not expect to be woken in the near future and so must flush the
 -       * change by waking the device.
 -       *
 -       * We choose to take the media powerwell (either would do to trick the
 -       * punit into committing the voltage change) as that takes a lot less
 -       * power than the render powerwell.
 -       */
 -      intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_MEDIA);
 -      err = valleyview_set_rps(dev_priv, val);
 -      intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_MEDIA);
 -
 -      if (err)
 -              DRM_ERROR("Failed to set RPS for idle\n");
 -}
 -
 -void gen6_rps_busy(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -
 -      mutex_lock(&rps->lock);
 -      if (rps->enabled) {
 -              u8 freq;
 -
 -              if (dev_priv->pm_rps_events & GEN6_PM_RP_UP_EI_EXPIRED)
 -                      gen6_rps_reset_ei(dev_priv);
 -              I915_WRITE(GEN6_PMINTRMSK,
 -                         gen6_rps_pm_mask(dev_priv, rps->cur_freq));
 -
 -              gen6_enable_rps_interrupts(dev_priv);
 -
 -              /* Use the user's desired frequency as a guide, but for better
 -               * performance, jump directly to RPe as our starting frequency.
 -               */
 -              freq = max(rps->cur_freq,
 -                         rps->efficient_freq);
 -
 -              if (intel_set_rps(dev_priv,
 -                                clamp(freq,
 -                                      rps->min_freq_softlimit,
 -                                      rps->max_freq_softlimit)))
 -                      DRM_DEBUG_DRIVER("Failed to set idle frequency\n");
 -      }
 -      mutex_unlock(&rps->lock);
 -}
 -
 -void gen6_rps_idle(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -
 -      /* Flush our bottom-half so that it does not race with us
 -       * setting the idle frequency and so that it is bounded by
 -       * our rpm wakeref. And then disable the interrupts to stop any
 -       * futher RPS reclocking whilst we are asleep.
 -       */
 -      gen6_disable_rps_interrupts(dev_priv);
 -
 -      mutex_lock(&rps->lock);
 -      if (rps->enabled) {
 -              if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
 -                      vlv_set_rps_idle(dev_priv);
 -              else
 -                      gen6_set_rps(dev_priv, rps->idle_freq);
 -              rps->last_adj = 0;
 -              I915_WRITE(GEN6_PMINTRMSK,
 -                         gen6_sanitize_rps_pm_mask(dev_priv, ~0));
 -      }
 -      mutex_unlock(&rps->lock);
 -}
 -
 -void gen6_rps_boost(struct i915_request *rq)
 -{
 -      struct intel_rps *rps = &rq->i915->gt_pm.rps;
 -      unsigned long flags;
 -      bool boost;
 -
 -      /* This is intentionally racy! We peek at the state here, then
 -       * validate inside the RPS worker.
 -       */
 -      if (!rps->enabled)
 -              return;
 -
 -      if (i915_request_signaled(rq))
 -              return;
 -
 -      /* Serializes with i915_request_retire() */
 -      boost = false;
 -      spin_lock_irqsave(&rq->lock, flags);
 -      if (!i915_request_has_waitboost(rq) &&
 -          !dma_fence_is_signaled_locked(&rq->fence)) {
 -              boost = !atomic_fetch_inc(&rps->num_waiters);
 -              rq->flags |= I915_REQUEST_WAITBOOST;
 -      }
 -      spin_unlock_irqrestore(&rq->lock, flags);
 -      if (!boost)
 -              return;
 -
 -      if (READ_ONCE(rps->cur_freq) < rps->boost_freq)
 -              schedule_work(&rps->work);
 -
 -      atomic_inc(&rps->boosts);
 -}
 -
 -int intel_set_rps(struct drm_i915_private *dev_priv, u8 val)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -      int err;
 -
 -      lockdep_assert_held(&rps->lock);
 -      GEM_BUG_ON(val > rps->max_freq);
 -      GEM_BUG_ON(val < rps->min_freq);
 -
 -      if (!rps->enabled) {
 -              rps->cur_freq = val;
 -              return 0;
 -      }
 -
 -      if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
 -              err = valleyview_set_rps(dev_priv, val);
 -      else
 -              err = gen6_set_rps(dev_priv, val);
 -
 -      return err;
 -}
 -
 -static void gen9_disable_rc6(struct drm_i915_private *dev_priv)
 -{
 -      I915_WRITE(GEN6_RC_CONTROL, 0);
 -      I915_WRITE(GEN9_PG_ENABLE, 0);
 -}
 -
 -static void gen9_disable_rps(struct drm_i915_private *dev_priv)
 -{
 -      I915_WRITE(GEN6_RP_CONTROL, 0);
 -}
 -
 -static void gen6_disable_rc6(struct drm_i915_private *dev_priv)
 -{
 -      I915_WRITE(GEN6_RC_CONTROL, 0);
 -}
 -
 -static void gen6_disable_rps(struct drm_i915_private *dev_priv)
 -{
 -      I915_WRITE(GEN6_RPNSWREQ, 1 << 31);
 -      I915_WRITE(GEN6_RP_CONTROL, 0);
 -}
 -
 -static void cherryview_disable_rc6(struct drm_i915_private *dev_priv)
 -{
 -      I915_WRITE(GEN6_RC_CONTROL, 0);
 -}
 -
 -static void cherryview_disable_rps(struct drm_i915_private *dev_priv)
 -{
 -      I915_WRITE(GEN6_RP_CONTROL, 0);
 -}
 -
 -static void valleyview_disable_rc6(struct drm_i915_private *dev_priv)
 -{
 -      /* We're doing forcewake before Disabling RC6,
 -       * This what the BIOS expects when going into suspend */
 -      intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
 -
 -      I915_WRITE(GEN6_RC_CONTROL, 0);
 -
 -      intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 -}
 -
 -static void valleyview_disable_rps(struct drm_i915_private *dev_priv)
 -{
 -      I915_WRITE(GEN6_RP_CONTROL, 0);
 -}
 -
 -static bool bxt_check_bios_rc6_setup(struct drm_i915_private *dev_priv)
 -{
 -      bool enable_rc6 = true;
 -      unsigned long rc6_ctx_base;
 -      u32 rc_ctl;
 -      int rc_sw_target;
 -
 -      rc_ctl = I915_READ(GEN6_RC_CONTROL);
 -      rc_sw_target = (I915_READ(GEN6_RC_STATE) & RC_SW_TARGET_STATE_MASK) >>
 -                     RC_SW_TARGET_STATE_SHIFT;
 -      DRM_DEBUG_DRIVER("BIOS enabled RC states: "
 -                       "HW_CTRL %s HW_RC6 %s SW_TARGET_STATE %x\n",
 -                       onoff(rc_ctl & GEN6_RC_CTL_HW_ENABLE),
 -                       onoff(rc_ctl & GEN6_RC_CTL_RC6_ENABLE),
 -                       rc_sw_target);
 -
 -      if (!(I915_READ(RC6_LOCATION) & RC6_CTX_IN_DRAM)) {
 -              DRM_DEBUG_DRIVER("RC6 Base location not set properly.\n");
 -              enable_rc6 = false;
 -      }
 -
 -      /*
 -       * The exact context size is not known for BXT, so assume a page size
 -       * for this check.
 -       */
 -      rc6_ctx_base = I915_READ(RC6_CTX_BASE) & RC6_CTX_BASE_MASK;
 -      if (!((rc6_ctx_base >= dev_priv->dsm_reserved.start) &&
 -            (rc6_ctx_base + PAGE_SIZE < dev_priv->dsm_reserved.end))) {
 -              DRM_DEBUG_DRIVER("RC6 Base address not as expected.\n");
 -              enable_rc6 = false;
 -      }
 -
 -      if (!(((I915_READ(PWRCTX_MAXCNT_RCSUNIT) & IDLE_TIME_MASK) > 1) &&
 -            ((I915_READ(PWRCTX_MAXCNT_VCSUNIT0) & IDLE_TIME_MASK) > 1) &&
 -            ((I915_READ(PWRCTX_MAXCNT_BCSUNIT) & IDLE_TIME_MASK) > 1) &&
 -            ((I915_READ(PWRCTX_MAXCNT_VECSUNIT) & IDLE_TIME_MASK) > 1))) {
 -              DRM_DEBUG_DRIVER("Engine Idle wait time not set properly.\n");
 -              enable_rc6 = false;
 -      }
 -
 -      if (!I915_READ(GEN8_PUSHBUS_CONTROL) ||
 -          !I915_READ(GEN8_PUSHBUS_ENABLE) ||
 -          !I915_READ(GEN8_PUSHBUS_SHIFT)) {
 -              DRM_DEBUG_DRIVER("Pushbus not setup properly.\n");
 -              enable_rc6 = false;
 -      }
 -
 -      if (!I915_READ(GEN6_GFXPAUSE)) {
 -              DRM_DEBUG_DRIVER("GFX pause not setup properly.\n");
 -              enable_rc6 = false;
 -      }
 -
 -      if (!I915_READ(GEN8_MISC_CTRL0)) {
 -              DRM_DEBUG_DRIVER("GPM control not setup properly.\n");
 -              enable_rc6 = false;
 -      }
 -
 -      return enable_rc6;
 -}
 -
 -static bool sanitize_rc6(struct drm_i915_private *i915)
 -{
 -      struct intel_device_info *info = mkwrite_device_info(i915);
 -
 -      /* Powersaving is controlled by the host when inside a VM */
 -      if (intel_vgpu_active(i915)) {
 -              info->has_rc6 = 0;
 -              info->has_rps = false;
 -      }
 -
 -      if (info->has_rc6 &&
 -          IS_GEN9_LP(i915) && !bxt_check_bios_rc6_setup(i915)) {
 -              DRM_INFO("RC6 disabled by BIOS\n");
 -              info->has_rc6 = 0;
 -      }
 -
 -      /*
 -       * We assume that we do not have any deep rc6 levels if we don't have
 -       * have the previous rc6 level supported, i.e. we use HAS_RC6()
 -       * as the initial coarse check for rc6 in general, moving on to
 -       * progressively finer/deeper levels.
 -       */
 -      if (!info->has_rc6 && info->has_rc6p)
 -              info->has_rc6p = 0;
 -
 -      return info->has_rc6;
 -}
 -
 -static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -
 -      /* All of these values are in units of 50MHz */
 -
 -      /* static values from HW: RP0 > RP1 > RPn (min_freq) */
 -      if (IS_GEN9_LP(dev_priv)) {
 -              u32 rp_state_cap = I915_READ(BXT_RP_STATE_CAP);
 -              rps->rp0_freq = (rp_state_cap >> 16) & 0xff;
 -              rps->rp1_freq = (rp_state_cap >>  8) & 0xff;
 -              rps->min_freq = (rp_state_cap >>  0) & 0xff;
 -      } else {
 -              u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
 -              rps->rp0_freq = (rp_state_cap >>  0) & 0xff;
 -              rps->rp1_freq = (rp_state_cap >>  8) & 0xff;
 -              rps->min_freq = (rp_state_cap >> 16) & 0xff;
 -      }
 -      /* hw_max = RP0 until we check for overclocking */
 -      rps->max_freq = rps->rp0_freq;
 -
 -      rps->efficient_freq = rps->rp1_freq;
 -      if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
 -          IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) {
 -              u32 ddcc_status = 0;
 -
 -              if (sandybridge_pcode_read(dev_priv,
 -                                         HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL,
 -                                         &ddcc_status, NULL) == 0)
 -                      rps->efficient_freq =
 -                              clamp_t(u8,
 -                                      ((ddcc_status >> 8) & 0xff),
 -                                      rps->min_freq,
 -                                      rps->max_freq);
 -      }
 -
 -      if (IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) {
 -              /* Store the frequency values in 16.66 MHZ units, which is
 -               * the natural hardware unit for SKL
 -               */
 -              rps->rp0_freq *= GEN9_FREQ_SCALER;
 -              rps->rp1_freq *= GEN9_FREQ_SCALER;
 -              rps->min_freq *= GEN9_FREQ_SCALER;
 -              rps->max_freq *= GEN9_FREQ_SCALER;
 -              rps->efficient_freq *= GEN9_FREQ_SCALER;
 -      }
 -}
 -
 -static void reset_rps(struct drm_i915_private *dev_priv,
 -                    int (*set)(struct drm_i915_private *, u8))
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -      u8 freq = rps->cur_freq;
 -
 -      /* force a reset */
 -      rps->power.mode = -1;
 -      rps->cur_freq = -1;
 -
 -      if (set(dev_priv, freq))
 -              DRM_ERROR("Failed to reset RPS to initial values\n");
 -}
 -
 -/* See the Gen9_GT_PM_Programming_Guide doc for the below */
 -static void gen9_enable_rps(struct drm_i915_private *dev_priv)
 -{
 -      intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
 -
 -      /* Program defaults and thresholds for RPS */
 -      if (IS_GEN(dev_priv, 9))
 -              I915_WRITE(GEN6_RC_VIDEO_FREQ,
 -                      GEN9_FREQUENCY(dev_priv->gt_pm.rps.rp1_freq));
 -
 -      /* 1 second timeout*/
 -      I915_WRITE(GEN6_RP_DOWN_TIMEOUT,
 -              GT_INTERVAL_FROM_US(dev_priv, 1000000));
 -
 -      I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 0xa);
 -
 -      /* Leaning on the below call to gen6_set_rps to program/setup the
 -       * Up/Down EI & threshold registers, as well as the RP_CONTROL,
 -       * RP_INTERRUPT_LIMITS & RPNSWREQ registers */
 -      reset_rps(dev_priv, gen6_set_rps);
 -
 -      intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 -}
 -
 -static void gen11_enable_rc6(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_engine_cs *engine;
 -      enum intel_engine_id id;
 -
 -      /* 1a: Software RC state - RC0 */
 -      I915_WRITE(GEN6_RC_STATE, 0);
 -
 -      /*
 -       * 1b: Get forcewake during program sequence. Although the driver
 -       * hasn't enabled a state yet where we need forcewake, BIOS may have.
 -       */
 -      intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
 -
 -      /* 2a: Disable RC states. */
 -      I915_WRITE(GEN6_RC_CONTROL, 0);
 -
 -      /* 2b: Program RC6 thresholds.*/
 -      I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16 | 85);
 -      I915_WRITE(GEN10_MEDIA_WAKE_RATE_LIMIT, 150);
 -
 -      I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
 -      I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
 -      for_each_engine(engine, dev_priv, id)
 -              I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
 -
 -      if (HAS_GT_UC(dev_priv))
 -              I915_WRITE(GUC_MAX_IDLE_COUNT, 0xA);
 -
 -      I915_WRITE(GEN6_RC_SLEEP, 0);
 -
 -      I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */
 -
 -      /*
 -       * 2c: Program Coarse Power Gating Policies.
 -       *
 -       * Bspec's guidance is to use 25us (really 25 * 1280ns) here. What we
 -       * use instead is a more conservative estimate for the maximum time
 -       * it takes us to service a CS interrupt and submit a new ELSP - that
 -       * is the time which the GPU is idle waiting for the CPU to select the
 -       * next request to execute. If the idle hysteresis is less than that
 -       * interrupt service latency, the hardware will automatically gate
 -       * the power well and we will then incur the wake up cost on top of
 -       * the service latency. A similar guide from plane_state is that we
 -       * do not want the enable hysteresis to less than the wakeup latency.
 -       *
 -       * igt/gem_exec_nop/sequential provides a rough estimate for the
 -       * service latency, and puts it around 10us for Broadwell (and other
 -       * big core) and around 40us for Broxton (and other low power cores).
 -       * [Note that for legacy ringbuffer submission, this is less than 1us!]
 -       * However, the wakeup latency on Broxton is closer to 100us. To be
 -       * conservative, we have to factor in a context switch on top (due
 -       * to ksoftirqd).
 -       */
 -      I915_WRITE(GEN9_MEDIA_PG_IDLE_HYSTERESIS, 250);
 -      I915_WRITE(GEN9_RENDER_PG_IDLE_HYSTERESIS, 250);
 -
 -      /* 3a: Enable RC6 */
 -      I915_WRITE(GEN6_RC_CONTROL,
 -                 GEN6_RC_CTL_HW_ENABLE |
 -                 GEN6_RC_CTL_RC6_ENABLE |
 -                 GEN6_RC_CTL_EI_MODE(1));
 -
 -      /* 3b: Enable Coarse Power Gating only when RC6 is enabled. */
 -      I915_WRITE(GEN9_PG_ENABLE,
 -                 GEN9_RENDER_PG_ENABLE |
 -                 GEN9_MEDIA_PG_ENABLE |
 -                 GEN11_MEDIA_SAMPLER_PG_ENABLE);
 -
 -      intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 -}
 -
 -static void gen9_enable_rc6(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_engine_cs *engine;
 -      enum intel_engine_id id;
 -      u32 rc6_mode;
 -
 -      /* 1a: Software RC state - RC0 */
 -      I915_WRITE(GEN6_RC_STATE, 0);
 -
 -      /* 1b: Get forcewake during program sequence. Although the driver
 -       * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
 -      intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
 -
 -      /* 2a: Disable RC states. */
 -      I915_WRITE(GEN6_RC_CONTROL, 0);
 -
 -      /* 2b: Program RC6 thresholds.*/
 -      if (INTEL_GEN(dev_priv) >= 10) {
 -              I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16 | 85);
 -              I915_WRITE(GEN10_MEDIA_WAKE_RATE_LIMIT, 150);
 -      } else if (IS_SKYLAKE(dev_priv)) {
 -              /*
 -               * WaRsDoubleRc6WrlWithCoarsePowerGating:skl Doubling WRL only
 -               * when CPG is enabled
 -               */
 -              I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 108 << 16);
 -      } else {
 -              I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16);
 -      }
 -
 -      I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
 -      I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
 -      for_each_engine(engine, dev_priv, id)
 -              I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
 -
 -      if (HAS_GT_UC(dev_priv))
 -              I915_WRITE(GUC_MAX_IDLE_COUNT, 0xA);
 -
 -      I915_WRITE(GEN6_RC_SLEEP, 0);
 -
 -      /*
 -       * 2c: Program Coarse Power Gating Policies.
 -       *
 -       * Bspec's guidance is to use 25us (really 25 * 1280ns) here. What we
 -       * use instead is a more conservative estimate for the maximum time
 -       * it takes us to service a CS interrupt and submit a new ELSP - that
 -       * is the time which the GPU is idle waiting for the CPU to select the
 -       * next request to execute. If the idle hysteresis is less than that
 -       * interrupt service latency, the hardware will automatically gate
 -       * the power well and we will then incur the wake up cost on top of
 -       * the service latency. A similar guide from plane_state is that we
 -       * do not want the enable hysteresis to less than the wakeup latency.
 -       *
 -       * igt/gem_exec_nop/sequential provides a rough estimate for the
 -       * service latency, and puts it around 10us for Broadwell (and other
 -       * big core) and around 40us for Broxton (and other low power cores).
 -       * [Note that for legacy ringbuffer submission, this is less than 1us!]
 -       * However, the wakeup latency on Broxton is closer to 100us. To be
 -       * conservative, we have to factor in a context switch on top (due
 -       * to ksoftirqd).
 -       */
 -      I915_WRITE(GEN9_MEDIA_PG_IDLE_HYSTERESIS, 250);
 -      I915_WRITE(GEN9_RENDER_PG_IDLE_HYSTERESIS, 250);
 -
 -      /* 3a: Enable RC6 */
 -      I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
 -
 -      /* WaRsUseTimeoutMode:cnl (pre-prod) */
 -      if (IS_CNL_REVID(dev_priv, CNL_REVID_A0, CNL_REVID_C0))
 -              rc6_mode = GEN7_RC_CTL_TO_MODE;
 -      else
 -              rc6_mode = GEN6_RC_CTL_EI_MODE(1);
 -
 -      I915_WRITE(GEN6_RC_CONTROL,
 -                 GEN6_RC_CTL_HW_ENABLE |
 -                 GEN6_RC_CTL_RC6_ENABLE |
 -                 rc6_mode);
 -
 -      /*
 -       * 3b: Enable Coarse Power Gating only when RC6 is enabled.
 -       * WaRsDisableCoarsePowerGating:skl,cnl - Render/Media PG need to be disabled with RC6.
 -       */
 -      if (NEEDS_WaRsDisableCoarsePowerGating(dev_priv))
 -              I915_WRITE(GEN9_PG_ENABLE, 0);
 -      else
 -              I915_WRITE(GEN9_PG_ENABLE,
 -                         GEN9_RENDER_PG_ENABLE | GEN9_MEDIA_PG_ENABLE);
 -
 -      intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 -}
 -
 -static void gen8_enable_rc6(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_engine_cs *engine;
 -      enum intel_engine_id id;
 -
 -      /* 1a: Software RC state - RC0 */
 -      I915_WRITE(GEN6_RC_STATE, 0);
 -
 -      /* 1b: Get forcewake during program sequence. Although the driver
 -       * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
 -      intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
 -
 -      /* 2a: Disable RC states. */
 -      I915_WRITE(GEN6_RC_CONTROL, 0);
 -
 -      /* 2b: Program RC6 thresholds.*/
 -      I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
 -      I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
 -      I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
 -      for_each_engine(engine, dev_priv, id)
 -              I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
 -      I915_WRITE(GEN6_RC_SLEEP, 0);
 -      I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us/1.28 for TO */
 -
 -      /* 3: Enable RC6 */
 -
 -      I915_WRITE(GEN6_RC_CONTROL,
 -                 GEN6_RC_CTL_HW_ENABLE |
 -                 GEN7_RC_CTL_TO_MODE |
 -                 GEN6_RC_CTL_RC6_ENABLE);
 -
 -      intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 -}
 -
 -static void gen8_enable_rps(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -
 -      intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
 -
 -      /* 1 Program defaults and thresholds for RPS*/
 -      I915_WRITE(GEN6_RPNSWREQ,
 -                 HSW_FREQUENCY(rps->rp1_freq));
 -      I915_WRITE(GEN6_RC_VIDEO_FREQ,
 -                 HSW_FREQUENCY(rps->rp1_freq));
 -      /* NB: Docs say 1s, and 1000000 - which aren't equivalent */
 -      I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 100000000 / 128); /* 1 second timeout */
 -
 -      /* Docs recommend 900MHz, and 300 MHz respectively */
 -      I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
 -                 rps->max_freq_softlimit << 24 |
 -                 rps->min_freq_softlimit << 16);
 -
 -      I915_WRITE(GEN6_RP_UP_THRESHOLD, 7600000 / 128); /* 76ms busyness per EI, 90% */
 -      I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 31300000 / 128); /* 313ms busyness per EI, 70%*/
 -      I915_WRITE(GEN6_RP_UP_EI, 66000); /* 84.48ms, XXX: random? */
 -      I915_WRITE(GEN6_RP_DOWN_EI, 350000); /* 448ms, XXX: random? */
 -
 -      I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
 -
 -      /* 2: Enable RPS */
 -      I915_WRITE(GEN6_RP_CONTROL,
 -                 GEN6_RP_MEDIA_TURBO |
 -                 GEN6_RP_MEDIA_HW_NORMAL_MODE |
 -                 GEN6_RP_MEDIA_IS_GFX |
 -                 GEN6_RP_ENABLE |
 -                 GEN6_RP_UP_BUSY_AVG |
 -                 GEN6_RP_DOWN_IDLE_AVG);
 -
 -      reset_rps(dev_priv, gen6_set_rps);
 -
 -      intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 -}
 -
 -static void gen6_enable_rc6(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_engine_cs *engine;
 -      enum intel_engine_id id;
 -      u32 rc6vids, rc6_mask;
 -      u32 gtfifodbg;
 -      int ret;
 -
 -      I915_WRITE(GEN6_RC_STATE, 0);
 -
 -      /* Clear the DBG now so we don't confuse earlier errors */
 -      gtfifodbg = I915_READ(GTFIFODBG);
 -      if (gtfifodbg) {
 -              DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg);
 -              I915_WRITE(GTFIFODBG, gtfifodbg);
 -      }
 -
 -      intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
 -
 -      /* disable the counters and set deterministic thresholds */
 -      I915_WRITE(GEN6_RC_CONTROL, 0);
 -
 -      I915_WRITE(GEN6_RC1_WAKE_RATE_LIMIT, 1000 << 16);
 -      I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16 | 30);
 -      I915_WRITE(GEN6_RC6pp_WAKE_RATE_LIMIT, 30);
 -      I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000);
 -      I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25);
 -
 -      for_each_engine(engine, dev_priv, id)
 -              I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
 -
 -      I915_WRITE(GEN6_RC_SLEEP, 0);
 -      I915_WRITE(GEN6_RC1e_THRESHOLD, 1000);
 -      if (IS_IVYBRIDGE(dev_priv))
 -              I915_WRITE(GEN6_RC6_THRESHOLD, 125000);
 -      else
 -              I915_WRITE(GEN6_RC6_THRESHOLD, 50000);
 -      I915_WRITE(GEN6_RC6p_THRESHOLD, 150000);
 -      I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
 -
 -      /* We don't use those on Haswell */
 -      rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
 -      if (HAS_RC6p(dev_priv))
 -              rc6_mask |= GEN6_RC_CTL_RC6p_ENABLE;
 -      if (HAS_RC6pp(dev_priv))
 -              rc6_mask |= GEN6_RC_CTL_RC6pp_ENABLE;
 -      I915_WRITE(GEN6_RC_CONTROL,
 -                 rc6_mask |
 -                 GEN6_RC_CTL_EI_MODE(1) |
 -                 GEN6_RC_CTL_HW_ENABLE);
 -
 -      rc6vids = 0;
 -      ret = sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS,
 -                                   &rc6vids, NULL);
 -      if (IS_GEN(dev_priv, 6) && ret) {
 -              DRM_DEBUG_DRIVER("Couldn't check for BIOS workaround\n");
 -      } else if (IS_GEN(dev_priv, 6) && (GEN6_DECODE_RC6_VID(rc6vids & 0xff) < 450)) {
 -              DRM_DEBUG_DRIVER("You should update your BIOS. Correcting minimum rc6 voltage (%dmV->%dmV)\n",
 -                        GEN6_DECODE_RC6_VID(rc6vids & 0xff), 450);
 -              rc6vids &= 0xffff00;
 -              rc6vids |= GEN6_ENCODE_RC6_VID(450);
 -              ret = sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_RC6VIDS, rc6vids);
 -              if (ret)
 -                      DRM_ERROR("Couldn't fix incorrect rc6 voltage\n");
 -      }
 -
 -      intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 -}
 -
 -static void gen6_enable_rps(struct drm_i915_private *dev_priv)
 -{
 -      /* Here begins a magic sequence of register writes to enable
 -       * auto-downclocking.
 -       *
 -       * Perhaps there might be some value in exposing these to
 -       * userspace...
 -       */
 -      intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
 -
 -      /* Power down if completely idle for over 50ms */
 -      I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 50000);
 -      I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
 -
 -      reset_rps(dev_priv, gen6_set_rps);
 -
 -      intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 -}
 -
 -static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -      const int min_freq = 15;
 -      const int scaling_factor = 180;
 -      unsigned int gpu_freq;
 -      unsigned int max_ia_freq, min_ring_freq;
 -      unsigned int max_gpu_freq, min_gpu_freq;
 -      struct cpufreq_policy *policy;
 -
 -      lockdep_assert_held(&rps->lock);
 -
 -      if (rps->max_freq <= rps->min_freq)
 -              return;
 -
 -      policy = cpufreq_cpu_get(0);
 -      if (policy) {
 -              max_ia_freq = policy->cpuinfo.max_freq;
 -              cpufreq_cpu_put(policy);
 -      } else {
 -              /*
 -               * Default to measured freq if none found, PCU will ensure we
 -               * don't go over
 -               */
 -              max_ia_freq = tsc_khz;
 -      }
 -
 -      /* Convert from kHz to MHz */
 -      max_ia_freq /= 1000;
 -
 -      min_ring_freq = I915_READ(DCLK) & 0xf;
 -      /* convert DDR frequency from units of 266.6MHz to bandwidth */
 -      min_ring_freq = mult_frac(min_ring_freq, 8, 3);
 -
 -      min_gpu_freq = rps->min_freq;
 -      max_gpu_freq = rps->max_freq;
 -      if (IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) {
 -              /* Convert GT frequency to 50 HZ units */
 -              min_gpu_freq /= GEN9_FREQ_SCALER;
 -              max_gpu_freq /= GEN9_FREQ_SCALER;
 -      }
 -
 -      /*
 -       * For each potential GPU frequency, load a ring frequency we'd like
 -       * to use for memory access.  We do this by specifying the IA frequency
 -       * the PCU should use as a reference to determine the ring frequency.
 -       */
 -      for (gpu_freq = max_gpu_freq; gpu_freq >= min_gpu_freq; gpu_freq--) {
 -              const int diff = max_gpu_freq - gpu_freq;
 -              unsigned int ia_freq = 0, ring_freq = 0;
 -
 -              if (IS_GEN9_BC(dev_priv) || INTEL_GEN(dev_priv) >= 10) {
 -                      /*
 -                       * ring_freq = 2 * GT. ring_freq is in 100MHz units
 -                       * No floor required for ring frequency on SKL.
 -                       */
 -                      ring_freq = gpu_freq;
 -              } else if (INTEL_GEN(dev_priv) >= 8) {
 -                      /* max(2 * GT, DDR). NB: GT is 50MHz units */
 -                      ring_freq = max(min_ring_freq, gpu_freq);
 -              } else if (IS_HASWELL(dev_priv)) {
 -                      ring_freq = mult_frac(gpu_freq, 5, 4);
 -                      ring_freq = max(min_ring_freq, ring_freq);
 -                      /* leave ia_freq as the default, chosen by cpufreq */
 -              } else {
 -                      /* On older processors, there is no separate ring
 -                       * clock domain, so in order to boost the bandwidth
 -                       * of the ring, we need to upclock the CPU (ia_freq).
 -                       *
 -                       * For GPU frequencies less than 750MHz,
 -                       * just use the lowest ring freq.
 -                       */
 -                      if (gpu_freq < min_freq)
 -                              ia_freq = 800;
 -                      else
 -                              ia_freq = max_ia_freq - ((diff * scaling_factor) / 2);
 -                      ia_freq = DIV_ROUND_CLOSEST(ia_freq, 100);
 -              }
 -
 -              sandybridge_pcode_write(dev_priv,
 -                                      GEN6_PCODE_WRITE_MIN_FREQ_TABLE,
 -                                      ia_freq << GEN6_PCODE_FREQ_IA_RATIO_SHIFT |
 -                                      ring_freq << GEN6_PCODE_FREQ_RING_RATIO_SHIFT |
 -                                      gpu_freq);
 -      }
 -}
 -
 -static int cherryview_rps_max_freq(struct drm_i915_private *dev_priv)
 -{
 -      u32 val, rp0;
 -
 -      val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE);
 -
 -      switch (RUNTIME_INFO(dev_priv)->sseu.eu_total) {
 -      case 8:
 -              /* (2 * 4) config */
 -              rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT);
 -              break;
 -      case 12:
 -              /* (2 * 6) config */
 -              rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS6EU_FUSE_SHIFT);
 -              break;
 -      case 16:
 -              /* (2 * 8) config */
 -      default:
 -              /* Setting (2 * 8) Min RP0 for any other combination */
 -              rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS8EU_FUSE_SHIFT);
 -              break;
 -      }
 -
 -      rp0 = (rp0 & FB_GFX_FREQ_FUSE_MASK);
 -
 -      return rp0;
 -}
 -
 -static int cherryview_rps_rpe_freq(struct drm_i915_private *dev_priv)
 -{
 -      u32 val, rpe;
 -
 -      val = vlv_punit_read(dev_priv, PUNIT_GPU_DUTYCYCLE_REG);
 -      rpe = (val >> PUNIT_GPU_DUTYCYCLE_RPE_FREQ_SHIFT) & PUNIT_GPU_DUTYCYCLE_RPE_FREQ_MASK;
 -
 -      return rpe;
 -}
 -
 -static int cherryview_rps_guar_freq(struct drm_i915_private *dev_priv)
 -{
 -      u32 val, rp1;
 -
 -      val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE);
 -      rp1 = (val & FB_GFX_FREQ_FUSE_MASK);
 -
 -      return rp1;
 -}
 -
 -static u32 cherryview_rps_min_freq(struct drm_i915_private *dev_priv)
 -{
 -      u32 val, rpn;
 -
 -      val = vlv_punit_read(dev_priv, FB_GFX_FMIN_AT_VMIN_FUSE);
 -      rpn = ((val >> FB_GFX_FMIN_AT_VMIN_FUSE_SHIFT) &
 -                     FB_GFX_FREQ_FUSE_MASK);
 -
 -      return rpn;
 -}
 -
 -static int valleyview_rps_guar_freq(struct drm_i915_private *dev_priv)
 -{
 -      u32 val, rp1;
 -
 -      val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE);
 -
 -      rp1 = (val & FB_GFX_FGUARANTEED_FREQ_FUSE_MASK) >> FB_GFX_FGUARANTEED_FREQ_FUSE_SHIFT;
 -
 -      return rp1;
 -}
 -
 -static int valleyview_rps_max_freq(struct drm_i915_private *dev_priv)
 -{
 -      u32 val, rp0;
 -
 -      val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE);
 -
 -      rp0 = (val & FB_GFX_MAX_FREQ_FUSE_MASK) >> FB_GFX_MAX_FREQ_FUSE_SHIFT;
 -      /* Clamp to max */
 -      rp0 = min_t(u32, rp0, 0xea);
 -
 -      return rp0;
 -}
 -
 -static int valleyview_rps_rpe_freq(struct drm_i915_private *dev_priv)
 -{
 -      u32 val, rpe;
 -
 -      val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_LO);
 -      rpe = (val & FB_FMAX_VMIN_FREQ_LO_MASK) >> FB_FMAX_VMIN_FREQ_LO_SHIFT;
 -      val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_HI);
 -      rpe |= (val & FB_FMAX_VMIN_FREQ_HI_MASK) << 5;
 -
 -      return rpe;
 -}
 -
 -static int valleyview_rps_min_freq(struct drm_i915_private *dev_priv)
 -{
 -      u32 val;
 -
 -      val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) & 0xff;
 -      /*
 -       * According to the BYT Punit GPU turbo HAS 1.1.6.3 the minimum value
 -       * for the minimum frequency in GPLL mode is 0xc1. Contrary to this on
 -       * a BYT-M B0 the above register contains 0xbf. Moreover when setting
 -       * a frequency Punit will not allow values below 0xc0. Clamp it 0xc0
 -       * to make sure it matches what Punit accepts.
 -       */
 -      return max_t(u32, val, 0xc0);
 -}
 -
 -/* Check that the pctx buffer wasn't move under us. */
 -static void valleyview_check_pctx(struct drm_i915_private *dev_priv)
 -{
 -      unsigned long pctx_addr = I915_READ(VLV_PCBR) & ~4095;
 -
 -      WARN_ON(pctx_addr != dev_priv->dsm.start +
 -                           dev_priv->vlv_pctx->stolen->start);
 -}
 -
 -
 -/* Check that the pcbr address is not empty. */
 -static void cherryview_check_pctx(struct drm_i915_private *dev_priv)
 -{
 -      unsigned long pctx_addr = I915_READ(VLV_PCBR) & ~4095;
 -
 -      WARN_ON((pctx_addr >> VLV_PCBR_ADDR_SHIFT) == 0);
 -}
 -
 -static void cherryview_setup_pctx(struct drm_i915_private *dev_priv)
 -{
 -      resource_size_t pctx_paddr, paddr;
 -      resource_size_t pctx_size = 32*1024;
 -      u32 pcbr;
 -
 -      pcbr = I915_READ(VLV_PCBR);
 -      if ((pcbr >> VLV_PCBR_ADDR_SHIFT) == 0) {
 -              DRM_DEBUG_DRIVER("BIOS didn't set up PCBR, fixing up\n");
 -              paddr = dev_priv->dsm.end + 1 - pctx_size;
 -              GEM_BUG_ON(paddr > U32_MAX);
 -
 -              pctx_paddr = (paddr & (~4095));
 -              I915_WRITE(VLV_PCBR, pctx_paddr);
 -      }
 -
 -      DRM_DEBUG_DRIVER("PCBR: 0x%08x\n", I915_READ(VLV_PCBR));
 -}
 -
 -static void valleyview_setup_pctx(struct drm_i915_private *dev_priv)
 -{
 -      struct drm_i915_gem_object *pctx;
 -      resource_size_t pctx_paddr;
 -      resource_size_t pctx_size = 24*1024;
 -      u32 pcbr;
 -
 -      pcbr = I915_READ(VLV_PCBR);
 -      if (pcbr) {
 -              /* BIOS set it up already, grab the pre-alloc'd space */
 -              resource_size_t pcbr_offset;
 -
 -              pcbr_offset = (pcbr & (~4095)) - dev_priv->dsm.start;
 -              pctx = i915_gem_object_create_stolen_for_preallocated(dev_priv,
 -                                                                    pcbr_offset,
 -                                                                    I915_GTT_OFFSET_NONE,
 -                                                                    pctx_size);
 -              goto out;
 -      }
 -
 -      DRM_DEBUG_DRIVER("BIOS didn't set up PCBR, fixing up\n");
 -
 -      /*
 -       * From the Gunit register HAS:
 -       * The Gfx driver is expected to program this register and ensure
 -       * proper allocation within Gfx stolen memory.  For example, this
 -       * register should be programmed such than the PCBR range does not
 -       * overlap with other ranges, such as the frame buffer, protected
 -       * memory, or any other relevant ranges.
 -       */
 -      pctx = i915_gem_object_create_stolen(dev_priv, pctx_size);
 -      if (!pctx) {
 -              DRM_DEBUG("not enough stolen space for PCTX, disabling\n");
 -              goto out;
 -      }
 -
 -      GEM_BUG_ON(range_overflows_t(u64,
 -                                   dev_priv->dsm.start,
 -                                   pctx->stolen->start,
 -                                   U32_MAX));
 -      pctx_paddr = dev_priv->dsm.start + pctx->stolen->start;
 -      I915_WRITE(VLV_PCBR, pctx_paddr);
 -
 -out:
 -      DRM_DEBUG_DRIVER("PCBR: 0x%08x\n", I915_READ(VLV_PCBR));
 -      dev_priv->vlv_pctx = pctx;
 -}
 -
 -static void valleyview_cleanup_pctx(struct drm_i915_private *dev_priv)
 -{
 -      struct drm_i915_gem_object *pctx;
 -
 -      pctx = fetch_and_zero(&dev_priv->vlv_pctx);
 -      if (pctx)
 -              i915_gem_object_put(pctx);
 -}
 -
 -static void vlv_init_gpll_ref_freq(struct drm_i915_private *dev_priv)
 -{
 -      dev_priv->gt_pm.rps.gpll_ref_freq =
 -              vlv_get_cck_clock(dev_priv, "GPLL ref",
 -                                CCK_GPLL_CLOCK_CONTROL,
 -                                dev_priv->czclk_freq);
 -
 -      DRM_DEBUG_DRIVER("GPLL reference freq: %d kHz\n",
 -                       dev_priv->gt_pm.rps.gpll_ref_freq);
 -}
 -
 -static void valleyview_init_gt_powersave(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -      u32 val;
 -
 -      valleyview_setup_pctx(dev_priv);
 -
 -      vlv_iosf_sb_get(dev_priv,
 -                      BIT(VLV_IOSF_SB_PUNIT) |
 -                      BIT(VLV_IOSF_SB_NC) |
 -                      BIT(VLV_IOSF_SB_CCK));
 -
 -      vlv_init_gpll_ref_freq(dev_priv);
 -
 -      val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
 -      switch ((val >> 6) & 3) {
 -      case 0:
 -      case 1:
 -              dev_priv->mem_freq = 800;
 -              break;
 -      case 2:
 -              dev_priv->mem_freq = 1066;
 -              break;
 -      case 3:
 -              dev_priv->mem_freq = 1333;
 -              break;
 -      }
 -      DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq);
 -
 -      rps->max_freq = valleyview_rps_max_freq(dev_priv);
 -      rps->rp0_freq = rps->max_freq;
 -      DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
 -                       intel_gpu_freq(dev_priv, rps->max_freq),
 -                       rps->max_freq);
 -
 -      rps->efficient_freq = valleyview_rps_rpe_freq(dev_priv);
 -      DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
 -                       intel_gpu_freq(dev_priv, rps->efficient_freq),
 -                       rps->efficient_freq);
 -
 -      rps->rp1_freq = valleyview_rps_guar_freq(dev_priv);
 -      DRM_DEBUG_DRIVER("RP1(Guar Freq) GPU freq: %d MHz (%u)\n",
 -                       intel_gpu_freq(dev_priv, rps->rp1_freq),
 -                       rps->rp1_freq);
 -
 -      rps->min_freq = valleyview_rps_min_freq(dev_priv);
 -      DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
 -                       intel_gpu_freq(dev_priv, rps->min_freq),
 -                       rps->min_freq);
 -
 -      vlv_iosf_sb_put(dev_priv,
 -                      BIT(VLV_IOSF_SB_PUNIT) |
 -                      BIT(VLV_IOSF_SB_NC) |
 -                      BIT(VLV_IOSF_SB_CCK));
 -}
 -
 -static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -      u32 val;
 -
 -      cherryview_setup_pctx(dev_priv);
 -
 -      vlv_iosf_sb_get(dev_priv,
 -                      BIT(VLV_IOSF_SB_PUNIT) |
 -                      BIT(VLV_IOSF_SB_NC) |
 -                      BIT(VLV_IOSF_SB_CCK));
 -
 -      vlv_init_gpll_ref_freq(dev_priv);
 -
 -      val = vlv_cck_read(dev_priv, CCK_FUSE_REG);
 -
 -      switch ((val >> 2) & 0x7) {
 -      case 3:
 -              dev_priv->mem_freq = 2000;
 -              break;
 -      default:
 -              dev_priv->mem_freq = 1600;
 -              break;
 -      }
 -      DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq);
 -
 -      rps->max_freq = cherryview_rps_max_freq(dev_priv);
 -      rps->rp0_freq = rps->max_freq;
 -      DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
 -                       intel_gpu_freq(dev_priv, rps->max_freq),
 -                       rps->max_freq);
 -
 -      rps->efficient_freq = cherryview_rps_rpe_freq(dev_priv);
 -      DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
 -                       intel_gpu_freq(dev_priv, rps->efficient_freq),
 -                       rps->efficient_freq);
 -
 -      rps->rp1_freq = cherryview_rps_guar_freq(dev_priv);
 -      DRM_DEBUG_DRIVER("RP1(Guar) GPU freq: %d MHz (%u)\n",
 -                       intel_gpu_freq(dev_priv, rps->rp1_freq),
 -                       rps->rp1_freq);
 -
 -      rps->min_freq = cherryview_rps_min_freq(dev_priv);
 -      DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
 -                       intel_gpu_freq(dev_priv, rps->min_freq),
 -                       rps->min_freq);
 -
 -      vlv_iosf_sb_put(dev_priv,
 -                      BIT(VLV_IOSF_SB_PUNIT) |
 -                      BIT(VLV_IOSF_SB_NC) |
 -                      BIT(VLV_IOSF_SB_CCK));
 -
 -      WARN_ONCE((rps->max_freq | rps->efficient_freq | rps->rp1_freq |
 -                 rps->min_freq) & 1,
 -                "Odd GPU freq values\n");
 -}
 -
 -static void valleyview_cleanup_gt_powersave(struct drm_i915_private *dev_priv)
 -{
 -      valleyview_cleanup_pctx(dev_priv);
 -}
 -
 -static void cherryview_enable_rc6(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_engine_cs *engine;
 -      enum intel_engine_id id;
 -      u32 gtfifodbg, rc6_mode, pcbr;
 -
 -      gtfifodbg = I915_READ(GTFIFODBG) & ~(GT_FIFO_SBDEDICATE_FREE_ENTRY_CHV |
 -                                           GT_FIFO_FREE_ENTRIES_CHV);
 -      if (gtfifodbg) {
 -              DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n",
 -                               gtfifodbg);
 -              I915_WRITE(GTFIFODBG, gtfifodbg);
 -      }
 -
 -      cherryview_check_pctx(dev_priv);
 -
 -      /* 1a & 1b: Get forcewake during program sequence. Although the driver
 -       * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
 -      intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
 -
 -      /*  Disable RC states. */
 -      I915_WRITE(GEN6_RC_CONTROL, 0);
 -
 -      /* 2a: Program RC6 thresholds.*/
 -      I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
 -      I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
 -      I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
 -
 -      for_each_engine(engine, dev_priv, id)
 -              I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
 -      I915_WRITE(GEN6_RC_SLEEP, 0);
 -
 -      /* TO threshold set to 500 us ( 0x186 * 1.28 us) */
 -      I915_WRITE(GEN6_RC6_THRESHOLD, 0x186);
 -
 -      /* Allows RC6 residency counter to work */
 -      I915_WRITE(VLV_COUNTER_CONTROL,
 -                 _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH |
 -                                    VLV_MEDIA_RC6_COUNT_EN |
 -                                    VLV_RENDER_RC6_COUNT_EN));
 -
 -      /* For now we assume BIOS is allocating and populating the PCBR  */
 -      pcbr = I915_READ(VLV_PCBR);
 -
 -      /* 3: Enable RC6 */
 -      rc6_mode = 0;
 -      if (pcbr >> VLV_PCBR_ADDR_SHIFT)
 -              rc6_mode = GEN7_RC_CTL_TO_MODE;
 -      I915_WRITE(GEN6_RC_CONTROL, rc6_mode);
 -
 -      intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 -}
 -
 -static void cherryview_enable_rps(struct drm_i915_private *dev_priv)
 -{
 -      u32 val;
 -
 -      intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
 -
 -      /* 1: Program defaults and thresholds for RPS*/
 -      I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
 -      I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
 -      I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
 -      I915_WRITE(GEN6_RP_UP_EI, 66000);
 -      I915_WRITE(GEN6_RP_DOWN_EI, 350000);
 -
 -      I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
 -
 -      /* 2: Enable RPS */
 -      I915_WRITE(GEN6_RP_CONTROL,
 -                 GEN6_RP_MEDIA_HW_NORMAL_MODE |
 -                 GEN6_RP_MEDIA_IS_GFX |
 -                 GEN6_RP_ENABLE |
 -                 GEN6_RP_UP_BUSY_AVG |
 -                 GEN6_RP_DOWN_IDLE_AVG);
 -
 -      /* Setting Fixed Bias */
 -      vlv_punit_get(dev_priv);
 -
 -      val = VLV_OVERRIDE_EN | VLV_SOC_TDP_EN | CHV_BIAS_CPU_50_SOC_50;
 -      vlv_punit_write(dev_priv, VLV_TURBO_SOC_OVERRIDE, val);
 -
 -      val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
 -
 -      vlv_punit_put(dev_priv);
 -
 -      /* RPS code assumes GPLL is used */
 -      WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n");
 -
 -      DRM_DEBUG_DRIVER("GPLL enabled? %s\n", yesno(val & GPLLENABLE));
 -      DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val);
 -
 -      reset_rps(dev_priv, valleyview_set_rps);
 -
 -      intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 -}
 -
 -static void valleyview_enable_rc6(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_engine_cs *engine;
 -      enum intel_engine_id id;
 -      u32 gtfifodbg;
 -
 -      valleyview_check_pctx(dev_priv);
 -
 -      gtfifodbg = I915_READ(GTFIFODBG);
 -      if (gtfifodbg) {
 -              DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n",
 -                               gtfifodbg);
 -              I915_WRITE(GTFIFODBG, gtfifodbg);
 -      }
 -
 -      intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
 -
 -      /*  Disable RC states. */
 -      I915_WRITE(GEN6_RC_CONTROL, 0);
 -
 -      I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 0x00280000);
 -      I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000);
 -      I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25);
 -
 -      for_each_engine(engine, dev_priv, id)
 -              I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10);
 -
 -      I915_WRITE(GEN6_RC6_THRESHOLD, 0x557);
 -
 -      /* Allows RC6 residency counter to work */
 -      I915_WRITE(VLV_COUNTER_CONTROL,
 -                 _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH |
 -                                    VLV_MEDIA_RC0_COUNT_EN |
 -                                    VLV_RENDER_RC0_COUNT_EN |
 -                                    VLV_MEDIA_RC6_COUNT_EN |
 -                                    VLV_RENDER_RC6_COUNT_EN));
 -
 -      I915_WRITE(GEN6_RC_CONTROL,
 -                 GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL);
 -
 -      intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 -}
 -
 -static void valleyview_enable_rps(struct drm_i915_private *dev_priv)
 -{
 -      u32 val;
 -
 -      intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL);
 -
 -      I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
 -      I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
 -      I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
 -      I915_WRITE(GEN6_RP_UP_EI, 66000);
 -      I915_WRITE(GEN6_RP_DOWN_EI, 350000);
 -
 -      I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
 -
 -      I915_WRITE(GEN6_RP_CONTROL,
 -                 GEN6_RP_MEDIA_TURBO |
 -                 GEN6_RP_MEDIA_HW_NORMAL_MODE |
 -                 GEN6_RP_MEDIA_IS_GFX |
 -                 GEN6_RP_ENABLE |
 -                 GEN6_RP_UP_BUSY_AVG |
 -                 GEN6_RP_DOWN_IDLE_CONT);
 -
 -      vlv_punit_get(dev_priv);
 -
 -      /* Setting Fixed Bias */
 -      val = VLV_OVERRIDE_EN | VLV_SOC_TDP_EN | VLV_BIAS_CPU_125_SOC_875;
 -      vlv_punit_write(dev_priv, VLV_TURBO_SOC_OVERRIDE, val);
 -
 -      val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
 -
 -      vlv_punit_put(dev_priv);
 -
 -      /* RPS code assumes GPLL is used */
 -      WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n");
 -
 -      DRM_DEBUG_DRIVER("GPLL enabled? %s\n", yesno(val & GPLLENABLE));
 -      DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val);
 -
 -      reset_rps(dev_priv, valleyview_set_rps);
 -
 -      intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
 -}
 -
 -static unsigned long intel_pxfreq(u32 vidfreq)
 -{
 -      unsigned long freq;
 -      int div = (vidfreq & 0x3f0000) >> 16;
 -      int post = (vidfreq & 0x3000) >> 12;
 -      int pre = (vidfreq & 0x7);
 -
 -      if (!pre)
 -              return 0;
 -
 -      freq = ((div * 133333) / ((1<<post) * pre));
 -
 -      return freq;
 -}
 -
 -static const struct cparams {
 -      u16 i;
 -      u16 t;
 -      u16 m;
 -      u16 c;
 -} cparams[] = {
 -      { 1, 1333, 301, 28664 },
 -      { 1, 1066, 294, 24460 },
 -      { 1, 800, 294, 25192 },
 -      { 0, 1333, 276, 27605 },
 -      { 0, 1066, 276, 27605 },
 -      { 0, 800, 231, 23784 },
 -};
 -
 -static unsigned long __i915_chipset_val(struct drm_i915_private *dev_priv)
 -{
 -      u64 total_count, diff, ret;
 -      u32 count1, count2, count3, m = 0, c = 0;
 -      unsigned long now = jiffies_to_msecs(jiffies), diff1;
 -      int i;
 -
 -      lockdep_assert_held(&mchdev_lock);
 -
 -      diff1 = now - dev_priv->ips.last_time1;
 -
 -      /* Prevent division-by-zero if we are asking too fast.
 -       * Also, we don't get interesting results if we are polling
 -       * faster than once in 10ms, so just return the saved value
 -       * in such cases.
 -       */
 -      if (diff1 <= 10)
 -              return dev_priv->ips.chipset_power;
 -
 -      count1 = I915_READ(DMIEC);
 -      count2 = I915_READ(DDREC);
 -      count3 = I915_READ(CSIEC);
 -
 -      total_count = count1 + count2 + count3;
 -
 -      /* FIXME: handle per-counter overflow */
 -      if (total_count < dev_priv->ips.last_count1) {
 -              diff = ~0UL - dev_priv->ips.last_count1;
 -              diff += total_count;
 -      } else {
 -              diff = total_count - dev_priv->ips.last_count1;
 -      }
 -
 -      for (i = 0; i < ARRAY_SIZE(cparams); i++) {
 -              if (cparams[i].i == dev_priv->ips.c_m &&
 -                  cparams[i].t == dev_priv->ips.r_t) {
 -                      m = cparams[i].m;
 -                      c = cparams[i].c;
 -                      break;
 -              }
 -      }
 -
 -      diff = div_u64(diff, diff1);
 -      ret = ((m * diff) + c);
 -      ret = div_u64(ret, 10);
 -
 -      dev_priv->ips.last_count1 = total_count;
 -      dev_priv->ips.last_time1 = now;
 -
 -      dev_priv->ips.chipset_power = ret;
 -
 -      return ret;
 -}
 -
 -unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
 -{
 -      intel_wakeref_t wakeref;
 -      unsigned long val = 0;
 -
 -      if (!IS_GEN(dev_priv, 5))
 -              return 0;
 -
 -      with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) {
 -              spin_lock_irq(&mchdev_lock);
 -              val = __i915_chipset_val(dev_priv);
 -              spin_unlock_irq(&mchdev_lock);
 -      }
 -
 -      return val;
 -}
 -
 -unsigned long i915_mch_val(struct drm_i915_private *i915)
 -{
 -      unsigned long m, x, b;
 -      u32 tsfs;
 -
 -      tsfs = intel_uncore_read(&i915->uncore, TSFS);
 -
 -      m = ((tsfs & TSFS_SLOPE_MASK) >> TSFS_SLOPE_SHIFT);
 -      x = intel_uncore_read8(&i915->uncore, TR1);
 -
 -      b = tsfs & TSFS_INTR_MASK;
 -
 -      return ((m * x) / 127) - b;
 -}
 -
 -static int _pxvid_to_vd(u8 pxvid)
 -{
 -      if (pxvid == 0)
 -              return 0;
 -
 -      if (pxvid >= 8 && pxvid < 31)
 -              pxvid = 31;
 -
 -      return (pxvid + 2) * 125;
 -}
 -
 -static u32 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
 -{
 -      const int vd = _pxvid_to_vd(pxvid);
 -      const int vm = vd - 1125;
 -
 -      if (INTEL_INFO(dev_priv)->is_mobile)
 -              return vm > 0 ? vm : 0;
 -
 -      return vd;
 -}
 -
 -static void __i915_update_gfx_val(struct drm_i915_private *dev_priv)
 -{
 -      u64 now, diff, diffms;
 -      u32 count;
 -
 -      lockdep_assert_held(&mchdev_lock);
 -
 -      now = ktime_get_raw_ns();
 -      diffms = now - dev_priv->ips.last_time2;
 -      do_div(diffms, NSEC_PER_MSEC);
 -
 -      /* Don't divide by 0 */
 -      if (!diffms)
 -              return;
 -
 -      count = I915_READ(GFXEC);
 -
 -      if (count < dev_priv->ips.last_count2) {
 -              diff = ~0UL - dev_priv->ips.last_count2;
 -              diff += count;
 -      } else {
 -              diff = count - dev_priv->ips.last_count2;
 -      }
 -
 -      dev_priv->ips.last_count2 = count;
 -      dev_priv->ips.last_time2 = now;
 -
 -      /* More magic constants... */
 -      diff = diff * 1181;
 -      diff = div_u64(diff, diffms * 10);
 -      dev_priv->ips.gfx_power = diff;
 -}
 -
 -void i915_update_gfx_val(struct drm_i915_private *dev_priv)
 -{
 -      intel_wakeref_t wakeref;
 -
 -      if (!IS_GEN(dev_priv, 5))
 -              return;
 -
 -      with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) {
 -              spin_lock_irq(&mchdev_lock);
 -              __i915_update_gfx_val(dev_priv);
 -              spin_unlock_irq(&mchdev_lock);
 -      }
 -}
 -
 -static unsigned long __i915_gfx_val(struct drm_i915_private *dev_priv)
 -{
 -      unsigned long t, corr, state1, corr2, state2;
 -      u32 pxvid, ext_v;
 -
 -      lockdep_assert_held(&mchdev_lock);
 -
 -      pxvid = I915_READ(PXVFREQ(dev_priv->gt_pm.rps.cur_freq));
 -      pxvid = (pxvid >> 24) & 0x7f;
 -      ext_v = pvid_to_extvid(dev_priv, pxvid);
 -
 -      state1 = ext_v;
 -
 -      t = i915_mch_val(dev_priv);
 -
 -      /* Revel in the empirically derived constants */
 -
 -      /* Correction factor in 1/100000 units */
 -      if (t > 80)
 -              corr = ((t * 2349) + 135940);
 -      else if (t >= 50)
 -              corr = ((t * 964) + 29317);
 -      else /* < 50 */
 -              corr = ((t * 301) + 1004);
 -
 -      corr = corr * ((150142 * state1) / 10000 - 78642);
 -      corr /= 100000;
 -      corr2 = (corr * dev_priv->ips.corr);
 -
 -      state2 = (corr2 * state1) / 10000;
 -      state2 /= 100; /* convert to mW */
 -
 -      __i915_update_gfx_val(dev_priv);
 -
 -      return dev_priv->ips.gfx_power + state2;
 -}
 -
 -unsigned long i915_gfx_val(struct drm_i915_private *dev_priv)
 -{
 -      intel_wakeref_t wakeref;
 -      unsigned long val = 0;
 -
 -      if (!IS_GEN(dev_priv, 5))
 -              return 0;
 -
 -      with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) {
 -              spin_lock_irq(&mchdev_lock);
 -              val = __i915_gfx_val(dev_priv);
 -              spin_unlock_irq(&mchdev_lock);
 -      }
 -
 -      return val;
 -}
 -
 -static struct drm_i915_private __rcu *i915_mch_dev;
 -
 -static struct drm_i915_private *mchdev_get(void)
 -{
 -      struct drm_i915_private *i915;
 -
 -      rcu_read_lock();
 -      i915 = rcu_dereference(i915_mch_dev);
 -      if (!kref_get_unless_zero(&i915->drm.ref))
 -              i915 = NULL;
 -      rcu_read_unlock();
 -
 -      return i915;
 -}
 -
 -/**
 - * i915_read_mch_val - return value for IPS use
 - *
 - * Calculate and return a value for the IPS driver to use when deciding whether
 - * we have thermal and power headroom to increase CPU or GPU power budget.
 - */
 -unsigned long i915_read_mch_val(void)
 -{
 -      struct drm_i915_private *i915;
 -      unsigned long chipset_val = 0;
 -      unsigned long graphics_val = 0;
 -      intel_wakeref_t wakeref;
 -
 -      i915 = mchdev_get();
 -      if (!i915)
 -              return 0;
 -
 -      with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
 -              spin_lock_irq(&mchdev_lock);
 -              chipset_val = __i915_chipset_val(i915);
 -              graphics_val = __i915_gfx_val(i915);
 -              spin_unlock_irq(&mchdev_lock);
 -      }
 -
 -      drm_dev_put(&i915->drm);
 -      return chipset_val + graphics_val;
 -}
 -EXPORT_SYMBOL_GPL(i915_read_mch_val);
 -
 -/**
 - * i915_gpu_raise - raise GPU frequency limit
 - *
 - * Raise the limit; IPS indicates we have thermal headroom.
 - */
 -bool i915_gpu_raise(void)
 -{
 -      struct drm_i915_private *i915;
 -
 -      i915 = mchdev_get();
 -      if (!i915)
 -              return false;
 -
 -      spin_lock_irq(&mchdev_lock);
 -      if (i915->ips.max_delay > i915->ips.fmax)
 -              i915->ips.max_delay--;
 -      spin_unlock_irq(&mchdev_lock);
 -
 -      drm_dev_put(&i915->drm);
 -      return true;
 -}
 -EXPORT_SYMBOL_GPL(i915_gpu_raise);
 -
 -/**
 - * i915_gpu_lower - lower GPU frequency limit
 - *
 - * IPS indicates we're close to a thermal limit, so throttle back the GPU
 - * frequency maximum.
 - */
 -bool i915_gpu_lower(void)
 -{
 -      struct drm_i915_private *i915;
 -
 -      i915 = mchdev_get();
 -      if (!i915)
 -              return false;
 -
 -      spin_lock_irq(&mchdev_lock);
 -      if (i915->ips.max_delay < i915->ips.min_delay)
 -              i915->ips.max_delay++;
 -      spin_unlock_irq(&mchdev_lock);
 -
 -      drm_dev_put(&i915->drm);
 -      return true;
 -}
 -EXPORT_SYMBOL_GPL(i915_gpu_lower);
 -
 -/**
 - * i915_gpu_busy - indicate GPU business to IPS
 - *
 - * Tell the IPS driver whether or not the GPU is busy.
 - */
 -bool i915_gpu_busy(void)
 -{
 -      struct drm_i915_private *i915;
 -      bool ret;
 -
 -      i915 = mchdev_get();
 -      if (!i915)
 -              return false;
 -
 -      ret = i915->gt.awake;
 -
 -      drm_dev_put(&i915->drm);
 -      return ret;
 -}
 -EXPORT_SYMBOL_GPL(i915_gpu_busy);
 -
 -/**
 - * i915_gpu_turbo_disable - disable graphics turbo
 - *
 - * Disable graphics turbo by resetting the max frequency and setting the
 - * current frequency to the default.
 - */
 -bool i915_gpu_turbo_disable(void)
 -{
 -      struct drm_i915_private *i915;
 -      bool ret;
 -
 -      i915 = mchdev_get();
 -      if (!i915)
 -              return false;
 -
 -      spin_lock_irq(&mchdev_lock);
 -      i915->ips.max_delay = i915->ips.fstart;
 -      ret = ironlake_set_drps(i915, i915->ips.fstart);
 -      spin_unlock_irq(&mchdev_lock);
 -
 -      drm_dev_put(&i915->drm);
 -      return ret;
 -}
 -EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable);
 -
 -/**
 - * Tells the intel_ips driver that the i915 driver is now loaded, if
 - * IPS got loaded first.
 - *
 - * This awkward dance is so that neither module has to depend on the
 - * other in order for IPS to do the appropriate communication of
 - * GPU turbo limits to i915.
 - */
 -static void
 -ips_ping_for_i915_load(void)
 -{
 -      void (*link)(void);
 -
 -      link = symbol_get(ips_link_to_i915_driver);
 -      if (link) {
 -              link();
 -              symbol_put(ips_link_to_i915_driver);
 -      }
 -}
 -
 -void intel_gpu_ips_init(struct drm_i915_private *dev_priv)
 -{
 -      /* We only register the i915 ips part with intel-ips once everything is
 -       * set up, to avoid intel-ips sneaking in and reading bogus values. */
 -      rcu_assign_pointer(i915_mch_dev, dev_priv);
 -
 -      ips_ping_for_i915_load();
 -}
 -
 -void intel_gpu_ips_teardown(void)
 -{
 -      rcu_assign_pointer(i915_mch_dev, NULL);
 -}
 -
 -static void intel_init_emon(struct drm_i915_private *dev_priv)
 -{
 -      u32 lcfuse;
 -      u8 pxw[16];
 -      int i;
 -
 -      /* Disable to program */
 -      I915_WRITE(ECR, 0);
 -      POSTING_READ(ECR);
 -
 -      /* Program energy weights for various events */
 -      I915_WRITE(SDEW, 0x15040d00);
 -      I915_WRITE(CSIEW0, 0x007f0000);
 -      I915_WRITE(CSIEW1, 0x1e220004);
 -      I915_WRITE(CSIEW2, 0x04000004);
 -
 -      for (i = 0; i < 5; i++)
 -              I915_WRITE(PEW(i), 0);
 -      for (i = 0; i < 3; i++)
 -              I915_WRITE(DEW(i), 0);
 -
 -      /* Program P-state weights to account for frequency power adjustment */
 -      for (i = 0; i < 16; i++) {
 -              u32 pxvidfreq = I915_READ(PXVFREQ(i));
 -              unsigned long freq = intel_pxfreq(pxvidfreq);
 -              unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >>
 -                      PXVFREQ_PX_SHIFT;
 -              unsigned long val;
 -
 -              val = vid * vid;
 -              val *= (freq / 1000);
 -              val *= 255;
 -              val /= (127*127*900);
 -              if (val > 0xff)
 -                      DRM_ERROR("bad pxval: %ld\n", val);
 -              pxw[i] = val;
 -      }
 -      /* Render standby states get 0 weight */
 -      pxw[14] = 0;
 -      pxw[15] = 0;
 -
 -      for (i = 0; i < 4; i++) {
 -              u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) |
 -                      (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]);
 -              I915_WRITE(PXW(i), val);
 -      }
 -
 -      /* Adjust magic regs to magic values (more experimental results) */
 -      I915_WRITE(OGW0, 0);
 -      I915_WRITE(OGW1, 0);
 -      I915_WRITE(EG0, 0x00007f00);
 -      I915_WRITE(EG1, 0x0000000e);
 -      I915_WRITE(EG2, 0x000e0000);
 -      I915_WRITE(EG3, 0x68000300);
 -      I915_WRITE(EG4, 0x42000000);
 -      I915_WRITE(EG5, 0x00140031);
 -      I915_WRITE(EG6, 0);
 -      I915_WRITE(EG7, 0);
 -
 -      for (i = 0; i < 8; i++)
 -              I915_WRITE(PXWL(i), 0);
 -
 -      /* Enable PMON + select events */
 -      I915_WRITE(ECR, 0x80000019);
 -
 -      lcfuse = I915_READ(LCFUSE02);
 -
 -      dev_priv->ips.corr = (lcfuse & LCFUSE_HIV_MASK);
 -}
 -
 -static bool i915_rc6_ctx_corrupted(struct drm_i915_private *dev_priv)
 -{
 -      return !I915_READ(GEN8_RC6_CTX_INFO);
 -}
 -
 -static void i915_rc6_ctx_wa_init(struct drm_i915_private *i915)
 -{
 -      if (!NEEDS_RC6_CTX_CORRUPTION_WA(i915))
 -              return;
 -
 -      if (i915_rc6_ctx_corrupted(i915)) {
 -              DRM_INFO("RC6 context corrupted, disabling runtime power management\n");
 -              i915->gt_pm.rc6.ctx_corrupted = true;
 -              i915->gt_pm.rc6.ctx_corrupted_wakeref =
 -                      intel_runtime_pm_get(&i915->runtime_pm);
 -      }
 -}
 -
 -static void i915_rc6_ctx_wa_cleanup(struct drm_i915_private *i915)
 -{
 -      if (i915->gt_pm.rc6.ctx_corrupted) {
 -              intel_runtime_pm_put(&i915->runtime_pm,
 -                                   i915->gt_pm.rc6.ctx_corrupted_wakeref);
 -              i915->gt_pm.rc6.ctx_corrupted = false;
 -      }
 -}
 -
 -/**
 - * i915_rc6_ctx_wa_suspend - system suspend sequence for the RC6 CTX WA
 - * @i915: i915 device
 - *
 - * Perform any steps needed to clean up the RC6 CTX WA before system suspend.
 - */
 -void i915_rc6_ctx_wa_suspend(struct drm_i915_private *i915)
 -{
 -      if (i915->gt_pm.rc6.ctx_corrupted)
 -              intel_runtime_pm_put(&i915->runtime_pm,
 -                                   i915->gt_pm.rc6.ctx_corrupted_wakeref);
 -}
 -
 -/**
 - * i915_rc6_ctx_wa_resume - system resume sequence for the RC6 CTX WA
 - * @i915: i915 device
 - *
 - * Perform any steps needed to re-init the RC6 CTX WA after system resume.
 - */
 -void i915_rc6_ctx_wa_resume(struct drm_i915_private *i915)
 -{
 -      if (!i915->gt_pm.rc6.ctx_corrupted)
 -              return;
 -
 -      if (i915_rc6_ctx_corrupted(i915)) {
 -              i915->gt_pm.rc6.ctx_corrupted_wakeref =
 -                      intel_runtime_pm_get(&i915->runtime_pm);
 -              return;
 -      }
 -
 -      DRM_INFO("RC6 context restored, re-enabling runtime power management\n");
 -      i915->gt_pm.rc6.ctx_corrupted = false;
 -}
 -
 -static void intel_disable_rc6(struct drm_i915_private *dev_priv);
 -
 -/**
 - * i915_rc6_ctx_wa_check - check for a new RC6 CTX corruption
 - * @i915: i915 device
 - *
 - * Check if an RC6 CTX corruption has happened since the last check and if so
 - * disable RC6 and runtime power management.
 - *
 - * Return false if no context corruption has happened since the last call of
 - * this function, true otherwise.
 -*/
 -bool i915_rc6_ctx_wa_check(struct drm_i915_private *i915)
 -{
 -      if (!NEEDS_RC6_CTX_CORRUPTION_WA(i915))
 -              return false;
 -
 -      if (i915->gt_pm.rc6.ctx_corrupted)
 -              return false;
 -
 -      if (!i915_rc6_ctx_corrupted(i915))
 -              return false;
 -
 -      DRM_NOTE("RC6 context corruption, disabling runtime power management\n");
 -
 -      intel_disable_rc6(i915);
 -      i915->gt_pm.rc6.ctx_corrupted = true;
 -      i915->gt_pm.rc6.ctx_corrupted_wakeref =
 -              intel_runtime_pm_get_noresume(&i915->runtime_pm);
 -
 -      return true;
 -}
 -
 -void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -
 -      /*
 -       * RPM depends on RC6 to save restore the GT HW context, so make RC6 a
 -       * requirement.
 -       */
 -      if (!sanitize_rc6(dev_priv)) {
 -              DRM_INFO("RC6 disabled, disabling runtime PM support\n");
 -              pm_runtime_get(&dev_priv->drm.pdev->dev);
 -      }
 -
 -      i915_rc6_ctx_wa_init(dev_priv);
 -
 -      /* Initialize RPS limits (for userspace) */
 -      if (IS_CHERRYVIEW(dev_priv))
 -              cherryview_init_gt_powersave(dev_priv);
 -      else if (IS_VALLEYVIEW(dev_priv))
 -              valleyview_init_gt_powersave(dev_priv);
 -      else if (INTEL_GEN(dev_priv) >= 6)
 -              gen6_init_rps_frequencies(dev_priv);
 -
 -      /* Derive initial user preferences/limits from the hardware limits */
 -      rps->max_freq_softlimit = rps->max_freq;
 -      rps->min_freq_softlimit = rps->min_freq;
 -
 -      /* After setting max-softlimit, find the overclock max freq */
 -      if (IS_GEN(dev_priv, 6) ||
 -          IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) {
 -              u32 params = 0;
 -
 -              sandybridge_pcode_read(dev_priv, GEN6_READ_OC_PARAMS,
 -                                     &params, NULL);
 -              if (params & BIT(31)) { /* OC supported */
 -                      DRM_DEBUG_DRIVER("Overclocking supported, max: %dMHz, overclock: %dMHz\n",
 -                                       (rps->max_freq & 0xff) * 50,
 -                                       (params & 0xff) * 50);
 -                      rps->max_freq = params & 0xff;
 -              }
 -      }
 -
 -      /* Finally allow us to boost to max by default */
 -      rps->boost_freq = rps->max_freq;
 -      rps->idle_freq = rps->min_freq;
 -      rps->cur_freq = rps->idle_freq;
 -}
 -
 -void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv)
 -{
 -      if (IS_VALLEYVIEW(dev_priv))
 -              valleyview_cleanup_gt_powersave(dev_priv);
 -
 -      i915_rc6_ctx_wa_cleanup(dev_priv);
 -
 -      if (!HAS_RC6(dev_priv))
 -              pm_runtime_put(&dev_priv->drm.pdev->dev);
 -}
 -
 -void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv)
 -{
 -      dev_priv->gt_pm.rps.enabled = true; /* force RPS disabling */
 -      dev_priv->gt_pm.rc6.enabled = true; /* force RC6 disabling */
 -      intel_disable_gt_powersave(dev_priv);
 -
 -      if (INTEL_GEN(dev_priv) >= 11)
 -              gen11_reset_rps_interrupts(dev_priv);
 -      else if (INTEL_GEN(dev_priv) >= 6)
 -              gen6_reset_rps_interrupts(dev_priv);
 -}
 -
 -static inline void intel_disable_llc_pstate(struct drm_i915_private *i915)
 -{
 -      lockdep_assert_held(&i915->gt_pm.rps.lock);
 -
 -      if (!i915->gt_pm.llc_pstate.enabled)
 -              return;
 -
 -      /* Currently there is no HW configuration to be done to disable. */
 -
 -      i915->gt_pm.llc_pstate.enabled = false;
 -}
 -
 -static void __intel_disable_rc6(struct drm_i915_private *dev_priv)
 -{
 -      lockdep_assert_held(&dev_priv->gt_pm.rps.lock);
 -
 -      if (!dev_priv->gt_pm.rc6.enabled)
 -              return;
 -
 -      if (INTEL_GEN(dev_priv) >= 9)
 -              gen9_disable_rc6(dev_priv);
 -      else if (IS_CHERRYVIEW(dev_priv))
 -              cherryview_disable_rc6(dev_priv);
 -      else if (IS_VALLEYVIEW(dev_priv))
 -              valleyview_disable_rc6(dev_priv);
 -      else if (INTEL_GEN(dev_priv) >= 6)
 -              gen6_disable_rc6(dev_priv);
 -
 -      dev_priv->gt_pm.rc6.enabled = false;
 -}
 -
 -static void intel_disable_rc6(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -
 -      mutex_lock(&rps->lock);
 -      __intel_disable_rc6(dev_priv);
 -      mutex_unlock(&rps->lock);
 -}
 -
 -static void intel_disable_rps(struct drm_i915_private *dev_priv)
 -{
 -      lockdep_assert_held(&dev_priv->gt_pm.rps.lock);
 -
 -      if (!dev_priv->gt_pm.rps.enabled)
 -              return;
 -
 -      if (INTEL_GEN(dev_priv) >= 9)
 -              gen9_disable_rps(dev_priv);
 -      else if (IS_CHERRYVIEW(dev_priv))
 -              cherryview_disable_rps(dev_priv);
 -      else if (IS_VALLEYVIEW(dev_priv))
 -              valleyview_disable_rps(dev_priv);
 -      else if (INTEL_GEN(dev_priv) >= 6)
 -              gen6_disable_rps(dev_priv);
 -      else if (IS_IRONLAKE_M(dev_priv))
 -              ironlake_disable_drps(dev_priv);
 -
 -      dev_priv->gt_pm.rps.enabled = false;
 -}
 -
 -void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
 -{
 -      mutex_lock(&dev_priv->gt_pm.rps.lock);
 -
 -      __intel_disable_rc6(dev_priv);
 -      intel_disable_rps(dev_priv);
 -      if (HAS_LLC(dev_priv))
 -              intel_disable_llc_pstate(dev_priv);
 -
 -      mutex_unlock(&dev_priv->gt_pm.rps.lock);
 -}
 -
 -static inline void intel_enable_llc_pstate(struct drm_i915_private *i915)
 -{
 -      lockdep_assert_held(&i915->gt_pm.rps.lock);
 -
 -      if (i915->gt_pm.llc_pstate.enabled)
 -              return;
 -
 -      gen6_update_ring_freq(i915);
 -
 -      i915->gt_pm.llc_pstate.enabled = true;
 -}
 -
 -static void intel_enable_rc6(struct drm_i915_private *dev_priv)
 -{
 -      lockdep_assert_held(&dev_priv->gt_pm.rps.lock);
 -
 -      if (dev_priv->gt_pm.rc6.enabled)
 -              return;
 -
 -      if (dev_priv->gt_pm.rc6.ctx_corrupted)
 -              return;
 -
 -      if (IS_CHERRYVIEW(dev_priv))
 -              cherryview_enable_rc6(dev_priv);
 -      else if (IS_VALLEYVIEW(dev_priv))
 -              valleyview_enable_rc6(dev_priv);
 -      else if (INTEL_GEN(dev_priv) >= 11)
 -              gen11_enable_rc6(dev_priv);
 -      else if (INTEL_GEN(dev_priv) >= 9)
 -              gen9_enable_rc6(dev_priv);
 -      else if (IS_BROADWELL(dev_priv))
 -              gen8_enable_rc6(dev_priv);
 -      else if (INTEL_GEN(dev_priv) >= 6)
 -              gen6_enable_rc6(dev_priv);
 -
 -      dev_priv->gt_pm.rc6.enabled = true;
 -}
 -
 -static void intel_enable_rps(struct drm_i915_private *dev_priv)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -
 -      lockdep_assert_held(&rps->lock);
 -
 -      if (rps->enabled)
 -              return;
 -
 -      if (IS_CHERRYVIEW(dev_priv)) {
 -              cherryview_enable_rps(dev_priv);
 -      } else if (IS_VALLEYVIEW(dev_priv)) {
 -              valleyview_enable_rps(dev_priv);
 -      } else if (INTEL_GEN(dev_priv) >= 9) {
 -              gen9_enable_rps(dev_priv);
 -      } else if (IS_BROADWELL(dev_priv)) {
 -              gen8_enable_rps(dev_priv);
 -      } else if (INTEL_GEN(dev_priv) >= 6) {
 -              gen6_enable_rps(dev_priv);
 -      } else if (IS_IRONLAKE_M(dev_priv)) {
 -              ironlake_enable_drps(dev_priv);
 -              intel_init_emon(dev_priv);
 -      }
 -
 -      WARN_ON(rps->max_freq < rps->min_freq);
 -      WARN_ON(rps->idle_freq > rps->max_freq);
 -
 -      WARN_ON(rps->efficient_freq < rps->min_freq);
 -      WARN_ON(rps->efficient_freq > rps->max_freq);
 -
 -      rps->enabled = true;
 -}
 -
 -void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
 -{
 -      /* Powersaving is controlled by the host when inside a VM */
 -      if (intel_vgpu_active(dev_priv))
 -              return;
 -
 -      mutex_lock(&dev_priv->gt_pm.rps.lock);
 -
 -      if (HAS_RC6(dev_priv))
 -              intel_enable_rc6(dev_priv);
 -      if (HAS_RPS(dev_priv))
 -              intel_enable_rps(dev_priv);
 -      if (HAS_LLC(dev_priv))
 -              intel_enable_llc_pstate(dev_priv);
 -
 -      mutex_unlock(&dev_priv->gt_pm.rps.lock);
 -}
 -
 -static void ibx_init_clock_gating(struct drm_i915_private *dev_priv)
 -{
 -      /*
 -       * On Ibex Peak and Cougar Point, we need to disable clock
 -       * gating for the panel power sequencer or it will fail to
 -       * start up when no ports are active.
 -       */
 -      I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
 -}
 -
 -static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv)
 -{
 -      enum pipe pipe;
 -
 -      for_each_pipe(dev_priv, pipe) {
 -              I915_WRITE(DSPCNTR(pipe),
 -                         I915_READ(DSPCNTR(pipe)) |
 -                         DISPPLANE_TRICKLE_FEED_DISABLE);
 -
 -              I915_WRITE(DSPSURF(pipe), I915_READ(DSPSURF(pipe)));
 -              POSTING_READ(DSPSURF(pipe));
 -      }
 -}
 -
 -static void ilk_init_clock_gating(struct drm_i915_private *dev_priv)
 -{
 -      u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE;
 -
 -      /*
 -       * Required for FBC
 -       * WaFbcDisableDpfcClockGating:ilk
 -       */
 -      dspclk_gate |= ILK_DPFCRUNIT_CLOCK_GATE_DISABLE |
 -                 ILK_DPFCUNIT_CLOCK_GATE_DISABLE |
 -                 ILK_DPFDUNIT_CLOCK_GATE_ENABLE;
 -
 -      I915_WRITE(PCH_3DCGDIS0,
 -                 MARIUNIT_CLOCK_GATE_DISABLE |
 -                 SVSMUNIT_CLOCK_GATE_DISABLE);
 -      I915_WRITE(PCH_3DCGDIS1,
 -                 VFMUNIT_CLOCK_GATE_DISABLE);
 -
 -      /*
 -       * According to the spec the following bits should be set in
 -       * order to enable memory self-refresh
 -       * The bit 22/21 of 0x42004
 -       * The bit 5 of 0x42020
 -       * The bit 15 of 0x45000
 -       */
 -      I915_WRITE(ILK_DISPLAY_CHICKEN2,
 -                 (I915_READ(ILK_DISPLAY_CHICKEN2) |
 -                  ILK_DPARB_GATE | ILK_VSDPFD_FULL));
 -      dspclk_gate |= ILK_DPARBUNIT_CLOCK_GATE_ENABLE;
 -      I915_WRITE(DISP_ARB_CTL,
 -                 (I915_READ(DISP_ARB_CTL) |
 -                  DISP_FBC_WM_DIS));
 -
 -      /*
 -       * Based on the document from hardware guys the following bits
 -       * should be set unconditionally in order to enable FBC.
 -       * The bit 22 of 0x42000
 -       * The bit 22 of 0x42004
 -       * The bit 7,8,9 of 0x42020.
 -       */
 -      if (IS_IRONLAKE_M(dev_priv)) {
 -              /* WaFbcAsynchFlipDisableFbcQueue:ilk */
 -              I915_WRITE(ILK_DISPLAY_CHICKEN1,
 -                         I915_READ(ILK_DISPLAY_CHICKEN1) |
 -                         ILK_FBCQ_DIS);
 -              I915_WRITE(ILK_DISPLAY_CHICKEN2,
 -                         I915_READ(ILK_DISPLAY_CHICKEN2) |
 -                         ILK_DPARB_GATE);
 -      }
 -
 -      I915_WRITE(ILK_DSPCLK_GATE_D, dspclk_gate);
 -
 -      I915_WRITE(ILK_DISPLAY_CHICKEN2,
 -                 I915_READ(ILK_DISPLAY_CHICKEN2) |
 -                 ILK_ELPIN_409_SELECT);
 -      I915_WRITE(_3D_CHICKEN2,
 -                 _3D_CHICKEN2_WM_READ_PIPELINED << 16 |
 -                 _3D_CHICKEN2_WM_READ_PIPELINED);
 -
 -      /* WaDisableRenderCachePipelinedFlush:ilk */
 -      I915_WRITE(CACHE_MODE_0,
 -                 _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE));
 -
 -      /* WaDisable_RenderCache_OperationalFlush:ilk */
 -      I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
 -
 -      g4x_disable_trickle_feed(dev_priv);
 -
 -      ibx_init_clock_gating(dev_priv);
 -}
 -
 -static void cpt_init_clock_gating(struct drm_i915_private *dev_priv)
 -{
 -      int pipe;
 -      u32 val;
 +      enum pipe pipe;
 +      u32 val;
  
        /*
         * On Ibex Peak and Cougar Point, we need to disable clock
@@@ -6559,22 -9196,6 +6567,22 @@@ static void icl_init_clock_gating(struc
                   _MASKED_BIT_ENABLE(GEN11_ENABLE_32_PLANE_MODE));
  }
  
 +static void tgl_init_clock_gating(struct drm_i915_private *dev_priv)
 +{
 +      u32 vd_pg_enable = 0;
 +      unsigned int i;
 +
 +      /* This is not a WA. Enable VD HCP & MFX_ENC powergate */
 +      for (i = 0; i < I915_MAX_VCS; i++) {
 +              if (HAS_ENGINE(dev_priv, _VCS(i)))
 +                      vd_pg_enable |= VDN_HCP_POWERGATE_ENABLE(i) |
 +                                      VDN_MFX_POWERGATE_ENABLE(i);
 +      }
 +
 +      I915_WRITE(POWERGATE_ENABLE,
 +                 I915_READ(POWERGATE_ENABLE) | vd_pg_enable);
 +}
 +
  static void cnp_init_clock_gating(struct drm_i915_private *dev_priv)
  {
        if (!HAS_PCH_CNP(dev_priv))
@@@ -7095,7 -9716,7 +7103,7 @@@ static void nop_init_clock_gating(struc
  void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv)
  {
        if (IS_GEN(dev_priv, 12))
 -              dev_priv->display.init_clock_gating = nop_init_clock_gating;
 +              dev_priv->display.init_clock_gating = tgl_init_clock_gating;
        else if (IS_GEN(dev_priv, 11))
                dev_priv->display.init_clock_gating = icl_init_clock_gating;
        else if (IS_CANNONLAKE(dev_priv))
@@@ -7151,9 -9772,6 +7159,9 @@@ void intel_init_pm(struct drm_i915_priv
        else if (IS_GEN(dev_priv, 5))
                i915_ironlake_get_mem_freq(dev_priv);
  
 +      if (intel_has_sagv(dev_priv))
 +              skl_setup_sagv_block_time(dev_priv);
 +
        /* For FIFO watermark updates */
        if (INTEL_GEN(dev_priv) >= 9) {
                skl_setup_wm_latency(dev_priv);
                dev_priv->display.update_wm = i9xx_update_wm;
                dev_priv->display.get_fifo_size = i9xx_get_fifo_size;
        } else if (IS_GEN(dev_priv, 2)) {
 -              if (INTEL_INFO(dev_priv)->num_pipes == 1) {
 +              if (INTEL_NUM_PIPES(dev_priv) == 1) {
                        dev_priv->display.update_wm = i845_update_wm;
                        dev_priv->display.get_fifo_size = i845_get_fifo_size;
                } else {
        }
  }
  
 -static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -
 -      /*
 -       * N = val - 0xb7
 -       * Slow = Fast = GPLL ref * N
 -       */
 -      return DIV_ROUND_CLOSEST(rps->gpll_ref_freq * (val - 0xb7), 1000);
 -}
 -
 -static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -
 -      return DIV_ROUND_CLOSEST(1000 * val, rps->gpll_ref_freq) + 0xb7;
 -}
 -
 -static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -
 -      /*
 -       * N = val / 2
 -       * CU (slow) = CU2x (fast) / 2 = GPLL ref * N / 2
 -       */
 -      return DIV_ROUND_CLOSEST(rps->gpll_ref_freq * val, 2 * 2 * 1000);
 -}
 -
 -static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
 -{
 -      struct intel_rps *rps = &dev_priv->gt_pm.rps;
 -
 -      /* CHV needs even values */
 -      return DIV_ROUND_CLOSEST(2 * 1000 * val, rps->gpll_ref_freq) * 2;
 -}
 -
 -int intel_gpu_freq(struct drm_i915_private *dev_priv, int val)
 -{
 -      if (INTEL_GEN(dev_priv) >= 9)
 -              return DIV_ROUND_CLOSEST(val * GT_FREQUENCY_MULTIPLIER,
 -                                       GEN9_FREQ_SCALER);
 -      else if (IS_CHERRYVIEW(dev_priv))
 -              return chv_gpu_freq(dev_priv, val);
 -      else if (IS_VALLEYVIEW(dev_priv))
 -              return byt_gpu_freq(dev_priv, val);
 -      else
 -              return val * GT_FREQUENCY_MULTIPLIER;
 -}
 -
 -int intel_freq_opcode(struct drm_i915_private *dev_priv, int val)
 -{
 -      if (INTEL_GEN(dev_priv) >= 9)
 -              return DIV_ROUND_CLOSEST(val * GEN9_FREQ_SCALER,
 -                                       GT_FREQUENCY_MULTIPLIER);
 -      else if (IS_CHERRYVIEW(dev_priv))
 -              return chv_freq_opcode(dev_priv, val);
 -      else if (IS_VALLEYVIEW(dev_priv))
 -              return byt_freq_opcode(dev_priv, val);
 -      else
 -              return DIV_ROUND_CLOSEST(val, GT_FREQUENCY_MULTIPLIER);
 -}
 -
  void intel_pm_setup(struct drm_i915_private *dev_priv)
  {
 -      mutex_init(&dev_priv->gt_pm.rps.lock);
 -      mutex_init(&dev_priv->gt_pm.rps.power.mutex);
 -
 -      atomic_set(&dev_priv->gt_pm.rps.num_waiters, 0);
 -
        dev_priv->runtime_pm.suspended = false;
        atomic_set(&dev_priv->runtime_pm.wakeref_count, 0);
  }
 -
 -static u64 vlv_residency_raw(struct drm_i915_private *dev_priv,
 -                           const i915_reg_t reg)
 -{
 -      u32 lower, upper, tmp;
 -      int loop = 2;
 -
 -      /*
 -       * The register accessed do not need forcewake. We borrow
 -       * uncore lock to prevent concurrent access to range reg.
 -       */
 -      lockdep_assert_held(&dev_priv->uncore.lock);
 -
 -      /*
 -       * vlv and chv residency counters are 40 bits in width.
 -       * With a control bit, we can choose between upper or lower
 -       * 32bit window into this counter.
 -       *
 -       * Although we always use the counter in high-range mode elsewhere,
 -       * userspace may attempt to read the value before rc6 is initialised,
 -       * before we have set the default VLV_COUNTER_CONTROL value. So always
 -       * set the high bit to be safe.
 -       */
 -      I915_WRITE_FW(VLV_COUNTER_CONTROL,
 -                    _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH));
 -      upper = I915_READ_FW(reg);
 -      do {
 -              tmp = upper;
 -
 -              I915_WRITE_FW(VLV_COUNTER_CONTROL,
 -                            _MASKED_BIT_DISABLE(VLV_COUNT_RANGE_HIGH));
 -              lower = I915_READ_FW(reg);
 -
 -              I915_WRITE_FW(VLV_COUNTER_CONTROL,
 -                            _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH));
 -              upper = I915_READ_FW(reg);
 -      } while (upper != tmp && --loop);
 -
 -      /*
 -       * Everywhere else we always use VLV_COUNTER_CONTROL with the
 -       * VLV_COUNT_RANGE_HIGH bit set - so it is safe to leave it set
 -       * now.
 -       */
 -
 -      return lower | (u64)upper << 8;
 -}
 -
 -u64 intel_rc6_residency_ns(struct drm_i915_private *dev_priv,
 -                         const i915_reg_t reg)
 -{
 -      struct intel_uncore *uncore = &dev_priv->uncore;
 -      u64 time_hw, prev_hw, overflow_hw;
 -      unsigned int fw_domains;
 -      unsigned long flags;
 -      unsigned int i;
 -      u32 mul, div;
 -
 -      if (!HAS_RC6(dev_priv))
 -              return 0;
 -
 -      /*
 -       * Store previous hw counter values for counter wrap-around handling.
 -       *
 -       * There are only four interesting registers and they live next to each
 -       * other so we can use the relative address, compared to the smallest
 -       * one as the index into driver storage.
 -       */
 -      i = (i915_mmio_reg_offset(reg) -
 -           i915_mmio_reg_offset(GEN6_GT_GFX_RC6_LOCKED)) / sizeof(u32);
 -      if (WARN_ON_ONCE(i >= ARRAY_SIZE(dev_priv->gt_pm.rc6.cur_residency)))
 -              return 0;
 -
 -      fw_domains = intel_uncore_forcewake_for_reg(uncore, reg, FW_REG_READ);
 -
 -      spin_lock_irqsave(&uncore->lock, flags);
 -      intel_uncore_forcewake_get__locked(uncore, fw_domains);
 -
 -      /* On VLV and CHV, residency time is in CZ units rather than 1.28us */
 -      if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
 -              mul = 1000000;
 -              div = dev_priv->czclk_freq;
 -              overflow_hw = BIT_ULL(40);
 -              time_hw = vlv_residency_raw(dev_priv, reg);
 -      } else {
 -              /* 833.33ns units on Gen9LP, 1.28us elsewhere. */
 -              if (IS_GEN9_LP(dev_priv)) {
 -                      mul = 10000;
 -                      div = 12;
 -              } else {
 -                      mul = 1280;
 -                      div = 1;
 -              }
 -
 -              overflow_hw = BIT_ULL(32);
 -              time_hw = intel_uncore_read_fw(uncore, reg);
 -      }
 -
 -      /*
 -       * Counter wrap handling.
 -       *
 -       * But relying on a sufficient frequency of queries otherwise counters
 -       * can still wrap.
 -       */
 -      prev_hw = dev_priv->gt_pm.rc6.prev_hw_residency[i];
 -      dev_priv->gt_pm.rc6.prev_hw_residency[i] = time_hw;
 -
 -      /* RC6 delta from last sample. */
 -      if (time_hw >= prev_hw)
 -              time_hw -= prev_hw;
 -      else
 -              time_hw += overflow_hw - prev_hw;
 -
 -      /* Add delta to RC6 extended raw driver copy. */
 -      time_hw += dev_priv->gt_pm.rc6.cur_residency[i];
 -      dev_priv->gt_pm.rc6.cur_residency[i] = time_hw;
 -
 -      intel_uncore_forcewake_put__locked(uncore, fw_domains);
 -      spin_unlock_irqrestore(&uncore->lock, flags);
 -
 -      return mul_u64_u32_div(time_hw, mul, div);
 -}
 -
 -u64 intel_rc6_residency_us(struct drm_i915_private *dev_priv,
 -                         i915_reg_t reg)
 -{
 -      return DIV_ROUND_UP_ULL(intel_rc6_residency_ns(dev_priv, reg), 1000);
 -}
 -
 -u32 intel_get_cagf(struct drm_i915_private *dev_priv, u32 rpstat)
 -{
 -      u32 cagf;
 -
 -      if (INTEL_GEN(dev_priv) >= 9)
 -              cagf = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
 -      else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
 -              cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
 -      else
 -              cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
 -
 -      return  cagf;
 -}
This page took 0.355946 seconds and 4 git commands to generate.