linux/drivers/gpu/drm/i915/intel_mocs.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2015 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 * The above copyright notice and this permission notice (including the next
  11 * paragraph) shall be included in all copies or substantial portions of the
  12 * Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20 * SOFTWARE.
  21 */
  22
  23#include "intel_mocs.h"
  24#include "intel_lrc.h"
  25#include "intel_ringbuffer.h"
  26
  27/* structures required */
  28struct drm_i915_mocs_entry {
  29        u32 control_value;
  30        u16 l3cc_value;
  31};
  32
  33struct drm_i915_mocs_table {
  34        u32 size;
  35        const struct drm_i915_mocs_entry *table;
  36};
  37
  38/* Defines for the tables (XXX_MOCS_0 - XXX_MOCS_63) */
  39#define LE_CACHEABILITY(value)  ((value) << 0)
  40#define LE_TGT_CACHE(value)     ((value) << 2)
  41#define LE_LRUM(value)          ((value) << 4)
  42#define LE_AOM(value)           ((value) << 6)
  43#define LE_RSC(value)           ((value) << 7)
  44#define LE_SCC(value)           ((value) << 8)
  45#define LE_PFM(value)           ((value) << 11)
  46#define LE_SCF(value)           ((value) << 14)
  47
  48/* Defines for the tables (LNCFMOCS0 - LNCFMOCS31) - two entries per word */
  49#define L3_ESC(value)           ((value) << 0)
  50#define L3_SCC(value)           ((value) << 1)
  51#define L3_CACHEABILITY(value)  ((value) << 4)
  52
  53/* Helper defines */
  54#define GEN9_NUM_MOCS_ENTRIES   62  /* 62 out of 64 - 63 & 64 are reserved. */
  55
  56/* (e)LLC caching options */
  57#define LE_PAGETABLE            0
  58#define LE_UC                   1
  59#define LE_WT                   2
  60#define LE_WB                   3
  61
  62/* L3 caching options */
  63#define L3_DIRECT               0
  64#define L3_UC                   1
  65#define L3_RESERVED             2
  66#define L3_WB                   3
  67
  68/* Target cache */
  69#define LE_TC_PAGETABLE         0
  70#define LE_TC_LLC               1
  71#define LE_TC_LLC_ELLC          2
  72#define LE_TC_LLC_ELLC_ALT      3
  73
  74/*
  75 * MOCS tables
  76 *
  77 * These are the MOCS tables that are programmed across all the rings.
  78 * The control value is programmed to all the rings that support the
  79 * MOCS registers. While the l3cc_values are only programmed to the
  80 * LNCFCMOCS0 - LNCFCMOCS32 registers.
  81 *
  82 * These tables are intended to be kept reasonably consistent across
  83 * platforms. However some of the fields are not applicable to all of
  84 * them.
  85 *
  86 * Entries not part of the following tables are undefined as far as
  87 * userspace is concerned and shouldn't be relied upon.  For the time
  88 * being they will be implicitly initialized to the strictest caching
  89 * configuration (uncached) to guarantee forwards compatibility with
  90 * userspace programs written against more recent kernels providing
  91 * additional MOCS entries.
  92 *
  93 * NOTE: These tables MUST start with being uncached and the length
  94 *       MUST be less than 63 as the last two registers are reserved
  95 *       by the hardware.  These tables are part of the kernel ABI and
  96 *       may only be updated incrementally by adding entries at the
  97 *       end.
  98 */
  99static const struct drm_i915_mocs_entry skylake_mocs_table[] = {
 100        [I915_MOCS_UNCACHED] = {
 101          /* 0x00000009 */
 102          .control_value = LE_CACHEABILITY(LE_UC) |
 103                           LE_TGT_CACHE(LE_TC_LLC_ELLC) |
 104                           LE_LRUM(0) | LE_AOM(0) | LE_RSC(0) | LE_SCC(0) |
 105                           LE_PFM(0) | LE_SCF(0),
 106
 107          /* 0x0010 */
 108          .l3cc_value =    L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_UC),
 109        },
 110        [I915_MOCS_PTE] = {
 111          /* 0x00000038 */
 112          .control_value = LE_CACHEABILITY(LE_PAGETABLE) |
 113                           LE_TGT_CACHE(LE_TC_LLC_ELLC) |
 114                           LE_LRUM(3) | LE_AOM(0) | LE_RSC(0) | LE_SCC(0) |
 115                           LE_PFM(0) | LE_SCF(0),
 116          /* 0x0030 */
 117          .l3cc_value =    L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_WB),
 118        },
 119        [I915_MOCS_CACHED] = {
 120          /* 0x0000003b */
 121          .control_value = LE_CACHEABILITY(LE_WB) |
 122                           LE_TGT_CACHE(LE_TC_LLC_ELLC) |
 123                           LE_LRUM(3) | LE_AOM(0) | LE_RSC(0) | LE_SCC(0) |
 124                           LE_PFM(0) | LE_SCF(0),
 125          /* 0x0030 */
 126          .l3cc_value =   L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_WB),
 127        },
 128};
 129
 130/* NOTE: the LE_TGT_CACHE is not used on Broxton */
 131static const struct drm_i915_mocs_entry broxton_mocs_table[] = {
 132        [I915_MOCS_UNCACHED] = {
 133          /* 0x00000009 */
 134          .control_value = LE_CACHEABILITY(LE_UC) |
 135                           LE_TGT_CACHE(LE_TC_LLC_ELLC) |
 136                           LE_LRUM(0) | LE_AOM(0) | LE_RSC(0) | LE_SCC(0) |
 137                           LE_PFM(0) | LE_SCF(0),
 138
 139          /* 0x0010 */
 140          .l3cc_value =    L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_UC),
 141        },
 142        [I915_MOCS_PTE] = {
 143          /* 0x00000038 */
 144          .control_value = LE_CACHEABILITY(LE_PAGETABLE) |
 145                           LE_TGT_CACHE(LE_TC_LLC_ELLC) |
 146                           LE_LRUM(3) | LE_AOM(0) | LE_RSC(0) | LE_SCC(0) |
 147                           LE_PFM(0) | LE_SCF(0),
 148
 149          /* 0x0030 */
 150          .l3cc_value =    L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_WB),
 151        },
 152        [I915_MOCS_CACHED] = {
 153          /* 0x00000039 */
 154          .control_value = LE_CACHEABILITY(LE_UC) |
 155                           LE_TGT_CACHE(LE_TC_LLC_ELLC) |
 156                           LE_LRUM(3) | LE_AOM(0) | LE_RSC(0) | LE_SCC(0) |
 157                           LE_PFM(0) | LE_SCF(0),
 158
 159          /* 0x0030 */
 160          .l3cc_value =    L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_WB),
 161        },
 162};
 163
 164/**
 165 * get_mocs_settings()
 166 * @dev_priv:   i915 device.
 167 * @table:      Output table that will be made to point at appropriate
 168 *            MOCS values for the device.
 169 *
 170 * This function will return the values of the MOCS table that needs to
 171 * be programmed for the platform. It will return the values that need
 172 * to be programmed and if they need to be programmed.
 173 *
 174 * Return: true if there are applicable MOCS settings for the device.
 175 */
 176static bool get_mocs_settings(struct drm_i915_private *dev_priv,
 177                              struct drm_i915_mocs_table *table)
 178{
 179        bool result = false;
 180
 181        if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
 182                table->size  = ARRAY_SIZE(skylake_mocs_table);
 183                table->table = skylake_mocs_table;
 184                result = true;
 185        } else if (IS_GEN9_LP(dev_priv)) {
 186                table->size  = ARRAY_SIZE(broxton_mocs_table);
 187                table->table = broxton_mocs_table;
 188                result = true;
 189        } else {
 190                WARN_ONCE(INTEL_INFO(dev_priv)->gen >= 9,
 191                          "Platform that should have a MOCS table does not.\n");
 192        }
 193
 194        /* WaDisableSkipCaching:skl,bxt,kbl,glk */
 195        if (IS_GEN9(dev_priv)) {
 196                int i;
 197
 198                for (i = 0; i < table->size; i++)
 199                        if (WARN_ON(table->table[i].l3cc_value &
 200                                    (L3_ESC(1) | L3_SCC(0x7))))
 201                                return false;
 202        }
 203
 204        return result;
 205}
 206
 207static i915_reg_t mocs_register(enum intel_engine_id engine_id, int index)
 208{
 209        switch (engine_id) {
 210        case RCS:
 211                return GEN9_GFX_MOCS(index);
 212        case VCS:
 213                return GEN9_MFX0_MOCS(index);
 214        case BCS:
 215                return GEN9_BLT_MOCS(index);
 216        case VECS:
 217                return GEN9_VEBOX_MOCS(index);
 218        case VCS2:
 219                return GEN9_MFX1_MOCS(index);
 220        default:
 221                MISSING_CASE(engine_id);
 222                return INVALID_MMIO_REG;
 223        }
 224}
 225
 226/**
 227 * intel_mocs_init_engine() - emit the mocs control table
 228 * @engine:     The engine for whom to emit the registers.
 229 *
 230 * This function simply emits a MI_LOAD_REGISTER_IMM command for the
 231 * given table starting at the given address.
 232 *
 233 * Return: 0 on success, otherwise the error status.
 234 */
 235int intel_mocs_init_engine(struct intel_engine_cs *engine)
 236{
 237        struct drm_i915_private *dev_priv = engine->i915;
 238        struct drm_i915_mocs_table table;
 239        unsigned int index;
 240
 241        if (!get_mocs_settings(dev_priv, &table))
 242                return 0;
 243
 244        if (WARN_ON(table.size > GEN9_NUM_MOCS_ENTRIES))
 245                return -ENODEV;
 246
 247        for (index = 0; index < table.size; index++)
 248                I915_WRITE(mocs_register(engine->id, index),
 249                           table.table[index].control_value);
 250
 251        /*
 252         * Ok, now set the unused entries to uncached. These entries
 253         * are officially undefined and no contract for the contents
 254         * and settings is given for these entries.
 255         *
 256         * Entry 0 in the table is uncached - so we are just writing
 257         * that value to all the used entries.
 258         */
 259        for (; index < GEN9_NUM_MOCS_ENTRIES; index++)
 260                I915_WRITE(mocs_register(engine->id, index),
 261                           table.table[0].control_value);
 262
 263        return 0;
 264}
 265
 266/**
 267 * emit_mocs_control_table() - emit the mocs control table
 268 * @req:        Request to set up the MOCS table for.
 269 * @table:      The values to program into the control regs.
 270 *
 271 * This function simply emits a MI_LOAD_REGISTER_IMM command for the
 272 * given table starting at the given address.
 273 *
 274 * Return: 0 on success, otherwise the error status.
 275 */
 276static int emit_mocs_control_table(struct drm_i915_gem_request *req,
 277                                   const struct drm_i915_mocs_table *table)
 278{
 279        enum intel_engine_id engine = req->engine->id;
 280        unsigned int index;
 281        u32 *cs;
 282
 283        if (WARN_ON(table->size > GEN9_NUM_MOCS_ENTRIES))
 284                return -ENODEV;
 285
 286        cs = intel_ring_begin(req, 2 + 2 * GEN9_NUM_MOCS_ENTRIES);
 287        if (IS_ERR(cs))
 288                return PTR_ERR(cs);
 289
 290        *cs++ = MI_LOAD_REGISTER_IMM(GEN9_NUM_MOCS_ENTRIES);
 291
 292        for (index = 0; index < table->size; index++) {
 293                *cs++ = i915_mmio_reg_offset(mocs_register(engine, index));
 294                *cs++ = table->table[index].control_value;
 295        }
 296
 297        /*
 298         * Ok, now set the unused entries to uncached. These entries
 299         * are officially undefined and no contract for the contents
 300         * and settings is given for these entries.
 301         *
 302         * Entry 0 in the table is uncached - so we are just writing
 303         * that value to all the used entries.
 304         */
 305        for (; index < GEN9_NUM_MOCS_ENTRIES; index++) {
 306                *cs++ = i915_mmio_reg_offset(mocs_register(engine, index));
 307                *cs++ = table->table[0].control_value;
 308        }
 309
 310        *cs++ = MI_NOOP;
 311        intel_ring_advance(req, cs);
 312
 313        return 0;
 314}
 315
 316static inline u32 l3cc_combine(const struct drm_i915_mocs_table *table,
 317                               u16 low,
 318                               u16 high)
 319{
 320        return table->table[low].l3cc_value |
 321               table->table[high].l3cc_value << 16;
 322}
 323
 324/**
 325 * emit_mocs_l3cc_table() - emit the mocs control table
 326 * @req:        Request to set up the MOCS table for.
 327 * @table:      The values to program into the control regs.
 328 *
 329 * This function simply emits a MI_LOAD_REGISTER_IMM command for the
 330 * given table starting at the given address. This register set is
 331 * programmed in pairs.
 332 *
 333 * Return: 0 on success, otherwise the error status.
 334 */
 335static int emit_mocs_l3cc_table(struct drm_i915_gem_request *req,
 336                                const struct drm_i915_mocs_table *table)
 337{
 338        unsigned int i;
 339        u32 *cs;
 340
 341        if (WARN_ON(table->size > GEN9_NUM_MOCS_ENTRIES))
 342                return -ENODEV;
 343
 344        cs = intel_ring_begin(req, 2 + GEN9_NUM_MOCS_ENTRIES);
 345        if (IS_ERR(cs))
 346                return PTR_ERR(cs);
 347
 348        *cs++ = MI_LOAD_REGISTER_IMM(GEN9_NUM_MOCS_ENTRIES / 2);
 349
 350        for (i = 0; i < table->size/2; i++) {
 351                *cs++ = i915_mmio_reg_offset(GEN9_LNCFCMOCS(i));
 352                *cs++ = l3cc_combine(table, 2 * i, 2 * i + 1);
 353        }
 354
 355        if (table->size & 0x01) {
 356                /* Odd table size - 1 left over */
 357                *cs++ = i915_mmio_reg_offset(GEN9_LNCFCMOCS(i));
 358                *cs++ = l3cc_combine(table, 2 * i, 0);
 359                i++;
 360        }
 361
 362        /*
 363         * Now set the rest of the table to uncached - use entry 0 as
 364         * this will be uncached. Leave the last pair uninitialised as
 365         * they are reserved by the hardware.
 366         */
 367        for (; i < GEN9_NUM_MOCS_ENTRIES / 2; i++) {
 368                *cs++ = i915_mmio_reg_offset(GEN9_LNCFCMOCS(i));
 369                *cs++ = l3cc_combine(table, 0, 0);
 370        }
 371
 372        *cs++ = MI_NOOP;
 373        intel_ring_advance(req, cs);
 374
 375        return 0;
 376}
 377
 378/**
 379 * intel_mocs_init_l3cc_table() - program the mocs control table
 380 * @dev_priv:      i915 device private
 381 *
 382 * This function simply programs the mocs registers for the given table
 383 * starting at the given address. This register set is  programmed in pairs.
 384 *
 385 * These registers may get programmed more than once, it is simpler to
 386 * re-program 32 registers than maintain the state of when they were programmed.
 387 * We are always reprogramming with the same values and this only on context
 388 * start.
 389 *
 390 * Return: Nothing.
 391 */
 392void intel_mocs_init_l3cc_table(struct drm_i915_private *dev_priv)
 393{
 394        struct drm_i915_mocs_table table;
 395        unsigned int i;
 396
 397        if (!get_mocs_settings(dev_priv, &table))
 398                return;
 399
 400        for (i = 0; i < table.size/2; i++)
 401                I915_WRITE(GEN9_LNCFCMOCS(i), l3cc_combine(&table, 2*i, 2*i+1));
 402
 403        /* Odd table size - 1 left over */
 404        if (table.size & 0x01) {
 405                I915_WRITE(GEN9_LNCFCMOCS(i), l3cc_combine(&table, 2*i, 0));
 406                i++;
 407        }
 408
 409        /*
 410         * Now set the rest of the table to uncached - use entry 0 as
 411         * this will be uncached. Leave the last pair as initialised as
 412         * they are reserved by the hardware.
 413         */
 414        for (; i < (GEN9_NUM_MOCS_ENTRIES / 2); i++)
 415                I915_WRITE(GEN9_LNCFCMOCS(i), l3cc_combine(&table, 0, 0));
 416}
 417
 418/**
 419 * intel_rcs_context_init_mocs() - program the MOCS register.
 420 * @req:        Request to set up the MOCS tables for.
 421 *
 422 * This function will emit a batch buffer with the values required for
 423 * programming the MOCS register values for all the currently supported
 424 * rings.
 425 *
 426 * These registers are partially stored in the RCS context, so they are
 427 * emitted at the same time so that when a context is created these registers
 428 * are set up. These registers have to be emitted into the start of the
 429 * context as setting the ELSP will re-init some of these registers back
 430 * to the hw values.
 431 *
 432 * Return: 0 on success, otherwise the error status.
 433 */
 434int intel_rcs_context_init_mocs(struct drm_i915_gem_request *req)
 435{
 436        struct drm_i915_mocs_table t;
 437        int ret;
 438
 439        if (get_mocs_settings(req->i915, &t)) {
 440                /* Program the RCS control registers */
 441                ret = emit_mocs_control_table(req, &t);
 442                if (ret)
 443                        return ret;
 444
 445                /* Now program the l3cc registers */
 446                ret = emit_mocs_l3cc_table(req, &t);
 447                if (ret)
 448                        return ret;
 449        }
 450
 451        return 0;
 452}
 453