Subversion Repositories Kolibri OS

Rev

Rev 6937 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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 */
  28. struct drm_i915_mocs_entry {
  29.         u32 control_value;
  30.         u16 l3cc_value;
  31. };
  32.  
  33. struct 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 ELLC                    0
  70. #define LLC                     1
  71. #define LLC_ELLC                2
  72.  
  73. /*
  74.  * MOCS tables
  75.  *
  76.  * These are the MOCS tables that are programmed across all the rings.
  77.  * The control value is programmed to all the rings that support the
  78.  * MOCS registers. While the l3cc_values are only programmed to the
  79.  * LNCFCMOCS0 - LNCFCMOCS32 registers.
  80.  *
  81.  * These tables are intended to be kept reasonably consistent across
  82.  * platforms. However some of the fields are not applicable to all of
  83.  * them.
  84.  *
  85.  * Entries not part of the following tables are undefined as far as
  86.  * userspace is concerned and shouldn't be relied upon.  For the time
  87.  * being they will be implicitly initialized to the strictest caching
  88.  * configuration (uncached) to guarantee forwards compatibility with
  89.  * userspace programs written against more recent kernels providing
  90.  * additional MOCS entries.
  91.  *
  92.  * NOTE: These tables MUST start with being uncached and the length
  93.  *       MUST be less than 63 as the last two registers are reserved
  94.  *       by the hardware.  These tables are part of the kernel ABI and
  95.  *       may only be updated incrementally by adding entries at the
  96.  *       end.
  97.  */
  98. static const struct drm_i915_mocs_entry skylake_mocs_table[] = {
  99.         /* { 0x00000009, 0x0010 } */
  100.         { (LE_CACHEABILITY(LE_UC) | LE_TGT_CACHE(LLC_ELLC) | LE_LRUM(0) |
  101.            LE_AOM(0) | LE_RSC(0) | LE_SCC(0) | LE_PFM(0) | LE_SCF(0)),
  102.           (L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_UC)) },
  103.         /* { 0x00000038, 0x0030 } */
  104.         { (LE_CACHEABILITY(LE_PAGETABLE) | LE_TGT_CACHE(LLC_ELLC) | LE_LRUM(3) |
  105.            LE_AOM(0) | LE_RSC(0) | LE_SCC(0) | LE_PFM(0) | LE_SCF(0)),
  106.           (L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_WB)) },
  107.         /* { 0x0000003b, 0x0030 } */
  108.         { (LE_CACHEABILITY(LE_WB) | LE_TGT_CACHE(LLC_ELLC) | LE_LRUM(3) |
  109.            LE_AOM(0) | LE_RSC(0) | LE_SCC(0) | LE_PFM(0) | LE_SCF(0)),
  110.           (L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_WB)) }
  111. };
  112.  
  113. /* NOTE: the LE_TGT_CACHE is not used on Broxton */
  114. static const struct drm_i915_mocs_entry broxton_mocs_table[] = {
  115.         /* { 0x00000009, 0x0010 } */
  116.         { (LE_CACHEABILITY(LE_UC) | LE_TGT_CACHE(LLC_ELLC) | LE_LRUM(0) |
  117.            LE_AOM(0) | LE_RSC(0) | LE_SCC(0) | LE_PFM(0) | LE_SCF(0)),
  118.           (L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_UC)) },
  119.         /* { 0x00000038, 0x0030 } */
  120.         { (LE_CACHEABILITY(LE_PAGETABLE) | LE_TGT_CACHE(LLC_ELLC) | LE_LRUM(3) |
  121.            LE_AOM(0) | LE_RSC(0) | LE_SCC(0) | LE_PFM(0) | LE_SCF(0)),
  122.           (L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_WB)) },
  123.         /* { 0x0000003b, 0x0030 } */
  124.         { (LE_CACHEABILITY(LE_WB) | LE_TGT_CACHE(LLC_ELLC) | LE_LRUM(3) |
  125.            LE_AOM(0) | LE_RSC(0) | LE_SCC(0) | LE_PFM(0) | LE_SCF(0)),
  126.           (L3_ESC(0) | L3_SCC(0) | L3_CACHEABILITY(L3_WB)) }
  127. };
  128.  
  129. /**
  130.  * get_mocs_settings()
  131.  * @dev:        DRM device.
  132.  * @table:      Output table that will be made to point at appropriate
  133.  *              MOCS values for the device.
  134.  *
  135.  * This function will return the values of the MOCS table that needs to
  136.  * be programmed for the platform. It will return the values that need
  137.  * to be programmed and if they need to be programmed.
  138.  *
  139.  * Return: true if there are applicable MOCS settings for the device.
  140.  */
  141. static bool get_mocs_settings(struct drm_device *dev,
  142.                               struct drm_i915_mocs_table *table)
  143. {
  144.         bool result = false;
  145.  
  146.         if (IS_SKYLAKE(dev)) {
  147.                 table->size  = ARRAY_SIZE(skylake_mocs_table);
  148.                 table->table = skylake_mocs_table;
  149.                 result = true;
  150.         } else if (IS_BROXTON(dev)) {
  151.                 table->size  = ARRAY_SIZE(broxton_mocs_table);
  152.                 table->table = broxton_mocs_table;
  153.                 result = true;
  154.         } else {
  155.                 WARN_ONCE(INTEL_INFO(dev)->gen >= 9,
  156.                           "Platform that should have a MOCS table does not.\n");
  157.         }
  158.  
  159.         return result;
  160. }
  161.  
  162. /**
  163.  * emit_mocs_control_table() - emit the mocs control table
  164.  * @req:        Request to set up the MOCS table for.
  165.  * @table:      The values to program into the control regs.
  166.  * @reg_base:   The base for the engine that needs to be programmed.
  167.  *
  168.  * This function simply emits a MI_LOAD_REGISTER_IMM command for the
  169.  * given table starting at the given address.
  170.  *
  171.  * Return: 0 on success, otherwise the error status.
  172.  */
  173. static int emit_mocs_control_table(struct drm_i915_gem_request *req,
  174.                                    const struct drm_i915_mocs_table *table,
  175.                                    u32 reg_base)
  176. {
  177.         struct intel_ringbuffer *ringbuf = req->ringbuf;
  178.         unsigned int index;
  179.         int ret;
  180.  
  181.         if (WARN_ON(table->size > GEN9_NUM_MOCS_ENTRIES))
  182.                 return -ENODEV;
  183.  
  184.         ret = intel_logical_ring_begin(req, 2 + 2 * GEN9_NUM_MOCS_ENTRIES);
  185.         if (ret) {
  186.                 DRM_DEBUG("intel_logical_ring_begin failed %d\n", ret);
  187.                 return ret;
  188.         }
  189.  
  190.         intel_logical_ring_emit(ringbuf,
  191.                                 MI_LOAD_REGISTER_IMM(GEN9_NUM_MOCS_ENTRIES));
  192.  
  193.         for (index = 0; index < table->size; index++) {
  194.                 intel_logical_ring_emit(ringbuf, reg_base + index * 4);
  195.                 intel_logical_ring_emit(ringbuf,
  196.                                         table->table[index].control_value);
  197.         }
  198.  
  199.         /*
  200.          * Ok, now set the unused entries to uncached. These entries
  201.          * are officially undefined and no contract for the contents
  202.          * and settings is given for these entries.
  203.          *
  204.          * Entry 0 in the table is uncached - so we are just writing
  205.          * that value to all the used entries.
  206.          */
  207.         for (; index < GEN9_NUM_MOCS_ENTRIES; index++) {
  208.                 intel_logical_ring_emit(ringbuf, reg_base + index * 4);
  209.                 intel_logical_ring_emit(ringbuf, table->table[0].control_value);
  210.         }
  211.  
  212.         intel_logical_ring_emit(ringbuf, MI_NOOP);
  213.         intel_logical_ring_advance(ringbuf);
  214.  
  215.         return 0;
  216. }
  217.  
  218. /**
  219.  * emit_mocs_l3cc_table() - emit the mocs control table
  220.  * @req:        Request to set up the MOCS table for.
  221.  * @table:      The values to program into the control regs.
  222.  *
  223.  * This function simply emits a MI_LOAD_REGISTER_IMM command for the
  224.  * given table starting at the given address. This register set is
  225.  * programmed in pairs.
  226.  *
  227.  * Return: 0 on success, otherwise the error status.
  228.  */
  229. static int emit_mocs_l3cc_table(struct drm_i915_gem_request *req,
  230.                                 const struct drm_i915_mocs_table *table)
  231. {
  232.         struct intel_ringbuffer *ringbuf = req->ringbuf;
  233.         unsigned int count;
  234.         unsigned int i;
  235.         u32 value;
  236.         u32 filler = (table->table[0].l3cc_value & 0xffff) |
  237.                         ((table->table[0].l3cc_value & 0xffff) << 16);
  238.         int ret;
  239.  
  240.         if (WARN_ON(table->size > GEN9_NUM_MOCS_ENTRIES))
  241.                 return -ENODEV;
  242.  
  243.         ret = intel_logical_ring_begin(req, 2 + GEN9_NUM_MOCS_ENTRIES);
  244.         if (ret) {
  245.                 DRM_DEBUG("intel_logical_ring_begin failed %d\n", ret);
  246.                 return ret;
  247.         }
  248.  
  249.         intel_logical_ring_emit(ringbuf,
  250.                         MI_LOAD_REGISTER_IMM(GEN9_NUM_MOCS_ENTRIES / 2));
  251.  
  252.         for (i = 0, count = 0; i < table->size / 2; i++, count += 2) {
  253.                 value = (table->table[count].l3cc_value & 0xffff) |
  254.                         ((table->table[count + 1].l3cc_value & 0xffff) << 16);
  255.  
  256.                 intel_logical_ring_emit(ringbuf, GEN9_LNCFCMOCS0 + i * 4);
  257.                 intel_logical_ring_emit(ringbuf, value);
  258.         }
  259.  
  260.         if (table->size & 0x01) {
  261.                 /* Odd table size - 1 left over */
  262.                 value = (table->table[count].l3cc_value & 0xffff) |
  263.                         ((table->table[0].l3cc_value & 0xffff) << 16);
  264.         } else
  265.                 value = filler;
  266.  
  267.         /*
  268.          * Now set the rest of the table to uncached - use entry 0 as
  269.          * this will be uncached. Leave the last pair uninitialised as
  270.          * they are reserved by the hardware.
  271.          */
  272.         for (; i < GEN9_NUM_MOCS_ENTRIES / 2; i++) {
  273.                 intel_logical_ring_emit(ringbuf, GEN9_LNCFCMOCS0 + i * 4);
  274.                 intel_logical_ring_emit(ringbuf, value);
  275.  
  276.                 value = filler;
  277.         }
  278.  
  279.         intel_logical_ring_emit(ringbuf, MI_NOOP);
  280.         intel_logical_ring_advance(ringbuf);
  281.  
  282.         return 0;
  283. }
  284.  
  285. /**
  286.  * intel_rcs_context_init_mocs() - program the MOCS register.
  287.  * @req:        Request to set up the MOCS tables for.
  288.  *
  289.  * This function will emit a batch buffer with the values required for
  290.  * programming the MOCS register values for all the currently supported
  291.  * rings.
  292.  *
  293.  * These registers are partially stored in the RCS context, so they are
  294.  * emitted at the same time so that when a context is created these registers
  295.  * are set up. These registers have to be emitted into the start of the
  296.  * context as setting the ELSP will re-init some of these registers back
  297.  * to the hw values.
  298.  *
  299.  * Return: 0 on success, otherwise the error status.
  300.  */
  301. int intel_rcs_context_init_mocs(struct drm_i915_gem_request *req)
  302. {
  303.         struct drm_i915_mocs_table t;
  304.         int ret;
  305.  
  306.         if (get_mocs_settings(req->ring->dev, &t)) {
  307.                 /* Program the control registers */
  308.                 ret = emit_mocs_control_table(req, &t, GEN9_GFX_MOCS_0);
  309.                 if (ret)
  310.                         return ret;
  311.  
  312.                 ret = emit_mocs_control_table(req, &t, GEN9_MFX0_MOCS_0);
  313.                 if (ret)
  314.                         return ret;
  315.  
  316.                 ret = emit_mocs_control_table(req, &t, GEN9_MFX1_MOCS_0);
  317.                 if (ret)
  318.                         return ret;
  319.  
  320.                 ret = emit_mocs_control_table(req, &t, GEN9_VEBOX_MOCS_0);
  321.                 if (ret)
  322.                         return ret;
  323.  
  324.                 ret = emit_mocs_control_table(req, &t, GEN9_BLT_MOCS_0);
  325.                 if (ret)
  326.                         return ret;
  327.  
  328.                 /* Now program the l3cc registers */
  329.                 ret = emit_mocs_l3cc_table(req, &t);
  330.                 if (ret)
  331.                         return ret;
  332.         }
  333.  
  334.         return 0;
  335. }
  336.