linux/drivers/gpu/drm/i915/intel_uncore.h
<<
>>
Prefs
   1/*
   2 * Copyright © 2017 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
  25#ifndef __INTEL_UNCORE_H__
  26#define __INTEL_UNCORE_H__
  27
  28#include <linux/spinlock.h>
  29#include <linux/notifier.h>
  30#include <linux/hrtimer.h>
  31#include <linux/io-64-nonatomic-lo-hi.h>
  32
  33#include "i915_reg.h"
  34
  35struct drm_i915_private;
  36struct intel_runtime_pm;
  37struct intel_uncore;
  38struct intel_gt;
  39
  40struct intel_uncore_mmio_debug {
  41        spinlock_t lock; /** lock is also taken in irq contexts. */
  42        int unclaimed_mmio_check;
  43        int saved_mmio_check;
  44        u32 suspend_count;
  45};
  46
  47enum forcewake_domain_id {
  48        FW_DOMAIN_ID_RENDER = 0,
  49        FW_DOMAIN_ID_GT,        /* also includes blitter engine */
  50        FW_DOMAIN_ID_MEDIA,
  51        FW_DOMAIN_ID_MEDIA_VDBOX0,
  52        FW_DOMAIN_ID_MEDIA_VDBOX1,
  53        FW_DOMAIN_ID_MEDIA_VDBOX2,
  54        FW_DOMAIN_ID_MEDIA_VDBOX3,
  55        FW_DOMAIN_ID_MEDIA_VDBOX4,
  56        FW_DOMAIN_ID_MEDIA_VDBOX5,
  57        FW_DOMAIN_ID_MEDIA_VDBOX6,
  58        FW_DOMAIN_ID_MEDIA_VDBOX7,
  59        FW_DOMAIN_ID_MEDIA_VEBOX0,
  60        FW_DOMAIN_ID_MEDIA_VEBOX1,
  61        FW_DOMAIN_ID_MEDIA_VEBOX2,
  62        FW_DOMAIN_ID_MEDIA_VEBOX3,
  63
  64        FW_DOMAIN_ID_COUNT
  65};
  66
  67enum forcewake_domains {
  68        FORCEWAKE_RENDER        = BIT(FW_DOMAIN_ID_RENDER),
  69        FORCEWAKE_GT            = BIT(FW_DOMAIN_ID_GT),
  70        FORCEWAKE_MEDIA         = BIT(FW_DOMAIN_ID_MEDIA),
  71        FORCEWAKE_MEDIA_VDBOX0  = BIT(FW_DOMAIN_ID_MEDIA_VDBOX0),
  72        FORCEWAKE_MEDIA_VDBOX1  = BIT(FW_DOMAIN_ID_MEDIA_VDBOX1),
  73        FORCEWAKE_MEDIA_VDBOX2  = BIT(FW_DOMAIN_ID_MEDIA_VDBOX2),
  74        FORCEWAKE_MEDIA_VDBOX3  = BIT(FW_DOMAIN_ID_MEDIA_VDBOX3),
  75        FORCEWAKE_MEDIA_VDBOX4  = BIT(FW_DOMAIN_ID_MEDIA_VDBOX4),
  76        FORCEWAKE_MEDIA_VDBOX5  = BIT(FW_DOMAIN_ID_MEDIA_VDBOX5),
  77        FORCEWAKE_MEDIA_VDBOX6  = BIT(FW_DOMAIN_ID_MEDIA_VDBOX6),
  78        FORCEWAKE_MEDIA_VDBOX7  = BIT(FW_DOMAIN_ID_MEDIA_VDBOX7),
  79        FORCEWAKE_MEDIA_VEBOX0  = BIT(FW_DOMAIN_ID_MEDIA_VEBOX0),
  80        FORCEWAKE_MEDIA_VEBOX1  = BIT(FW_DOMAIN_ID_MEDIA_VEBOX1),
  81        FORCEWAKE_MEDIA_VEBOX2  = BIT(FW_DOMAIN_ID_MEDIA_VEBOX2),
  82        FORCEWAKE_MEDIA_VEBOX3  = BIT(FW_DOMAIN_ID_MEDIA_VEBOX3),
  83
  84        FORCEWAKE_ALL = BIT(FW_DOMAIN_ID_COUNT) - 1,
  85};
  86
  87struct intel_uncore_funcs {
  88        void (*force_wake_get)(struct intel_uncore *uncore,
  89                               enum forcewake_domains domains);
  90        void (*force_wake_put)(struct intel_uncore *uncore,
  91                               enum forcewake_domains domains);
  92
  93        enum forcewake_domains (*read_fw_domains)(struct intel_uncore *uncore,
  94                                                  i915_reg_t r);
  95        enum forcewake_domains (*write_fw_domains)(struct intel_uncore *uncore,
  96                                                   i915_reg_t r);
  97
  98        u8 (*mmio_readb)(struct intel_uncore *uncore,
  99                         i915_reg_t r, bool trace);
 100        u16 (*mmio_readw)(struct intel_uncore *uncore,
 101                          i915_reg_t r, bool trace);
 102        u32 (*mmio_readl)(struct intel_uncore *uncore,
 103                          i915_reg_t r, bool trace);
 104        u64 (*mmio_readq)(struct intel_uncore *uncore,
 105                          i915_reg_t r, bool trace);
 106
 107        void (*mmio_writeb)(struct intel_uncore *uncore,
 108                            i915_reg_t r, u8 val, bool trace);
 109        void (*mmio_writew)(struct intel_uncore *uncore,
 110                            i915_reg_t r, u16 val, bool trace);
 111        void (*mmio_writel)(struct intel_uncore *uncore,
 112                            i915_reg_t r, u32 val, bool trace);
 113};
 114
 115struct intel_forcewake_range {
 116        u32 start;
 117        u32 end;
 118
 119        enum forcewake_domains domains;
 120};
 121
 122struct intel_uncore {
 123        void __iomem *regs;
 124
 125        struct drm_i915_private *i915;
 126        struct intel_runtime_pm *rpm;
 127
 128        spinlock_t lock; /** lock is also taken in irq contexts. */
 129
 130        unsigned int flags;
 131#define UNCORE_HAS_FORCEWAKE            BIT(0)
 132#define UNCORE_HAS_FPGA_DBG_UNCLAIMED   BIT(1)
 133#define UNCORE_HAS_DBG_UNCLAIMED        BIT(2)
 134#define UNCORE_HAS_FIFO                 BIT(3)
 135
 136        const struct intel_forcewake_range *fw_domains_table;
 137        unsigned int fw_domains_table_entries;
 138
 139        struct notifier_block pmic_bus_access_nb;
 140        struct intel_uncore_funcs funcs;
 141
 142        unsigned int fifo_count;
 143
 144        enum forcewake_domains fw_domains;
 145        enum forcewake_domains fw_domains_active;
 146        enum forcewake_domains fw_domains_timer;
 147        enum forcewake_domains fw_domains_saved; /* user domains saved for S3 */
 148
 149        struct intel_uncore_forcewake_domain {
 150                struct intel_uncore *uncore;
 151                enum forcewake_domain_id id;
 152                enum forcewake_domains mask;
 153                unsigned int wake_count;
 154                bool active;
 155                struct hrtimer timer;
 156                u32 __iomem *reg_set;
 157                u32 __iomem *reg_ack;
 158        } *fw_domain[FW_DOMAIN_ID_COUNT];
 159
 160        unsigned int user_forcewake_count;
 161
 162        struct intel_uncore_mmio_debug *debug;
 163};
 164
 165/* Iterate over initialised fw domains */
 166#define for_each_fw_domain_masked(domain__, mask__, uncore__, tmp__) \
 167        for (tmp__ = (mask__); tmp__ ;) \
 168                for_each_if(domain__ = (uncore__)->fw_domain[__mask_next_bit(tmp__)])
 169
 170#define for_each_fw_domain(domain__, uncore__, tmp__) \
 171        for_each_fw_domain_masked(domain__, (uncore__)->fw_domains, uncore__, tmp__)
 172
 173static inline bool
 174intel_uncore_has_forcewake(const struct intel_uncore *uncore)
 175{
 176        return uncore->flags & UNCORE_HAS_FORCEWAKE;
 177}
 178
 179static inline bool
 180intel_uncore_has_fpga_dbg_unclaimed(const struct intel_uncore *uncore)
 181{
 182        return uncore->flags & UNCORE_HAS_FPGA_DBG_UNCLAIMED;
 183}
 184
 185static inline bool
 186intel_uncore_has_dbg_unclaimed(const struct intel_uncore *uncore)
 187{
 188        return uncore->flags & UNCORE_HAS_DBG_UNCLAIMED;
 189}
 190
 191static inline bool
 192intel_uncore_has_fifo(const struct intel_uncore *uncore)
 193{
 194        return uncore->flags & UNCORE_HAS_FIFO;
 195}
 196
 197u32 intel_uncore_read_with_mcr_steering_fw(struct intel_uncore *uncore,
 198                                           i915_reg_t reg,
 199                                           int slice, int subslice);
 200u32 intel_uncore_read_with_mcr_steering(struct intel_uncore *uncore,
 201                                        i915_reg_t reg, int slice, int subslice);
 202
 203void
 204intel_uncore_mmio_debug_init_early(struct intel_uncore_mmio_debug *mmio_debug);
 205void intel_uncore_init_early(struct intel_uncore *uncore,
 206                             struct drm_i915_private *i915);
 207int intel_uncore_init_mmio(struct intel_uncore *uncore);
 208void intel_uncore_prune_engine_fw_domains(struct intel_uncore *uncore,
 209                                          struct intel_gt *gt);
 210bool intel_uncore_unclaimed_mmio(struct intel_uncore *uncore);
 211bool intel_uncore_arm_unclaimed_mmio_detection(struct intel_uncore *uncore);
 212void intel_uncore_fini_mmio(struct intel_uncore *uncore);
 213void intel_uncore_suspend(struct intel_uncore *uncore);
 214void intel_uncore_resume_early(struct intel_uncore *uncore);
 215void intel_uncore_runtime_resume(struct intel_uncore *uncore);
 216
 217void assert_forcewakes_inactive(struct intel_uncore *uncore);
 218void assert_forcewakes_active(struct intel_uncore *uncore,
 219                              enum forcewake_domains fw_domains);
 220const char *intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id);
 221
 222enum forcewake_domains
 223intel_uncore_forcewake_for_reg(struct intel_uncore *uncore,
 224                               i915_reg_t reg, unsigned int op);
 225#define FW_REG_READ  (1)
 226#define FW_REG_WRITE (2)
 227
 228void intel_uncore_forcewake_get(struct intel_uncore *uncore,
 229                                enum forcewake_domains domains);
 230void intel_uncore_forcewake_put(struct intel_uncore *uncore,
 231                                enum forcewake_domains domains);
 232void intel_uncore_forcewake_flush(struct intel_uncore *uncore,
 233                                  enum forcewake_domains fw_domains);
 234
 235/*
 236 * Like above but the caller must manage the uncore.lock itself.
 237 * Must be used with intel_uncore_read_fw() and friends.
 238 */
 239void intel_uncore_forcewake_get__locked(struct intel_uncore *uncore,
 240                                        enum forcewake_domains domains);
 241void intel_uncore_forcewake_put__locked(struct intel_uncore *uncore,
 242                                        enum forcewake_domains domains);
 243
 244void intel_uncore_forcewake_user_get(struct intel_uncore *uncore);
 245void intel_uncore_forcewake_user_put(struct intel_uncore *uncore);
 246
 247int __intel_wait_for_register(struct intel_uncore *uncore,
 248                              i915_reg_t reg,
 249                              u32 mask,
 250                              u32 value,
 251                              unsigned int fast_timeout_us,
 252                              unsigned int slow_timeout_ms,
 253                              u32 *out_value);
 254static inline int
 255intel_wait_for_register(struct intel_uncore *uncore,
 256                        i915_reg_t reg,
 257                        u32 mask,
 258                        u32 value,
 259                        unsigned int timeout_ms)
 260{
 261        return __intel_wait_for_register(uncore, reg, mask, value, 2,
 262                                         timeout_ms, NULL);
 263}
 264
 265int __intel_wait_for_register_fw(struct intel_uncore *uncore,
 266                                 i915_reg_t reg,
 267                                 u32 mask,
 268                                 u32 value,
 269                                 unsigned int fast_timeout_us,
 270                                 unsigned int slow_timeout_ms,
 271                                 u32 *out_value);
 272static inline int
 273intel_wait_for_register_fw(struct intel_uncore *uncore,
 274                           i915_reg_t reg,
 275                           u32 mask,
 276                           u32 value,
 277                               unsigned int timeout_ms)
 278{
 279        return __intel_wait_for_register_fw(uncore, reg, mask, value,
 280                                            2, timeout_ms, NULL);
 281}
 282
 283/* register access functions */
 284#define __raw_read(x__, s__) \
 285static inline u##x__ __raw_uncore_read##x__(const struct intel_uncore *uncore, \
 286                                            i915_reg_t reg) \
 287{ \
 288        return read##s__(uncore->regs + i915_mmio_reg_offset(reg)); \
 289}
 290
 291#define __raw_write(x__, s__) \
 292static inline void __raw_uncore_write##x__(const struct intel_uncore *uncore, \
 293                                           i915_reg_t reg, u##x__ val) \
 294{ \
 295        write##s__(val, uncore->regs + i915_mmio_reg_offset(reg)); \
 296}
 297__raw_read(8, b)
 298__raw_read(16, w)
 299__raw_read(32, l)
 300__raw_read(64, q)
 301
 302__raw_write(8, b)
 303__raw_write(16, w)
 304__raw_write(32, l)
 305__raw_write(64, q)
 306
 307#undef __raw_read
 308#undef __raw_write
 309
 310#define __uncore_read(name__, x__, s__, trace__) \
 311static inline u##x__ intel_uncore_##name__(struct intel_uncore *uncore, \
 312                                           i915_reg_t reg) \
 313{ \
 314        return uncore->funcs.mmio_read##s__(uncore, reg, (trace__)); \
 315}
 316
 317#define __uncore_write(name__, x__, s__, trace__) \
 318static inline void intel_uncore_##name__(struct intel_uncore *uncore, \
 319                                         i915_reg_t reg, u##x__ val) \
 320{ \
 321        uncore->funcs.mmio_write##s__(uncore, reg, val, (trace__)); \
 322}
 323
 324__uncore_read(read8, 8, b, true)
 325__uncore_read(read16, 16, w, true)
 326__uncore_read(read, 32, l, true)
 327__uncore_read(read16_notrace, 16, w, false)
 328__uncore_read(read_notrace, 32, l, false)
 329
 330__uncore_write(write8, 8, b, true)
 331__uncore_write(write16, 16, w, true)
 332__uncore_write(write, 32, l, true)
 333__uncore_write(write_notrace, 32, l, false)
 334
 335/* Be very careful with read/write 64-bit values. On 32-bit machines, they
 336 * will be implemented using 2 32-bit writes in an arbitrary order with
 337 * an arbitrary delay between them. This can cause the hardware to
 338 * act upon the intermediate value, possibly leading to corruption and
 339 * machine death. For this reason we do not support intel_uncore_write64,
 340 * or uncore->funcs.mmio_writeq.
 341 *
 342 * When reading a 64-bit value as two 32-bit values, the delay may cause
 343 * the two reads to mismatch, e.g. a timestamp overflowing. Also note that
 344 * occasionally a 64-bit register does not actually support a full readq
 345 * and must be read using two 32-bit reads.
 346 *
 347 * You have been warned.
 348 */
 349__uncore_read(read64, 64, q, true)
 350
 351static inline u64
 352intel_uncore_read64_2x32(struct intel_uncore *uncore,
 353                         i915_reg_t lower_reg, i915_reg_t upper_reg)
 354{
 355        u32 upper, lower, old_upper, loop = 0;
 356        upper = intel_uncore_read(uncore, upper_reg);
 357        do {
 358                old_upper = upper;
 359                lower = intel_uncore_read(uncore, lower_reg);
 360                upper = intel_uncore_read(uncore, upper_reg);
 361        } while (upper != old_upper && loop++ < 2);
 362        return (u64)upper << 32 | lower;
 363}
 364
 365#define intel_uncore_posting_read(...) ((void)intel_uncore_read_notrace(__VA_ARGS__))
 366#define intel_uncore_posting_read16(...) ((void)intel_uncore_read16_notrace(__VA_ARGS__))
 367
 368#undef __uncore_read
 369#undef __uncore_write
 370
 371/* These are untraced mmio-accessors that are only valid to be used inside
 372 * critical sections, such as inside IRQ handlers, where forcewake is explicitly
 373 * controlled.
 374 *
 375 * Think twice, and think again, before using these.
 376 *
 377 * As an example, these accessors can possibly be used between:
 378 *
 379 * spin_lock_irq(&uncore->lock);
 380 * intel_uncore_forcewake_get__locked();
 381 *
 382 * and
 383 *
 384 * intel_uncore_forcewake_put__locked();
 385 * spin_unlock_irq(&uncore->lock);
 386 *
 387 *
 388 * Note: some registers may not need forcewake held, so
 389 * intel_uncore_forcewake_{get,put} can be omitted, see
 390 * intel_uncore_forcewake_for_reg().
 391 *
 392 * Certain architectures will die if the same cacheline is concurrently accessed
 393 * by different clients (e.g. on Ivybridge). Access to registers should
 394 * therefore generally be serialised, by either the dev_priv->uncore.lock or
 395 * a more localised lock guarding all access to that bank of registers.
 396 */
 397#define intel_uncore_read_fw(...) __raw_uncore_read32(__VA_ARGS__)
 398#define intel_uncore_write_fw(...) __raw_uncore_write32(__VA_ARGS__)
 399#define intel_uncore_write64_fw(...) __raw_uncore_write64(__VA_ARGS__)
 400#define intel_uncore_posting_read_fw(...) ((void)intel_uncore_read_fw(__VA_ARGS__))
 401
 402static inline void intel_uncore_rmw(struct intel_uncore *uncore,
 403                                    i915_reg_t reg, u32 clear, u32 set)
 404{
 405        u32 old, val;
 406
 407        old = intel_uncore_read(uncore, reg);
 408        val = (old & ~clear) | set;
 409        if (val != old)
 410                intel_uncore_write(uncore, reg, val);
 411}
 412
 413static inline void intel_uncore_rmw_fw(struct intel_uncore *uncore,
 414                                       i915_reg_t reg, u32 clear, u32 set)
 415{
 416        u32 old, val;
 417
 418        old = intel_uncore_read_fw(uncore, reg);
 419        val = (old & ~clear) | set;
 420        if (val != old)
 421                intel_uncore_write_fw(uncore, reg, val);
 422}
 423
 424static inline int intel_uncore_write_and_verify(struct intel_uncore *uncore,
 425                                                i915_reg_t reg, u32 val,
 426                                                u32 mask, u32 expected_val)
 427{
 428        u32 reg_val;
 429
 430        intel_uncore_write(uncore, reg, val);
 431        reg_val = intel_uncore_read(uncore, reg);
 432
 433        return (reg_val & mask) != expected_val ? -EINVAL : 0;
 434}
 435
 436#define raw_reg_read(base, reg) \
 437        readl(base + i915_mmio_reg_offset(reg))
 438#define raw_reg_write(base, reg, value) \
 439        writel(value, base + i915_mmio_reg_offset(reg))
 440
 441#endif /* !__INTEL_UNCORE_H__ */
 442