[igt-dev] [PATCH i-g-t] i915/gem_mocs_settings: Add mocs table for icelake

Lucas De Marchi lucas.de.marchi at gmail.com
Thu Feb 21 22:48:45 UTC 2019


On Fri, Feb 15, 2019 at 1:32 PM Prathap Kumar Valsan
<prathap.kumar.valsan at intel.com> wrote:
>
> From: "Kumar Valsan, Prathap" <prathap.kumar.valsan at intel.com>
>
> This patch adds mocs table for icelake with expected L3 and eDRAM
> control values.
>
> Signed-off-by: Kumar Valsan, Prathap <prathap.kumar.valsan at intel.com>
> ---
>  tests/i915/gem_mocs_settings.c | 145 +++++++++++++++++++++++++++------
>  1 file changed, 122 insertions(+), 23 deletions(-)
>
> diff --git a/tests/i915/gem_mocs_settings.c b/tests/i915/gem_mocs_settings.c
> index 5b3b6bc1..b84273a0 100644
> --- a/tests/i915/gem_mocs_settings.c
> +++ b/tests/i915/gem_mocs_settings.c
> @@ -33,6 +33,10 @@
>  #include "igt_sysfs.h"
>
>  #define MAX_NUMBER_MOCS_REGISTERS      (64)
> +#define GEN9_NUM_MOCS_ENTRIES   62  /* 62 out of 64 - 63 & 64 are reserved. */
> +#define GEN11_NUM_MOCS_ENTRIES  64  /* 63-64 are reserved, but configured. */
> +#define MOCS_PTE_INDEX         (0x1)
> +
>  enum {
>         NONE,
>         RESET,
> @@ -65,6 +69,7 @@ static const char * const test_modes[] = {
>  struct mocs_entry {
>         uint32_t        control_value;
>         uint16_t        l3cc_value;
> +       uint8_t         used;
>  };
>
>  struct mocs_table {
> @@ -73,37 +78,113 @@ struct mocs_table {
>  };
>
>  /* The first entries in the MOCS tables are defined by uABI */
> -static const struct mocs_entry skylake_mocs_table[] = {
> -       { 0x00000009, 0x0010 },
> -       { 0x00000038, 0x0030 },
> -       { 0x0000003b, 0x0030 },
> +static struct mocs_entry icelake_mocs_table[GEN11_NUM_MOCS_ENTRIES] = {
> +       [0]  = { 0x00000005, 0x0010, 0x1 },
> +       [1]  = { 0x00000004, 0x0030, 0x1 },
> +       [2]  = { 0x00000037, 0x0030, 0x1 },
> +       [3]  = { 0x00000005, 0x0010, 0x1 },
> +       [4]  = { 0x00000005, 0x0030, 0x1 },
> +       [5]  = { 0x00000037, 0x0010, 0x1 },
> +       [6]  = { 0x00000017, 0x0010, 0x1 },
> +       [7]  = { 0x00000017, 0x0030, 0x1 },
> +       [8]  = { 0x00000027, 0x0010, 0x1 },
> +       [9]  = { 0x00000027, 0x0030, 0x1 },
> +       [10] = { 0x00000077, 0x0010, 0x1 },
> +       [11] = { 0x00000077, 0x0030, 0x1 },
> +       [12] = { 0x00000057, 0x0010, 0x1 },
> +       [13] = { 0x00000057, 0x0030, 0x1 },
> +       [14] = { 0x00000067, 0x0010, 0x1 },
> +       [15] = { 0x00000067, 0x0030, 0x1 },
> +       [18] = { 0x00060037, 0x0030, 0x1 },
> +       [19] = { 0x00000737, 0x0030, 0x1 },
> +       [20] = { 0x00000337, 0x0030, 0x1 },
> +       [21] = { 0x00000137, 0x0030, 0x1 },
> +       [22] = { 0x000003b7, 0x0030, 0x1 },
> +       [23] = { 0x000007b7, 0x0030, 0x1 },
> +       [62] = { 0x00000037, 0x0010, 0x1 },
> +       [63] = { 0x00000037, 0x0010, 0x1 },
> +};
> +
> +static struct mocs_entry dirty_icelake_mocs_table[GEN11_NUM_MOCS_ENTRIES] = {
> +       [0]  = { 0x0007FFFF, 0x003F },
> +       [1]  = { 0x0007FFFF, 0x003F },
> +       [2]  = { 0x0007FFFF, 0x003F },
> +       [3]  = { 0x0007FFFF, 0x003F },
> +       [4]  = { 0x0007FFFF, 0x003F },
> +       [5]  = { 0x0007FFFF, 0x003F },
> +       [6]  = { 0x0007FFFF, 0x003F },
> +       [7]  = { 0x0007FFFF, 0x003F },
> +       [8]  = { 0x0007FFFF, 0x003F },
> +       [9]  = { 0x0007FFFF, 0x003F },
> +       [10] = { 0x0007FFFF, 0x003F },
> +       [11] = { 0x0007FFFF, 0x003F },
> +       [12] = { 0x0007FFFF, 0x003F },
> +       [13] = { 0x0007FFFF, 0x003F },
> +       [14] = { 0x0007FFFF, 0x003F },
> +       [15] = { 0x0007FFFF, 0x003F },
> +       [18] = { 0x0007FFFF, 0x003F },
> +       [19] = { 0x0007FFFF, 0x003F },
> +       [21] = { 0x0007FFFF, 0x003F },
> +       [22] = { 0x0007FFFF, 0x003F },
> +       [23] = { 0x0007FFFF, 0x003F },
> +       [62] = { 0x0007FFFF, 0x003F },
> +       [63] = { 0x0007FFFF, 0x003F },
>  };
>
> -static const struct mocs_entry dirty_skylake_mocs_table[] = {
> -       { 0x00003FFF, 0x003F }, /* no snoop bit */
> -       { 0x00003FFF, 0x003F },
> -       { 0x00003FFF, 0x003F },
> +static struct mocs_entry skylake_mocs_table[GEN9_NUM_MOCS_ENTRIES] = {
> +       { 0x00000009, 0x0010, 0x1 },
> +       { 0x00000038, 0x0030, 0x1 },
> +       { 0x0000003b, 0x0030, 0x1 },
>  };
>
> -static const struct mocs_entry broxton_mocs_table[] = {
> -       { 0x00000009, 0x0010 },
> -       { 0x00000038, 0x0030 },
> -       { 0x00000039, 0x0030 },
> +static struct mocs_entry dirty_skylake_mocs_table[GEN9_NUM_MOCS_ENTRIES] = {
> +       { 0x00003FFF, 0x003F, 0x1 }, /* no snoop bit */
> +       { 0x00003FFF, 0x003F, 0x1 },
> +       { 0x00003FFF, 0x003F, 0x1 },
>  };
>
> -static const struct mocs_entry dirty_broxton_mocs_table[] = {
> -       { 0x00007FFF, 0x003F },
> -       { 0x00007FFF, 0x003F },
> -       { 0x00007FFF, 0x003F },
> +static struct mocs_entry broxton_mocs_table[GEN9_NUM_MOCS_ENTRIES] = {
> +       { 0x00000009, 0x0010, 0x1 },
> +       { 0x00000038, 0x0030, 0x1 },
> +       { 0x00000039, 0x0030, 0x1 },
>  };
>
> -static const uint32_t write_values[] = {
> -       0xFFFFFFFF,
> -       0xFFFFFFFF,
> -       0xFFFFFFFF,
> -       0xFFFFFFFF
> +static struct mocs_entry dirty_broxton_mocs_table[GEN9_NUM_MOCS_ENTRIES] = {
> +       { 0x00007FFF, 0x003F, 0x1 },
> +       { 0x00007FFF, 0x003F, 0x1 },
> +       { 0x00007FFF, 0x003F, 0x1 },

These are all the same, why bother defining the array?

>  };
>
> +static uint32_t write_values[MAX_NUMBER_MOCS_REGISTERS];
> +
> +static void set_mocs_settings(void)
> +{
> +       uint8_t index;
> +       /* Set un-used entries to PTE */
> +       for (index = 0; index < MAX_NUMBER_MOCS_REGISTERS; index++) {

I think this is too verbose to fix the issue. IMO we should

a) continue with *const* tables
b) not have this function to modify the values

for that I think it's reasonable to have something like:

static const struct mocs_entry icelake_mocs_pte = { 0x00000004, 0x0030, 0x1 };
static struct mocs_entry icelake_mocs_table[GEN11_NUM_MOCS_ENTRIES] = {
       [0]  = { 0x00000005, 0x0010, 0x1 },
       [1]  = icelake_mocs_pte,
       [2]  = { 0x00000037, 0x0030, 0x1 },
...
       [20]  = icelake_mocs_pte,
...

So... you basically define all entries and don't need to overwrite the
values like you are doing.

Lucas De Marchi

> +               if (index < GEN9_NUM_MOCS_ENTRIES) {
> +                       if (!skylake_mocs_table[index].used) {
> +                               skylake_mocs_table[index] =  skylake_mocs_table[MOCS_PTE_INDEX];
> +                               dirty_skylake_mocs_table[index] =  dirty_skylake_mocs_table[MOCS_PTE_INDEX];
> +                       }
> +                       if (!broxton_mocs_table[index].used) {
> +                               broxton_mocs_table[index] =  broxton_mocs_table[MOCS_PTE_INDEX];
> +                               dirty_broxton_mocs_table[index] =  dirty_broxton_mocs_table[MOCS_PTE_INDEX];
> +                       }
> +                       if (!icelake_mocs_table[index].used) {
> +                               icelake_mocs_table[index] =  icelake_mocs_table[MOCS_PTE_INDEX];
> +                               dirty_icelake_mocs_table[index] =  dirty_icelake_mocs_table[MOCS_PTE_INDEX];
> +                       }
> +               } else { /*icelake has 64 entries */
> +                       if (!icelake_mocs_table[index].used) {
> +                               icelake_mocs_table[index] =  icelake_mocs_table[MOCS_PTE_INDEX];
> +                               dirty_icelake_mocs_table[index] =  dirty_icelake_mocs_table[MOCS_PTE_INDEX];
> +                       }
> +               }
> +       }
> +       memset((char *)write_values, 0xFF, MAX_NUMBER_MOCS_REGISTERS * sizeof(uint32_t));
> +}
> +
>  static bool get_mocs_settings(int fd, struct mocs_table *table, bool dirty)
>  {
>         uint32_t devid = intel_get_drm_devid(fd);
> @@ -127,6 +208,15 @@ static bool get_mocs_settings(int fd, struct mocs_table *table, bool dirty)
>                         table->table = broxton_mocs_table;
>                 }
>                 result = true;
> +       } else if (IS_ICELAKE(devid)) {
> +               if (dirty) {
> +                       table->size  = ARRAY_SIZE(dirty_icelake_mocs_table);
> +                       table->table = dirty_icelake_mocs_table;
> +               } else {
> +                       table->size  = ARRAY_SIZE(icelake_mocs_table);
> +                       table->table = icelake_mocs_table;
> +               }
> +               result = true;
>         }
>
>         return result;
> @@ -374,13 +464,21 @@ static void check_mocs_values(int fd, unsigned engine, uint32_t ctx_id, bool dir
>
>  static void write_dirty_mocs(int fd, unsigned engine, uint32_t ctx_id)
>  {
> +       uint32_t devid = intel_get_drm_devid(fd);
> +       int num_of_mocs_entries;
> +
> +       if (IS_ICELAKE(devid))
> +               num_of_mocs_entries = GEN11_NUM_MOCS_ENTRIES;
> +       else
> +               num_of_mocs_entries = GEN9_NUM_MOCS_ENTRIES;
> +
>         write_registers(fd, ctx_id, get_engine_base(engine),
> -                       write_values, ARRAY_SIZE(write_values),
> +                       write_values, num_of_mocs_entries,
>                         engine);
>
>         if (engine == I915_EXEC_RENDER)
>                 write_registers(fd, ctx_id, GEN9_LNCFCMOCS0,
> -                               write_values, ARRAY_SIZE(write_values),
> +                               write_values, num_of_mocs_entries/2,
>                                 engine);
>  }
>
> @@ -440,6 +538,7 @@ igt_main
>                 fd = drm_open_driver_master(DRIVER_INTEL); /* for SECURE */
>                 igt_require_gem(fd);
>                 gem_require_mocs_registers(fd);
> +               set_mocs_settings();
>                 igt_require(get_mocs_settings(fd, &table, false));
>         }
>
> --
> 2.20.1
>


-- 
Lucas De Marchi


More information about the igt-dev mailing list