LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915/gt - intel_engine.h (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 50 0.0 %
Date: 2022-03-28 13:20:08 Functions: 0 1 0.0 %
Branches: 0 28 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: MIT */
       2                 :            : #ifndef _INTEL_RINGBUFFER_H_
       3                 :            : #define _INTEL_RINGBUFFER_H_
       4                 :            : 
       5                 :            : #include <drm/drm_util.h>
       6                 :            : 
       7                 :            : #include <linux/hashtable.h>
       8                 :            : #include <linux/irq_work.h>
       9                 :            : #include <linux/random.h>
      10                 :            : #include <linux/seqlock.h>
      11                 :            : 
      12                 :            : #include "i915_pmu.h"
      13                 :            : #include "i915_reg.h"
      14                 :            : #include "i915_request.h"
      15                 :            : #include "i915_selftest.h"
      16                 :            : #include "gt/intel_timeline.h"
      17                 :            : #include "intel_engine_types.h"
      18                 :            : #include "intel_gpu_commands.h"
      19                 :            : #include "intel_workarounds.h"
      20                 :            : 
      21                 :            : struct drm_printer;
      22                 :            : struct intel_gt;
      23                 :            : 
      24                 :            : /* Early gen2 devices have a cacheline of just 32 bytes, using 64 is overkill,
      25                 :            :  * but keeps the logic simple. Indeed, the whole purpose of this macro is just
      26                 :            :  * to give some inclination as to some of the magic values used in the various
      27                 :            :  * workarounds!
      28                 :            :  */
      29                 :            : #define CACHELINE_BYTES 64
      30                 :            : #define CACHELINE_DWORDS (CACHELINE_BYTES / sizeof(u32))
      31                 :            : 
      32                 :            : #define ENGINE_TRACE(e, fmt, ...) do {                                  \
      33                 :            :         const struct intel_engine_cs *e__ __maybe_unused = (e);         \
      34                 :            :         GEM_TRACE("%s %s: " fmt,                                      \
      35                 :            :                   dev_name(e__->i915->drm.dev), e__->name,             \
      36                 :            :                   ##__VA_ARGS__);                                       \
      37                 :            : } while (0)
      38                 :            : 
      39                 :            : /*
      40                 :            :  * The register defines to be used with the following macros need to accept a
      41                 :            :  * base param, e.g:
      42                 :            :  *
      43                 :            :  * REG_FOO(base) _MMIO((base) + <relative offset>)
      44                 :            :  * ENGINE_READ(engine, REG_FOO);
      45                 :            :  *
      46                 :            :  * register arrays are to be defined and accessed as follows:
      47                 :            :  *
      48                 :            :  * REG_BAR(base, i) _MMIO((base) + <relative offset> + (i) * <shift>)
      49                 :            :  * ENGINE_READ_IDX(engine, REG_BAR, i)
      50                 :            :  */
      51                 :            : 
      52                 :            : #define __ENGINE_REG_OP(op__, engine__, ...) \
      53                 :            :         intel_uncore_##op__((engine__)->uncore, __VA_ARGS__)
      54                 :            : 
      55                 :            : #define __ENGINE_READ_OP(op__, engine__, reg__) \
      56                 :            :         __ENGINE_REG_OP(op__, (engine__), reg__((engine__)->mmio_base))
      57                 :            : 
      58                 :            : #define ENGINE_READ16(...)      __ENGINE_READ_OP(read16, __VA_ARGS__)
      59                 :            : #define ENGINE_READ(...)        __ENGINE_READ_OP(read, __VA_ARGS__)
      60                 :            : #define ENGINE_READ_FW(...)     __ENGINE_READ_OP(read_fw, __VA_ARGS__)
      61                 :            : #define ENGINE_POSTING_READ(...) __ENGINE_READ_OP(posting_read_fw, __VA_ARGS__)
      62                 :            : #define ENGINE_POSTING_READ16(...) __ENGINE_READ_OP(posting_read16, __VA_ARGS__)
      63                 :            : 
      64                 :            : #define ENGINE_READ64(engine__, lower_reg__, upper_reg__) \
      65                 :            :         __ENGINE_REG_OP(read64_2x32, (engine__), \
      66                 :            :                         lower_reg__((engine__)->mmio_base), \
      67                 :            :                         upper_reg__((engine__)->mmio_base))
      68                 :            : 
      69                 :            : #define ENGINE_READ_IDX(engine__, reg__, idx__) \
      70                 :            :         __ENGINE_REG_OP(read, (engine__), reg__((engine__)->mmio_base, (idx__)))
      71                 :            : 
      72                 :            : #define __ENGINE_WRITE_OP(op__, engine__, reg__, val__) \
      73                 :            :         __ENGINE_REG_OP(op__, (engine__), reg__((engine__)->mmio_base), (val__))
      74                 :            : 
      75                 :            : #define ENGINE_WRITE16(...)     __ENGINE_WRITE_OP(write16, __VA_ARGS__)
      76                 :            : #define ENGINE_WRITE(...)       __ENGINE_WRITE_OP(write, __VA_ARGS__)
      77                 :            : #define ENGINE_WRITE_FW(...)    __ENGINE_WRITE_OP(write_fw, __VA_ARGS__)
      78                 :            : 
      79                 :            : #define GEN6_RING_FAULT_REG_READ(engine__) \
      80                 :            :         intel_uncore_read((engine__)->uncore, RING_FAULT_REG(engine__))
      81                 :            : 
      82                 :            : #define GEN6_RING_FAULT_REG_POSTING_READ(engine__) \
      83                 :            :         intel_uncore_posting_read((engine__)->uncore, RING_FAULT_REG(engine__))
      84                 :            : 
      85                 :            : #define GEN6_RING_FAULT_REG_RMW(engine__, clear__, set__) \
      86                 :            : ({ \
      87                 :            :         u32 __val; \
      88                 :            : \
      89                 :            :         __val = intel_uncore_read((engine__)->uncore, \
      90                 :            :                                   RING_FAULT_REG(engine__)); \
      91                 :            :         __val &= ~(clear__); \
      92                 :            :         __val |= (set__); \
      93                 :            :         intel_uncore_write((engine__)->uncore, RING_FAULT_REG(engine__), \
      94                 :            :                            __val); \
      95                 :            : })
      96                 :            : 
      97                 :            : /* seqno size is actually only a uint32, but since we plan to use MI_FLUSH_DW to
      98                 :            :  * do the writes, and that must have qw aligned offsets, simply pretend it's 8b.
      99                 :            :  */
     100                 :            : 
     101                 :            : static inline unsigned int
     102                 :          0 : execlists_num_ports(const struct intel_engine_execlists * const execlists)
     103                 :            : {
     104                 :          0 :         return execlists->port_mask + 1;
     105                 :            : }
     106                 :            : 
     107                 :            : static inline struct i915_request *
     108                 :          0 : execlists_active(const struct intel_engine_execlists *execlists)
     109                 :            : {
     110   [ #  #  #  # ]:          0 :         return *READ_ONCE(execlists->active);
     111                 :            : }
     112                 :            : 
     113                 :            : static inline void
     114                 :          0 : execlists_active_lock_bh(struct intel_engine_execlists *execlists)
     115                 :            : {
     116                 :          0 :         local_bh_disable(); /* prevent local softirq and lock recursion */
     117                 :          0 :         tasklet_lock(&execlists->tasklet);
     118                 :          0 : }
     119                 :            : 
     120                 :            : static inline void
     121                 :          0 : execlists_active_unlock_bh(struct intel_engine_execlists *execlists)
     122                 :            : {
     123                 :          0 :         tasklet_unlock(&execlists->tasklet);
     124                 :          0 :         local_bh_enable(); /* restore softirq, and kick ksoftirqd! */
     125                 :            : }
     126                 :            : 
     127                 :            : struct i915_request *
     128                 :            : execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists);
     129                 :            : 
     130                 :            : static inline u32
     131                 :            : intel_read_status_page(const struct intel_engine_cs *engine, int reg)
     132                 :            : {
     133                 :            :         /* Ensure that the compiler doesn't optimize away the load. */
     134                 :            :         return READ_ONCE(engine->status_page.addr[reg]);
     135                 :            : }
     136                 :            : 
     137                 :            : static inline void
     138                 :            : intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value)
     139                 :            : {
     140                 :            :         /* Writing into the status page should be done sparingly. Since
     141                 :            :          * we do when we are uncertain of the device state, we take a bit
     142                 :            :          * of extra paranoia to try and ensure that the HWS takes the value
     143                 :            :          * we give and that it doesn't end up trapped inside the CPU!
     144                 :            :          */
     145                 :            :         if (static_cpu_has(X86_FEATURE_CLFLUSH)) {
     146                 :            :                 mb();
     147                 :            :                 clflush(&engine->status_page.addr[reg]);
     148                 :            :                 engine->status_page.addr[reg] = value;
     149                 :            :                 clflush(&engine->status_page.addr[reg]);
     150                 :            :                 mb();
     151                 :            :         } else {
     152                 :            :                 WRITE_ONCE(engine->status_page.addr[reg], value);
     153                 :            :         }
     154                 :            : }
     155                 :            : 
     156                 :            : /*
     157                 :            :  * Reads a dword out of the status page, which is written to from the command
     158                 :            :  * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or
     159                 :            :  * MI_STORE_DATA_IMM.
     160                 :            :  *
     161                 :            :  * The following dwords have a reserved meaning:
     162                 :            :  * 0x00: ISR copy, updated when an ISR bit not set in the HWSTAM changes.
     163                 :            :  * 0x04: ring 0 head pointer
     164                 :            :  * 0x05: ring 1 head pointer (915-class)
     165                 :            :  * 0x06: ring 2 head pointer (915-class)
     166                 :            :  * 0x10-0x1b: Context status DWords (GM45)
     167                 :            :  * 0x1f: Last written status offset. (GM45)
     168                 :            :  * 0x20-0x2f: Reserved (Gen6+)
     169                 :            :  *
     170                 :            :  * The area from dword 0x30 to 0x3ff is available for driver usage.
     171                 :            :  */
     172                 :            : #define I915_GEM_HWS_PREEMPT            0x32
     173                 :            : #define I915_GEM_HWS_PREEMPT_ADDR       (I915_GEM_HWS_PREEMPT * sizeof(u32))
     174                 :            : #define I915_GEM_HWS_SEQNO              0x40
     175                 :            : #define I915_GEM_HWS_SEQNO_ADDR         (I915_GEM_HWS_SEQNO * sizeof(u32))
     176                 :            : #define I915_GEM_HWS_SCRATCH            0x80
     177                 :            : #define I915_GEM_HWS_SCRATCH_ADDR       (I915_GEM_HWS_SCRATCH * sizeof(u32))
     178                 :            : 
     179                 :            : #define I915_HWS_CSB_BUF0_INDEX         0x10
     180                 :            : #define I915_HWS_CSB_WRITE_INDEX        0x1f
     181                 :            : #define CNL_HWS_CSB_WRITE_INDEX         0x2f
     182                 :            : 
     183                 :            : void intel_engine_stop(struct intel_engine_cs *engine);
     184                 :            : void intel_engine_cleanup(struct intel_engine_cs *engine);
     185                 :            : 
     186                 :            : int intel_engines_init_mmio(struct intel_gt *gt);
     187                 :            : int intel_engines_init(struct intel_gt *gt);
     188                 :            : 
     189                 :            : void intel_engines_release(struct intel_gt *gt);
     190                 :            : void intel_engines_free(struct intel_gt *gt);
     191                 :            : 
     192                 :            : int intel_engine_init_common(struct intel_engine_cs *engine);
     193                 :            : void intel_engine_cleanup_common(struct intel_engine_cs *engine);
     194                 :            : 
     195                 :            : int intel_ring_submission_setup(struct intel_engine_cs *engine);
     196                 :            : 
     197                 :            : int intel_engine_stop_cs(struct intel_engine_cs *engine);
     198                 :            : void intel_engine_cancel_stop_cs(struct intel_engine_cs *engine);
     199                 :            : 
     200                 :            : void intel_engine_set_hwsp_writemask(struct intel_engine_cs *engine, u32 mask);
     201                 :            : 
     202                 :            : u64 intel_engine_get_active_head(const struct intel_engine_cs *engine);
     203                 :            : u64 intel_engine_get_last_batch_head(const struct intel_engine_cs *engine);
     204                 :            : 
     205                 :            : void intel_engine_get_instdone(const struct intel_engine_cs *engine,
     206                 :            :                                struct intel_instdone *instdone);
     207                 :            : 
     208                 :            : void intel_engine_init_execlists(struct intel_engine_cs *engine);
     209                 :            : 
     210                 :            : void intel_engine_init_breadcrumbs(struct intel_engine_cs *engine);
     211                 :            : void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine);
     212                 :            : 
     213                 :            : void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine);
     214                 :            : 
     215                 :            : static inline void
     216                 :          0 : intel_engine_signal_breadcrumbs(struct intel_engine_cs *engine)
     217                 :            : {
     218                 :          0 :         irq_work_queue(&engine->breadcrumbs.irq_work);
     219                 :          0 : }
     220                 :            : 
     221                 :            : void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine);
     222                 :            : void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine);
     223                 :            : 
     224                 :            : void intel_engine_print_breadcrumbs(struct intel_engine_cs *engine,
     225                 :            :                                     struct drm_printer *p);
     226                 :            : 
     227                 :          0 : static inline u32 *gen8_emit_pipe_control(u32 *batch, u32 flags, u32 offset)
     228                 :            : {
     229                 :          0 :         memset(batch, 0, 6 * sizeof(u32));
     230                 :            : 
     231                 :          0 :         batch[0] = GFX_OP_PIPE_CONTROL(6);
     232                 :          0 :         batch[1] = flags;
     233                 :          0 :         batch[2] = offset;
     234                 :            : 
     235   [ #  #  #  # ]:          0 :         return batch + 6;
     236                 :            : }
     237                 :            : 
     238                 :            : static inline u32 *
     239                 :          0 : gen8_emit_ggtt_write_rcs(u32 *cs, u32 value, u32 gtt_offset, u32 flags)
     240                 :            : {
     241                 :            :         /* We're using qword write, offset should be aligned to 8 bytes. */
     242                 :          0 :         GEM_BUG_ON(!IS_ALIGNED(gtt_offset, 8));
     243                 :            : 
     244                 :            :         /* w/a for post sync ops following a GPGPU operation we
     245                 :            :          * need a prior CS_STALL, which is emitted by the flush
     246                 :            :          * following the batch.
     247                 :            :          */
     248                 :          0 :         *cs++ = GFX_OP_PIPE_CONTROL(6);
     249                 :          0 :         *cs++ = flags | PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_GLOBAL_GTT_IVB;
     250                 :          0 :         *cs++ = gtt_offset;
     251                 :          0 :         *cs++ = 0;
     252                 :          0 :         *cs++ = value;
     253                 :            :         /* We're thrashing one dword of HWS. */
     254                 :          0 :         *cs++ = 0;
     255                 :            : 
     256   [ #  #  #  #  :          0 :         return cs;
                   #  # ]
     257                 :            : }
     258                 :            : 
     259                 :            : static inline u32 *
     260                 :          0 : gen8_emit_ggtt_write(u32 *cs, u32 value, u32 gtt_offset, u32 flags)
     261                 :            : {
     262                 :            :         /* w/a: bit 5 needs to be zero for MI_FLUSH_DW address. */
     263                 :          0 :         GEM_BUG_ON(gtt_offset & (1 << 5));
     264                 :            :         /* Offset should be aligned to 8 bytes for both (QW/DW) write types */
     265                 :          0 :         GEM_BUG_ON(!IS_ALIGNED(gtt_offset, 8));
     266                 :            : 
     267                 :          0 :         *cs++ = (MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW | flags;
     268                 :          0 :         *cs++ = gtt_offset | MI_FLUSH_DW_USE_GTT;
     269                 :          0 :         *cs++ = 0;
     270                 :          0 :         *cs++ = value;
     271                 :            : 
     272   [ #  #  #  # ]:          0 :         return cs;
     273                 :            : }
     274                 :            : 
     275                 :          0 : static inline void __intel_engine_reset(struct intel_engine_cs *engine,
     276                 :            :                                         bool stalled)
     277                 :            : {
     278   [ #  #  #  # ]:          0 :         if (engine->reset.rewind)
     279                 :          0 :                 engine->reset.rewind(engine, stalled);
     280                 :          0 :         engine->serial++; /* contexts lost */
     281                 :          0 : }
     282                 :            : 
     283                 :            : bool intel_engines_are_idle(struct intel_gt *gt);
     284                 :            : bool intel_engine_is_idle(struct intel_engine_cs *engine);
     285                 :            : void intel_engine_flush_submission(struct intel_engine_cs *engine);
     286                 :            : 
     287                 :            : void intel_engines_reset_default_submission(struct intel_gt *gt);
     288                 :            : 
     289                 :            : bool intel_engine_can_store_dword(struct intel_engine_cs *engine);
     290                 :            : 
     291                 :            : __printf(3, 4)
     292                 :            : void intel_engine_dump(struct intel_engine_cs *engine,
     293                 :            :                        struct drm_printer *m,
     294                 :            :                        const char *header, ...);
     295                 :            : 
     296                 :            : int intel_enable_engine_stats(struct intel_engine_cs *engine);
     297                 :            : void intel_disable_engine_stats(struct intel_engine_cs *engine);
     298                 :            : 
     299                 :            : ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine);
     300                 :            : 
     301                 :            : struct i915_request *
     302                 :            : intel_engine_find_active_request(struct intel_engine_cs *engine);
     303                 :            : 
     304                 :            : u32 intel_engine_context_size(struct intel_gt *gt, u8 class);
     305                 :            : 
     306                 :            : #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
     307                 :            : 
     308                 :            : static inline bool inject_preempt_hang(struct intel_engine_execlists *execlists)
     309                 :            : {
     310                 :            :         if (!execlists->preempt_hang.inject_hang)
     311                 :            :                 return false;
     312                 :            : 
     313                 :            :         complete(&execlists->preempt_hang.completion);
     314                 :            :         return true;
     315                 :            : }
     316                 :            : 
     317                 :            : #else
     318                 :            : 
     319                 :          0 : static inline bool inject_preempt_hang(struct intel_engine_execlists *execlists)
     320                 :            : {
     321                 :          0 :         return false;
     322                 :            : }
     323                 :            : 
     324                 :            : #endif
     325                 :            : 
     326                 :            : void intel_engine_init_active(struct intel_engine_cs *engine,
     327                 :            :                               unsigned int subclass);
     328                 :            : #define ENGINE_PHYSICAL 0
     329                 :            : #define ENGINE_MOCK     1
     330                 :            : #define ENGINE_VIRTUAL  2
     331                 :            : 
     332                 :            : static inline bool
     333                 :          0 : intel_engine_has_preempt_reset(const struct intel_engine_cs *engine)
     334                 :            : {
     335                 :          0 :         if (!IS_ACTIVE(CONFIG_DRM_I915_PREEMPT_TIMEOUT))
     336                 :            :                 return false;
     337                 :            : 
     338         [ #  # ]:          0 :         return intel_engine_has_preemption(engine);
     339                 :            : }
     340                 :            : 
     341                 :            : static inline bool
     342                 :          0 : intel_engine_has_timeslices(const struct intel_engine_cs *engine)
     343                 :            : {
     344                 :          0 :         if (!IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION))
     345                 :            :                 return false;
     346                 :            : 
     347   [ #  #  #  # ]:          0 :         return intel_engine_has_semaphores(engine);
     348                 :            : }
     349                 :            : 
     350                 :            : #endif /* _INTEL_RINGBUFFER_H_ */

Generated by: LCOV version 1.14