LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915 - intel_uncore.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 698 0.0 %
Date: 2022-04-01 13:59:58 Functions: 0 106 0.0 %
Branches: 0 583 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright © 2013 Intel Corporation
       3                 :            :  *
       4                 :            :  * Permission is hereby granted, free of charge, to any person obtaining a
       5                 :            :  * copy of this software and associated documentation files (the "Software"),
       6                 :            :  * to deal in the Software without restriction, including without limitation
       7                 :            :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8                 :            :  * and/or sell copies of the Software, and to permit persons to whom the
       9                 :            :  * Software is furnished to do so, subject to the following conditions:
      10                 :            :  *
      11                 :            :  * The above copyright notice and this permission notice (including the next
      12                 :            :  * paragraph) shall be included in all copies or substantial portions of the
      13                 :            :  * Software.
      14                 :            :  *
      15                 :            :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16                 :            :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17                 :            :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      18                 :            :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19                 :            :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      20                 :            :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
      21                 :            :  * IN THE SOFTWARE.
      22                 :            :  */
      23                 :            : 
      24                 :            : #include <linux/pm_runtime.h>
      25                 :            : #include <asm/iosf_mbi.h>
      26                 :            : 
      27                 :            : #include "i915_drv.h"
      28                 :            : #include "i915_trace.h"
      29                 :            : #include "i915_vgpu.h"
      30                 :            : #include "intel_pm.h"
      31                 :            : 
      32                 :            : #define FORCEWAKE_ACK_TIMEOUT_MS 50
      33                 :            : #define GT_FIFO_TIMEOUT_MS       10
      34                 :            : 
      35                 :            : #define __raw_posting_read(...) ((void)__raw_uncore_read32(__VA_ARGS__))
      36                 :            : 
      37                 :            : void
      38                 :          0 : intel_uncore_mmio_debug_init_early(struct intel_uncore_mmio_debug *mmio_debug)
      39                 :            : {
      40                 :          0 :         spin_lock_init(&mmio_debug->lock);
      41                 :          0 :         mmio_debug->unclaimed_mmio_check = 1;
      42                 :          0 : }
      43                 :            : 
      44                 :          0 : static void mmio_debug_suspend(struct intel_uncore_mmio_debug *mmio_debug)
      45                 :            : {
      46                 :          0 :         lockdep_assert_held(&mmio_debug->lock);
      47                 :            : 
      48                 :            :         /* Save and disable mmio debugging for the user bypass */
      49                 :          0 :         if (!mmio_debug->suspend_count++) {
      50                 :          0 :                 mmio_debug->saved_mmio_check = mmio_debug->unclaimed_mmio_check;
      51                 :          0 :                 mmio_debug->unclaimed_mmio_check = 0;
      52                 :            :         }
      53                 :            : }
      54                 :            : 
      55                 :          0 : static void mmio_debug_resume(struct intel_uncore_mmio_debug *mmio_debug)
      56                 :            : {
      57                 :          0 :         lockdep_assert_held(&mmio_debug->lock);
      58                 :            : 
      59                 :          0 :         if (!--mmio_debug->suspend_count)
      60                 :          0 :                 mmio_debug->unclaimed_mmio_check = mmio_debug->saved_mmio_check;
      61                 :            : }
      62                 :            : 
      63                 :            : static const char * const forcewake_domain_names[] = {
      64                 :            :         "render",
      65                 :            :         "blitter",
      66                 :            :         "media",
      67                 :            :         "vdbox0",
      68                 :            :         "vdbox1",
      69                 :            :         "vdbox2",
      70                 :            :         "vdbox3",
      71                 :            :         "vebox0",
      72                 :            :         "vebox1",
      73                 :            : };
      74                 :            : 
      75                 :            : const char *
      76                 :          0 : intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id)
      77                 :            : {
      78                 :          0 :         BUILD_BUG_ON(ARRAY_SIZE(forcewake_domain_names) != FW_DOMAIN_ID_COUNT);
      79                 :            : 
      80         [ #  # ]:          0 :         if (id >= 0 && id < FW_DOMAIN_ID_COUNT)
      81                 :          0 :                 return forcewake_domain_names[id];
      82                 :            : 
      83                 :          0 :         WARN_ON(id);
      84                 :            : 
      85                 :          0 :         return "unknown";
      86                 :            : }
      87                 :            : 
      88                 :            : #define fw_ack(d) readl((d)->reg_ack)
      89                 :            : #define fw_set(d, val) writel(_MASKED_BIT_ENABLE((val)), (d)->reg_set)
      90                 :            : #define fw_clear(d, val) writel(_MASKED_BIT_DISABLE((val)), (d)->reg_set)
      91                 :            : 
      92                 :            : static inline void
      93                 :          0 : fw_domain_reset(const struct intel_uncore_forcewake_domain *d)
      94                 :            : {
      95                 :            :         /*
      96                 :            :          * We don't really know if the powerwell for the forcewake domain we are
      97                 :            :          * trying to reset here does exist at this point (engines could be fused
      98                 :            :          * off in ICL+), so no waiting for acks
      99                 :            :          */
     100                 :            :         /* WaRsClearFWBitsAtReset:bdw,skl */
     101                 :          0 :         fw_clear(d, 0xffff);
     102                 :          0 : }
     103                 :            : 
     104                 :            : static inline void
     105                 :          0 : fw_domain_arm_timer(struct intel_uncore_forcewake_domain *d)
     106                 :            : {
     107                 :          0 :         GEM_BUG_ON(d->uncore->fw_domains_timer & d->mask);
     108                 :          0 :         d->uncore->fw_domains_timer |= d->mask;
     109                 :          0 :         d->wake_count++;
     110                 :          0 :         hrtimer_start_range_ns(&d->timer,
     111                 :            :                                NSEC_PER_MSEC,
     112                 :            :                                NSEC_PER_MSEC,
     113                 :            :                                HRTIMER_MODE_REL);
     114                 :          0 : }
     115                 :            : 
     116                 :            : static inline int
     117                 :            : __wait_for_ack(const struct intel_uncore_forcewake_domain *d,
     118                 :            :                const u32 ack,
     119                 :            :                const u32 value)
     120                 :            : {
     121                 :            :         return wait_for_atomic((fw_ack(d) & ack) == value,
     122                 :            :                                FORCEWAKE_ACK_TIMEOUT_MS);
     123                 :            : }
     124                 :            : 
     125                 :            : static inline int
     126                 :          0 : wait_ack_clear(const struct intel_uncore_forcewake_domain *d,
     127                 :            :                const u32 ack)
     128                 :            : {
     129                 :          0 :         return __wait_for_ack(d, ack, 0);
     130                 :            : }
     131                 :            : 
     132                 :            : static inline int
     133                 :          0 : wait_ack_set(const struct intel_uncore_forcewake_domain *d,
     134                 :            :              const u32 ack)
     135                 :            : {
     136                 :          0 :         return __wait_for_ack(d, ack, ack);
     137                 :            : }
     138                 :            : 
     139                 :            : static inline void
     140                 :          0 : fw_domain_wait_ack_clear(const struct intel_uncore_forcewake_domain *d)
     141                 :            : {
     142         [ #  # ]:          0 :         if (wait_ack_clear(d, FORCEWAKE_KERNEL)) {
     143                 :          0 :                 DRM_ERROR("%s: timed out waiting for forcewake ack to clear.\n",
     144                 :            :                           intel_uncore_forcewake_domain_to_str(d->id));
     145                 :          0 :                 add_taint_for_CI(TAINT_WARN); /* CI now unreliable */
     146                 :            :         }
     147                 :          0 : }
     148                 :            : 
     149                 :            : enum ack_type {
     150                 :            :         ACK_CLEAR = 0,
     151                 :            :         ACK_SET
     152                 :            : };
     153                 :            : 
     154                 :            : static int
     155                 :          0 : fw_domain_wait_ack_with_fallback(const struct intel_uncore_forcewake_domain *d,
     156                 :            :                                  const enum ack_type type)
     157                 :            : {
     158                 :          0 :         const u32 ack_bit = FORCEWAKE_KERNEL;
     159         [ #  # ]:          0 :         const u32 value = type == ACK_SET ? ack_bit : 0;
     160                 :          0 :         unsigned int pass;
     161                 :          0 :         bool ack_detected;
     162                 :            : 
     163                 :            :         /*
     164                 :            :          * There is a possibility of driver's wake request colliding
     165                 :            :          * with hardware's own wake requests and that can cause
     166                 :            :          * hardware to not deliver the driver's ack message.
     167                 :            :          *
     168                 :            :          * Use a fallback bit toggle to kick the gpu state machine
     169                 :            :          * in the hope that the original ack will be delivered along with
     170                 :            :          * the fallback ack.
     171                 :            :          *
     172                 :            :          * This workaround is described in HSDES #1604254524 and it's known as:
     173                 :            :          * WaRsForcewakeAddDelayForAck:skl,bxt,kbl,glk,cfl,cnl,icl
     174                 :            :          * although the name is a bit misleading.
     175                 :            :          */
     176                 :            : 
     177                 :          0 :         pass = 1;
     178                 :          0 :         do {
     179                 :          0 :                 wait_ack_clear(d, FORCEWAKE_KERNEL_FALLBACK);
     180                 :            : 
     181                 :          0 :                 fw_set(d, FORCEWAKE_KERNEL_FALLBACK);
     182                 :            :                 /* Give gt some time to relax before the polling frenzy */
     183         [ #  # ]:          0 :                 udelay(10 * pass);
     184                 :          0 :                 wait_ack_set(d, FORCEWAKE_KERNEL_FALLBACK);
     185                 :            : 
     186                 :          0 :                 ack_detected = (fw_ack(d) & ack_bit) == value;
     187                 :            : 
     188                 :          0 :                 fw_clear(d, FORCEWAKE_KERNEL_FALLBACK);
     189   [ #  #  #  # ]:          0 :         } while (!ack_detected && pass++ < 10);
     190                 :            : 
     191         [ #  # ]:          0 :         DRM_DEBUG_DRIVER("%s had to use fallback to %s ack, 0x%x (passes %u)\n",
     192                 :            :                          intel_uncore_forcewake_domain_to_str(d->id),
     193                 :            :                          type == ACK_SET ? "set" : "clear",
     194                 :            :                          fw_ack(d),
     195                 :            :                          pass);
     196                 :            : 
     197         [ #  # ]:          0 :         return ack_detected ? 0 : -ETIMEDOUT;
     198                 :            : }
     199                 :            : 
     200                 :            : static inline void
     201                 :          0 : fw_domain_wait_ack_clear_fallback(const struct intel_uncore_forcewake_domain *d)
     202                 :            : {
     203         [ #  # ]:          0 :         if (likely(!wait_ack_clear(d, FORCEWAKE_KERNEL)))
     204                 :            :                 return;
     205                 :            : 
     206         [ #  # ]:          0 :         if (fw_domain_wait_ack_with_fallback(d, ACK_CLEAR))
     207                 :          0 :                 fw_domain_wait_ack_clear(d);
     208                 :            : }
     209                 :            : 
     210                 :            : static inline void
     211                 :          0 : fw_domain_get(const struct intel_uncore_forcewake_domain *d)
     212                 :            : {
     213                 :          0 :         fw_set(d, FORCEWAKE_KERNEL);
     214                 :          0 : }
     215                 :            : 
     216                 :            : static inline void
     217                 :          0 : fw_domain_wait_ack_set(const struct intel_uncore_forcewake_domain *d)
     218                 :            : {
     219         [ #  # ]:          0 :         if (wait_ack_set(d, FORCEWAKE_KERNEL)) {
     220                 :          0 :                 DRM_ERROR("%s: timed out waiting for forcewake ack request.\n",
     221                 :            :                           intel_uncore_forcewake_domain_to_str(d->id));
     222                 :          0 :                 add_taint_for_CI(TAINT_WARN); /* CI now unreliable */
     223                 :            :         }
     224                 :          0 : }
     225                 :            : 
     226                 :            : static inline void
     227                 :          0 : fw_domain_wait_ack_set_fallback(const struct intel_uncore_forcewake_domain *d)
     228                 :            : {
     229         [ #  # ]:          0 :         if (likely(!wait_ack_set(d, FORCEWAKE_KERNEL)))
     230                 :            :                 return;
     231                 :            : 
     232         [ #  # ]:          0 :         if (fw_domain_wait_ack_with_fallback(d, ACK_SET))
     233                 :          0 :                 fw_domain_wait_ack_set(d);
     234                 :            : }
     235                 :            : 
     236                 :            : static inline void
     237                 :          0 : fw_domain_put(const struct intel_uncore_forcewake_domain *d)
     238                 :            : {
     239                 :          0 :         fw_clear(d, FORCEWAKE_KERNEL);
     240                 :          0 : }
     241                 :            : 
     242                 :            : static void
     243                 :          0 : fw_domains_get(struct intel_uncore *uncore, enum forcewake_domains fw_domains)
     244                 :            : {
     245                 :          0 :         struct intel_uncore_forcewake_domain *d;
     246                 :          0 :         unsigned int tmp;
     247                 :            : 
     248                 :          0 :         GEM_BUG_ON(fw_domains & ~uncore->fw_domains);
     249                 :            : 
     250   [ #  #  #  # ]:          0 :         for_each_fw_domain_masked(d, fw_domains, uncore, tmp) {
     251                 :          0 :                 fw_domain_wait_ack_clear(d);
     252                 :          0 :                 fw_domain_get(d);
     253                 :            :         }
     254                 :            : 
     255   [ #  #  #  # ]:          0 :         for_each_fw_domain_masked(d, fw_domains, uncore, tmp)
     256                 :          0 :                 fw_domain_wait_ack_set(d);
     257                 :            : 
     258                 :          0 :         uncore->fw_domains_active |= fw_domains;
     259                 :          0 : }
     260                 :            : 
     261                 :            : static void
     262                 :          0 : fw_domains_get_with_fallback(struct intel_uncore *uncore,
     263                 :            :                              enum forcewake_domains fw_domains)
     264                 :            : {
     265                 :          0 :         struct intel_uncore_forcewake_domain *d;
     266                 :          0 :         unsigned int tmp;
     267                 :            : 
     268                 :          0 :         GEM_BUG_ON(fw_domains & ~uncore->fw_domains);
     269                 :            : 
     270   [ #  #  #  # ]:          0 :         for_each_fw_domain_masked(d, fw_domains, uncore, tmp) {
     271                 :          0 :                 fw_domain_wait_ack_clear_fallback(d);
     272                 :          0 :                 fw_domain_get(d);
     273                 :            :         }
     274                 :            : 
     275   [ #  #  #  # ]:          0 :         for_each_fw_domain_masked(d, fw_domains, uncore, tmp)
     276                 :          0 :                 fw_domain_wait_ack_set_fallback(d);
     277                 :            : 
     278                 :          0 :         uncore->fw_domains_active |= fw_domains;
     279                 :          0 : }
     280                 :            : 
     281                 :            : static void
     282                 :          0 : fw_domains_put(struct intel_uncore *uncore, enum forcewake_domains fw_domains)
     283                 :            : {
     284                 :          0 :         struct intel_uncore_forcewake_domain *d;
     285                 :          0 :         unsigned int tmp;
     286                 :            : 
     287                 :          0 :         GEM_BUG_ON(fw_domains & ~uncore->fw_domains);
     288                 :            : 
     289   [ #  #  #  #  :          0 :         for_each_fw_domain_masked(d, fw_domains, uncore, tmp)
             #  #  #  # ]
     290                 :          0 :                 fw_domain_put(d);
     291                 :            : 
     292                 :          0 :         uncore->fw_domains_active &= ~fw_domains;
     293                 :          0 : }
     294                 :            : 
     295                 :            : static void
     296                 :          0 : fw_domains_reset(struct intel_uncore *uncore,
     297                 :            :                  enum forcewake_domains fw_domains)
     298                 :            : {
     299                 :          0 :         struct intel_uncore_forcewake_domain *d;
     300                 :          0 :         unsigned int tmp;
     301                 :            : 
     302                 :          0 :         if (!fw_domains)
     303                 :            :                 return;
     304                 :            : 
     305                 :            :         GEM_BUG_ON(fw_domains & ~uncore->fw_domains);
     306                 :            : 
     307   [ #  #  #  # ]:          0 :         for_each_fw_domain_masked(d, fw_domains, uncore, tmp)
     308                 :          0 :                 fw_domain_reset(d);
     309                 :            : }
     310                 :            : 
     311                 :          0 : static inline u32 gt_thread_status(struct intel_uncore *uncore)
     312                 :            : {
     313                 :          0 :         u32 val;
     314                 :            : 
     315                 :          0 :         val = __raw_uncore_read32(uncore, GEN6_GT_THREAD_STATUS_REG);
     316                 :          0 :         val &= GEN6_GT_THREAD_STATUS_CORE_MASK;
     317                 :            : 
     318                 :          0 :         return val;
     319                 :            : }
     320                 :            : 
     321                 :          0 : static void __gen6_gt_wait_for_thread_c0(struct intel_uncore *uncore)
     322                 :            : {
     323                 :            :         /*
     324                 :            :          * w/a for a sporadic read returning 0 by waiting for the GT
     325                 :            :          * thread to wake up.
     326                 :            :          */
     327   [ #  #  #  #  :          0 :         WARN_ONCE(wait_for_atomic_us(gt_thread_status(uncore) == 0, 5000),
             #  #  #  # ]
     328                 :            :                   "GT thread status wait timed out\n");
     329                 :          0 : }
     330                 :            : 
     331                 :          0 : static void fw_domains_get_with_thread_status(struct intel_uncore *uncore,
     332                 :            :                                               enum forcewake_domains fw_domains)
     333                 :            : {
     334                 :          0 :         fw_domains_get(uncore, fw_domains);
     335                 :            : 
     336                 :            :         /* WaRsForcewakeWaitTC0:snb,ivb,hsw,bdw,vlv */
     337                 :          0 :         __gen6_gt_wait_for_thread_c0(uncore);
     338                 :          0 : }
     339                 :            : 
     340                 :          0 : static inline u32 fifo_free_entries(struct intel_uncore *uncore)
     341                 :            : {
     342                 :          0 :         u32 count = __raw_uncore_read32(uncore, GTFIFOCTL);
     343                 :            : 
     344                 :          0 :         return count & GT_FIFO_FREE_ENTRIES_MASK;
     345                 :            : }
     346                 :            : 
     347                 :          0 : static void __gen6_gt_wait_for_fifo(struct intel_uncore *uncore)
     348                 :            : {
     349                 :          0 :         u32 n;
     350                 :            : 
     351                 :            :         /* On VLV, FIFO will be shared by both SW and HW.
     352                 :            :          * So, we need to read the FREE_ENTRIES everytime */
     353         [ #  # ]:          0 :         if (IS_VALLEYVIEW(uncore->i915))
     354                 :          0 :                 n = fifo_free_entries(uncore);
     355                 :            :         else
     356                 :          0 :                 n = uncore->fifo_count;
     357                 :            : 
     358         [ #  # ]:          0 :         if (n <= GT_FIFO_NUM_RESERVED_ENTRIES) {
     359   [ #  #  #  #  :          0 :                 if (wait_for_atomic((n = fifo_free_entries(uncore)) >
                   #  # ]
     360                 :            :                                     GT_FIFO_NUM_RESERVED_ENTRIES,
     361                 :            :                                     GT_FIFO_TIMEOUT_MS)) {
     362                 :          0 :                         drm_dbg(&uncore->i915->drm,
     363                 :            :                                 "GT_FIFO timeout, entries: %u\n", n);
     364                 :          0 :                         return;
     365                 :            :                 }
     366                 :            :         }
     367                 :            : 
     368                 :          0 :         uncore->fifo_count = n - 1;
     369                 :            : }
     370                 :            : 
     371                 :            : static enum hrtimer_restart
     372                 :          0 : intel_uncore_fw_release_timer(struct hrtimer *timer)
     373                 :            : {
     374                 :          0 :         struct intel_uncore_forcewake_domain *domain =
     375                 :          0 :                container_of(timer, struct intel_uncore_forcewake_domain, timer);
     376                 :          0 :         struct intel_uncore *uncore = domain->uncore;
     377                 :          0 :         unsigned long irqflags;
     378                 :            : 
     379                 :          0 :         assert_rpm_device_not_suspended(uncore->rpm);
     380                 :            : 
     381         [ #  # ]:          0 :         if (xchg(&domain->active, false))
     382                 :            :                 return HRTIMER_RESTART;
     383                 :            : 
     384                 :          0 :         spin_lock_irqsave(&uncore->lock, irqflags);
     385                 :            : 
     386                 :          0 :         uncore->fw_domains_timer &= ~domain->mask;
     387                 :            : 
     388                 :          0 :         GEM_BUG_ON(!domain->wake_count);
     389         [ #  # ]:          0 :         if (--domain->wake_count == 0)
     390                 :          0 :                 uncore->funcs.force_wake_put(uncore, domain->mask);
     391                 :            : 
     392                 :          0 :         spin_unlock_irqrestore(&uncore->lock, irqflags);
     393                 :            : 
     394                 :          0 :         return HRTIMER_NORESTART;
     395                 :            : }
     396                 :            : 
     397                 :            : /* Note callers must have acquired the PUNIT->PMIC bus, before calling this. */
     398                 :            : static unsigned int
     399                 :          0 : intel_uncore_forcewake_reset(struct intel_uncore *uncore)
     400                 :            : {
     401                 :          0 :         unsigned long irqflags;
     402                 :          0 :         struct intel_uncore_forcewake_domain *domain;
     403                 :          0 :         int retry_count = 100;
     404                 :          0 :         enum forcewake_domains fw, active_domains;
     405                 :            : 
     406                 :          0 :         iosf_mbi_assert_punit_acquired();
     407                 :            : 
     408                 :            :         /* Hold uncore.lock across reset to prevent any register access
     409                 :            :          * with forcewake not set correctly. Wait until all pending
     410                 :            :          * timers are run before holding.
     411                 :            :          */
     412                 :          0 :         while (1) {
     413                 :          0 :                 unsigned int tmp;
     414                 :            : 
     415                 :          0 :                 active_domains = 0;
     416                 :            : 
     417   [ #  #  #  # ]:          0 :                 for_each_fw_domain(domain, uncore, tmp) {
     418                 :          0 :                         smp_store_mb(domain->active, false);
     419         [ #  # ]:          0 :                         if (hrtimer_cancel(&domain->timer) == 0)
     420                 :          0 :                                 continue;
     421                 :            : 
     422                 :          0 :                         intel_uncore_fw_release_timer(&domain->timer);
     423                 :            :                 }
     424                 :            : 
     425                 :          0 :                 spin_lock_irqsave(&uncore->lock, irqflags);
     426                 :            : 
     427   [ #  #  #  # ]:          0 :                 for_each_fw_domain(domain, uncore, tmp) {
     428         [ #  # ]:          0 :                         if (hrtimer_active(&domain->timer))
     429                 :          0 :                                 active_domains |= domain->mask;
     430                 :            :                 }
     431                 :            : 
     432         [ #  # ]:          0 :                 if (active_domains == 0)
     433                 :            :                         break;
     434                 :            : 
     435         [ #  # ]:          0 :                 if (--retry_count == 0) {
     436                 :          0 :                         drm_err(&uncore->i915->drm, "Timed out waiting for forcewake timers to finish\n");
     437                 :          0 :                         break;
     438                 :            :                 }
     439                 :            : 
     440                 :          0 :                 spin_unlock_irqrestore(&uncore->lock, irqflags);
     441                 :          0 :                 cond_resched();
     442                 :            :         }
     443                 :            : 
     444         [ #  # ]:          0 :         WARN_ON(active_domains);
     445                 :            : 
     446                 :          0 :         fw = uncore->fw_domains_active;
     447         [ #  # ]:          0 :         if (fw)
     448                 :          0 :                 uncore->funcs.force_wake_put(uncore, fw);
     449                 :            : 
     450         [ #  # ]:          0 :         fw_domains_reset(uncore, uncore->fw_domains);
     451                 :          0 :         assert_forcewakes_inactive(uncore);
     452                 :            : 
     453                 :          0 :         spin_unlock_irqrestore(&uncore->lock, irqflags);
     454                 :            : 
     455                 :          0 :         return fw; /* track the lost user forcewake domains */
     456                 :            : }
     457                 :            : 
     458                 :            : static bool
     459                 :          0 : fpga_check_for_unclaimed_mmio(struct intel_uncore *uncore)
     460                 :            : {
     461                 :          0 :         u32 dbg;
     462                 :            : 
     463                 :          0 :         dbg = __raw_uncore_read32(uncore, FPGA_DBG);
     464         [ #  # ]:          0 :         if (likely(!(dbg & FPGA_DBG_RM_NOCLAIM)))
     465                 :            :                 return false;
     466                 :            : 
     467                 :          0 :         __raw_uncore_write32(uncore, FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
     468                 :            : 
     469                 :          0 :         return true;
     470                 :            : }
     471                 :            : 
     472                 :            : static bool
     473                 :          0 : vlv_check_for_unclaimed_mmio(struct intel_uncore *uncore)
     474                 :            : {
     475                 :          0 :         u32 cer;
     476                 :            : 
     477                 :          0 :         cer = __raw_uncore_read32(uncore, CLAIM_ER);
     478         [ #  # ]:          0 :         if (likely(!(cer & (CLAIM_ER_OVERFLOW | CLAIM_ER_CTR_MASK))))
     479                 :            :                 return false;
     480                 :            : 
     481                 :          0 :         __raw_uncore_write32(uncore, CLAIM_ER, CLAIM_ER_CLR);
     482                 :            : 
     483                 :          0 :         return true;
     484                 :            : }
     485                 :            : 
     486                 :            : static bool
     487                 :          0 : gen6_check_for_fifo_debug(struct intel_uncore *uncore)
     488                 :            : {
     489                 :          0 :         u32 fifodbg;
     490                 :            : 
     491                 :          0 :         fifodbg = __raw_uncore_read32(uncore, GTFIFODBG);
     492                 :            : 
     493         [ #  # ]:          0 :         if (unlikely(fifodbg)) {
     494                 :          0 :                 drm_dbg(&uncore->i915->drm, "GTFIFODBG = 0x08%x\n", fifodbg);
     495                 :          0 :                 __raw_uncore_write32(uncore, GTFIFODBG, fifodbg);
     496                 :            :         }
     497                 :            : 
     498                 :          0 :         return fifodbg;
     499                 :            : }
     500                 :            : 
     501                 :            : static bool
     502                 :          0 : check_for_unclaimed_mmio(struct intel_uncore *uncore)
     503                 :            : {
     504                 :          0 :         bool ret = false;
     505                 :            : 
     506                 :          0 :         lockdep_assert_held(&uncore->debug->lock);
     507                 :            : 
     508         [ #  # ]:          0 :         if (uncore->debug->suspend_count)
     509                 :            :                 return false;
     510                 :            : 
     511         [ #  # ]:          0 :         if (intel_uncore_has_fpga_dbg_unclaimed(uncore))
     512                 :          0 :                 ret |= fpga_check_for_unclaimed_mmio(uncore);
     513                 :            : 
     514         [ #  # ]:          0 :         if (intel_uncore_has_dbg_unclaimed(uncore))
     515                 :          0 :                 ret |= vlv_check_for_unclaimed_mmio(uncore);
     516                 :            : 
     517         [ #  # ]:          0 :         if (intel_uncore_has_fifo(uncore))
     518                 :          0 :                 ret |= gen6_check_for_fifo_debug(uncore);
     519                 :            : 
     520                 :            :         return ret;
     521                 :            : }
     522                 :            : 
     523                 :          0 : static void forcewake_early_sanitize(struct intel_uncore *uncore,
     524                 :            :                                      unsigned int restore_forcewake)
     525                 :            : {
     526                 :          0 :         GEM_BUG_ON(!intel_uncore_has_forcewake(uncore));
     527                 :            : 
     528                 :            :         /* WaDisableShadowRegForCpd:chv */
     529         [ #  # ]:          0 :         if (IS_CHERRYVIEW(uncore->i915)) {
     530                 :          0 :                 __raw_uncore_write32(uncore, GTFIFOCTL,
     531                 :          0 :                                      __raw_uncore_read32(uncore, GTFIFOCTL) |
     532                 :            :                                      GT_FIFO_CTL_BLOCK_ALL_POLICY_STALL |
     533                 :            :                                      GT_FIFO_CTL_RC6_POLICY_STALL);
     534                 :            :         }
     535                 :            : 
     536                 :          0 :         iosf_mbi_punit_acquire();
     537                 :          0 :         intel_uncore_forcewake_reset(uncore);
     538         [ #  # ]:          0 :         if (restore_forcewake) {
     539                 :          0 :                 spin_lock_irq(&uncore->lock);
     540                 :          0 :                 uncore->funcs.force_wake_get(uncore, restore_forcewake);
     541                 :            : 
     542         [ #  # ]:          0 :                 if (intel_uncore_has_fifo(uncore))
     543                 :          0 :                         uncore->fifo_count = fifo_free_entries(uncore);
     544                 :          0 :                 spin_unlock_irq(&uncore->lock);
     545                 :            :         }
     546                 :          0 :         iosf_mbi_punit_release();
     547                 :          0 : }
     548                 :            : 
     549                 :          0 : void intel_uncore_suspend(struct intel_uncore *uncore)
     550                 :            : {
     551         [ #  # ]:          0 :         if (!intel_uncore_has_forcewake(uncore))
     552                 :            :                 return;
     553                 :            : 
     554                 :          0 :         iosf_mbi_punit_acquire();
     555                 :          0 :         iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(
     556                 :            :                 &uncore->pmic_bus_access_nb);
     557                 :          0 :         uncore->fw_domains_saved = intel_uncore_forcewake_reset(uncore);
     558                 :          0 :         iosf_mbi_punit_release();
     559                 :            : }
     560                 :            : 
     561                 :          0 : void intel_uncore_resume_early(struct intel_uncore *uncore)
     562                 :            : {
     563                 :          0 :         unsigned int restore_forcewake;
     564                 :            : 
     565         [ #  # ]:          0 :         if (intel_uncore_unclaimed_mmio(uncore))
     566                 :          0 :                 drm_dbg(&uncore->i915->drm, "unclaimed mmio detected on resume, clearing\n");
     567                 :            : 
     568         [ #  # ]:          0 :         if (!intel_uncore_has_forcewake(uncore))
     569                 :            :                 return;
     570                 :            : 
     571                 :          0 :         restore_forcewake = fetch_and_zero(&uncore->fw_domains_saved);
     572                 :          0 :         forcewake_early_sanitize(uncore, restore_forcewake);
     573                 :            : 
     574                 :          0 :         iosf_mbi_register_pmic_bus_access_notifier(&uncore->pmic_bus_access_nb);
     575                 :            : }
     576                 :            : 
     577                 :          0 : void intel_uncore_runtime_resume(struct intel_uncore *uncore)
     578                 :            : {
     579         [ #  # ]:          0 :         if (!intel_uncore_has_forcewake(uncore))
     580                 :            :                 return;
     581                 :            : 
     582                 :          0 :         iosf_mbi_register_pmic_bus_access_notifier(&uncore->pmic_bus_access_nb);
     583                 :            : }
     584                 :            : 
     585                 :          0 : static void __intel_uncore_forcewake_get(struct intel_uncore *uncore,
     586                 :            :                                          enum forcewake_domains fw_domains)
     587                 :            : {
     588                 :          0 :         struct intel_uncore_forcewake_domain *domain;
     589                 :          0 :         unsigned int tmp;
     590                 :            : 
     591                 :          0 :         fw_domains &= uncore->fw_domains;
     592                 :            : 
     593   [ #  #  #  # ]:          0 :         for_each_fw_domain_masked(domain, fw_domains, uncore, tmp) {
     594         [ #  # ]:          0 :                 if (domain->wake_count++) {
     595                 :          0 :                         fw_domains &= ~domain->mask;
     596                 :          0 :                         domain->active = true;
     597                 :            :                 }
     598                 :            :         }
     599                 :            : 
     600         [ #  # ]:          0 :         if (fw_domains)
     601                 :          0 :                 uncore->funcs.force_wake_get(uncore, fw_domains);
     602                 :          0 : }
     603                 :            : 
     604                 :            : /**
     605                 :            :  * intel_uncore_forcewake_get - grab forcewake domain references
     606                 :            :  * @uncore: the intel_uncore structure
     607                 :            :  * @fw_domains: forcewake domains to get reference on
     608                 :            :  *
     609                 :            :  * This function can be used get GT's forcewake domain references.
     610                 :            :  * Normal register access will handle the forcewake domains automatically.
     611                 :            :  * However if some sequence requires the GT to not power down a particular
     612                 :            :  * forcewake domains this function should be called at the beginning of the
     613                 :            :  * sequence. And subsequently the reference should be dropped by symmetric
     614                 :            :  * call to intel_unforce_forcewake_put(). Usually caller wants all the domains
     615                 :            :  * to be kept awake so the @fw_domains would be then FORCEWAKE_ALL.
     616                 :            :  */
     617                 :          0 : void intel_uncore_forcewake_get(struct intel_uncore *uncore,
     618                 :            :                                 enum forcewake_domains fw_domains)
     619                 :            : {
     620                 :          0 :         unsigned long irqflags;
     621                 :            : 
     622         [ #  # ]:          0 :         if (!uncore->funcs.force_wake_get)
     623                 :            :                 return;
     624                 :            : 
     625                 :          0 :         assert_rpm_wakelock_held(uncore->rpm);
     626                 :            : 
     627                 :          0 :         spin_lock_irqsave(&uncore->lock, irqflags);
     628                 :          0 :         __intel_uncore_forcewake_get(uncore, fw_domains);
     629                 :          0 :         spin_unlock_irqrestore(&uncore->lock, irqflags);
     630                 :            : }
     631                 :            : 
     632                 :            : /**
     633                 :            :  * intel_uncore_forcewake_user_get - claim forcewake on behalf of userspace
     634                 :            :  * @uncore: the intel_uncore structure
     635                 :            :  *
     636                 :            :  * This function is a wrapper around intel_uncore_forcewake_get() to acquire
     637                 :            :  * the GT powerwell and in the process disable our debugging for the
     638                 :            :  * duration of userspace's bypass.
     639                 :            :  */
     640                 :          0 : void intel_uncore_forcewake_user_get(struct intel_uncore *uncore)
     641                 :            : {
     642                 :          0 :         spin_lock_irq(&uncore->lock);
     643         [ #  # ]:          0 :         if (!uncore->user_forcewake_count++) {
     644                 :          0 :                 intel_uncore_forcewake_get__locked(uncore, FORCEWAKE_ALL);
     645                 :          0 :                 spin_lock(&uncore->debug->lock);
     646         [ #  # ]:          0 :                 mmio_debug_suspend(uncore->debug);
     647                 :          0 :                 spin_unlock(&uncore->debug->lock);
     648                 :            :         }
     649                 :          0 :         spin_unlock_irq(&uncore->lock);
     650                 :          0 : }
     651                 :            : 
     652                 :            : /**
     653                 :            :  * intel_uncore_forcewake_user_put - release forcewake on behalf of userspace
     654                 :            :  * @uncore: the intel_uncore structure
     655                 :            :  *
     656                 :            :  * This function complements intel_uncore_forcewake_user_get() and releases
     657                 :            :  * the GT powerwell taken on behalf of the userspace bypass.
     658                 :            :  */
     659                 :          0 : void intel_uncore_forcewake_user_put(struct intel_uncore *uncore)
     660                 :            : {
     661                 :          0 :         spin_lock_irq(&uncore->lock);
     662         [ #  # ]:          0 :         if (!--uncore->user_forcewake_count) {
     663                 :          0 :                 spin_lock(&uncore->debug->lock);
     664         [ #  # ]:          0 :                 mmio_debug_resume(uncore->debug);
     665                 :            : 
     666         [ #  # ]:          0 :                 if (check_for_unclaimed_mmio(uncore))
     667                 :          0 :                         dev_info(uncore->i915->drm.dev,
     668                 :            :                                  "Invalid mmio detected during user access\n");
     669                 :          0 :                 spin_unlock(&uncore->debug->lock);
     670                 :            : 
     671                 :          0 :                 intel_uncore_forcewake_put__locked(uncore, FORCEWAKE_ALL);
     672                 :            :         }
     673                 :          0 :         spin_unlock_irq(&uncore->lock);
     674                 :          0 : }
     675                 :            : 
     676                 :            : /**
     677                 :            :  * intel_uncore_forcewake_get__locked - grab forcewake domain references
     678                 :            :  * @uncore: the intel_uncore structure
     679                 :            :  * @fw_domains: forcewake domains to get reference on
     680                 :            :  *
     681                 :            :  * See intel_uncore_forcewake_get(). This variant places the onus
     682                 :            :  * on the caller to explicitly handle the dev_priv->uncore.lock spinlock.
     683                 :            :  */
     684                 :          0 : void intel_uncore_forcewake_get__locked(struct intel_uncore *uncore,
     685                 :            :                                         enum forcewake_domains fw_domains)
     686                 :            : {
     687                 :          0 :         lockdep_assert_held(&uncore->lock);
     688                 :            : 
     689   [ #  #  #  # ]:          0 :         if (!uncore->funcs.force_wake_get)
     690                 :            :                 return;
     691                 :            : 
     692                 :          0 :         __intel_uncore_forcewake_get(uncore, fw_domains);
     693                 :            : }
     694                 :            : 
     695                 :          0 : static void __intel_uncore_forcewake_put(struct intel_uncore *uncore,
     696                 :            :                                          enum forcewake_domains fw_domains)
     697                 :            : {
     698                 :          0 :         struct intel_uncore_forcewake_domain *domain;
     699                 :          0 :         unsigned int tmp;
     700                 :            : 
     701                 :          0 :         fw_domains &= uncore->fw_domains;
     702                 :            : 
     703   [ #  #  #  # ]:          0 :         for_each_fw_domain_masked(domain, fw_domains, uncore, tmp) {
     704                 :          0 :                 GEM_BUG_ON(!domain->wake_count);
     705                 :            : 
     706         [ #  # ]:          0 :                 if (--domain->wake_count) {
     707                 :          0 :                         domain->active = true;
     708                 :          0 :                         continue;
     709                 :            :                 }
     710                 :            : 
     711                 :          0 :                 fw_domain_arm_timer(domain);
     712                 :            :         }
     713                 :          0 : }
     714                 :            : 
     715                 :            : /**
     716                 :            :  * intel_uncore_forcewake_put - release a forcewake domain reference
     717                 :            :  * @uncore: the intel_uncore structure
     718                 :            :  * @fw_domains: forcewake domains to put references
     719                 :            :  *
     720                 :            :  * This function drops the device-level forcewakes for specified
     721                 :            :  * domains obtained by intel_uncore_forcewake_get().
     722                 :            :  */
     723                 :          0 : void intel_uncore_forcewake_put(struct intel_uncore *uncore,
     724                 :            :                                 enum forcewake_domains fw_domains)
     725                 :            : {
     726                 :          0 :         unsigned long irqflags;
     727                 :            : 
     728         [ #  # ]:          0 :         if (!uncore->funcs.force_wake_put)
     729                 :            :                 return;
     730                 :            : 
     731                 :          0 :         spin_lock_irqsave(&uncore->lock, irqflags);
     732                 :          0 :         __intel_uncore_forcewake_put(uncore, fw_domains);
     733                 :          0 :         spin_unlock_irqrestore(&uncore->lock, irqflags);
     734                 :            : }
     735                 :            : 
     736                 :            : /**
     737                 :            :  * intel_uncore_forcewake_put__locked - grab forcewake domain references
     738                 :            :  * @uncore: the intel_uncore structure
     739                 :            :  * @fw_domains: forcewake domains to get reference on
     740                 :            :  *
     741                 :            :  * See intel_uncore_forcewake_put(). This variant places the onus
     742                 :            :  * on the caller to explicitly handle the dev_priv->uncore.lock spinlock.
     743                 :            :  */
     744                 :          0 : void intel_uncore_forcewake_put__locked(struct intel_uncore *uncore,
     745                 :            :                                         enum forcewake_domains fw_domains)
     746                 :            : {
     747                 :          0 :         lockdep_assert_held(&uncore->lock);
     748                 :            : 
     749   [ #  #  #  # ]:          0 :         if (!uncore->funcs.force_wake_put)
     750                 :            :                 return;
     751                 :            : 
     752                 :          0 :         __intel_uncore_forcewake_put(uncore, fw_domains);
     753                 :            : }
     754                 :            : 
     755                 :          0 : void assert_forcewakes_inactive(struct intel_uncore *uncore)
     756                 :            : {
     757         [ #  # ]:          0 :         if (!uncore->funcs.force_wake_get)
     758                 :            :                 return;
     759                 :            : 
     760         [ #  # ]:          0 :         WARN(uncore->fw_domains_active,
     761                 :            :              "Expected all fw_domains to be inactive, but %08x are still on\n",
     762                 :            :              uncore->fw_domains_active);
     763                 :            : }
     764                 :            : 
     765                 :          0 : void assert_forcewakes_active(struct intel_uncore *uncore,
     766                 :            :                               enum forcewake_domains fw_domains)
     767                 :            : {
     768                 :          0 :         struct intel_uncore_forcewake_domain *domain;
     769                 :          0 :         unsigned int tmp;
     770                 :            : 
     771                 :          0 :         if (!IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM))
     772                 :          0 :                 return;
     773                 :            : 
     774                 :            :         if (!uncore->funcs.force_wake_get)
     775                 :            :                 return;
     776                 :            : 
     777                 :            :         spin_lock_irq(&uncore->lock);
     778                 :            : 
     779                 :            :         assert_rpm_wakelock_held(uncore->rpm);
     780                 :            : 
     781                 :            :         fw_domains &= uncore->fw_domains;
     782                 :            :         WARN(fw_domains & ~uncore->fw_domains_active,
     783                 :            :              "Expected %08x fw_domains to be active, but %08x are off\n",
     784                 :            :              fw_domains, fw_domains & ~uncore->fw_domains_active);
     785                 :            : 
     786                 :            :         /*
     787                 :            :          * Check that the caller has an explicit wakeref and we don't mistake
     788                 :            :          * it for the auto wakeref.
     789                 :            :          */
     790                 :            :         for_each_fw_domain_masked(domain, fw_domains, uncore, tmp) {
     791                 :            :                 unsigned int actual = READ_ONCE(domain->wake_count);
     792                 :            :                 unsigned int expect = 1;
     793                 :            : 
     794                 :            :                 if (uncore->fw_domains_timer & domain->mask)
     795                 :            :                         expect++; /* pending automatic release */
     796                 :            : 
     797                 :            :                 if (WARN(actual < expect,
     798                 :            :                          "Expected domain %d to be held awake by caller, count=%d\n",
     799                 :            :                          domain->id, actual))
     800                 :            :                         break;
     801                 :            :         }
     802                 :            : 
     803                 :            :         spin_unlock_irq(&uncore->lock);
     804                 :            : }
     805                 :            : 
     806                 :            : /* We give fast paths for the really cool registers */
     807                 :            : #define NEEDS_FORCE_WAKE(reg) ((reg) < 0x40000)
     808                 :            : 
     809                 :            : #define __gen6_reg_read_fw_domains(uncore, offset) \
     810                 :            : ({ \
     811                 :            :         enum forcewake_domains __fwd; \
     812                 :            :         if (NEEDS_FORCE_WAKE(offset)) \
     813                 :            :                 __fwd = FORCEWAKE_RENDER; \
     814                 :            :         else \
     815                 :            :                 __fwd = 0; \
     816                 :            :         __fwd; \
     817                 :            : })
     818                 :            : 
     819                 :          0 : static int fw_range_cmp(u32 offset, const struct intel_forcewake_range *entry)
     820                 :            : {
     821                 :          0 :         if (offset < entry->start)
     822                 :            :                 return -1;
     823         [ #  # ]:          0 :         else if (offset > entry->end)
     824                 :            :                 return 1;
     825                 :            :         else
     826                 :            :                 return 0;
     827                 :            : }
     828                 :            : 
     829                 :            : /* Copied and "macroized" from lib/bsearch.c */
     830                 :            : #define BSEARCH(key, base, num, cmp) ({                                 \
     831                 :            :         unsigned int start__ = 0, end__ = (num);                        \
     832                 :            :         typeof(base) result__ = NULL;                                   \
     833                 :            :         while (start__ < end__) {                                       \
     834                 :            :                 unsigned int mid__ = start__ + (end__ - start__) / 2;   \
     835                 :            :                 int ret__ = (cmp)((key), (base) + mid__);               \
     836                 :            :                 if (ret__ < 0) {                                        \
     837                 :            :                         end__ = mid__;                                  \
     838                 :            :                 } else if (ret__ > 0) {                                 \
     839                 :            :                         start__ = mid__ + 1;                            \
     840                 :            :                 } else {                                                \
     841                 :            :                         result__ = (base) + mid__;                      \
     842                 :            :                         break;                                          \
     843                 :            :                 }                                                       \
     844                 :            :         }                                                               \
     845                 :            :         result__;                                                       \
     846                 :            : })
     847                 :            : 
     848                 :            : static enum forcewake_domains
     849                 :          0 : find_fw_domain(struct intel_uncore *uncore, u32 offset)
     850                 :            : {
     851                 :          0 :         const struct intel_forcewake_range *entry;
     852                 :            : 
     853   [ #  #  #  #  :          0 :         entry = BSEARCH(offset,
                   #  # ]
     854                 :            :                         uncore->fw_domains_table,
     855                 :            :                         uncore->fw_domains_table_entries,
     856                 :            :                         fw_range_cmp);
     857                 :            : 
     858         [ #  # ]:          0 :         if (!entry)
     859                 :            :                 return 0;
     860                 :            : 
     861                 :            :         /*
     862                 :            :          * The list of FW domains depends on the SKU in gen11+ so we
     863                 :            :          * can't determine it statically. We use FORCEWAKE_ALL and
     864                 :            :          * translate it here to the list of available domains.
     865                 :            :          */
     866         [ #  # ]:          0 :         if (entry->domains == FORCEWAKE_ALL)
     867                 :          0 :                 return uncore->fw_domains;
     868                 :            : 
     869         [ #  # ]:          0 :         WARN(entry->domains & ~uncore->fw_domains,
     870                 :            :              "Uninitialized forcewake domain(s) 0x%x accessed at 0x%x\n",
     871                 :            :              entry->domains & ~uncore->fw_domains, offset);
     872                 :            : 
     873                 :          0 :         return entry->domains;
     874                 :            : }
     875                 :            : 
     876                 :            : #define GEN_FW_RANGE(s, e, d) \
     877                 :            :         { .start = (s), .end = (e), .domains = (d) }
     878                 :            : 
     879                 :            : #define HAS_FWTABLE(dev_priv) \
     880                 :            :         (INTEL_GEN(dev_priv) >= 9 || \
     881                 :            :          IS_CHERRYVIEW(dev_priv) || \
     882                 :            :          IS_VALLEYVIEW(dev_priv))
     883                 :            : 
     884                 :            : /* *Must* be sorted by offset ranges! See intel_fw_table_check(). */
     885                 :            : static const struct intel_forcewake_range __vlv_fw_ranges[] = {
     886                 :            :         GEN_FW_RANGE(0x2000, 0x3fff, FORCEWAKE_RENDER),
     887                 :            :         GEN_FW_RANGE(0x5000, 0x7fff, FORCEWAKE_RENDER),
     888                 :            :         GEN_FW_RANGE(0xb000, 0x11fff, FORCEWAKE_RENDER),
     889                 :            :         GEN_FW_RANGE(0x12000, 0x13fff, FORCEWAKE_MEDIA),
     890                 :            :         GEN_FW_RANGE(0x22000, 0x23fff, FORCEWAKE_MEDIA),
     891                 :            :         GEN_FW_RANGE(0x2e000, 0x2ffff, FORCEWAKE_RENDER),
     892                 :            :         GEN_FW_RANGE(0x30000, 0x3ffff, FORCEWAKE_MEDIA),
     893                 :            : };
     894                 :            : 
     895                 :            : #define __fwtable_reg_read_fw_domains(uncore, offset) \
     896                 :            : ({ \
     897                 :            :         enum forcewake_domains __fwd = 0; \
     898                 :            :         if (NEEDS_FORCE_WAKE((offset))) \
     899                 :            :                 __fwd = find_fw_domain(uncore, offset); \
     900                 :            :         __fwd; \
     901                 :            : })
     902                 :            : 
     903                 :            : #define __gen11_fwtable_reg_read_fw_domains(uncore, offset) \
     904                 :            :         find_fw_domain(uncore, offset)
     905                 :            : 
     906                 :            : #define __gen12_fwtable_reg_read_fw_domains(uncore, offset) \
     907                 :            :         find_fw_domain(uncore, offset)
     908                 :            : 
     909                 :            : /* *Must* be sorted by offset! See intel_shadow_table_check(). */
     910                 :            : static const i915_reg_t gen8_shadowed_regs[] = {
     911                 :            :         RING_TAIL(RENDER_RING_BASE),    /* 0x2000 (base) */
     912                 :            :         GEN6_RPNSWREQ,                  /* 0xA008 */
     913                 :            :         GEN6_RC_VIDEO_FREQ,             /* 0xA00C */
     914                 :            :         RING_TAIL(GEN6_BSD_RING_BASE),  /* 0x12000 (base) */
     915                 :            :         RING_TAIL(VEBOX_RING_BASE),     /* 0x1a000 (base) */
     916                 :            :         RING_TAIL(BLT_RING_BASE),       /* 0x22000 (base) */
     917                 :            :         /* TODO: Other registers are not yet used */
     918                 :            : };
     919                 :            : 
     920                 :            : static const i915_reg_t gen11_shadowed_regs[] = {
     921                 :            :         RING_TAIL(RENDER_RING_BASE),            /* 0x2000 (base) */
     922                 :            :         GEN6_RPNSWREQ,                          /* 0xA008 */
     923                 :            :         GEN6_RC_VIDEO_FREQ,                     /* 0xA00C */
     924                 :            :         RING_TAIL(BLT_RING_BASE),               /* 0x22000 (base) */
     925                 :            :         RING_TAIL(GEN11_BSD_RING_BASE),         /* 0x1C0000 (base) */
     926                 :            :         RING_TAIL(GEN11_BSD2_RING_BASE),        /* 0x1C4000 (base) */
     927                 :            :         RING_TAIL(GEN11_VEBOX_RING_BASE),       /* 0x1C8000 (base) */
     928                 :            :         RING_TAIL(GEN11_BSD3_RING_BASE),        /* 0x1D0000 (base) */
     929                 :            :         RING_TAIL(GEN11_BSD4_RING_BASE),        /* 0x1D4000 (base) */
     930                 :            :         RING_TAIL(GEN11_VEBOX2_RING_BASE),      /* 0x1D8000 (base) */
     931                 :            :         /* TODO: Other registers are not yet used */
     932                 :            : };
     933                 :            : 
     934                 :            : static const i915_reg_t gen12_shadowed_regs[] = {
     935                 :            :         RING_TAIL(RENDER_RING_BASE),            /* 0x2000 (base) */
     936                 :            :         GEN6_RPNSWREQ,                          /* 0xA008 */
     937                 :            :         GEN6_RC_VIDEO_FREQ,                     /* 0xA00C */
     938                 :            :         RING_TAIL(BLT_RING_BASE),               /* 0x22000 (base) */
     939                 :            :         RING_TAIL(GEN11_BSD_RING_BASE),         /* 0x1C0000 (base) */
     940                 :            :         RING_TAIL(GEN11_BSD2_RING_BASE),        /* 0x1C4000 (base) */
     941                 :            :         RING_TAIL(GEN11_VEBOX_RING_BASE),       /* 0x1C8000 (base) */
     942                 :            :         RING_TAIL(GEN11_BSD3_RING_BASE),        /* 0x1D0000 (base) */
     943                 :            :         RING_TAIL(GEN11_BSD4_RING_BASE),        /* 0x1D4000 (base) */
     944                 :            :         RING_TAIL(GEN11_VEBOX2_RING_BASE),      /* 0x1D8000 (base) */
     945                 :            :         /* TODO: Other registers are not yet used */
     946                 :            : };
     947                 :            : 
     948                 :          0 : static int mmio_reg_cmp(u32 key, const i915_reg_t *reg)
     949                 :            : {
     950                 :          0 :         u32 offset = i915_mmio_reg_offset(*reg);
     951                 :            : 
     952   [ #  #  #  #  :          0 :         if (key < offset)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     953                 :            :                 return -1;
     954   [ #  #  #  #  :          0 :         else if (key > offset)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     955                 :            :                 return 1;
     956                 :            :         else
     957                 :            :                 return 0;
     958                 :            : }
     959                 :            : 
     960                 :            : #define __is_genX_shadowed(x) \
     961                 :            : static bool is_gen##x##_shadowed(u32 offset) \
     962                 :            : { \
     963                 :            :         const i915_reg_t *regs = gen##x##_shadowed_regs; \
     964                 :            :         return BSEARCH(offset, regs, ARRAY_SIZE(gen##x##_shadowed_regs), \
     965                 :            :                        mmio_reg_cmp); \
     966                 :            : }
     967                 :            : 
     968   [ #  #  #  #  :          0 : __is_genX_shadowed(8)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     969   [ #  #  #  #  :          0 : __is_genX_shadowed(11)
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     970   [ #  #  #  #  :          0 : __is_genX_shadowed(12)
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     971                 :            : 
     972                 :            : static enum forcewake_domains
     973                 :          0 : gen6_reg_write_fw_domains(struct intel_uncore *uncore, i915_reg_t reg)
     974                 :            : {
     975                 :          0 :         return FORCEWAKE_RENDER;
     976                 :            : }
     977                 :            : 
     978                 :            : #define __gen8_reg_write_fw_domains(uncore, offset) \
     979                 :            : ({ \
     980                 :            :         enum forcewake_domains __fwd; \
     981                 :            :         if (NEEDS_FORCE_WAKE(offset) && !is_gen8_shadowed(offset)) \
     982                 :            :                 __fwd = FORCEWAKE_RENDER; \
     983                 :            :         else \
     984                 :            :                 __fwd = 0; \
     985                 :            :         __fwd; \
     986                 :            : })
     987                 :            : 
     988                 :            : /* *Must* be sorted by offset ranges! See intel_fw_table_check(). */
     989                 :            : static const struct intel_forcewake_range __chv_fw_ranges[] = {
     990                 :            :         GEN_FW_RANGE(0x2000, 0x3fff, FORCEWAKE_RENDER),
     991                 :            :         GEN_FW_RANGE(0x4000, 0x4fff, FORCEWAKE_RENDER | FORCEWAKE_MEDIA),
     992                 :            :         GEN_FW_RANGE(0x5200, 0x7fff, FORCEWAKE_RENDER),
     993                 :            :         GEN_FW_RANGE(0x8000, 0x82ff, FORCEWAKE_RENDER | FORCEWAKE_MEDIA),
     994                 :            :         GEN_FW_RANGE(0x8300, 0x84ff, FORCEWAKE_RENDER),
     995                 :            :         GEN_FW_RANGE(0x8500, 0x85ff, FORCEWAKE_RENDER | FORCEWAKE_MEDIA),
     996                 :            :         GEN_FW_RANGE(0x8800, 0x88ff, FORCEWAKE_MEDIA),
     997                 :            :         GEN_FW_RANGE(0x9000, 0xafff, FORCEWAKE_RENDER | FORCEWAKE_MEDIA),
     998                 :            :         GEN_FW_RANGE(0xb000, 0xb47f, FORCEWAKE_RENDER),
     999                 :            :         GEN_FW_RANGE(0xd000, 0xd7ff, FORCEWAKE_MEDIA),
    1000                 :            :         GEN_FW_RANGE(0xe000, 0xe7ff, FORCEWAKE_RENDER),
    1001                 :            :         GEN_FW_RANGE(0xf000, 0xffff, FORCEWAKE_RENDER | FORCEWAKE_MEDIA),
    1002                 :            :         GEN_FW_RANGE(0x12000, 0x13fff, FORCEWAKE_MEDIA),
    1003                 :            :         GEN_FW_RANGE(0x1a000, 0x1bfff, FORCEWAKE_MEDIA),
    1004                 :            :         GEN_FW_RANGE(0x1e800, 0x1e9ff, FORCEWAKE_MEDIA),
    1005                 :            :         GEN_FW_RANGE(0x30000, 0x37fff, FORCEWAKE_MEDIA),
    1006                 :            : };
    1007                 :            : 
    1008                 :            : #define __fwtable_reg_write_fw_domains(uncore, offset) \
    1009                 :            : ({ \
    1010                 :            :         enum forcewake_domains __fwd = 0; \
    1011                 :            :         if (NEEDS_FORCE_WAKE((offset)) && !is_gen8_shadowed(offset)) \
    1012                 :            :                 __fwd = find_fw_domain(uncore, offset); \
    1013                 :            :         __fwd; \
    1014                 :            : })
    1015                 :            : 
    1016                 :            : #define __gen11_fwtable_reg_write_fw_domains(uncore, offset) \
    1017                 :            : ({ \
    1018                 :            :         enum forcewake_domains __fwd = 0; \
    1019                 :            :         const u32 __offset = (offset); \
    1020                 :            :         if (!is_gen11_shadowed(__offset)) \
    1021                 :            :                 __fwd = find_fw_domain(uncore, __offset); \
    1022                 :            :         __fwd; \
    1023                 :            : })
    1024                 :            : 
    1025                 :            : #define __gen12_fwtable_reg_write_fw_domains(uncore, offset) \
    1026                 :            : ({ \
    1027                 :            :         enum forcewake_domains __fwd = 0; \
    1028                 :            :         const u32 __offset = (offset); \
    1029                 :            :         if (!is_gen12_shadowed(__offset)) \
    1030                 :            :                 __fwd = find_fw_domain(uncore, __offset); \
    1031                 :            :         __fwd; \
    1032                 :            : })
    1033                 :            : 
    1034                 :            : /* *Must* be sorted by offset ranges! See intel_fw_table_check(). */
    1035                 :            : static const struct intel_forcewake_range __gen9_fw_ranges[] = {
    1036                 :            :         GEN_FW_RANGE(0x0, 0xaff, FORCEWAKE_BLITTER),
    1037                 :            :         GEN_FW_RANGE(0xb00, 0x1fff, 0), /* uncore range */
    1038                 :            :         GEN_FW_RANGE(0x2000, 0x26ff, FORCEWAKE_RENDER),
    1039                 :            :         GEN_FW_RANGE(0x2700, 0x2fff, FORCEWAKE_BLITTER),
    1040                 :            :         GEN_FW_RANGE(0x3000, 0x3fff, FORCEWAKE_RENDER),
    1041                 :            :         GEN_FW_RANGE(0x4000, 0x51ff, FORCEWAKE_BLITTER),
    1042                 :            :         GEN_FW_RANGE(0x5200, 0x7fff, FORCEWAKE_RENDER),
    1043                 :            :         GEN_FW_RANGE(0x8000, 0x812f, FORCEWAKE_BLITTER),
    1044                 :            :         GEN_FW_RANGE(0x8130, 0x813f, FORCEWAKE_MEDIA),
    1045                 :            :         GEN_FW_RANGE(0x8140, 0x815f, FORCEWAKE_RENDER),
    1046                 :            :         GEN_FW_RANGE(0x8160, 0x82ff, FORCEWAKE_BLITTER),
    1047                 :            :         GEN_FW_RANGE(0x8300, 0x84ff, FORCEWAKE_RENDER),
    1048                 :            :         GEN_FW_RANGE(0x8500, 0x87ff, FORCEWAKE_BLITTER),
    1049                 :            :         GEN_FW_RANGE(0x8800, 0x89ff, FORCEWAKE_MEDIA),
    1050                 :            :         GEN_FW_RANGE(0x8a00, 0x8bff, FORCEWAKE_BLITTER),
    1051                 :            :         GEN_FW_RANGE(0x8c00, 0x8cff, FORCEWAKE_RENDER),
    1052                 :            :         GEN_FW_RANGE(0x8d00, 0x93ff, FORCEWAKE_BLITTER),
    1053                 :            :         GEN_FW_RANGE(0x9400, 0x97ff, FORCEWAKE_RENDER | FORCEWAKE_MEDIA),
    1054                 :            :         GEN_FW_RANGE(0x9800, 0xafff, FORCEWAKE_BLITTER),
    1055                 :            :         GEN_FW_RANGE(0xb000, 0xb47f, FORCEWAKE_RENDER),
    1056                 :            :         GEN_FW_RANGE(0xb480, 0xcfff, FORCEWAKE_BLITTER),
    1057                 :            :         GEN_FW_RANGE(0xd000, 0xd7ff, FORCEWAKE_MEDIA),
    1058                 :            :         GEN_FW_RANGE(0xd800, 0xdfff, FORCEWAKE_BLITTER),
    1059                 :            :         GEN_FW_RANGE(0xe000, 0xe8ff, FORCEWAKE_RENDER),
    1060                 :            :         GEN_FW_RANGE(0xe900, 0x11fff, FORCEWAKE_BLITTER),
    1061                 :            :         GEN_FW_RANGE(0x12000, 0x13fff, FORCEWAKE_MEDIA),
    1062                 :            :         GEN_FW_RANGE(0x14000, 0x19fff, FORCEWAKE_BLITTER),
    1063                 :            :         GEN_FW_RANGE(0x1a000, 0x1e9ff, FORCEWAKE_MEDIA),
    1064                 :            :         GEN_FW_RANGE(0x1ea00, 0x243ff, FORCEWAKE_BLITTER),
    1065                 :            :         GEN_FW_RANGE(0x24400, 0x247ff, FORCEWAKE_RENDER),
    1066                 :            :         GEN_FW_RANGE(0x24800, 0x2ffff, FORCEWAKE_BLITTER),
    1067                 :            :         GEN_FW_RANGE(0x30000, 0x3ffff, FORCEWAKE_MEDIA),
    1068                 :            : };
    1069                 :            : 
    1070                 :            : /* *Must* be sorted by offset ranges! See intel_fw_table_check(). */
    1071                 :            : static const struct intel_forcewake_range __gen11_fw_ranges[] = {
    1072                 :            :         GEN_FW_RANGE(0x0, 0xaff, FORCEWAKE_BLITTER),
    1073                 :            :         GEN_FW_RANGE(0xb00, 0x1fff, 0), /* uncore range */
    1074                 :            :         GEN_FW_RANGE(0x2000, 0x26ff, FORCEWAKE_RENDER),
    1075                 :            :         GEN_FW_RANGE(0x2700, 0x2fff, FORCEWAKE_BLITTER),
    1076                 :            :         GEN_FW_RANGE(0x3000, 0x3fff, FORCEWAKE_RENDER),
    1077                 :            :         GEN_FW_RANGE(0x4000, 0x51ff, FORCEWAKE_BLITTER),
    1078                 :            :         GEN_FW_RANGE(0x5200, 0x7fff, FORCEWAKE_RENDER),
    1079                 :            :         GEN_FW_RANGE(0x8000, 0x813f, FORCEWAKE_BLITTER),
    1080                 :            :         GEN_FW_RANGE(0x8140, 0x815f, FORCEWAKE_RENDER),
    1081                 :            :         GEN_FW_RANGE(0x8160, 0x82ff, FORCEWAKE_BLITTER),
    1082                 :            :         GEN_FW_RANGE(0x8300, 0x84ff, FORCEWAKE_RENDER),
    1083                 :            :         GEN_FW_RANGE(0x8500, 0x8bff, FORCEWAKE_BLITTER),
    1084                 :            :         GEN_FW_RANGE(0x8c00, 0x8cff, FORCEWAKE_RENDER),
    1085                 :            :         GEN_FW_RANGE(0x8d00, 0x93ff, FORCEWAKE_BLITTER),
    1086                 :            :         GEN_FW_RANGE(0x9400, 0x97ff, FORCEWAKE_ALL),
    1087                 :            :         GEN_FW_RANGE(0x9800, 0xafff, FORCEWAKE_BLITTER),
    1088                 :            :         GEN_FW_RANGE(0xb000, 0xb47f, FORCEWAKE_RENDER),
    1089                 :            :         GEN_FW_RANGE(0xb480, 0xdeff, FORCEWAKE_BLITTER),
    1090                 :            :         GEN_FW_RANGE(0xdf00, 0xe8ff, FORCEWAKE_RENDER),
    1091                 :            :         GEN_FW_RANGE(0xe900, 0x16dff, FORCEWAKE_BLITTER),
    1092                 :            :         GEN_FW_RANGE(0x16e00, 0x19fff, FORCEWAKE_RENDER),
    1093                 :            :         GEN_FW_RANGE(0x1a000, 0x243ff, FORCEWAKE_BLITTER),
    1094                 :            :         GEN_FW_RANGE(0x24400, 0x247ff, FORCEWAKE_RENDER),
    1095                 :            :         GEN_FW_RANGE(0x24800, 0x3ffff, FORCEWAKE_BLITTER),
    1096                 :            :         GEN_FW_RANGE(0x40000, 0x1bffff, 0),
    1097                 :            :         GEN_FW_RANGE(0x1c0000, 0x1c3fff, FORCEWAKE_MEDIA_VDBOX0),
    1098                 :            :         GEN_FW_RANGE(0x1c4000, 0x1c7fff, FORCEWAKE_MEDIA_VDBOX1),
    1099                 :            :         GEN_FW_RANGE(0x1c8000, 0x1cbfff, FORCEWAKE_MEDIA_VEBOX0),
    1100                 :            :         GEN_FW_RANGE(0x1cc000, 0x1cffff, FORCEWAKE_BLITTER),
    1101                 :            :         GEN_FW_RANGE(0x1d0000, 0x1d3fff, FORCEWAKE_MEDIA_VDBOX2),
    1102                 :            :         GEN_FW_RANGE(0x1d4000, 0x1d7fff, FORCEWAKE_MEDIA_VDBOX3),
    1103                 :            :         GEN_FW_RANGE(0x1d8000, 0x1dbfff, FORCEWAKE_MEDIA_VEBOX1)
    1104                 :            : };
    1105                 :            : 
    1106                 :            : /* *Must* be sorted by offset ranges! See intel_fw_table_check(). */
    1107                 :            : static const struct intel_forcewake_range __gen12_fw_ranges[] = {
    1108                 :            :         GEN_FW_RANGE(0x0, 0xaff, FORCEWAKE_BLITTER),
    1109                 :            :         GEN_FW_RANGE(0xb00, 0x1fff, 0), /* uncore range */
    1110                 :            :         GEN_FW_RANGE(0x2000, 0x26ff, FORCEWAKE_RENDER),
    1111                 :            :         GEN_FW_RANGE(0x2700, 0x2fff, FORCEWAKE_BLITTER),
    1112                 :            :         GEN_FW_RANGE(0x3000, 0x3fff, FORCEWAKE_RENDER),
    1113                 :            :         GEN_FW_RANGE(0x4000, 0x51ff, FORCEWAKE_BLITTER),
    1114                 :            :         GEN_FW_RANGE(0x5200, 0x7fff, FORCEWAKE_RENDER),
    1115                 :            :         GEN_FW_RANGE(0x8000, 0x813f, FORCEWAKE_BLITTER),
    1116                 :            :         GEN_FW_RANGE(0x8140, 0x815f, FORCEWAKE_RENDER),
    1117                 :            :         GEN_FW_RANGE(0x8160, 0x82ff, FORCEWAKE_BLITTER),
    1118                 :            :         GEN_FW_RANGE(0x8300, 0x84ff, FORCEWAKE_RENDER),
    1119                 :            :         GEN_FW_RANGE(0x8500, 0x8bff, FORCEWAKE_BLITTER),
    1120                 :            :         GEN_FW_RANGE(0x8c00, 0x8cff, FORCEWAKE_RENDER),
    1121                 :            :         GEN_FW_RANGE(0x8d00, 0x93ff, FORCEWAKE_BLITTER),
    1122                 :            :         GEN_FW_RANGE(0x9400, 0x97ff, FORCEWAKE_ALL),
    1123                 :            :         GEN_FW_RANGE(0x9800, 0xafff, FORCEWAKE_BLITTER),
    1124                 :            :         GEN_FW_RANGE(0xb000, 0xb47f, FORCEWAKE_RENDER),
    1125                 :            :         GEN_FW_RANGE(0xb480, 0xdfff, FORCEWAKE_BLITTER),
    1126                 :            :         GEN_FW_RANGE(0xe000, 0xe8ff, FORCEWAKE_RENDER),
    1127                 :            :         GEN_FW_RANGE(0xe900, 0x147ff, FORCEWAKE_BLITTER),
    1128                 :            :         GEN_FW_RANGE(0x14800, 0x148ff, FORCEWAKE_RENDER),
    1129                 :            :         GEN_FW_RANGE(0x14900, 0x19fff, FORCEWAKE_BLITTER),
    1130                 :            :         GEN_FW_RANGE(0x1a000, 0x1a7ff, FORCEWAKE_RENDER),
    1131                 :            :         GEN_FW_RANGE(0x1a800, 0x1afff, FORCEWAKE_BLITTER),
    1132                 :            :         GEN_FW_RANGE(0x1b000, 0x1bfff, FORCEWAKE_RENDER),
    1133                 :            :         GEN_FW_RANGE(0x1c000, 0x243ff, FORCEWAKE_BLITTER),
    1134                 :            :         GEN_FW_RANGE(0x24400, 0x247ff, FORCEWAKE_RENDER),
    1135                 :            :         GEN_FW_RANGE(0x24800, 0x3ffff, FORCEWAKE_BLITTER),
    1136                 :            :         GEN_FW_RANGE(0x40000, 0x1bffff, 0),
    1137                 :            :         GEN_FW_RANGE(0x1c0000, 0x1c3fff, FORCEWAKE_MEDIA_VDBOX0),
    1138                 :            :         GEN_FW_RANGE(0x1c4000, 0x1c7fff, FORCEWAKE_MEDIA_VDBOX1),
    1139                 :            :         GEN_FW_RANGE(0x1c8000, 0x1cbfff, FORCEWAKE_MEDIA_VEBOX0),
    1140                 :            :         GEN_FW_RANGE(0x1cc000, 0x1cffff, FORCEWAKE_BLITTER),
    1141                 :            :         GEN_FW_RANGE(0x1d0000, 0x1d3fff, FORCEWAKE_MEDIA_VDBOX2),
    1142                 :            :         GEN_FW_RANGE(0x1d4000, 0x1d7fff, FORCEWAKE_MEDIA_VDBOX3),
    1143                 :            :         GEN_FW_RANGE(0x1d8000, 0x1dbfff, FORCEWAKE_MEDIA_VEBOX1)
    1144                 :            : };
    1145                 :            : 
    1146                 :            : static void
    1147                 :          0 : ilk_dummy_write(struct intel_uncore *uncore)
    1148                 :            : {
    1149                 :            :         /* WaIssueDummyWriteToWakeupFromRC6:ilk Issue a dummy write to wake up
    1150                 :            :          * the chip from rc6 before touching it for real. MI_MODE is masked,
    1151                 :            :          * hence harmless to write 0 into. */
    1152                 :          0 :         __raw_uncore_write32(uncore, MI_MODE, 0);
    1153                 :            : }
    1154                 :            : 
    1155                 :            : static void
    1156                 :          0 : __unclaimed_reg_debug(struct intel_uncore *uncore,
    1157                 :            :                       const i915_reg_t reg,
    1158                 :            :                       const bool read,
    1159                 :            :                       const bool before)
    1160                 :            : {
    1161   [ #  #  #  #  :          0 :         if (WARN(check_for_unclaimed_mmio(uncore) && !before,
          #  #  #  #  #  
                      # ]
    1162                 :            :                  "Unclaimed %s register 0x%x\n",
    1163                 :            :                  read ? "read from" : "write to",
    1164                 :            :                  i915_mmio_reg_offset(reg)))
    1165                 :            :                 /* Only report the first N failures */
    1166                 :          0 :                 i915_modparams.mmio_debug--;
    1167                 :          0 : }
    1168                 :            : 
    1169                 :            : static inline void
    1170                 :          0 : unclaimed_reg_debug(struct intel_uncore *uncore,
    1171                 :            :                     const i915_reg_t reg,
    1172                 :            :                     const bool read,
    1173                 :            :                     const bool before)
    1174                 :            : {
    1175         [ #  # ]:          0 :         if (likely(!i915_modparams.mmio_debug))
    1176                 :            :                 return;
    1177                 :            : 
    1178                 :            :         /* interrupts are disabled and re-enabled around uncore->lock usage */
    1179                 :          0 :         lockdep_assert_held(&uncore->lock);
    1180                 :            : 
    1181         [ #  # ]:          0 :         if (before)
    1182                 :          0 :                 spin_lock(&uncore->debug->lock);
    1183                 :            : 
    1184                 :          0 :         __unclaimed_reg_debug(uncore, reg, read, before);
    1185                 :            : 
    1186         [ #  # ]:          0 :         if (!before)
    1187                 :          0 :                 spin_unlock(&uncore->debug->lock);
    1188                 :            : }
    1189                 :            : 
    1190                 :            : #define GEN2_READ_HEADER(x) \
    1191                 :            :         u##x val = 0; \
    1192                 :            :         assert_rpm_wakelock_held(uncore->rpm);
    1193                 :            : 
    1194                 :            : #define GEN2_READ_FOOTER \
    1195                 :            :         trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
    1196                 :            :         return val
    1197                 :            : 
    1198                 :            : #define __gen2_read(x) \
    1199                 :            : static u##x \
    1200                 :            : gen2_read##x(struct intel_uncore *uncore, i915_reg_t reg, bool trace) { \
    1201                 :            :         GEN2_READ_HEADER(x); \
    1202                 :            :         val = __raw_uncore_read##x(uncore, reg); \
    1203                 :            :         GEN2_READ_FOOTER; \
    1204                 :            : }
    1205                 :            : 
    1206                 :            : #define __gen5_read(x) \
    1207                 :            : static u##x \
    1208                 :            : gen5_read##x(struct intel_uncore *uncore, i915_reg_t reg, bool trace) { \
    1209                 :            :         GEN2_READ_HEADER(x); \
    1210                 :            :         ilk_dummy_write(uncore); \
    1211                 :            :         val = __raw_uncore_read##x(uncore, reg); \
    1212                 :            :         GEN2_READ_FOOTER; \
    1213                 :            : }
    1214                 :            : 
    1215                 :          0 : __gen5_read(8)
    1216                 :          0 : __gen5_read(16)
    1217                 :          0 : __gen5_read(32)
    1218                 :          0 : __gen5_read(64)
    1219                 :          0 : __gen2_read(8)
    1220                 :          0 : __gen2_read(16)
    1221                 :          0 : __gen2_read(32)
    1222                 :          0 : __gen2_read(64)
    1223                 :            : 
    1224                 :            : #undef __gen5_read
    1225                 :            : #undef __gen2_read
    1226                 :            : 
    1227                 :            : #undef GEN2_READ_FOOTER
    1228                 :            : #undef GEN2_READ_HEADER
    1229                 :            : 
    1230                 :            : #define GEN6_READ_HEADER(x) \
    1231                 :            :         u32 offset = i915_mmio_reg_offset(reg); \
    1232                 :            :         unsigned long irqflags; \
    1233                 :            :         u##x val = 0; \
    1234                 :            :         assert_rpm_wakelock_held(uncore->rpm); \
    1235                 :            :         spin_lock_irqsave(&uncore->lock, irqflags); \
    1236                 :            :         unclaimed_reg_debug(uncore, reg, true, true)
    1237                 :            : 
    1238                 :            : #define GEN6_READ_FOOTER \
    1239                 :            :         unclaimed_reg_debug(uncore, reg, true, false); \
    1240                 :            :         spin_unlock_irqrestore(&uncore->lock, irqflags); \
    1241                 :            :         trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
    1242                 :            :         return val
    1243                 :            : 
    1244                 :          0 : static noinline void ___force_wake_auto(struct intel_uncore *uncore,
    1245                 :            :                                         enum forcewake_domains fw_domains)
    1246                 :            : {
    1247                 :          0 :         struct intel_uncore_forcewake_domain *domain;
    1248                 :          0 :         unsigned int tmp;
    1249                 :            : 
    1250                 :          0 :         GEM_BUG_ON(fw_domains & ~uncore->fw_domains);
    1251                 :            : 
    1252   [ #  #  #  # ]:          0 :         for_each_fw_domain_masked(domain, fw_domains, uncore, tmp)
    1253                 :          0 :                 fw_domain_arm_timer(domain);
    1254                 :            : 
    1255                 :          0 :         uncore->funcs.force_wake_get(uncore, fw_domains);
    1256                 :          0 : }
    1257                 :            : 
    1258                 :          0 : static inline void __force_wake_auto(struct intel_uncore *uncore,
    1259                 :            :                                      enum forcewake_domains fw_domains)
    1260                 :            : {
    1261                 :          0 :         GEM_BUG_ON(!fw_domains);
    1262                 :            : 
    1263                 :            :         /* Turn on all requested but inactive supported forcewake domains. */
    1264                 :          0 :         fw_domains &= uncore->fw_domains;
    1265                 :          0 :         fw_domains &= ~uncore->fw_domains_active;
    1266                 :            : 
    1267                 :          0 :         if (fw_domains)
    1268                 :          0 :                 ___force_wake_auto(uncore, fw_domains);
    1269                 :            : }
    1270                 :            : 
    1271                 :            : #define __gen_read(func, x) \
    1272                 :            : static u##x \
    1273                 :            : func##_read##x(struct intel_uncore *uncore, i915_reg_t reg, bool trace) { \
    1274                 :            :         enum forcewake_domains fw_engine; \
    1275                 :            :         GEN6_READ_HEADER(x); \
    1276                 :            :         fw_engine = __##func##_reg_read_fw_domains(uncore, offset); \
    1277                 :            :         if (fw_engine) \
    1278                 :            :                 __force_wake_auto(uncore, fw_engine); \
    1279                 :            :         val = __raw_uncore_read##x(uncore, reg); \
    1280                 :            :         GEN6_READ_FOOTER; \
    1281                 :            : }
    1282                 :            : 
    1283                 :            : #define __gen_reg_read_funcs(func) \
    1284                 :            : static enum forcewake_domains \
    1285                 :            : func##_reg_read_fw_domains(struct intel_uncore *uncore, i915_reg_t reg) { \
    1286                 :            :         return __##func##_reg_read_fw_domains(uncore, i915_mmio_reg_offset(reg)); \
    1287                 :            : } \
    1288                 :            : \
    1289                 :            : __gen_read(func, 8) \
    1290                 :            : __gen_read(func, 16) \
    1291                 :            : __gen_read(func, 32) \
    1292                 :            : __gen_read(func, 64)
    1293                 :            : 
    1294   [ #  #  #  # ]:          0 : __gen_reg_read_funcs(gen12_fwtable);
    1295   [ #  #  #  # ]:          0 : __gen_reg_read_funcs(gen11_fwtable);
    1296   [ #  #  #  #  :          0 : __gen_reg_read_funcs(fwtable);
                   #  # ]
    1297   [ #  #  #  # ]:          0 : __gen_reg_read_funcs(gen6);
    1298                 :            : 
    1299                 :            : #undef __gen_reg_read_funcs
    1300                 :            : #undef GEN6_READ_FOOTER
    1301                 :            : #undef GEN6_READ_HEADER
    1302                 :            : 
    1303                 :            : #define GEN2_WRITE_HEADER \
    1304                 :            :         trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
    1305                 :            :         assert_rpm_wakelock_held(uncore->rpm); \
    1306                 :            : 
    1307                 :            : #define GEN2_WRITE_FOOTER
    1308                 :            : 
    1309                 :            : #define __gen2_write(x) \
    1310                 :            : static void \
    1311                 :            : gen2_write##x(struct intel_uncore *uncore, i915_reg_t reg, u##x val, bool trace) { \
    1312                 :            :         GEN2_WRITE_HEADER; \
    1313                 :            :         __raw_uncore_write##x(uncore, reg, val); \
    1314                 :            :         GEN2_WRITE_FOOTER; \
    1315                 :            : }
    1316                 :            : 
    1317                 :            : #define __gen5_write(x) \
    1318                 :            : static void \
    1319                 :            : gen5_write##x(struct intel_uncore *uncore, i915_reg_t reg, u##x val, bool trace) { \
    1320                 :            :         GEN2_WRITE_HEADER; \
    1321                 :            :         ilk_dummy_write(uncore); \
    1322                 :            :         __raw_uncore_write##x(uncore, reg, val); \
    1323                 :            :         GEN2_WRITE_FOOTER; \
    1324                 :            : }
    1325                 :            : 
    1326                 :          0 : __gen5_write(8)
    1327                 :          0 : __gen5_write(16)
    1328                 :          0 : __gen5_write(32)
    1329                 :          0 : __gen2_write(8)
    1330                 :          0 : __gen2_write(16)
    1331                 :          0 : __gen2_write(32)
    1332                 :            : 
    1333                 :            : #undef __gen5_write
    1334                 :            : #undef __gen2_write
    1335                 :            : 
    1336                 :            : #undef GEN2_WRITE_FOOTER
    1337                 :            : #undef GEN2_WRITE_HEADER
    1338                 :            : 
    1339                 :            : #define GEN6_WRITE_HEADER \
    1340                 :            :         u32 offset = i915_mmio_reg_offset(reg); \
    1341                 :            :         unsigned long irqflags; \
    1342                 :            :         trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
    1343                 :            :         assert_rpm_wakelock_held(uncore->rpm); \
    1344                 :            :         spin_lock_irqsave(&uncore->lock, irqflags); \
    1345                 :            :         unclaimed_reg_debug(uncore, reg, false, true)
    1346                 :            : 
    1347                 :            : #define GEN6_WRITE_FOOTER \
    1348                 :            :         unclaimed_reg_debug(uncore, reg, false, false); \
    1349                 :            :         spin_unlock_irqrestore(&uncore->lock, irqflags)
    1350                 :            : 
    1351                 :            : #define __gen6_write(x) \
    1352                 :            : static void \
    1353                 :            : gen6_write##x(struct intel_uncore *uncore, i915_reg_t reg, u##x val, bool trace) { \
    1354                 :            :         GEN6_WRITE_HEADER; \
    1355                 :            :         if (NEEDS_FORCE_WAKE(offset)) \
    1356                 :            :                 __gen6_gt_wait_for_fifo(uncore); \
    1357                 :            :         __raw_uncore_write##x(uncore, reg, val); \
    1358                 :            :         GEN6_WRITE_FOOTER; \
    1359                 :            : }
    1360         [ #  # ]:          0 : __gen6_write(8)
    1361         [ #  # ]:          0 : __gen6_write(16)
    1362         [ #  # ]:          0 : __gen6_write(32)
    1363                 :            : 
    1364                 :            : #define __gen_write(func, x) \
    1365                 :            : static void \
    1366                 :            : func##_write##x(struct intel_uncore *uncore, i915_reg_t reg, u##x val, bool trace) { \
    1367                 :            :         enum forcewake_domains fw_engine; \
    1368                 :            :         GEN6_WRITE_HEADER; \
    1369                 :            :         fw_engine = __##func##_reg_write_fw_domains(uncore, offset); \
    1370                 :            :         if (fw_engine) \
    1371                 :            :                 __force_wake_auto(uncore, fw_engine); \
    1372                 :            :         __raw_uncore_write##x(uncore, reg, val); \
    1373                 :            :         GEN6_WRITE_FOOTER; \
    1374                 :            : }
    1375                 :            : 
    1376                 :            : #define __gen_reg_write_funcs(func) \
    1377                 :            : static enum forcewake_domains \
    1378                 :            : func##_reg_write_fw_domains(struct intel_uncore *uncore, i915_reg_t reg) { \
    1379                 :            :         return __##func##_reg_write_fw_domains(uncore, i915_mmio_reg_offset(reg)); \
    1380                 :            : } \
    1381                 :            : \
    1382                 :            : __gen_write(func, 8) \
    1383                 :            : __gen_write(func, 16) \
    1384                 :            : __gen_write(func, 32)
    1385                 :            : 
    1386   [ #  #  #  #  :          0 : __gen_reg_write_funcs(gen12_fwtable);
                   #  # ]
    1387   [ #  #  #  #  :          0 : __gen_reg_write_funcs(gen11_fwtable);
                   #  # ]
    1388   [ #  #  #  #  :          0 : __gen_reg_write_funcs(fwtable);
             #  #  #  # ]
    1389   [ #  #  #  #  :          0 : __gen_reg_write_funcs(gen8);
                   #  # ]
    1390                 :            : 
    1391                 :            : #undef __gen_reg_write_funcs
    1392                 :            : #undef GEN6_WRITE_FOOTER
    1393                 :            : #undef GEN6_WRITE_HEADER
    1394                 :            : 
    1395                 :            : #define ASSIGN_RAW_WRITE_MMIO_VFUNCS(uncore, x) \
    1396                 :            : do { \
    1397                 :            :         (uncore)->funcs.mmio_writeb = x##_write8; \
    1398                 :            :         (uncore)->funcs.mmio_writew = x##_write16; \
    1399                 :            :         (uncore)->funcs.mmio_writel = x##_write32; \
    1400                 :            : } while (0)
    1401                 :            : 
    1402                 :            : #define ASSIGN_RAW_READ_MMIO_VFUNCS(uncore, x) \
    1403                 :            : do { \
    1404                 :            :         (uncore)->funcs.mmio_readb = x##_read8; \
    1405                 :            :         (uncore)->funcs.mmio_readw = x##_read16; \
    1406                 :            :         (uncore)->funcs.mmio_readl = x##_read32; \
    1407                 :            :         (uncore)->funcs.mmio_readq = x##_read64; \
    1408                 :            : } while (0)
    1409                 :            : 
    1410                 :            : #define ASSIGN_WRITE_MMIO_VFUNCS(uncore, x) \
    1411                 :            : do { \
    1412                 :            :         ASSIGN_RAW_WRITE_MMIO_VFUNCS((uncore), x); \
    1413                 :            :         (uncore)->funcs.write_fw_domains = x##_reg_write_fw_domains; \
    1414                 :            : } while (0)
    1415                 :            : 
    1416                 :            : #define ASSIGN_READ_MMIO_VFUNCS(uncore, x) \
    1417                 :            : do { \
    1418                 :            :         ASSIGN_RAW_READ_MMIO_VFUNCS(uncore, x); \
    1419                 :            :         (uncore)->funcs.read_fw_domains = x##_reg_read_fw_domains; \
    1420                 :            : } while (0)
    1421                 :            : 
    1422                 :          0 : static int __fw_domain_init(struct intel_uncore *uncore,
    1423                 :            :                             enum forcewake_domain_id domain_id,
    1424                 :            :                             i915_reg_t reg_set,
    1425                 :            :                             i915_reg_t reg_ack)
    1426                 :            : {
    1427                 :          0 :         struct intel_uncore_forcewake_domain *d;
    1428                 :            : 
    1429                 :          0 :         GEM_BUG_ON(domain_id >= FW_DOMAIN_ID_COUNT);
    1430                 :          0 :         GEM_BUG_ON(uncore->fw_domain[domain_id]);
    1431                 :            : 
    1432                 :          0 :         if (i915_inject_probe_failure(uncore->i915))
    1433                 :            :                 return -ENOMEM;
    1434                 :            : 
    1435                 :          0 :         d = kzalloc(sizeof(*d), GFP_KERNEL);
    1436         [ #  # ]:          0 :         if (!d)
    1437                 :            :                 return -ENOMEM;
    1438                 :            : 
    1439         [ #  # ]:          0 :         WARN_ON(!i915_mmio_reg_valid(reg_set));
    1440         [ #  # ]:          0 :         WARN_ON(!i915_mmio_reg_valid(reg_ack));
    1441                 :            : 
    1442                 :          0 :         d->uncore = uncore;
    1443                 :          0 :         d->wake_count = 0;
    1444                 :          0 :         d->reg_set = uncore->regs + i915_mmio_reg_offset(reg_set);
    1445                 :          0 :         d->reg_ack = uncore->regs + i915_mmio_reg_offset(reg_ack);
    1446                 :            : 
    1447                 :          0 :         d->id = domain_id;
    1448                 :            : 
    1449                 :          0 :         BUILD_BUG_ON(FORCEWAKE_RENDER != (1 << FW_DOMAIN_ID_RENDER));
    1450                 :          0 :         BUILD_BUG_ON(FORCEWAKE_BLITTER != (1 << FW_DOMAIN_ID_BLITTER));
    1451                 :          0 :         BUILD_BUG_ON(FORCEWAKE_MEDIA != (1 << FW_DOMAIN_ID_MEDIA));
    1452                 :          0 :         BUILD_BUG_ON(FORCEWAKE_MEDIA_VDBOX0 != (1 << FW_DOMAIN_ID_MEDIA_VDBOX0));
    1453                 :          0 :         BUILD_BUG_ON(FORCEWAKE_MEDIA_VDBOX1 != (1 << FW_DOMAIN_ID_MEDIA_VDBOX1));
    1454                 :          0 :         BUILD_BUG_ON(FORCEWAKE_MEDIA_VDBOX2 != (1 << FW_DOMAIN_ID_MEDIA_VDBOX2));
    1455                 :          0 :         BUILD_BUG_ON(FORCEWAKE_MEDIA_VDBOX3 != (1 << FW_DOMAIN_ID_MEDIA_VDBOX3));
    1456                 :          0 :         BUILD_BUG_ON(FORCEWAKE_MEDIA_VEBOX0 != (1 << FW_DOMAIN_ID_MEDIA_VEBOX0));
    1457                 :          0 :         BUILD_BUG_ON(FORCEWAKE_MEDIA_VEBOX1 != (1 << FW_DOMAIN_ID_MEDIA_VEBOX1));
    1458                 :            : 
    1459                 :          0 :         d->mask = BIT(domain_id);
    1460                 :            : 
    1461                 :          0 :         hrtimer_init(&d->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    1462                 :          0 :         d->timer.function = intel_uncore_fw_release_timer;
    1463                 :            : 
    1464                 :          0 :         uncore->fw_domains |= BIT(domain_id);
    1465                 :            : 
    1466                 :          0 :         fw_domain_reset(d);
    1467                 :            : 
    1468                 :          0 :         uncore->fw_domain[domain_id] = d;
    1469                 :            : 
    1470                 :          0 :         return 0;
    1471                 :            : }
    1472                 :            : 
    1473                 :          0 : static void fw_domain_fini(struct intel_uncore *uncore,
    1474                 :            :                            enum forcewake_domain_id domain_id)
    1475                 :            : {
    1476                 :          0 :         struct intel_uncore_forcewake_domain *d;
    1477                 :            : 
    1478                 :          0 :         GEM_BUG_ON(domain_id >= FW_DOMAIN_ID_COUNT);
    1479                 :            : 
    1480                 :          0 :         d = fetch_and_zero(&uncore->fw_domain[domain_id]);
    1481         [ #  # ]:          0 :         if (!d)
    1482                 :            :                 return;
    1483                 :            : 
    1484                 :          0 :         uncore->fw_domains &= ~BIT(domain_id);
    1485         [ #  # ]:          0 :         WARN_ON(d->wake_count);
    1486         [ #  # ]:          0 :         WARN_ON(hrtimer_cancel(&d->timer));
    1487                 :          0 :         kfree(d);
    1488                 :            : }
    1489                 :            : 
    1490                 :          0 : static void intel_uncore_fw_domains_fini(struct intel_uncore *uncore)
    1491                 :            : {
    1492                 :          0 :         struct intel_uncore_forcewake_domain *d;
    1493                 :          0 :         int tmp;
    1494                 :            : 
    1495   [ #  #  #  # ]:          0 :         for_each_fw_domain(d, uncore, tmp)
    1496                 :          0 :                 fw_domain_fini(uncore, d->id);
    1497                 :          0 : }
    1498                 :            : 
    1499                 :          0 : static int intel_uncore_fw_domains_init(struct intel_uncore *uncore)
    1500                 :            : {
    1501                 :          0 :         struct drm_i915_private *i915 = uncore->i915;
    1502                 :          0 :         int ret = 0;
    1503                 :            : 
    1504                 :          0 :         GEM_BUG_ON(!intel_uncore_has_forcewake(uncore));
    1505                 :            : 
    1506                 :            : #define fw_domain_init(uncore__, id__, set__, ack__) \
    1507                 :            :         (ret ?: (ret = __fw_domain_init((uncore__), (id__), (set__), (ack__))))
    1508                 :            : 
    1509         [ #  # ]:          0 :         if (INTEL_GEN(i915) >= 11) {
    1510                 :          0 :                 int i;
    1511                 :            : 
    1512                 :          0 :                 uncore->funcs.force_wake_get = fw_domains_get_with_fallback;
    1513                 :          0 :                 uncore->funcs.force_wake_put = fw_domains_put;
    1514                 :          0 :                 fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
    1515                 :            :                                FORCEWAKE_RENDER_GEN9,
    1516                 :            :                                FORCEWAKE_ACK_RENDER_GEN9);
    1517         [ #  # ]:          0 :                 fw_domain_init(uncore, FW_DOMAIN_ID_BLITTER,
    1518                 :            :                                FORCEWAKE_BLITTER_GEN9,
    1519                 :            :                                FORCEWAKE_ACK_BLITTER_GEN9);
    1520                 :            : 
    1521         [ #  # ]:          0 :                 for (i = 0; i < I915_MAX_VCS; i++) {
    1522         [ #  # ]:          0 :                         if (!HAS_ENGINE(i915, _VCS(i)))
    1523                 :          0 :                                 continue;
    1524                 :            : 
    1525         [ #  # ]:          0 :                         fw_domain_init(uncore, FW_DOMAIN_ID_MEDIA_VDBOX0 + i,
    1526                 :            :                                        FORCEWAKE_MEDIA_VDBOX_GEN11(i),
    1527                 :            :                                        FORCEWAKE_ACK_MEDIA_VDBOX_GEN11(i));
    1528                 :            :                 }
    1529         [ #  # ]:          0 :                 for (i = 0; i < I915_MAX_VECS; i++) {
    1530         [ #  # ]:          0 :                         if (!HAS_ENGINE(i915, _VECS(i)))
    1531                 :          0 :                                 continue;
    1532                 :            : 
    1533         [ #  # ]:          0 :                         fw_domain_init(uncore, FW_DOMAIN_ID_MEDIA_VEBOX0 + i,
    1534                 :            :                                        FORCEWAKE_MEDIA_VEBOX_GEN11(i),
    1535                 :            :                                        FORCEWAKE_ACK_MEDIA_VEBOX_GEN11(i));
    1536                 :            :                 }
    1537         [ #  # ]:          0 :         } else if (IS_GEN_RANGE(i915, 9, 10)) {
    1538                 :          0 :                 uncore->funcs.force_wake_get = fw_domains_get_with_fallback;
    1539                 :          0 :                 uncore->funcs.force_wake_put = fw_domains_put;
    1540                 :          0 :                 fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
    1541                 :            :                                FORCEWAKE_RENDER_GEN9,
    1542                 :            :                                FORCEWAKE_ACK_RENDER_GEN9);
    1543         [ #  # ]:          0 :                 fw_domain_init(uncore, FW_DOMAIN_ID_BLITTER,
    1544                 :            :                                FORCEWAKE_BLITTER_GEN9,
    1545                 :            :                                FORCEWAKE_ACK_BLITTER_GEN9);
    1546         [ #  # ]:          0 :                 fw_domain_init(uncore, FW_DOMAIN_ID_MEDIA,
    1547                 :            :                                FORCEWAKE_MEDIA_GEN9, FORCEWAKE_ACK_MEDIA_GEN9);
    1548   [ #  #  #  # ]:          0 :         } else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
    1549                 :          0 :                 uncore->funcs.force_wake_get = fw_domains_get;
    1550                 :          0 :                 uncore->funcs.force_wake_put = fw_domains_put;
    1551                 :          0 :                 fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
    1552                 :            :                                FORCEWAKE_VLV, FORCEWAKE_ACK_VLV);
    1553         [ #  # ]:          0 :                 fw_domain_init(uncore, FW_DOMAIN_ID_MEDIA,
    1554                 :            :                                FORCEWAKE_MEDIA_VLV, FORCEWAKE_ACK_MEDIA_VLV);
    1555   [ #  #  #  # ]:          0 :         } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
    1556                 :          0 :                 uncore->funcs.force_wake_get =
    1557                 :            :                         fw_domains_get_with_thread_status;
    1558                 :          0 :                 uncore->funcs.force_wake_put = fw_domains_put;
    1559                 :          0 :                 fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
    1560                 :            :                                FORCEWAKE_MT, FORCEWAKE_ACK_HSW);
    1561         [ #  # ]:          0 :         } else if (IS_IVYBRIDGE(i915)) {
    1562                 :          0 :                 u32 ecobus;
    1563                 :            : 
    1564                 :            :                 /* IVB configs may use multi-threaded forcewake */
    1565                 :            : 
    1566                 :            :                 /* A small trick here - if the bios hasn't configured
    1567                 :            :                  * MT forcewake, and if the device is in RC6, then
    1568                 :            :                  * force_wake_mt_get will not wake the device and the
    1569                 :            :                  * ECOBUS read will return zero. Which will be
    1570                 :            :                  * (correctly) interpreted by the test below as MT
    1571                 :            :                  * forcewake being disabled.
    1572                 :            :                  */
    1573                 :          0 :                 uncore->funcs.force_wake_get =
    1574                 :            :                         fw_domains_get_with_thread_status;
    1575                 :          0 :                 uncore->funcs.force_wake_put = fw_domains_put;
    1576                 :            : 
    1577                 :            :                 /* We need to init first for ECOBUS access and then
    1578                 :            :                  * determine later if we want to reinit, in case of MT access is
    1579                 :            :                  * not working. In this stage we don't know which flavour this
    1580                 :            :                  * ivb is, so it is better to reset also the gen6 fw registers
    1581                 :            :                  * before the ecobus check.
    1582                 :            :                  */
    1583                 :            : 
    1584                 :          0 :                 __raw_uncore_write32(uncore, FORCEWAKE, 0);
    1585                 :          0 :                 __raw_posting_read(uncore, ECOBUS);
    1586                 :            : 
    1587                 :          0 :                 ret = __fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
    1588                 :          0 :                                        FORCEWAKE_MT, FORCEWAKE_MT_ACK);
    1589         [ #  # ]:          0 :                 if (ret)
    1590                 :          0 :                         goto out;
    1591                 :            : 
    1592                 :          0 :                 spin_lock_irq(&uncore->lock);
    1593                 :          0 :                 fw_domains_get_with_thread_status(uncore, FORCEWAKE_RENDER);
    1594                 :          0 :                 ecobus = __raw_uncore_read32(uncore, ECOBUS);
    1595                 :          0 :                 fw_domains_put(uncore, FORCEWAKE_RENDER);
    1596                 :          0 :                 spin_unlock_irq(&uncore->lock);
    1597                 :            : 
    1598         [ #  # ]:          0 :                 if (!(ecobus & FORCEWAKE_MT_ENABLE)) {
    1599                 :          0 :                         drm_info(&i915->drm, "No MT forcewake available on Ivybridge, this can result in issues\n");
    1600                 :          0 :                         drm_info(&i915->drm, "when using vblank-synced partial screen updates.\n");
    1601                 :          0 :                         fw_domain_fini(uncore, FW_DOMAIN_ID_RENDER);
    1602                 :          0 :                         fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
    1603                 :            :                                        FORCEWAKE, FORCEWAKE_ACK);
    1604                 :            :                 }
    1605         [ #  # ]:          0 :         } else if (IS_GEN(i915, 6)) {
    1606                 :          0 :                 uncore->funcs.force_wake_get =
    1607                 :            :                         fw_domains_get_with_thread_status;
    1608                 :          0 :                 uncore->funcs.force_wake_put = fw_domains_put;
    1609                 :          0 :                 fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
    1610                 :            :                                FORCEWAKE, FORCEWAKE_ACK);
    1611                 :            :         }
    1612                 :            : 
    1613                 :            : #undef fw_domain_init
    1614                 :            : 
    1615                 :            :         /* All future platforms are expected to require complex power gating */
    1616   [ #  #  #  #  :          0 :         WARN_ON(!ret && uncore->fw_domains == 0);
                   #  # ]
    1617                 :            : 
    1618                 :          0 : out:
    1619         [ #  # ]:          0 :         if (ret)
    1620                 :          0 :                 intel_uncore_fw_domains_fini(uncore);
    1621                 :            : 
    1622                 :          0 :         return ret;
    1623                 :            : }
    1624                 :            : 
    1625                 :            : #define ASSIGN_FW_DOMAINS_TABLE(uncore, d) \
    1626                 :            : { \
    1627                 :            :         (uncore)->fw_domains_table = \
    1628                 :            :                         (struct intel_forcewake_range *)(d); \
    1629                 :            :         (uncore)->fw_domains_table_entries = ARRAY_SIZE((d)); \
    1630                 :            : }
    1631                 :            : 
    1632                 :          0 : static int i915_pmic_bus_access_notifier(struct notifier_block *nb,
    1633                 :            :                                          unsigned long action, void *data)
    1634                 :            : {
    1635                 :          0 :         struct intel_uncore *uncore = container_of(nb,
    1636                 :            :                         struct intel_uncore, pmic_bus_access_nb);
    1637                 :            : 
    1638      [ #  #  # ]:          0 :         switch (action) {
    1639                 :          0 :         case MBI_PMIC_BUS_ACCESS_BEGIN:
    1640                 :            :                 /*
    1641                 :            :                  * forcewake all now to make sure that we don't need to do a
    1642                 :            :                  * forcewake later which on systems where this notifier gets
    1643                 :            :                  * called requires the punit to access to the shared pmic i2c
    1644                 :            :                  * bus, which will be busy after this notification, leading to:
    1645                 :            :                  * "render: timed out waiting for forcewake ack request."
    1646                 :            :                  * errors.
    1647                 :            :                  *
    1648                 :            :                  * The notifier is unregistered during intel_runtime_suspend(),
    1649                 :            :                  * so it's ok to access the HW here without holding a RPM
    1650                 :            :                  * wake reference -> disable wakeref asserts for the time of
    1651                 :            :                  * the access.
    1652                 :            :                  */
    1653                 :          0 :                 disable_rpm_wakeref_asserts(uncore->rpm);
    1654                 :          0 :                 intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
    1655                 :          0 :                 enable_rpm_wakeref_asserts(uncore->rpm);
    1656                 :          0 :                 break;
    1657                 :          0 :         case MBI_PMIC_BUS_ACCESS_END:
    1658                 :          0 :                 intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL);
    1659                 :          0 :                 break;
    1660                 :            :         }
    1661                 :            : 
    1662                 :          0 :         return NOTIFY_OK;
    1663                 :            : }
    1664                 :            : 
    1665                 :            : static int uncore_mmio_setup(struct intel_uncore *uncore)
    1666                 :            : {
    1667                 :            :         struct drm_i915_private *i915 = uncore->i915;
    1668                 :            :         struct pci_dev *pdev = i915->drm.pdev;
    1669                 :            :         int mmio_bar;
    1670                 :            :         int mmio_size;
    1671                 :            : 
    1672                 :            :         mmio_bar = IS_GEN(i915, 2) ? 1 : 0;
    1673                 :            :         /*
    1674                 :            :          * Before gen4, the registers and the GTT are behind different BARs.
    1675                 :            :          * However, from gen4 onwards, the registers and the GTT are shared
    1676                 :            :          * in the same BAR, so we want to restrict this ioremap from
    1677                 :            :          * clobbering the GTT which we want ioremap_wc instead. Fortunately,
    1678                 :            :          * the register BAR remains the same size for all the earlier
    1679                 :            :          * generations up to Ironlake.
    1680                 :            :          */
    1681                 :            :         if (INTEL_GEN(i915) < 5)
    1682                 :            :                 mmio_size = 512 * 1024;
    1683                 :            :         else
    1684                 :            :                 mmio_size = 2 * 1024 * 1024;
    1685                 :            :         uncore->regs = pci_iomap(pdev, mmio_bar, mmio_size);
    1686                 :            :         if (uncore->regs == NULL) {
    1687                 :            :                 drm_err(&i915->drm, "failed to map registers\n");
    1688                 :            :                 return -EIO;
    1689                 :            :         }
    1690                 :            : 
    1691                 :            :         return 0;
    1692                 :            : }
    1693                 :            : 
    1694                 :          0 : static void uncore_mmio_cleanup(struct intel_uncore *uncore)
    1695                 :            : {
    1696                 :          0 :         struct pci_dev *pdev = uncore->i915->drm.pdev;
    1697                 :            : 
    1698                 :          0 :         pci_iounmap(pdev, uncore->regs);
    1699                 :            : }
    1700                 :            : 
    1701                 :          0 : void intel_uncore_init_early(struct intel_uncore *uncore,
    1702                 :            :                              struct drm_i915_private *i915)
    1703                 :            : {
    1704                 :          0 :         spin_lock_init(&uncore->lock);
    1705                 :          0 :         uncore->i915 = i915;
    1706                 :          0 :         uncore->rpm = &i915->runtime_pm;
    1707                 :          0 :         uncore->debug = &i915->mmio_debug;
    1708                 :          0 : }
    1709                 :            : 
    1710                 :          0 : static void uncore_raw_init(struct intel_uncore *uncore)
    1711                 :            : {
    1712                 :          0 :         GEM_BUG_ON(intel_uncore_has_forcewake(uncore));
    1713                 :            : 
    1714                 :          0 :         if (IS_GEN(uncore->i915, 5)) {
    1715                 :          0 :                 ASSIGN_RAW_WRITE_MMIO_VFUNCS(uncore, gen5);
    1716                 :          0 :                 ASSIGN_RAW_READ_MMIO_VFUNCS(uncore, gen5);
    1717                 :            :         } else {
    1718                 :          0 :                 ASSIGN_RAW_WRITE_MMIO_VFUNCS(uncore, gen2);
    1719                 :          0 :                 ASSIGN_RAW_READ_MMIO_VFUNCS(uncore, gen2);
    1720                 :            :         }
    1721                 :            : }
    1722                 :            : 
    1723                 :          0 : static int uncore_forcewake_init(struct intel_uncore *uncore)
    1724                 :            : {
    1725                 :          0 :         struct drm_i915_private *i915 = uncore->i915;
    1726                 :          0 :         int ret;
    1727                 :            : 
    1728                 :          0 :         GEM_BUG_ON(!intel_uncore_has_forcewake(uncore));
    1729                 :            : 
    1730                 :          0 :         ret = intel_uncore_fw_domains_init(uncore);
    1731         [ #  # ]:          0 :         if (ret)
    1732                 :            :                 return ret;
    1733                 :          0 :         forcewake_early_sanitize(uncore, 0);
    1734                 :            : 
    1735         [ #  # ]:          0 :         if (IS_GEN_RANGE(i915, 6, 7)) {
    1736                 :          0 :                 ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen6);
    1737                 :            : 
    1738         [ #  # ]:          0 :                 if (IS_VALLEYVIEW(i915)) {
    1739                 :          0 :                         ASSIGN_FW_DOMAINS_TABLE(uncore, __vlv_fw_ranges);
    1740                 :          0 :                         ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable);
    1741                 :            :                 } else {
    1742                 :          0 :                         ASSIGN_READ_MMIO_VFUNCS(uncore, gen6);
    1743                 :            :                 }
    1744         [ #  # ]:          0 :         } else if (IS_GEN(i915, 8)) {
    1745         [ #  # ]:          0 :                 if (IS_CHERRYVIEW(i915)) {
    1746                 :          0 :                         ASSIGN_FW_DOMAINS_TABLE(uncore, __chv_fw_ranges);
    1747                 :          0 :                         ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable);
    1748                 :          0 :                         ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable);
    1749                 :            :                 } else {
    1750                 :          0 :                         ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen8);
    1751                 :          0 :                         ASSIGN_READ_MMIO_VFUNCS(uncore, gen6);
    1752                 :            :                 }
    1753         [ #  # ]:          0 :         } else if (IS_GEN_RANGE(i915, 9, 10)) {
    1754                 :          0 :                 ASSIGN_FW_DOMAINS_TABLE(uncore, __gen9_fw_ranges);
    1755                 :          0 :                 ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable);
    1756                 :          0 :                 ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable);
    1757         [ #  # ]:          0 :         } else if (IS_GEN(i915, 11)) {
    1758                 :          0 :                 ASSIGN_FW_DOMAINS_TABLE(uncore, __gen11_fw_ranges);
    1759                 :          0 :                 ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen11_fwtable);
    1760                 :          0 :                 ASSIGN_READ_MMIO_VFUNCS(uncore, gen11_fwtable);
    1761                 :            :         } else {
    1762                 :          0 :                 ASSIGN_FW_DOMAINS_TABLE(uncore, __gen12_fw_ranges);
    1763                 :          0 :                 ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen12_fwtable);
    1764                 :          0 :                 ASSIGN_READ_MMIO_VFUNCS(uncore, gen12_fwtable);
    1765                 :            :         }
    1766                 :            : 
    1767                 :          0 :         uncore->pmic_bus_access_nb.notifier_call = i915_pmic_bus_access_notifier;
    1768                 :          0 :         iosf_mbi_register_pmic_bus_access_notifier(&uncore->pmic_bus_access_nb);
    1769                 :            : 
    1770                 :          0 :         return 0;
    1771                 :            : }
    1772                 :            : 
    1773                 :          0 : int intel_uncore_init_mmio(struct intel_uncore *uncore)
    1774                 :            : {
    1775                 :          0 :         struct drm_i915_private *i915 = uncore->i915;
    1776                 :          0 :         int ret;
    1777                 :            : 
    1778                 :          0 :         ret = uncore_mmio_setup(uncore);
    1779         [ #  # ]:          0 :         if (ret)
    1780                 :            :                 return ret;
    1781                 :            : 
    1782   [ #  #  #  # ]:          0 :         if (INTEL_GEN(i915) > 5 && !intel_vgpu_active(i915))
    1783                 :          0 :                 uncore->flags |= UNCORE_HAS_FORCEWAKE;
    1784                 :            : 
    1785         [ #  # ]:          0 :         if (!intel_uncore_has_forcewake(uncore)) {
    1786         [ #  # ]:          0 :                 uncore_raw_init(uncore);
    1787                 :            :         } else {
    1788                 :          0 :                 ret = uncore_forcewake_init(uncore);
    1789         [ #  # ]:          0 :                 if (ret)
    1790                 :          0 :                         goto out_mmio_cleanup;
    1791                 :            :         }
    1792                 :            : 
    1793                 :            :         /* make sure fw funcs are set if and only if we have fw*/
    1794                 :          0 :         GEM_BUG_ON(intel_uncore_has_forcewake(uncore) != !!uncore->funcs.force_wake_get);
    1795                 :          0 :         GEM_BUG_ON(intel_uncore_has_forcewake(uncore) != !!uncore->funcs.force_wake_put);
    1796                 :          0 :         GEM_BUG_ON(intel_uncore_has_forcewake(uncore) != !!uncore->funcs.read_fw_domains);
    1797                 :          0 :         GEM_BUG_ON(intel_uncore_has_forcewake(uncore) != !!uncore->funcs.write_fw_domains);
    1798                 :            : 
    1799         [ #  # ]:          0 :         if (HAS_FPGA_DBG_UNCLAIMED(i915))
    1800                 :          0 :                 uncore->flags |= UNCORE_HAS_FPGA_DBG_UNCLAIMED;
    1801                 :            : 
    1802   [ #  #  #  # ]:          0 :         if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
    1803                 :          0 :                 uncore->flags |= UNCORE_HAS_DBG_UNCLAIMED;
    1804                 :            : 
    1805         [ #  # ]:          0 :         if (IS_GEN_RANGE(i915, 6, 7))
    1806                 :          0 :                 uncore->flags |= UNCORE_HAS_FIFO;
    1807                 :            : 
    1808                 :            :         /* clear out unclaimed reg detection bit */
    1809         [ #  # ]:          0 :         if (intel_uncore_unclaimed_mmio(uncore))
    1810                 :          0 :                 drm_dbg(&i915->drm, "unclaimed mmio detected on uncore init, clearing\n");
    1811                 :            : 
    1812                 :            :         return 0;
    1813                 :            : 
    1814                 :            : out_mmio_cleanup:
    1815                 :          0 :         uncore_mmio_cleanup(uncore);
    1816                 :            : 
    1817                 :          0 :         return ret;
    1818                 :            : }
    1819                 :            : 
    1820                 :            : /*
    1821                 :            :  * We might have detected that some engines are fused off after we initialized
    1822                 :            :  * the forcewake domains. Prune them, to make sure they only reference existing
    1823                 :            :  * engines.
    1824                 :            :  */
    1825                 :          0 : void intel_uncore_prune_mmio_domains(struct intel_uncore *uncore)
    1826                 :            : {
    1827                 :          0 :         struct drm_i915_private *i915 = uncore->i915;
    1828                 :          0 :         enum forcewake_domains fw_domains = uncore->fw_domains;
    1829                 :          0 :         enum forcewake_domain_id domain_id;
    1830                 :          0 :         int i;
    1831                 :            : 
    1832   [ #  #  #  # ]:          0 :         if (!intel_uncore_has_forcewake(uncore) || INTEL_GEN(i915) < 11)
    1833                 :            :                 return;
    1834                 :            : 
    1835         [ #  # ]:          0 :         for (i = 0; i < I915_MAX_VCS; i++) {
    1836                 :          0 :                 domain_id = FW_DOMAIN_ID_MEDIA_VDBOX0 + i;
    1837                 :            : 
    1838         [ #  # ]:          0 :                 if (HAS_ENGINE(i915, _VCS(i)))
    1839                 :          0 :                         continue;
    1840                 :            : 
    1841         [ #  # ]:          0 :                 if (fw_domains & BIT(domain_id))
    1842                 :          0 :                         fw_domain_fini(uncore, domain_id);
    1843                 :            :         }
    1844                 :            : 
    1845         [ #  # ]:          0 :         for (i = 0; i < I915_MAX_VECS; i++) {
    1846                 :          0 :                 domain_id = FW_DOMAIN_ID_MEDIA_VEBOX0 + i;
    1847                 :            : 
    1848         [ #  # ]:          0 :                 if (HAS_ENGINE(i915, _VECS(i)))
    1849                 :          0 :                         continue;
    1850                 :            : 
    1851         [ #  # ]:          0 :                 if (fw_domains & BIT(domain_id))
    1852                 :          0 :                         fw_domain_fini(uncore, domain_id);
    1853                 :            :         }
    1854                 :            : }
    1855                 :            : 
    1856                 :          0 : void intel_uncore_fini_mmio(struct intel_uncore *uncore)
    1857                 :            : {
    1858         [ #  # ]:          0 :         if (intel_uncore_has_forcewake(uncore)) {
    1859                 :          0 :                 iosf_mbi_punit_acquire();
    1860                 :          0 :                 iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(
    1861                 :            :                         &uncore->pmic_bus_access_nb);
    1862                 :          0 :                 intel_uncore_forcewake_reset(uncore);
    1863                 :          0 :                 intel_uncore_fw_domains_fini(uncore);
    1864                 :          0 :                 iosf_mbi_punit_release();
    1865                 :            :         }
    1866                 :            : 
    1867                 :          0 :         uncore_mmio_cleanup(uncore);
    1868                 :          0 : }
    1869                 :            : 
    1870                 :            : static const struct reg_whitelist {
    1871                 :            :         i915_reg_t offset_ldw;
    1872                 :            :         i915_reg_t offset_udw;
    1873                 :            :         u16 gen_mask;
    1874                 :            :         u8 size;
    1875                 :            : } reg_read_whitelist[] = { {
    1876                 :            :         .offset_ldw = RING_TIMESTAMP(RENDER_RING_BASE),
    1877                 :            :         .offset_udw = RING_TIMESTAMP_UDW(RENDER_RING_BASE),
    1878                 :            :         .gen_mask = INTEL_GEN_MASK(4, 12),
    1879                 :            :         .size = 8
    1880                 :            : } };
    1881                 :            : 
    1882                 :          0 : int i915_reg_read_ioctl(struct drm_device *dev,
    1883                 :            :                         void *data, struct drm_file *file)
    1884                 :            : {
    1885                 :          0 :         struct drm_i915_private *i915 = to_i915(dev);
    1886                 :          0 :         struct intel_uncore *uncore = &i915->uncore;
    1887                 :          0 :         struct drm_i915_reg_read *reg = data;
    1888                 :          0 :         struct reg_whitelist const *entry;
    1889                 :          0 :         intel_wakeref_t wakeref;
    1890                 :          0 :         unsigned int flags;
    1891                 :          0 :         int remain;
    1892                 :          0 :         int ret = 0;
    1893                 :            : 
    1894                 :          0 :         entry = reg_read_whitelist;
    1895                 :          0 :         remain = ARRAY_SIZE(reg_read_whitelist);
    1896         [ #  # ]:          0 :         while (remain) {
    1897         [ #  # ]:          0 :                 u32 entry_offset = i915_mmio_reg_offset(entry->offset_ldw);
    1898                 :            : 
    1899                 :          0 :                 GEM_BUG_ON(!is_power_of_2(entry->size));
    1900                 :          0 :                 GEM_BUG_ON(entry->size > 8);
    1901                 :          0 :                 GEM_BUG_ON(entry_offset & (entry->size - 1));
    1902                 :            : 
    1903         [ #  # ]:          0 :                 if (INTEL_INFO(i915)->gen_mask & entry->gen_mask &&
    1904         [ #  # ]:          0 :                     entry_offset == (reg->offset & -entry->size))
    1905                 :            :                         break;
    1906                 :          0 :                 entry++;
    1907                 :          0 :                 remain--;
    1908                 :            :         }
    1909                 :            : 
    1910         [ #  # ]:          0 :         if (!remain)
    1911                 :            :                 return -EINVAL;
    1912                 :            : 
    1913                 :          0 :         flags = reg->offset & (entry->size - 1);
    1914                 :            : 
    1915         [ #  # ]:          0 :         with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
    1916   [ #  #  #  # ]:          0 :                 if (entry->size == 8 && flags == I915_REG_READ_8B_WA)
    1917                 :          0 :                         reg->val = intel_uncore_read64_2x32(uncore,
    1918                 :            :                                                             entry->offset_ldw,
    1919                 :            :                                                             entry->offset_udw);
    1920   [ #  #  #  # ]:          0 :                 else if (entry->size == 8 && flags == 0)
    1921                 :          0 :                         reg->val = intel_uncore_read64(uncore,
    1922                 :            :                                                        entry->offset_ldw);
    1923   [ #  #  #  # ]:          0 :                 else if (entry->size == 4 && flags == 0)
    1924                 :          0 :                         reg->val = intel_uncore_read(uncore, entry->offset_ldw);
    1925   [ #  #  #  # ]:          0 :                 else if (entry->size == 2 && flags == 0)
    1926                 :          0 :                         reg->val = intel_uncore_read16(uncore,
    1927                 :            :                                                        entry->offset_ldw);
    1928   [ #  #  #  # ]:          0 :                 else if (entry->size == 1 && flags == 0)
    1929                 :          0 :                         reg->val = intel_uncore_read8(uncore,
    1930                 :            :                                                       entry->offset_ldw);
    1931                 :            :                 else
    1932                 :            :                         ret = -EINVAL;
    1933                 :            :         }
    1934                 :            : 
    1935                 :            :         return ret;
    1936                 :            : }
    1937                 :            : 
    1938                 :            : /**
    1939                 :            :  * __intel_wait_for_register_fw - wait until register matches expected state
    1940                 :            :  * @uncore: the struct intel_uncore
    1941                 :            :  * @reg: the register to read
    1942                 :            :  * @mask: mask to apply to register value
    1943                 :            :  * @value: expected value
    1944                 :            :  * @fast_timeout_us: fast timeout in microsecond for atomic/tight wait
    1945                 :            :  * @slow_timeout_ms: slow timeout in millisecond
    1946                 :            :  * @out_value: optional placeholder to hold registry value
    1947                 :            :  *
    1948                 :            :  * This routine waits until the target register @reg contains the expected
    1949                 :            :  * @value after applying the @mask, i.e. it waits until ::
    1950                 :            :  *
    1951                 :            :  *     (I915_READ_FW(reg) & mask) == value
    1952                 :            :  *
    1953                 :            :  * Otherwise, the wait will timeout after @slow_timeout_ms milliseconds.
    1954                 :            :  * For atomic context @slow_timeout_ms must be zero and @fast_timeout_us
    1955                 :            :  * must be not larger than 20,0000 microseconds.
    1956                 :            :  *
    1957                 :            :  * Note that this routine assumes the caller holds forcewake asserted, it is
    1958                 :            :  * not suitable for very long waits. See intel_wait_for_register() if you
    1959                 :            :  * wish to wait without holding forcewake for the duration (i.e. you expect
    1960                 :            :  * the wait to be slow).
    1961                 :            :  *
    1962                 :            :  * Return: 0 if the register matches the desired condition, or -ETIMEDOUT.
    1963                 :            :  */
    1964                 :          0 : int __intel_wait_for_register_fw(struct intel_uncore *uncore,
    1965                 :            :                                  i915_reg_t reg,
    1966                 :            :                                  u32 mask,
    1967                 :            :                                  u32 value,
    1968                 :            :                                  unsigned int fast_timeout_us,
    1969                 :            :                                  unsigned int slow_timeout_ms,
    1970                 :            :                                  u32 *out_value)
    1971                 :            : {
    1972                 :          0 :         u32 uninitialized_var(reg_value);
    1973                 :            : #define done (((reg_value = intel_uncore_read_fw(uncore, reg)) & mask) == value)
    1974                 :          0 :         int ret;
    1975                 :            : 
    1976                 :            :         /* Catch any overuse of this function */
    1977         [ #  # ]:          0 :         might_sleep_if(slow_timeout_ms);
    1978                 :          0 :         GEM_BUG_ON(fast_timeout_us > 20000);
    1979                 :            : 
    1980                 :          0 :         ret = -ETIMEDOUT;
    1981         [ #  # ]:          0 :         if (fast_timeout_us && fast_timeout_us <= 20000)
    1982   [ #  #  #  #  :          0 :                 ret = _wait_for_atomic(done, fast_timeout_us, 0);
                   #  # ]
    1983         [ #  # ]:          0 :         if (ret && slow_timeout_ms)
    1984   [ #  #  #  #  :          0 :                 ret = wait_for(done, slow_timeout_ms);
                   #  # ]
    1985                 :            : 
    1986         [ #  # ]:          0 :         if (out_value)
    1987                 :          0 :                 *out_value = reg_value;
    1988                 :            : 
    1989                 :          0 :         return ret;
    1990                 :            : #undef done
    1991                 :            : }
    1992                 :            : 
    1993                 :            : /**
    1994                 :            :  * __intel_wait_for_register - wait until register matches expected state
    1995                 :            :  * @uncore: the struct intel_uncore
    1996                 :            :  * @reg: the register to read
    1997                 :            :  * @mask: mask to apply to register value
    1998                 :            :  * @value: expected value
    1999                 :            :  * @fast_timeout_us: fast timeout in microsecond for atomic/tight wait
    2000                 :            :  * @slow_timeout_ms: slow timeout in millisecond
    2001                 :            :  * @out_value: optional placeholder to hold registry value
    2002                 :            :  *
    2003                 :            :  * This routine waits until the target register @reg contains the expected
    2004                 :            :  * @value after applying the @mask, i.e. it waits until ::
    2005                 :            :  *
    2006                 :            :  *     (I915_READ(reg) & mask) == value
    2007                 :            :  *
    2008                 :            :  * Otherwise, the wait will timeout after @timeout_ms milliseconds.
    2009                 :            :  *
    2010                 :            :  * Return: 0 if the register matches the desired condition, or -ETIMEDOUT.
    2011                 :            :  */
    2012                 :          0 : int __intel_wait_for_register(struct intel_uncore *uncore,
    2013                 :            :                               i915_reg_t reg,
    2014                 :            :                               u32 mask,
    2015                 :            :                               u32 value,
    2016                 :            :                               unsigned int fast_timeout_us,
    2017                 :            :                               unsigned int slow_timeout_ms,
    2018                 :            :                               u32 *out_value)
    2019                 :            : {
    2020                 :          0 :         unsigned fw =
    2021                 :          0 :                 intel_uncore_forcewake_for_reg(uncore, reg, FW_REG_READ);
    2022                 :          0 :         u32 reg_value;
    2023                 :          0 :         int ret;
    2024                 :            : 
    2025         [ #  # ]:          0 :         might_sleep_if(slow_timeout_ms);
    2026                 :            : 
    2027                 :          0 :         spin_lock_irq(&uncore->lock);
    2028         [ #  # ]:          0 :         intel_uncore_forcewake_get__locked(uncore, fw);
    2029                 :            : 
    2030                 :          0 :         ret = __intel_wait_for_register_fw(uncore,
    2031                 :            :                                            reg, mask, value,
    2032                 :            :                                            fast_timeout_us, 0, &reg_value);
    2033                 :            : 
    2034         [ #  # ]:          0 :         intel_uncore_forcewake_put__locked(uncore, fw);
    2035                 :          0 :         spin_unlock_irq(&uncore->lock);
    2036                 :            : 
    2037         [ #  # ]:          0 :         if (ret && slow_timeout_ms)
    2038   [ #  #  #  #  :          0 :                 ret = __wait_for(reg_value = intel_uncore_read_notrace(uncore,
                   #  # ]
    2039                 :            :                                                                        reg),
    2040                 :            :                                  (reg_value & mask) == value,
    2041                 :            :                                  slow_timeout_ms * 1000, 10, 1000);
    2042                 :            : 
    2043                 :            :         /* just trace the final value */
    2044                 :          0 :         trace_i915_reg_rw(false, reg, reg_value, sizeof(reg_value), true);
    2045                 :            : 
    2046         [ #  # ]:          0 :         if (out_value)
    2047                 :          0 :                 *out_value = reg_value;
    2048                 :            : 
    2049                 :          0 :         return ret;
    2050                 :            : }
    2051                 :            : 
    2052                 :          0 : bool intel_uncore_unclaimed_mmio(struct intel_uncore *uncore)
    2053                 :            : {
    2054                 :          0 :         bool ret;
    2055                 :            : 
    2056                 :          0 :         spin_lock_irq(&uncore->debug->lock);
    2057                 :          0 :         ret = check_for_unclaimed_mmio(uncore);
    2058                 :          0 :         spin_unlock_irq(&uncore->debug->lock);
    2059                 :            : 
    2060                 :          0 :         return ret;
    2061                 :            : }
    2062                 :            : 
    2063                 :            : bool
    2064                 :          0 : intel_uncore_arm_unclaimed_mmio_detection(struct intel_uncore *uncore)
    2065                 :            : {
    2066                 :          0 :         bool ret = false;
    2067                 :            : 
    2068                 :          0 :         spin_lock_irq(&uncore->debug->lock);
    2069                 :            : 
    2070         [ #  # ]:          0 :         if (unlikely(uncore->debug->unclaimed_mmio_check <= 0))
    2071                 :          0 :                 goto out;
    2072                 :            : 
    2073         [ #  # ]:          0 :         if (unlikely(check_for_unclaimed_mmio(uncore))) {
    2074         [ #  # ]:          0 :                 if (!i915_modparams.mmio_debug) {
    2075                 :          0 :                         drm_dbg(&uncore->i915->drm,
    2076                 :            :                                 "Unclaimed register detected, "
    2077                 :            :                                 "enabling oneshot unclaimed register reporting. "
    2078                 :            :                                 "Please use i915.mmio_debug=N for more information.\n");
    2079                 :          0 :                         i915_modparams.mmio_debug++;
    2080                 :            :                 }
    2081                 :          0 :                 uncore->debug->unclaimed_mmio_check--;
    2082                 :          0 :                 ret = true;
    2083                 :            :         }
    2084                 :            : 
    2085                 :          0 : out:
    2086                 :          0 :         spin_unlock_irq(&uncore->debug->lock);
    2087                 :            : 
    2088                 :          0 :         return ret;
    2089                 :            : }
    2090                 :            : 
    2091                 :            : /**
    2092                 :            :  * intel_uncore_forcewake_for_reg - which forcewake domains are needed to access
    2093                 :            :  *                                  a register
    2094                 :            :  * @uncore: pointer to struct intel_uncore
    2095                 :            :  * @reg: register in question
    2096                 :            :  * @op: operation bitmask of FW_REG_READ and/or FW_REG_WRITE
    2097                 :            :  *
    2098                 :            :  * Returns a set of forcewake domains required to be taken with for example
    2099                 :            :  * intel_uncore_forcewake_get for the specified register to be accessible in the
    2100                 :            :  * specified mode (read, write or read/write) with raw mmio accessors.
    2101                 :            :  *
    2102                 :            :  * NOTE: On Gen6 and Gen7 write forcewake domain (FORCEWAKE_RENDER) requires the
    2103                 :            :  * callers to do FIFO management on their own or risk losing writes.
    2104                 :            :  */
    2105                 :            : enum forcewake_domains
    2106                 :          0 : intel_uncore_forcewake_for_reg(struct intel_uncore *uncore,
    2107                 :            :                                i915_reg_t reg, unsigned int op)
    2108                 :            : {
    2109                 :          0 :         enum forcewake_domains fw_domains = 0;
    2110                 :            : 
    2111         [ #  # ]:          0 :         WARN_ON(!op);
    2112                 :            : 
    2113         [ #  # ]:          0 :         if (!intel_uncore_has_forcewake(uncore))
    2114                 :            :                 return 0;
    2115                 :            : 
    2116         [ #  # ]:          0 :         if (op & FW_REG_READ)
    2117                 :          0 :                 fw_domains = uncore->funcs.read_fw_domains(uncore, reg);
    2118                 :            : 
    2119         [ #  # ]:          0 :         if (op & FW_REG_WRITE)
    2120                 :          0 :                 fw_domains |= uncore->funcs.write_fw_domains(uncore, reg);
    2121                 :            : 
    2122         [ #  # ]:          0 :         WARN_ON(fw_domains & ~uncore->fw_domains);
    2123                 :            : 
    2124                 :            :         return fw_domains;
    2125                 :            : }
    2126                 :            : 
    2127                 :            : #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
    2128                 :            : #include "selftests/mock_uncore.c"
    2129                 :            : #include "selftests/intel_uncore.c"
    2130                 :            : #endif

Generated by: LCOV version 1.14