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 "i915_drv.h" 24 25 #include "intel_engine.h" 26 #include "intel_mocs.h" 27 #include "intel_lrc.h" 28 29 /* structures required */ 30 struct drm_i915_mocs_entry { 31 u32 control_value; 32 u16 l3cc_value; 33 u16 used; 34 }; 35 36 struct drm_i915_mocs_table { 37 unsigned int size; 38 unsigned int n_entries; 39 const struct drm_i915_mocs_entry *table; 40 }; 41 42 /* Defines for the tables (XXX_MOCS_0 - XXX_MOCS_63) */ 43 #define _LE_CACHEABILITY(value) ((value) << 0) 44 #define _LE_TGT_CACHE(value) ((value) << 2) 45 #define LE_LRUM(value) ((value) << 4) 46 #define LE_AOM(value) ((value) << 6) 47 #define LE_RSC(value) ((value) << 7) 48 #define LE_SCC(value) ((value) << 8) 49 #define LE_PFM(value) ((value) << 11) 50 #define LE_SCF(value) ((value) << 14) 51 #define LE_COS(value) ((value) << 15) 52 #define LE_SSE(value) ((value) << 17) 53 54 /* Defines for the tables (LNCFMOCS0 - LNCFMOCS31) - two entries per word */ 55 #define L3_ESC(value) ((value) << 0) 56 #define L3_SCC(value) ((value) << 1) 57 #define _L3_CACHEABILITY(value) ((value) << 4) 58 59 /* Helper defines */ 60 #define GEN9_NUM_MOCS_ENTRIES 62 /* 62 out of 64 - 63 & 64 are reserved. */ 61 #define GEN11_NUM_MOCS_ENTRIES 64 /* 63-64 are reserved, but configured. */ 62 63 /* (e)LLC caching options */ 64 #define LE_0_PAGETABLE _LE_CACHEABILITY(0) 65 #define LE_1_UC _LE_CACHEABILITY(1) 66 #define LE_2_WT _LE_CACHEABILITY(2) 67 #define LE_3_WB _LE_CACHEABILITY(3) 68 69 /* Target cache */ 70 #define LE_TC_0_PAGETABLE _LE_TGT_CACHE(0) 71 #define LE_TC_1_LLC _LE_TGT_CACHE(1) 72 #define LE_TC_2_LLC_ELLC _LE_TGT_CACHE(2) 73 #define LE_TC_3_LLC_ELLC_ALT _LE_TGT_CACHE(3) 74 75 /* L3 caching options */ 76 #define L3_0_DIRECT _L3_CACHEABILITY(0) 77 #define L3_1_UC _L3_CACHEABILITY(1) 78 #define L3_2_RESERVED _L3_CACHEABILITY(2) 79 #define L3_3_WB _L3_CACHEABILITY(3) 80 81 #define MOCS_ENTRY(__idx, __control_value, __l3cc_value) \ 82 [__idx] = { \ 83 .control_value = __control_value, \ 84 .l3cc_value = __l3cc_value, \ 85 .used = 1, \ 86 } 87 88 /* 89 * MOCS tables 90 * 91 * These are the MOCS tables that are programmed across all the rings. 92 * The control value is programmed to all the rings that support the 93 * MOCS registers. While the l3cc_values are only programmed to the 94 * LNCFCMOCS0 - LNCFCMOCS32 registers. 95 * 96 * These tables are intended to be kept reasonably consistent across 97 * HW platforms, and for ICL+, be identical across OSes. To achieve 98 * that, for Icelake and above, list of entries is published as part 99 * of bspec. 100 * 101 * Entries not part of the following tables are undefined as far as 102 * userspace is concerned and shouldn't be relied upon. For the time 103 * being they will be initialized to PTE. 104 * 105 * The last two entries are reserved by the hardware. For ICL+ they 106 * should be initialized according to bspec and never used, for older 107 * platforms they should never be written to. 108 * 109 * NOTE: These tables are part of bspec and defined as part of hardware 110 * interface for ICL+. For older platforms, they are part of kernel 111 * ABI. It is expected that, for specific hardware platform, existing 112 * entries will remain constant and the table will only be updated by 113 * adding new entries, filling unused positions. 114 */ 115 #define GEN9_MOCS_ENTRIES \ 116 MOCS_ENTRY(I915_MOCS_UNCACHED, \ 117 LE_1_UC | LE_TC_2_LLC_ELLC, \ 118 L3_1_UC), \ 119 MOCS_ENTRY(I915_MOCS_PTE, \ 120 LE_0_PAGETABLE | LE_TC_2_LLC_ELLC | LE_LRUM(3), \ 121 L3_3_WB) 122 123 static const struct drm_i915_mocs_entry skylake_mocs_table[] = { 124 GEN9_MOCS_ENTRIES, 125 MOCS_ENTRY(I915_MOCS_CACHED, 126 LE_3_WB | LE_TC_2_LLC_ELLC | LE_LRUM(3), 127 L3_3_WB) 128 }; 129 130 /* NOTE: the LE_TGT_CACHE is not used on Broxton */ 131 static const struct drm_i915_mocs_entry broxton_mocs_table[] = { 132 GEN9_MOCS_ENTRIES, 133 MOCS_ENTRY(I915_MOCS_CACHED, 134 LE_1_UC | LE_TC_2_LLC_ELLC | LE_LRUM(3), 135 L3_3_WB) 136 }; 137 138 #define GEN11_MOCS_ENTRIES \ 139 /* Base - Uncached (Deprecated) */ \ 140 MOCS_ENTRY(I915_MOCS_UNCACHED, \ 141 LE_1_UC | LE_TC_1_LLC, \ 142 L3_1_UC), \ 143 /* Base - L3 + LeCC:PAT (Deprecated) */ \ 144 MOCS_ENTRY(I915_MOCS_PTE, \ 145 LE_0_PAGETABLE | LE_TC_1_LLC, \ 146 L3_3_WB), \ 147 /* Base - L3 + LLC */ \ 148 MOCS_ENTRY(2, \ 149 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), \ 150 L3_3_WB), \ 151 /* Base - Uncached */ \ 152 MOCS_ENTRY(3, \ 153 LE_1_UC | LE_TC_1_LLC, \ 154 L3_1_UC), \ 155 /* Base - L3 */ \ 156 MOCS_ENTRY(4, \ 157 LE_1_UC | LE_TC_1_LLC, \ 158 L3_3_WB), \ 159 /* Base - LLC */ \ 160 MOCS_ENTRY(5, \ 161 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), \ 162 L3_1_UC), \ 163 /* Age 0 - LLC */ \ 164 MOCS_ENTRY(6, \ 165 LE_3_WB | LE_TC_1_LLC | LE_LRUM(1), \ 166 L3_1_UC), \ 167 /* Age 0 - L3 + LLC */ \ 168 MOCS_ENTRY(7, \ 169 LE_3_WB | LE_TC_1_LLC | LE_LRUM(1), \ 170 L3_3_WB), \ 171 /* Age: Don't Chg. - LLC */ \ 172 MOCS_ENTRY(8, \ 173 LE_3_WB | LE_TC_1_LLC | LE_LRUM(2), \ 174 L3_1_UC), \ 175 /* Age: Don't Chg. - L3 + LLC */ \ 176 MOCS_ENTRY(9, \ 177 LE_3_WB | LE_TC_1_LLC | LE_LRUM(2), \ 178 L3_3_WB), \ 179 /* No AOM - LLC */ \ 180 MOCS_ENTRY(10, \ 181 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_AOM(1), \ 182 L3_1_UC), \ 183 /* No AOM - L3 + LLC */ \ 184 MOCS_ENTRY(11, \ 185 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_AOM(1), \ 186 L3_3_WB), \ 187 /* No AOM; Age 0 - LLC */ \ 188 MOCS_ENTRY(12, \ 189 LE_3_WB | LE_TC_1_LLC | LE_LRUM(1) | LE_AOM(1), \ 190 L3_1_UC), \ 191 /* No AOM; Age 0 - L3 + LLC */ \ 192 MOCS_ENTRY(13, \ 193 LE_3_WB | LE_TC_1_LLC | LE_LRUM(1) | LE_AOM(1), \ 194 L3_3_WB), \ 195 /* No AOM; Age:DC - LLC */ \ 196 MOCS_ENTRY(14, \ 197 LE_3_WB | LE_TC_1_LLC | LE_LRUM(2) | LE_AOM(1), \ 198 L3_1_UC), \ 199 /* No AOM; Age:DC - L3 + LLC */ \ 200 MOCS_ENTRY(15, \ 201 LE_3_WB | LE_TC_1_LLC | LE_LRUM(2) | LE_AOM(1), \ 202 L3_3_WB), \ 203 /* Self-Snoop - L3 + LLC */ \ 204 MOCS_ENTRY(18, \ 205 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_SSE(3), \ 206 L3_3_WB), \ 207 /* Skip Caching - L3 + LLC(12.5%) */ \ 208 MOCS_ENTRY(19, \ 209 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_SCC(7), \ 210 L3_3_WB), \ 211 /* Skip Caching - L3 + LLC(25%) */ \ 212 MOCS_ENTRY(20, \ 213 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_SCC(3), \ 214 L3_3_WB), \ 215 /* Skip Caching - L3 + LLC(50%) */ \ 216 MOCS_ENTRY(21, \ 217 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_SCC(1), \ 218 L3_3_WB), \ 219 /* Skip Caching - L3 + LLC(75%) */ \ 220 MOCS_ENTRY(22, \ 221 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_RSC(1) | LE_SCC(3), \ 222 L3_3_WB), \ 223 /* Skip Caching - L3 + LLC(87.5%) */ \ 224 MOCS_ENTRY(23, \ 225 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_RSC(1) | LE_SCC(7), \ 226 L3_3_WB), \ 227 /* HW Reserved - SW program but never use */ \ 228 MOCS_ENTRY(62, \ 229 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), \ 230 L3_1_UC), \ 231 /* HW Reserved - SW program but never use */ \ 232 MOCS_ENTRY(63, \ 233 LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), \ 234 L3_1_UC) 235 236 static const struct drm_i915_mocs_entry icelake_mocs_table[] = { 237 GEN11_MOCS_ENTRIES 238 }; 239 240 /** 241 * get_mocs_settings() 242 * @dev_priv: i915 device. 243 * @table: Output table that will be made to point at appropriate 244 * MOCS values for the device. 245 * 246 * This function will return the values of the MOCS table that needs to 247 * be programmed for the platform. It will return the values that need 248 * to be programmed and if they need to be programmed. 249 * 250 * Return: true if there are applicable MOCS settings for the device. 251 */ 252 static bool get_mocs_settings(struct drm_i915_private *dev_priv, 253 struct drm_i915_mocs_table *table) 254 { 255 bool result = false; 256 257 if (INTEL_GEN(dev_priv) >= 11) { 258 table->size = ARRAY_SIZE(icelake_mocs_table); 259 table->table = icelake_mocs_table; 260 table->n_entries = GEN11_NUM_MOCS_ENTRIES; 261 result = true; 262 } else if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { 263 table->size = ARRAY_SIZE(skylake_mocs_table); 264 table->n_entries = GEN9_NUM_MOCS_ENTRIES; 265 table->table = skylake_mocs_table; 266 result = true; 267 } else if (IS_GEN9_LP(dev_priv)) { 268 table->size = ARRAY_SIZE(broxton_mocs_table); 269 table->n_entries = GEN9_NUM_MOCS_ENTRIES; 270 table->table = broxton_mocs_table; 271 result = true; 272 } else { 273 WARN_ONCE(INTEL_GEN(dev_priv) >= 9, 274 "Platform that should have a MOCS table does not.\n"); 275 } 276 277 /* WaDisableSkipCaching:skl,bxt,kbl,glk */ 278 if (IS_GEN(dev_priv, 9)) { 279 int i; 280 281 for (i = 0; i < table->size; i++) 282 if (WARN_ON(table->table[i].l3cc_value & 283 (L3_ESC(1) | L3_SCC(0x7)))) 284 return false; 285 } 286 287 return result; 288 } 289 290 static i915_reg_t mocs_register(enum intel_engine_id engine_id, int index) 291 { 292 switch (engine_id) { 293 case RCS0: 294 return GEN9_GFX_MOCS(index); 295 case VCS0: 296 return GEN9_MFX0_MOCS(index); 297 case BCS0: 298 return GEN9_BLT_MOCS(index); 299 case VECS0: 300 return GEN9_VEBOX_MOCS(index); 301 case VCS1: 302 return GEN9_MFX1_MOCS(index); 303 case VCS2: 304 return GEN11_MFX2_MOCS(index); 305 default: 306 MISSING_CASE(engine_id); 307 return INVALID_MMIO_REG; 308 } 309 } 310 311 /* 312 * Get control_value from MOCS entry taking into account when it's not used: 313 * I915_MOCS_PTE's value is returned in this case. 314 */ 315 static u32 get_entry_control(const struct drm_i915_mocs_table *table, 316 unsigned int index) 317 { 318 if (table->table[index].used) 319 return table->table[index].control_value; 320 321 return table->table[I915_MOCS_PTE].control_value; 322 } 323 324 /** 325 * intel_mocs_init_engine() - emit the mocs control table 326 * @engine: The engine for whom to emit the registers. 327 * 328 * This function simply emits a MI_LOAD_REGISTER_IMM command for the 329 * given table starting at the given address. 330 */ 331 void intel_mocs_init_engine(struct intel_engine_cs *engine) 332 { 333 struct drm_i915_private *dev_priv = engine->i915; 334 struct drm_i915_mocs_table table; 335 unsigned int index; 336 u32 unused_value; 337 338 if (!get_mocs_settings(dev_priv, &table)) 339 return; 340 341 /* Set unused values to PTE */ 342 unused_value = table.table[I915_MOCS_PTE].control_value; 343 344 for (index = 0; index < table.size; index++) { 345 u32 value = get_entry_control(&table, index); 346 347 I915_WRITE(mocs_register(engine->id, index), value); 348 } 349 350 /* All remaining entries are also unused */ 351 for (; index < table.n_entries; index++) 352 I915_WRITE(mocs_register(engine->id, index), unused_value); 353 } 354 355 /** 356 * emit_mocs_control_table() - emit the mocs control table 357 * @rq: Request to set up the MOCS table for. 358 * @table: The values to program into the control regs. 359 * 360 * This function simply emits a MI_LOAD_REGISTER_IMM command for the 361 * given table starting at the given address. 362 * 363 * Return: 0 on success, otherwise the error status. 364 */ 365 static int emit_mocs_control_table(struct i915_request *rq, 366 const struct drm_i915_mocs_table *table) 367 { 368 enum intel_engine_id engine = rq->engine->id; 369 unsigned int index; 370 u32 unused_value; 371 u32 *cs; 372 373 if (GEM_WARN_ON(table->size > table->n_entries)) 374 return -ENODEV; 375 376 /* Set unused values to PTE */ 377 unused_value = table->table[I915_MOCS_PTE].control_value; 378 379 cs = intel_ring_begin(rq, 2 + 2 * table->n_entries); 380 if (IS_ERR(cs)) 381 return PTR_ERR(cs); 382 383 *cs++ = MI_LOAD_REGISTER_IMM(table->n_entries); 384 385 for (index = 0; index < table->size; index++) { 386 u32 value = get_entry_control(table, index); 387 388 *cs++ = i915_mmio_reg_offset(mocs_register(engine, index)); 389 *cs++ = value; 390 } 391 392 /* All remaining entries are also unused */ 393 for (; index < table->n_entries; index++) { 394 *cs++ = i915_mmio_reg_offset(mocs_register(engine, index)); 395 *cs++ = unused_value; 396 } 397 398 *cs++ = MI_NOOP; 399 intel_ring_advance(rq, cs); 400 401 return 0; 402 } 403 404 /* 405 * Get l3cc_value from MOCS entry taking into account when it's not used: 406 * I915_MOCS_PTE's value is returned in this case. 407 */ 408 static u16 get_entry_l3cc(const struct drm_i915_mocs_table *table, 409 unsigned int index) 410 { 411 if (table->table[index].used) 412 return table->table[index].l3cc_value; 413 414 return table->table[I915_MOCS_PTE].l3cc_value; 415 } 416 417 static inline u32 l3cc_combine(const struct drm_i915_mocs_table *table, 418 u16 low, 419 u16 high) 420 { 421 return low | high << 16; 422 } 423 424 /** 425 * emit_mocs_l3cc_table() - emit the mocs control table 426 * @rq: Request to set up the MOCS table for. 427 * @table: The values to program into the control regs. 428 * 429 * This function simply emits a MI_LOAD_REGISTER_IMM command for the 430 * given table starting at the given address. This register set is 431 * programmed in pairs. 432 * 433 * Return: 0 on success, otherwise the error status. 434 */ 435 static int emit_mocs_l3cc_table(struct i915_request *rq, 436 const struct drm_i915_mocs_table *table) 437 { 438 u16 unused_value; 439 unsigned int i; 440 u32 *cs; 441 442 if (GEM_WARN_ON(table->size > table->n_entries)) 443 return -ENODEV; 444 445 /* Set unused values to PTE */ 446 unused_value = table->table[I915_MOCS_PTE].l3cc_value; 447 448 cs = intel_ring_begin(rq, 2 + table->n_entries); 449 if (IS_ERR(cs)) 450 return PTR_ERR(cs); 451 452 *cs++ = MI_LOAD_REGISTER_IMM(table->n_entries / 2); 453 454 for (i = 0; i < table->size / 2; i++) { 455 u16 low = get_entry_l3cc(table, 2 * i); 456 u16 high = get_entry_l3cc(table, 2 * i + 1); 457 458 *cs++ = i915_mmio_reg_offset(GEN9_LNCFCMOCS(i)); 459 *cs++ = l3cc_combine(table, low, high); 460 } 461 462 /* Odd table size - 1 left over */ 463 if (table->size & 0x01) { 464 u16 low = get_entry_l3cc(table, 2 * i); 465 466 *cs++ = i915_mmio_reg_offset(GEN9_LNCFCMOCS(i)); 467 *cs++ = l3cc_combine(table, low, unused_value); 468 i++; 469 } 470 471 /* All remaining entries are also unused */ 472 for (; i < table->n_entries / 2; i++) { 473 *cs++ = i915_mmio_reg_offset(GEN9_LNCFCMOCS(i)); 474 *cs++ = l3cc_combine(table, unused_value, unused_value); 475 } 476 477 *cs++ = MI_NOOP; 478 intel_ring_advance(rq, cs); 479 480 return 0; 481 } 482 483 /** 484 * intel_mocs_init_l3cc_table() - program the mocs control table 485 * @dev_priv: i915 device private 486 * 487 * This function simply programs the mocs registers for the given table 488 * starting at the given address. This register set is programmed in pairs. 489 * 490 * These registers may get programmed more than once, it is simpler to 491 * re-program 32 registers than maintain the state of when they were programmed. 492 * We are always reprogramming with the same values and this only on context 493 * start. 494 * 495 * Return: Nothing. 496 */ 497 void intel_mocs_init_l3cc_table(struct drm_i915_private *dev_priv) 498 { 499 struct drm_i915_mocs_table table; 500 unsigned int i; 501 u16 unused_value; 502 503 if (!get_mocs_settings(dev_priv, &table)) 504 return; 505 506 /* Set unused values to PTE */ 507 unused_value = table.table[I915_MOCS_PTE].l3cc_value; 508 509 for (i = 0; i < table.size / 2; i++) { 510 u16 low = get_entry_l3cc(&table, 2 * i); 511 u16 high = get_entry_l3cc(&table, 2 * i + 1); 512 513 I915_WRITE(GEN9_LNCFCMOCS(i), 514 l3cc_combine(&table, low, high)); 515 } 516 517 /* Odd table size - 1 left over */ 518 if (table.size & 0x01) { 519 u16 low = get_entry_l3cc(&table, 2 * i); 520 521 I915_WRITE(GEN9_LNCFCMOCS(i), 522 l3cc_combine(&table, low, unused_value)); 523 i++; 524 } 525 526 /* All remaining entries are also unused */ 527 for (; i < table.n_entries / 2; i++) 528 I915_WRITE(GEN9_LNCFCMOCS(i), 529 l3cc_combine(&table, unused_value, unused_value)); 530 } 531 532 /** 533 * intel_rcs_context_init_mocs() - program the MOCS register. 534 * @rq: Request to set up the MOCS tables for. 535 * 536 * This function will emit a batch buffer with the values required for 537 * programming the MOCS register values for all the currently supported 538 * rings. 539 * 540 * These registers are partially stored in the RCS context, so they are 541 * emitted at the same time so that when a context is created these registers 542 * are set up. These registers have to be emitted into the start of the 543 * context as setting the ELSP will re-init some of these registers back 544 * to the hw values. 545 * 546 * Return: 0 on success, otherwise the error status. 547 */ 548 int intel_rcs_context_init_mocs(struct i915_request *rq) 549 { 550 struct drm_i915_mocs_table t; 551 int ret; 552 553 if (get_mocs_settings(rq->i915, &t)) { 554 /* Program the RCS control registers */ 555 ret = emit_mocs_control_table(rq, &t); 556 if (ret) 557 return ret; 558 559 /* Now program the l3cc registers */ 560 ret = emit_mocs_l3cc_table(rq, &t); 561 if (ret) 562 return ret; 563 } 564 565 return 0; 566 } 567