LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915 - intel_device_info.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 499 0.0 %
Date: 2022-04-01 14:35:51 Functions: 0 19 0.0 %
Branches: 0 440 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright © 2016 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                 :            : #include <drm/drm_print.h>
      26                 :            : 
      27                 :            : #include "intel_device_info.h"
      28                 :            : #include "i915_drv.h"
      29                 :            : 
      30                 :            : #define PLATFORM_NAME(x) [INTEL_##x] = #x
      31                 :            : static const char * const platform_names[] = {
      32                 :            :         PLATFORM_NAME(I830),
      33                 :            :         PLATFORM_NAME(I845G),
      34                 :            :         PLATFORM_NAME(I85X),
      35                 :            :         PLATFORM_NAME(I865G),
      36                 :            :         PLATFORM_NAME(I915G),
      37                 :            :         PLATFORM_NAME(I915GM),
      38                 :            :         PLATFORM_NAME(I945G),
      39                 :            :         PLATFORM_NAME(I945GM),
      40                 :            :         PLATFORM_NAME(G33),
      41                 :            :         PLATFORM_NAME(PINEVIEW),
      42                 :            :         PLATFORM_NAME(I965G),
      43                 :            :         PLATFORM_NAME(I965GM),
      44                 :            :         PLATFORM_NAME(G45),
      45                 :            :         PLATFORM_NAME(GM45),
      46                 :            :         PLATFORM_NAME(IRONLAKE),
      47                 :            :         PLATFORM_NAME(SANDYBRIDGE),
      48                 :            :         PLATFORM_NAME(IVYBRIDGE),
      49                 :            :         PLATFORM_NAME(VALLEYVIEW),
      50                 :            :         PLATFORM_NAME(HASWELL),
      51                 :            :         PLATFORM_NAME(BROADWELL),
      52                 :            :         PLATFORM_NAME(CHERRYVIEW),
      53                 :            :         PLATFORM_NAME(SKYLAKE),
      54                 :            :         PLATFORM_NAME(BROXTON),
      55                 :            :         PLATFORM_NAME(KABYLAKE),
      56                 :            :         PLATFORM_NAME(GEMINILAKE),
      57                 :            :         PLATFORM_NAME(COFFEELAKE),
      58                 :            :         PLATFORM_NAME(CANNONLAKE),
      59                 :            :         PLATFORM_NAME(ICELAKE),
      60                 :            :         PLATFORM_NAME(ELKHARTLAKE),
      61                 :            :         PLATFORM_NAME(TIGERLAKE),
      62                 :            : };
      63                 :            : #undef PLATFORM_NAME
      64                 :            : 
      65                 :          0 : const char *intel_platform_name(enum intel_platform platform)
      66                 :            : {
      67                 :          0 :         BUILD_BUG_ON(ARRAY_SIZE(platform_names) != INTEL_MAX_PLATFORMS);
      68                 :            : 
      69   [ #  #  #  #  :          0 :         if (WARN_ON_ONCE(platform >= ARRAY_SIZE(platform_names) ||
          #  #  #  #  #  
                      # ]
      70                 :            :                          platform_names[platform] == NULL))
      71                 :            :                 return "<unknown>";
      72                 :            : 
      73                 :          0 :         return platform_names[platform];
      74                 :            : }
      75                 :            : 
      76                 :          0 : static const char *iommu_name(void)
      77                 :            : {
      78                 :          0 :         const char *msg = "n/a";
      79                 :            : 
      80                 :            : #ifdef CONFIG_INTEL_IOMMU
      81                 :          0 :         msg = enableddisabled(intel_iommu_gfx_mapped);
      82                 :            : #endif
      83                 :            : 
      84                 :          0 :         return msg;
      85                 :            : }
      86                 :            : 
      87                 :          0 : void intel_device_info_print_static(const struct intel_device_info *info,
      88                 :            :                                     struct drm_printer *p)
      89                 :            : {
      90                 :          0 :         drm_printf(p, "engines: %x\n", info->engine_mask);
      91                 :          0 :         drm_printf(p, "gen: %d\n", info->gen);
      92                 :          0 :         drm_printf(p, "gt: %d\n", info->gt);
      93         [ #  # ]:          0 :         drm_printf(p, "iommu: %s\n", iommu_name());
      94                 :          0 :         drm_printf(p, "memory-regions: %x\n", info->memory_regions);
      95                 :          0 :         drm_printf(p, "page-sizes: %x\n", info->page_sizes);
      96                 :          0 :         drm_printf(p, "platform: %s\n", intel_platform_name(info->platform));
      97                 :          0 :         drm_printf(p, "ppgtt-size: %d\n", info->ppgtt_size);
      98                 :          0 :         drm_printf(p, "ppgtt-type: %d\n", info->ppgtt_type);
      99                 :            : 
     100                 :            : #define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, yesno(info->name));
     101   [ #  #  #  #  :          0 :         DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     102                 :            : #undef PRINT_FLAG
     103                 :            : 
     104                 :            : #define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, yesno(info->display.name));
     105   [ #  #  #  #  :          0 :         DEV_INFO_DISPLAY_FOR_EACH_FLAG(PRINT_FLAG);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     106                 :            : #undef PRINT_FLAG
     107                 :          0 : }
     108                 :            : 
     109                 :          0 : static void sseu_dump(const struct sseu_dev_info *sseu, struct drm_printer *p)
     110                 :            : {
     111                 :          0 :         int s;
     112                 :            : 
     113                 :          0 :         drm_printf(p, "slice total: %u, mask=%04x\n",
     114         [ #  # ]:          0 :                    hweight8(sseu->slice_mask), sseu->slice_mask);
     115                 :          0 :         drm_printf(p, "subslice total: %u\n", intel_sseu_subslice_total(sseu));
     116         [ #  # ]:          0 :         for (s = 0; s < sseu->max_slices; s++) {
     117                 :          0 :                 drm_printf(p, "slice%d: %u subslices, mask=%08x\n",
     118                 :            :                            s, intel_sseu_subslices_per_slice(sseu, s),
     119                 :            :                            intel_sseu_get_subslices(sseu, s));
     120                 :            :         }
     121                 :          0 :         drm_printf(p, "EU total: %u\n", sseu->eu_total);
     122                 :          0 :         drm_printf(p, "EU per subslice: %u\n", sseu->eu_per_subslice);
     123                 :          0 :         drm_printf(p, "has slice power gating: %s\n",
     124         [ #  # ]:          0 :                    yesno(sseu->has_slice_pg));
     125                 :          0 :         drm_printf(p, "has subslice power gating: %s\n",
     126         [ #  # ]:          0 :                    yesno(sseu->has_subslice_pg));
     127         [ #  # ]:          0 :         drm_printf(p, "has EU power gating: %s\n", yesno(sseu->has_eu_pg));
     128                 :          0 : }
     129                 :            : 
     130                 :          0 : void intel_device_info_print_runtime(const struct intel_runtime_info *info,
     131                 :            :                                      struct drm_printer *p)
     132                 :            : {
     133                 :          0 :         sseu_dump(&info->sseu, p);
     134                 :            : 
     135                 :          0 :         drm_printf(p, "CS timestamp frequency: %u kHz\n",
     136                 :            :                    info->cs_timestamp_frequency_khz);
     137                 :          0 : }
     138                 :            : 
     139                 :          0 : static int sseu_eu_idx(const struct sseu_dev_info *sseu, int slice,
     140                 :            :                        int subslice)
     141                 :            : {
     142                 :          0 :         int slice_stride = sseu->max_subslices * sseu->eu_stride;
     143                 :            : 
     144                 :          0 :         return slice * slice_stride + subslice * sseu->eu_stride;
     145                 :            : }
     146                 :            : 
     147                 :          0 : static u16 sseu_get_eus(const struct sseu_dev_info *sseu, int slice,
     148                 :            :                         int subslice)
     149                 :            : {
     150                 :          0 :         int i, offset = sseu_eu_idx(sseu, slice, subslice);
     151                 :          0 :         u16 eu_mask = 0;
     152                 :            : 
     153   [ #  #  #  # ]:          0 :         for (i = 0; i < sseu->eu_stride; i++) {
     154                 :          0 :                 eu_mask |= ((u16)sseu->eu_mask[offset + i]) <<
     155                 :          0 :                         (i * BITS_PER_BYTE);
     156                 :            :         }
     157                 :            : 
     158                 :          0 :         return eu_mask;
     159                 :            : }
     160                 :            : 
     161                 :          0 : static void sseu_set_eus(struct sseu_dev_info *sseu, int slice, int subslice,
     162                 :            :                          u16 eu_mask)
     163                 :            : {
     164                 :          0 :         int i, offset = sseu_eu_idx(sseu, slice, subslice);
     165                 :            : 
     166   [ #  #  #  #  :          0 :         for (i = 0; i < sseu->eu_stride; i++) {
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     167                 :          0 :                 sseu->eu_mask[offset + i] =
     168                 :          0 :                         (eu_mask >> (BITS_PER_BYTE * i)) & 0xff;
     169                 :            :         }
     170                 :            : }
     171                 :            : 
     172                 :          0 : void intel_device_info_print_topology(const struct sseu_dev_info *sseu,
     173                 :            :                                       struct drm_printer *p)
     174                 :            : {
     175                 :          0 :         int s, ss;
     176                 :            : 
     177         [ #  # ]:          0 :         if (sseu->max_slices == 0) {
     178                 :          0 :                 drm_printf(p, "Unavailable\n");
     179                 :          0 :                 return;
     180                 :            :         }
     181                 :            : 
     182         [ #  # ]:          0 :         for (s = 0; s < sseu->max_slices; s++) {
     183                 :          0 :                 drm_printf(p, "slice%d: %u subslice(s) (0x%08x):\n",
     184                 :            :                            s, intel_sseu_subslices_per_slice(sseu, s),
     185                 :            :                            intel_sseu_get_subslices(sseu, s));
     186                 :            : 
     187         [ #  # ]:          0 :                 for (ss = 0; ss < sseu->max_subslices; ss++) {
     188                 :          0 :                         u16 enabled_eus = sseu_get_eus(sseu, s, ss);
     189                 :            : 
     190                 :          0 :                         drm_printf(p, "\tsubslice%d: %u EUs (0x%hx)\n",
     191         [ #  # ]:          0 :                                    ss, hweight16(enabled_eus), enabled_eus);
     192                 :            :                 }
     193                 :            :         }
     194                 :            : }
     195                 :            : 
     196                 :          0 : static u16 compute_eu_total(const struct sseu_dev_info *sseu)
     197                 :            : {
     198                 :          0 :         u16 i, total = 0;
     199                 :            : 
     200         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(sseu->eu_mask); i++)
     201         [ #  # ]:          0 :                 total += hweight8(sseu->eu_mask[i]);
     202                 :            : 
     203                 :          0 :         return total;
     204                 :            : }
     205                 :            : 
     206                 :          0 : static void gen11_compute_sseu_info(struct sseu_dev_info *sseu,
     207                 :            :                                     u8 s_en, u32 ss_en, u16 eu_en)
     208                 :            : {
     209                 :          0 :         int s, ss;
     210                 :            : 
     211                 :            :         /* ss_en represents entire subslice mask across all slices */
     212                 :          0 :         GEM_BUG_ON(sseu->max_slices * sseu->max_subslices >
     213                 :            :                    sizeof(ss_en) * BITS_PER_BYTE);
     214                 :            : 
     215         [ #  # ]:          0 :         for (s = 0; s < sseu->max_slices; s++) {
     216         [ #  # ]:          0 :                 if ((s_en & BIT(s)) == 0)
     217                 :          0 :                         continue;
     218                 :            : 
     219                 :          0 :                 sseu->slice_mask |= BIT(s);
     220                 :            : 
     221                 :          0 :                 intel_sseu_set_subslices(sseu, s, ss_en);
     222                 :            : 
     223         [ #  # ]:          0 :                 for (ss = 0; ss < sseu->max_subslices; ss++)
     224         [ #  # ]:          0 :                         if (intel_sseu_has_subslice(sseu, s, ss))
     225                 :          0 :                                 sseu_set_eus(sseu, s, ss, eu_en);
     226                 :            :         }
     227         [ #  # ]:          0 :         sseu->eu_per_subslice = hweight16(eu_en);
     228                 :          0 :         sseu->eu_total = compute_eu_total(sseu);
     229                 :          0 : }
     230                 :            : 
     231                 :          0 : static void gen12_sseu_info_init(struct drm_i915_private *dev_priv)
     232                 :            : {
     233                 :          0 :         struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
     234                 :          0 :         u8 s_en;
     235                 :          0 :         u32 dss_en;
     236                 :          0 :         u16 eu_en = 0;
     237                 :          0 :         u8 eu_en_fuse;
     238                 :          0 :         int eu;
     239                 :            : 
     240                 :            :         /*
     241                 :            :          * Gen12 has Dual-Subslices, which behave similarly to 2 gen11 SS.
     242                 :            :          * Instead of splitting these, provide userspace with an array
     243                 :            :          * of DSS to more closely represent the hardware resource.
     244                 :            :          */
     245                 :          0 :         intel_sseu_set_info(sseu, 1, 6, 16);
     246                 :            : 
     247                 :          0 :         s_en = I915_READ(GEN11_GT_SLICE_ENABLE) & GEN11_GT_S_ENA_MASK;
     248                 :            : 
     249                 :          0 :         dss_en = I915_READ(GEN12_GT_DSS_ENABLE);
     250                 :            : 
     251                 :            :         /* one bit per pair of EUs */
     252                 :          0 :         eu_en_fuse = ~(I915_READ(GEN11_EU_DISABLE) & GEN11_EU_DIS_MASK);
     253         [ #  # ]:          0 :         for (eu = 0; eu < sseu->max_eus_per_subslice / 2; eu++)
     254         [ #  # ]:          0 :                 if (eu_en_fuse & BIT(eu))
     255                 :          0 :                         eu_en |= BIT(eu * 2) | BIT(eu * 2 + 1);
     256                 :            : 
     257                 :          0 :         gen11_compute_sseu_info(sseu, s_en, dss_en, eu_en);
     258                 :            : 
     259                 :            :         /* TGL only supports slice-level power gating */
     260                 :          0 :         sseu->has_slice_pg = 1;
     261                 :          0 : }
     262                 :            : 
     263                 :          0 : static void gen11_sseu_info_init(struct drm_i915_private *dev_priv)
     264                 :            : {
     265                 :          0 :         struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
     266                 :          0 :         u8 s_en;
     267                 :          0 :         u32 ss_en;
     268                 :          0 :         u8 eu_en;
     269                 :            : 
     270         [ #  # ]:          0 :         if (IS_ELKHARTLAKE(dev_priv))
     271                 :          0 :                 intel_sseu_set_info(sseu, 1, 4, 8);
     272                 :            :         else
     273                 :          0 :                 intel_sseu_set_info(sseu, 1, 8, 8);
     274                 :            : 
     275                 :          0 :         s_en = I915_READ(GEN11_GT_SLICE_ENABLE) & GEN11_GT_S_ENA_MASK;
     276                 :          0 :         ss_en = ~I915_READ(GEN11_GT_SUBSLICE_DISABLE);
     277                 :          0 :         eu_en = ~(I915_READ(GEN11_EU_DISABLE) & GEN11_EU_DIS_MASK);
     278                 :            : 
     279                 :          0 :         gen11_compute_sseu_info(sseu, s_en, ss_en, eu_en);
     280                 :            : 
     281                 :            :         /* ICL has no power gating restrictions. */
     282                 :          0 :         sseu->has_slice_pg = 1;
     283                 :          0 :         sseu->has_subslice_pg = 1;
     284                 :          0 :         sseu->has_eu_pg = 1;
     285                 :          0 : }
     286                 :            : 
     287                 :          0 : static void gen10_sseu_info_init(struct drm_i915_private *dev_priv)
     288                 :            : {
     289                 :          0 :         struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
     290                 :          0 :         const u32 fuse2 = I915_READ(GEN8_FUSE2);
     291                 :          0 :         int s, ss;
     292                 :          0 :         const int eu_mask = 0xff;
     293                 :          0 :         u32 subslice_mask, eu_en;
     294                 :            : 
     295                 :          0 :         intel_sseu_set_info(sseu, 6, 4, 8);
     296                 :            : 
     297                 :          0 :         sseu->slice_mask = (fuse2 & GEN10_F2_S_ENA_MASK) >>
     298                 :            :                             GEN10_F2_S_ENA_SHIFT;
     299                 :            : 
     300                 :            :         /* Slice0 */
     301                 :          0 :         eu_en = ~I915_READ(GEN8_EU_DISABLE0);
     302         [ #  # ]:          0 :         for (ss = 0; ss < sseu->max_subslices; ss++)
     303                 :          0 :                 sseu_set_eus(sseu, 0, ss, (eu_en >> (8 * ss)) & eu_mask);
     304                 :            :         /* Slice1 */
     305                 :          0 :         sseu_set_eus(sseu, 1, 0, (eu_en >> 24) & eu_mask);
     306                 :          0 :         eu_en = ~I915_READ(GEN8_EU_DISABLE1);
     307                 :          0 :         sseu_set_eus(sseu, 1, 1, eu_en & eu_mask);
     308                 :            :         /* Slice2 */
     309                 :          0 :         sseu_set_eus(sseu, 2, 0, (eu_en >> 8) & eu_mask);
     310                 :          0 :         sseu_set_eus(sseu, 2, 1, (eu_en >> 16) & eu_mask);
     311                 :            :         /* Slice3 */
     312                 :          0 :         sseu_set_eus(sseu, 3, 0, (eu_en >> 24) & eu_mask);
     313                 :          0 :         eu_en = ~I915_READ(GEN8_EU_DISABLE2);
     314                 :          0 :         sseu_set_eus(sseu, 3, 1, eu_en & eu_mask);
     315                 :            :         /* Slice4 */
     316                 :          0 :         sseu_set_eus(sseu, 4, 0, (eu_en >> 8) & eu_mask);
     317                 :          0 :         sseu_set_eus(sseu, 4, 1, (eu_en >> 16) & eu_mask);
     318                 :            :         /* Slice5 */
     319                 :          0 :         sseu_set_eus(sseu, 5, 0, (eu_en >> 24) & eu_mask);
     320                 :          0 :         eu_en = ~I915_READ(GEN10_EU_DISABLE3);
     321                 :          0 :         sseu_set_eus(sseu, 5, 1, eu_en & eu_mask);
     322                 :            : 
     323                 :          0 :         subslice_mask = (1 << 4) - 1;
     324                 :          0 :         subslice_mask &= ~((fuse2 & GEN10_F2_SS_DIS_MASK) >>
     325                 :            :                            GEN10_F2_SS_DIS_SHIFT);
     326                 :            : 
     327         [ #  # ]:          0 :         for (s = 0; s < sseu->max_slices; s++) {
     328                 :            :                 u32 subslice_mask_with_eus = subslice_mask;
     329                 :            : 
     330         [ #  # ]:          0 :                 for (ss = 0; ss < sseu->max_subslices; ss++) {
     331         [ #  # ]:          0 :                         if (sseu_get_eus(sseu, s, ss) == 0)
     332                 :          0 :                                 subslice_mask_with_eus &= ~BIT(ss);
     333                 :            :                 }
     334                 :            : 
     335                 :            :                 /*
     336                 :            :                  * Slice0 can have up to 3 subslices, but there are only 2 in
     337                 :            :                  * slice1/2.
     338                 :            :                  */
     339         [ #  # ]:          0 :                 intel_sseu_set_subslices(sseu, s, s == 0 ?
     340                 :            :                                                   subslice_mask_with_eus :
     341                 :            :                                                   subslice_mask_with_eus & 0x3);
     342                 :            :         }
     343                 :            : 
     344                 :          0 :         sseu->eu_total = compute_eu_total(sseu);
     345                 :            : 
     346                 :            :         /*
     347                 :            :          * CNL is expected to always have a uniform distribution
     348                 :            :          * of EU across subslices with the exception that any one
     349                 :            :          * EU in any one subslice may be fused off for die
     350                 :            :          * recovery.
     351                 :            :          */
     352         [ #  # ]:          0 :         sseu->eu_per_subslice = intel_sseu_subslice_total(sseu) ?
     353                 :          0 :                                 DIV_ROUND_UP(sseu->eu_total,
     354                 :            :                                              intel_sseu_subslice_total(sseu)) :
     355                 :            :                                 0;
     356                 :            : 
     357                 :            :         /* No restrictions on Power Gating */
     358                 :          0 :         sseu->has_slice_pg = 1;
     359                 :          0 :         sseu->has_subslice_pg = 1;
     360                 :          0 :         sseu->has_eu_pg = 1;
     361                 :          0 : }
     362                 :            : 
     363                 :          0 : static void cherryview_sseu_info_init(struct drm_i915_private *dev_priv)
     364                 :            : {
     365                 :          0 :         struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
     366                 :          0 :         u32 fuse;
     367                 :          0 :         u8 subslice_mask = 0;
     368                 :            : 
     369                 :          0 :         fuse = I915_READ(CHV_FUSE_GT);
     370                 :            : 
     371                 :          0 :         sseu->slice_mask = BIT(0);
     372                 :          0 :         intel_sseu_set_info(sseu, 1, 2, 8);
     373                 :            : 
     374         [ #  # ]:          0 :         if (!(fuse & CHV_FGT_DISABLE_SS0)) {
     375                 :          0 :                 u8 disabled_mask =
     376                 :          0 :                         ((fuse & CHV_FGT_EU_DIS_SS0_R0_MASK) >>
     377                 :            :                          CHV_FGT_EU_DIS_SS0_R0_SHIFT) |
     378                 :          0 :                         (((fuse & CHV_FGT_EU_DIS_SS0_R1_MASK) >>
     379                 :          0 :                           CHV_FGT_EU_DIS_SS0_R1_SHIFT) << 4);
     380                 :            : 
     381                 :          0 :                 subslice_mask |= BIT(0);
     382                 :          0 :                 sseu_set_eus(sseu, 0, 0, ~disabled_mask);
     383                 :            :         }
     384                 :            : 
     385         [ #  # ]:          0 :         if (!(fuse & CHV_FGT_DISABLE_SS1)) {
     386                 :          0 :                 u8 disabled_mask =
     387                 :          0 :                         ((fuse & CHV_FGT_EU_DIS_SS1_R0_MASK) >>
     388                 :            :                          CHV_FGT_EU_DIS_SS1_R0_SHIFT) |
     389                 :          0 :                         (((fuse & CHV_FGT_EU_DIS_SS1_R1_MASK) >>
     390                 :          0 :                           CHV_FGT_EU_DIS_SS1_R1_SHIFT) << 4);
     391                 :            : 
     392                 :          0 :                 subslice_mask |= BIT(1);
     393                 :          0 :                 sseu_set_eus(sseu, 0, 1, ~disabled_mask);
     394                 :            :         }
     395                 :            : 
     396                 :          0 :         intel_sseu_set_subslices(sseu, 0, subslice_mask);
     397                 :            : 
     398                 :          0 :         sseu->eu_total = compute_eu_total(sseu);
     399                 :            : 
     400                 :            :         /*
     401                 :            :          * CHV expected to always have a uniform distribution of EU
     402                 :            :          * across subslices.
     403                 :            :         */
     404         [ #  # ]:          0 :         sseu->eu_per_subslice = intel_sseu_subslice_total(sseu) ?
     405                 :          0 :                                 sseu->eu_total /
     406                 :          0 :                                         intel_sseu_subslice_total(sseu) :
     407                 :            :                                 0;
     408                 :            :         /*
     409                 :            :          * CHV supports subslice power gating on devices with more than
     410                 :            :          * one subslice, and supports EU power gating on devices with
     411                 :            :          * more than one EU pair per subslice.
     412                 :            :         */
     413                 :          0 :         sseu->has_slice_pg = 0;
     414                 :          0 :         sseu->has_subslice_pg = intel_sseu_subslice_total(sseu) > 1;
     415                 :          0 :         sseu->has_eu_pg = (sseu->eu_per_subslice > 2);
     416                 :          0 : }
     417                 :            : 
     418                 :          0 : static void gen9_sseu_info_init(struct drm_i915_private *dev_priv)
     419                 :            : {
     420                 :          0 :         struct intel_device_info *info = mkwrite_device_info(dev_priv);
     421                 :          0 :         struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
     422                 :          0 :         int s, ss;
     423                 :          0 :         u32 fuse2, eu_disable, subslice_mask;
     424                 :          0 :         const u8 eu_mask = 0xff;
     425                 :            : 
     426                 :          0 :         fuse2 = I915_READ(GEN8_FUSE2);
     427                 :          0 :         sseu->slice_mask = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT;
     428                 :            : 
     429                 :            :         /* BXT has a single slice and at most 3 subslices. */
     430   [ #  #  #  # ]:          0 :         intel_sseu_set_info(sseu, IS_GEN9_LP(dev_priv) ? 1 : 3,
     431   [ #  #  #  # ]:          0 :                             IS_GEN9_LP(dev_priv) ? 3 : 4, 8);
     432                 :            : 
     433                 :            :         /*
     434                 :            :          * The subslice disable field is global, i.e. it applies
     435                 :            :          * to each of the enabled slices.
     436                 :            :         */
     437                 :          0 :         subslice_mask = (1 << sseu->max_subslices) - 1;
     438                 :          0 :         subslice_mask &= ~((fuse2 & GEN9_F2_SS_DIS_MASK) >>
     439                 :            :                            GEN9_F2_SS_DIS_SHIFT);
     440                 :            : 
     441                 :            :         /*
     442                 :            :          * Iterate through enabled slices and subslices to
     443                 :            :          * count the total enabled EU.
     444                 :            :         */
     445         [ #  # ]:          0 :         for (s = 0; s < sseu->max_slices; s++) {
     446         [ #  # ]:          0 :                 if (!(sseu->slice_mask & BIT(s)))
     447                 :            :                         /* skip disabled slice */
     448                 :          0 :                         continue;
     449                 :            : 
     450                 :          0 :                 intel_sseu_set_subslices(sseu, s, subslice_mask);
     451                 :            : 
     452                 :          0 :                 eu_disable = I915_READ(GEN9_EU_DISABLE(s));
     453         [ #  # ]:          0 :                 for (ss = 0; ss < sseu->max_subslices; ss++) {
     454                 :          0 :                         int eu_per_ss;
     455                 :          0 :                         u8 eu_disabled_mask;
     456                 :            : 
     457         [ #  # ]:          0 :                         if (!intel_sseu_has_subslice(sseu, s, ss))
     458                 :            :                                 /* skip disabled subslice */
     459                 :          0 :                                 continue;
     460                 :            : 
     461                 :          0 :                         eu_disabled_mask = (eu_disable >> (ss * 8)) & eu_mask;
     462                 :            : 
     463                 :          0 :                         sseu_set_eus(sseu, s, ss, ~eu_disabled_mask);
     464                 :            : 
     465                 :          0 :                         eu_per_ss = sseu->max_eus_per_subslice -
     466         [ #  # ]:          0 :                                 hweight8(eu_disabled_mask);
     467                 :            : 
     468                 :            :                         /*
     469                 :            :                          * Record which subslice(s) has(have) 7 EUs. we
     470                 :            :                          * can tune the hash used to spread work among
     471                 :            :                          * subslices if they are unbalanced.
     472                 :            :                          */
     473         [ #  # ]:          0 :                         if (eu_per_ss == 7)
     474                 :          0 :                                 sseu->subslice_7eu[s] |= BIT(ss);
     475                 :            :                 }
     476                 :            :         }
     477                 :            : 
     478                 :          0 :         sseu->eu_total = compute_eu_total(sseu);
     479                 :            : 
     480                 :            :         /*
     481                 :            :          * SKL is expected to always have a uniform distribution
     482                 :            :          * of EU across subslices with the exception that any one
     483                 :            :          * EU in any one subslice may be fused off for die
     484                 :            :          * recovery. BXT is expected to be perfectly uniform in EU
     485                 :            :          * distribution.
     486                 :            :         */
     487         [ #  # ]:          0 :         sseu->eu_per_subslice = intel_sseu_subslice_total(sseu) ?
     488                 :          0 :                                 DIV_ROUND_UP(sseu->eu_total,
     489                 :            :                                              intel_sseu_subslice_total(sseu)) :
     490                 :            :                                 0;
     491                 :            :         /*
     492                 :            :          * SKL+ supports slice power gating on devices with more than
     493                 :            :          * one slice, and supports EU power gating on devices with
     494                 :            :          * more than one EU pair per subslice. BXT+ supports subslice
     495                 :            :          * power gating on devices with more than one subslice, and
     496                 :            :          * supports EU power gating on devices with more than one EU
     497                 :            :          * pair per subslice.
     498                 :            :         */
     499                 :          0 :         sseu->has_slice_pg =
     500   [ #  #  #  #  :          0 :                 !IS_GEN9_LP(dev_priv) && hweight8(sseu->slice_mask) > 1;
          #  #  #  #  #  
                      # ]
     501                 :          0 :         sseu->has_subslice_pg =
     502   [ #  #  #  #  :          0 :                 IS_GEN9_LP(dev_priv) && intel_sseu_subslice_total(sseu) > 1;
                   #  # ]
     503                 :          0 :         sseu->has_eu_pg = sseu->eu_per_subslice > 2;
     504                 :            : 
     505   [ #  #  #  # ]:          0 :         if (IS_GEN9_LP(dev_priv)) {
     506                 :            : #define IS_SS_DISABLED(ss)      (!(sseu->subslice_mask[0] & BIT(ss)))
     507         [ #  # ]:          0 :                 info->has_pooled_eu = hweight8(sseu->subslice_mask[0]) == 3;
     508                 :            : 
     509                 :          0 :                 sseu->min_eu_in_pool = 0;
     510         [ #  # ]:          0 :                 if (info->has_pooled_eu) {
     511         [ #  # ]:          0 :                         if (IS_SS_DISABLED(2) || IS_SS_DISABLED(0))
     512                 :          0 :                                 sseu->min_eu_in_pool = 3;
     513         [ #  # ]:          0 :                         else if (IS_SS_DISABLED(1))
     514                 :          0 :                                 sseu->min_eu_in_pool = 6;
     515                 :            :                         else
     516                 :          0 :                                 sseu->min_eu_in_pool = 9;
     517                 :            :                 }
     518                 :            : #undef IS_SS_DISABLED
     519                 :            :         }
     520                 :          0 : }
     521                 :            : 
     522                 :          0 : static void bdw_sseu_info_init(struct drm_i915_private *dev_priv)
     523                 :            : {
     524                 :          0 :         struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
     525                 :          0 :         int s, ss;
     526                 :          0 :         u32 fuse2, subslice_mask, eu_disable[3]; /* s_max */
     527                 :            : 
     528                 :          0 :         fuse2 = I915_READ(GEN8_FUSE2);
     529                 :          0 :         sseu->slice_mask = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT;
     530                 :          0 :         intel_sseu_set_info(sseu, 3, 3, 8);
     531                 :            : 
     532                 :            :         /*
     533                 :            :          * The subslice disable field is global, i.e. it applies
     534                 :            :          * to each of the enabled slices.
     535                 :            :          */
     536                 :          0 :         subslice_mask = GENMASK(sseu->max_subslices - 1, 0);
     537                 :          0 :         subslice_mask &= ~((fuse2 & GEN8_F2_SS_DIS_MASK) >>
     538                 :            :                            GEN8_F2_SS_DIS_SHIFT);
     539                 :            : 
     540                 :          0 :         eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK;
     541                 :          0 :         eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) |
     542                 :          0 :                         ((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) <<
     543                 :            :                          (32 - GEN8_EU_DIS0_S1_SHIFT));
     544                 :          0 :         eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) |
     545                 :          0 :                         ((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) <<
     546                 :            :                          (32 - GEN8_EU_DIS1_S2_SHIFT));
     547                 :            : 
     548                 :            :         /*
     549                 :            :          * Iterate through enabled slices and subslices to
     550                 :            :          * count the total enabled EU.
     551                 :            :          */
     552         [ #  # ]:          0 :         for (s = 0; s < sseu->max_slices; s++) {
     553         [ #  # ]:          0 :                 if (!(sseu->slice_mask & BIT(s)))
     554                 :            :                         /* skip disabled slice */
     555                 :          0 :                         continue;
     556                 :            : 
     557                 :          0 :                 intel_sseu_set_subslices(sseu, s, subslice_mask);
     558                 :            : 
     559         [ #  # ]:          0 :                 for (ss = 0; ss < sseu->max_subslices; ss++) {
     560                 :          0 :                         u8 eu_disabled_mask;
     561                 :          0 :                         u32 n_disabled;
     562                 :            : 
     563         [ #  # ]:          0 :                         if (!intel_sseu_has_subslice(sseu, s, ss))
     564                 :            :                                 /* skip disabled subslice */
     565                 :          0 :                                 continue;
     566                 :            : 
     567                 :          0 :                         eu_disabled_mask =
     568                 :          0 :                                 eu_disable[s] >> (ss * sseu->max_eus_per_subslice);
     569                 :            : 
     570                 :          0 :                         sseu_set_eus(sseu, s, ss, ~eu_disabled_mask);
     571                 :            : 
     572         [ #  # ]:          0 :                         n_disabled = hweight8(eu_disabled_mask);
     573                 :            : 
     574                 :            :                         /*
     575                 :            :                          * Record which subslices have 7 EUs.
     576                 :            :                          */
     577         [ #  # ]:          0 :                         if (sseu->max_eus_per_subslice - n_disabled == 7)
     578                 :          0 :                                 sseu->subslice_7eu[s] |= 1 << ss;
     579                 :            :                 }
     580                 :            :         }
     581                 :            : 
     582                 :          0 :         sseu->eu_total = compute_eu_total(sseu);
     583                 :            : 
     584                 :            :         /*
     585                 :            :          * BDW is expected to always have a uniform distribution of EU across
     586                 :            :          * subslices with the exception that any one EU in any one subslice may
     587                 :            :          * be fused off for die recovery.
     588                 :            :          */
     589         [ #  # ]:          0 :         sseu->eu_per_subslice = intel_sseu_subslice_total(sseu) ?
     590                 :          0 :                                 DIV_ROUND_UP(sseu->eu_total,
     591                 :            :                                              intel_sseu_subslice_total(sseu)) :
     592                 :            :                                 0;
     593                 :            : 
     594                 :            :         /*
     595                 :            :          * BDW supports slice power gating on devices with more than
     596                 :            :          * one slice.
     597                 :            :          */
     598         [ #  # ]:          0 :         sseu->has_slice_pg = hweight8(sseu->slice_mask) > 1;
     599                 :          0 :         sseu->has_subslice_pg = 0;
     600                 :          0 :         sseu->has_eu_pg = 0;
     601                 :          0 : }
     602                 :            : 
     603                 :          0 : static void hsw_sseu_info_init(struct drm_i915_private *dev_priv)
     604                 :            : {
     605                 :          0 :         struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
     606                 :          0 :         u32 fuse1;
     607                 :          0 :         u8 subslice_mask = 0;
     608                 :          0 :         int s, ss;
     609                 :            : 
     610                 :            :         /*
     611                 :            :          * There isn't a register to tell us how many slices/subslices. We
     612                 :            :          * work off the PCI-ids here.
     613                 :            :          */
     614   [ #  #  #  # ]:          0 :         switch (INTEL_INFO(dev_priv)->gt) {
     615                 :            :         default:
     616                 :          0 :                 MISSING_CASE(INTEL_INFO(dev_priv)->gt);
     617                 :            :                 /* fall through */
     618                 :          0 :         case 1:
     619                 :          0 :                 sseu->slice_mask = BIT(0);
     620                 :          0 :                 subslice_mask = BIT(0);
     621                 :          0 :                 break;
     622                 :          0 :         case 2:
     623                 :          0 :                 sseu->slice_mask = BIT(0);
     624                 :          0 :                 subslice_mask = BIT(0) | BIT(1);
     625                 :          0 :                 break;
     626                 :          0 :         case 3:
     627                 :          0 :                 sseu->slice_mask = BIT(0) | BIT(1);
     628                 :          0 :                 subslice_mask = BIT(0) | BIT(1);
     629                 :          0 :                 break;
     630                 :            :         }
     631                 :            : 
     632                 :          0 :         fuse1 = I915_READ(HSW_PAVP_FUSE1);
     633   [ #  #  #  # ]:          0 :         switch ((fuse1 & HSW_F1_EU_DIS_MASK) >> HSW_F1_EU_DIS_SHIFT) {
     634                 :            :         default:
     635                 :          0 :                 MISSING_CASE((fuse1 & HSW_F1_EU_DIS_MASK) >>
     636                 :            :                              HSW_F1_EU_DIS_SHIFT);
     637                 :            :                 /* fall through */
     638                 :          0 :         case HSW_F1_EU_DIS_10EUS:
     639                 :          0 :                 sseu->eu_per_subslice = 10;
     640                 :          0 :                 break;
     641                 :          0 :         case HSW_F1_EU_DIS_8EUS:
     642                 :          0 :                 sseu->eu_per_subslice = 8;
     643                 :          0 :                 break;
     644                 :          0 :         case HSW_F1_EU_DIS_6EUS:
     645                 :          0 :                 sseu->eu_per_subslice = 6;
     646                 :          0 :                 break;
     647                 :            :         }
     648                 :            : 
     649         [ #  # ]:          0 :         intel_sseu_set_info(sseu, hweight8(sseu->slice_mask),
     650                 :          0 :                             hweight8(subslice_mask),
     651         [ #  # ]:          0 :                             sseu->eu_per_subslice);
     652                 :            : 
     653         [ #  # ]:          0 :         for (s = 0; s < sseu->max_slices; s++) {
     654                 :          0 :                 intel_sseu_set_subslices(sseu, s, subslice_mask);
     655                 :            : 
     656         [ #  # ]:          0 :                 for (ss = 0; ss < sseu->max_subslices; ss++) {
     657                 :          0 :                         sseu_set_eus(sseu, s, ss,
     658                 :          0 :                                      (1UL << sseu->eu_per_subslice) - 1);
     659                 :            :                 }
     660                 :            :         }
     661                 :            : 
     662                 :          0 :         sseu->eu_total = compute_eu_total(sseu);
     663                 :            : 
     664                 :            :         /* No powergating for you. */
     665                 :          0 :         sseu->has_slice_pg = 0;
     666                 :          0 :         sseu->has_subslice_pg = 0;
     667                 :          0 :         sseu->has_eu_pg = 0;
     668                 :          0 : }
     669                 :            : 
     670                 :          0 : static u32 read_reference_ts_freq(struct drm_i915_private *dev_priv)
     671                 :            : {
     672                 :          0 :         u32 ts_override = I915_READ(GEN9_TIMESTAMP_OVERRIDE);
     673                 :          0 :         u32 base_freq, frac_freq;
     674                 :            : 
     675                 :          0 :         base_freq = ((ts_override & GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK) >>
     676                 :            :                      GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_SHIFT) + 1;
     677                 :          0 :         base_freq *= 1000;
     678                 :            : 
     679                 :          0 :         frac_freq = ((ts_override &
     680                 :          0 :                       GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK) >>
     681                 :            :                      GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_SHIFT);
     682                 :          0 :         frac_freq = 1000 / (frac_freq + 1);
     683                 :            : 
     684                 :          0 :         return base_freq + frac_freq;
     685                 :            : }
     686                 :            : 
     687                 :          0 : static u32 gen10_get_crystal_clock_freq(struct drm_i915_private *dev_priv,
     688                 :            :                                         u32 rpm_config_reg)
     689                 :            : {
     690                 :          0 :         u32 f19_2_mhz = 19200;
     691                 :          0 :         u32 f24_mhz = 24000;
     692                 :          0 :         u32 crystal_clock = (rpm_config_reg &
     693                 :          0 :                              GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >>
     694                 :            :                             GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT;
     695                 :            : 
     696                 :          0 :         switch (crystal_clock) {
     697                 :            :         case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ:
     698                 :            :                 return f19_2_mhz;
     699                 :          0 :         case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:
     700                 :          0 :                 return f24_mhz;
     701                 :            :         default:
     702                 :            :                 MISSING_CASE(crystal_clock);
     703                 :            :                 return 0;
     704                 :            :         }
     705                 :            : }
     706                 :            : 
     707                 :            : static u32 gen11_get_crystal_clock_freq(struct drm_i915_private *dev_priv,
     708                 :            :                                         u32 rpm_config_reg)
     709                 :            : {
     710                 :            :         u32 f19_2_mhz = 19200;
     711                 :            :         u32 f24_mhz = 24000;
     712                 :            :         u32 f25_mhz = 25000;
     713                 :            :         u32 f38_4_mhz = 38400;
     714                 :            :         u32 crystal_clock = (rpm_config_reg &
     715                 :            :                              GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >>
     716                 :            :                             GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT;
     717                 :            : 
     718                 :            :         switch (crystal_clock) {
     719                 :            :         case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:
     720                 :            :                 return f24_mhz;
     721                 :            :         case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ:
     722                 :            :                 return f19_2_mhz;
     723                 :            :         case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_38_4_MHZ:
     724                 :            :                 return f38_4_mhz;
     725                 :            :         case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_25_MHZ:
     726                 :            :                 return f25_mhz;
     727                 :            :         default:
     728                 :            :                 MISSING_CASE(crystal_clock);
     729                 :            :                 return 0;
     730                 :            :         }
     731                 :            : }
     732                 :            : 
     733                 :          0 : static u32 read_timestamp_frequency(struct drm_i915_private *dev_priv)
     734                 :            : {
     735                 :          0 :         u32 f12_5_mhz = 12500;
     736                 :          0 :         u32 f19_2_mhz = 19200;
     737                 :          0 :         u32 f24_mhz = 24000;
     738                 :            : 
     739         [ #  # ]:          0 :         if (INTEL_GEN(dev_priv) <= 4) {
     740                 :            :                 /* PRMs say:
     741                 :            :                  *
     742                 :            :                  *     "The value in this register increments once every 16
     743                 :            :                  *      hclks." (through the “Clocking Configuration”
     744                 :            :                  *      (“CLKCFG”) MCHBAR register)
     745                 :            :                  */
     746                 :          0 :                 return dev_priv->rawclk_freq / 16;
     747         [ #  # ]:          0 :         } else if (INTEL_GEN(dev_priv) <= 8) {
     748                 :            :                 /* PRMs say:
     749                 :            :                  *
     750                 :            :                  *     "The PCU TSC counts 10ns increments; this timestamp
     751                 :            :                  *      reflects bits 38:3 of the TSC (i.e. 80ns granularity,
     752                 :            :                  *      rolling over every 1.5 hours).
     753                 :            :                  */
     754                 :            :                 return f12_5_mhz;
     755         [ #  # ]:          0 :         } else if (INTEL_GEN(dev_priv) <= 9) {
     756                 :          0 :                 u32 ctc_reg = I915_READ(CTC_MODE);
     757                 :          0 :                 u32 freq = 0;
     758                 :            : 
     759         [ #  # ]:          0 :                 if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) {
     760                 :          0 :                         freq = read_reference_ts_freq(dev_priv);
     761                 :            :                 } else {
     762   [ #  #  #  # ]:          0 :                         freq = IS_GEN9_LP(dev_priv) ? f19_2_mhz : f24_mhz;
     763                 :            : 
     764                 :            :                         /* Now figure out how the command stream's timestamp
     765                 :            :                          * register increments from this frequency (it might
     766                 :            :                          * increment only every few clock cycle).
     767                 :            :                          */
     768                 :          0 :                         freq >>= 3 - ((ctc_reg & CTC_SHIFT_PARAMETER_MASK) >>
     769                 :            :                                       CTC_SHIFT_PARAMETER_SHIFT);
     770                 :            :                 }
     771                 :            : 
     772                 :          0 :                 return freq;
     773         [ #  # ]:          0 :         } else if (INTEL_GEN(dev_priv) <= 12) {
     774                 :          0 :                 u32 ctc_reg = I915_READ(CTC_MODE);
     775                 :          0 :                 u32 freq = 0;
     776                 :            : 
     777                 :            :                 /* First figure out the reference frequency. There are 2 ways
     778                 :            :                  * we can compute the frequency, either through the
     779                 :            :                  * TIMESTAMP_OVERRIDE register or through RPM_CONFIG. CTC_MODE
     780                 :            :                  * tells us which one we should use.
     781                 :            :                  */
     782         [ #  # ]:          0 :                 if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) {
     783                 :          0 :                         freq = read_reference_ts_freq(dev_priv);
     784                 :            :                 } else {
     785                 :          0 :                         u32 rpm_config_reg = I915_READ(RPM_CONFIG0);
     786                 :            : 
     787         [ #  # ]:          0 :                         if (INTEL_GEN(dev_priv) <= 10)
     788         [ #  # ]:          0 :                                 freq = gen10_get_crystal_clock_freq(dev_priv,
     789                 :            :                                                                 rpm_config_reg);
     790                 :            :                         else
     791                 :          0 :                                 freq = gen11_get_crystal_clock_freq(dev_priv,
     792                 :            :                                                                 rpm_config_reg);
     793                 :            : 
     794                 :            :                         /* Now figure out how the command stream's timestamp
     795                 :            :                          * register increments from this frequency (it might
     796                 :            :                          * increment only every few clock cycle).
     797                 :            :                          */
     798                 :          0 :                         freq >>= 3 - ((rpm_config_reg &
     799                 :          0 :                                        GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >>
     800                 :            :                                       GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT);
     801                 :            :                 }
     802                 :            : 
     803                 :          0 :                 return freq;
     804                 :            :         }
     805                 :            : 
     806                 :          0 :         MISSING_CASE("Unknown gen, unable to read command streamer timestamp frequency\n");
     807                 :          0 :         return 0;
     808                 :            : }
     809                 :            : 
     810                 :            : #undef INTEL_VGA_DEVICE
     811                 :            : #define INTEL_VGA_DEVICE(id, info) (id)
     812                 :            : 
     813                 :            : static const u16 subplatform_ult_ids[] = {
     814                 :            :         INTEL_HSW_ULT_GT1_IDS(0),
     815                 :            :         INTEL_HSW_ULT_GT2_IDS(0),
     816                 :            :         INTEL_HSW_ULT_GT3_IDS(0),
     817                 :            :         INTEL_BDW_ULT_GT1_IDS(0),
     818                 :            :         INTEL_BDW_ULT_GT2_IDS(0),
     819                 :            :         INTEL_BDW_ULT_GT3_IDS(0),
     820                 :            :         INTEL_BDW_ULT_RSVD_IDS(0),
     821                 :            :         INTEL_SKL_ULT_GT1_IDS(0),
     822                 :            :         INTEL_SKL_ULT_GT2_IDS(0),
     823                 :            :         INTEL_SKL_ULT_GT3_IDS(0),
     824                 :            :         INTEL_KBL_ULT_GT1_IDS(0),
     825                 :            :         INTEL_KBL_ULT_GT2_IDS(0),
     826                 :            :         INTEL_KBL_ULT_GT3_IDS(0),
     827                 :            :         INTEL_CFL_U_GT2_IDS(0),
     828                 :            :         INTEL_CFL_U_GT3_IDS(0),
     829                 :            :         INTEL_WHL_U_GT1_IDS(0),
     830                 :            :         INTEL_WHL_U_GT2_IDS(0),
     831                 :            :         INTEL_WHL_U_GT3_IDS(0),
     832                 :            :         INTEL_CML_U_GT1_IDS(0),
     833                 :            :         INTEL_CML_U_GT2_IDS(0),
     834                 :            : };
     835                 :            : 
     836                 :            : static const u16 subplatform_ulx_ids[] = {
     837                 :            :         INTEL_HSW_ULX_GT1_IDS(0),
     838                 :            :         INTEL_HSW_ULX_GT2_IDS(0),
     839                 :            :         INTEL_BDW_ULX_GT1_IDS(0),
     840                 :            :         INTEL_BDW_ULX_GT2_IDS(0),
     841                 :            :         INTEL_BDW_ULX_GT3_IDS(0),
     842                 :            :         INTEL_BDW_ULX_RSVD_IDS(0),
     843                 :            :         INTEL_SKL_ULX_GT1_IDS(0),
     844                 :            :         INTEL_SKL_ULX_GT2_IDS(0),
     845                 :            :         INTEL_KBL_ULX_GT1_IDS(0),
     846                 :            :         INTEL_KBL_ULX_GT2_IDS(0),
     847                 :            :         INTEL_AML_KBL_GT2_IDS(0),
     848                 :            :         INTEL_AML_CFL_GT2_IDS(0),
     849                 :            : };
     850                 :            : 
     851                 :            : static const u16 subplatform_portf_ids[] = {
     852                 :            :         INTEL_CNL_PORT_F_IDS(0),
     853                 :            :         INTEL_ICL_PORT_F_IDS(0),
     854                 :            : };
     855                 :            : 
     856                 :          0 : static bool find_devid(u16 id, const u16 *p, unsigned int num)
     857                 :            : {
     858   [ #  #  #  #  :          0 :         for (; num; num--, p++) {
                   #  # ]
     859   [ #  #  #  #  :          0 :                 if (*p == id)
                   #  # ]
     860                 :            :                         return true;
     861                 :            :         }
     862                 :            : 
     863                 :            :         return false;
     864                 :            : }
     865                 :            : 
     866                 :          0 : void intel_device_info_subplatform_init(struct drm_i915_private *i915)
     867                 :            : {
     868                 :          0 :         const struct intel_device_info *info = INTEL_INFO(i915);
     869                 :          0 :         const struct intel_runtime_info *rinfo = RUNTIME_INFO(i915);
     870                 :          0 :         const unsigned int pi = __platform_mask_index(rinfo, info->platform);
     871                 :          0 :         const unsigned int pb = __platform_mask_bit(rinfo, info->platform);
     872                 :          0 :         u16 devid = INTEL_DEVID(i915);
     873                 :          0 :         u32 mask = 0;
     874                 :            : 
     875                 :            :         /* Make sure IS_<platform> checks are working. */
     876                 :          0 :         RUNTIME_INFO(i915)->platform_mask[pi] = BIT(pb);
     877                 :            : 
     878                 :            :         /* Find and mark subplatform bits based on the PCI device id. */
     879         [ #  # ]:          0 :         if (find_devid(devid, subplatform_ult_ids,
     880                 :            :                        ARRAY_SIZE(subplatform_ult_ids))) {
     881                 :            :                 mask = BIT(INTEL_SUBPLATFORM_ULT);
     882         [ #  # ]:          0 :         } else if (find_devid(devid, subplatform_ulx_ids,
     883                 :            :                               ARRAY_SIZE(subplatform_ulx_ids))) {
     884                 :          0 :                 mask = BIT(INTEL_SUBPLATFORM_ULX);
     885   [ #  #  #  # ]:          0 :                 if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
     886                 :            :                         /* ULX machines are also considered ULT. */
     887                 :            :                         mask |= BIT(INTEL_SUBPLATFORM_ULT);
     888                 :            :                 }
     889         [ #  # ]:          0 :         } else if (find_devid(devid, subplatform_portf_ids,
     890                 :            :                               ARRAY_SIZE(subplatform_portf_ids))) {
     891                 :          0 :                 mask = BIT(INTEL_SUBPLATFORM_PORTF);
     892                 :            :         }
     893                 :            : 
     894                 :          0 :         GEM_BUG_ON(mask & ~INTEL_SUBPLATFORM_BITS);
     895                 :            : 
     896                 :          0 :         RUNTIME_INFO(i915)->platform_mask[pi] |= mask;
     897                 :          0 : }
     898                 :            : 
     899                 :            : /**
     900                 :            :  * intel_device_info_runtime_init - initialize runtime info
     901                 :            :  * @dev_priv: the i915 device
     902                 :            :  *
     903                 :            :  * Determine various intel_device_info fields at runtime.
     904                 :            :  *
     905                 :            :  * Use it when either:
     906                 :            :  *   - it's judged too laborious to fill n static structures with the limit
     907                 :            :  *     when a simple if statement does the job,
     908                 :            :  *   - run-time checks (eg read fuse/strap registers) are needed.
     909                 :            :  *
     910                 :            :  * This function needs to be called:
     911                 :            :  *   - after the MMIO has been setup as we are reading registers,
     912                 :            :  *   - after the PCH has been detected,
     913                 :            :  *   - before the first usage of the fields it can tweak.
     914                 :            :  */
     915                 :          0 : void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
     916                 :            : {
     917         [ #  # ]:          0 :         struct intel_device_info *info = mkwrite_device_info(dev_priv);
     918                 :          0 :         struct intel_runtime_info *runtime = RUNTIME_INFO(dev_priv);
     919                 :          0 :         enum pipe pipe;
     920                 :            : 
     921         [ #  # ]:          0 :         if (INTEL_GEN(dev_priv) >= 10) {
     922   [ #  #  #  # ]:          0 :                 for_each_pipe(dev_priv, pipe)
     923                 :          0 :                         runtime->num_scalers[pipe] = 2;
     924         [ #  # ]:          0 :         } else if (IS_GEN(dev_priv, 9)) {
     925                 :          0 :                 runtime->num_scalers[PIPE_A] = 2;
     926                 :          0 :                 runtime->num_scalers[PIPE_B] = 2;
     927                 :          0 :                 runtime->num_scalers[PIPE_C] = 1;
     928                 :            :         }
     929                 :            : 
     930                 :          0 :         BUILD_BUG_ON(BITS_PER_TYPE(intel_engine_mask_t) < I915_NUM_ENGINES);
     931                 :            : 
     932         [ #  # ]:          0 :         if (INTEL_GEN(dev_priv) >= 11)
     933   [ #  #  #  # ]:          0 :                 for_each_pipe(dev_priv, pipe)
     934                 :          0 :                         runtime->num_sprites[pipe] = 6;
     935   [ #  #  #  # ]:          0 :         else if (IS_GEN(dev_priv, 10) || IS_GEMINILAKE(dev_priv))
     936   [ #  #  #  # ]:          0 :                 for_each_pipe(dev_priv, pipe)
     937                 :          0 :                         runtime->num_sprites[pipe] = 3;
     938         [ #  # ]:          0 :         else if (IS_BROXTON(dev_priv)) {
     939                 :            :                 /*
     940                 :            :                  * Skylake and Broxton currently don't expose the topmost plane as its
     941                 :            :                  * use is exclusive with the legacy cursor and we only want to expose
     942                 :            :                  * one of those, not both. Until we can safely expose the topmost plane
     943                 :            :                  * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported,
     944                 :            :                  * we don't expose the topmost plane at all to prevent ABI breakage
     945                 :            :                  * down the line.
     946                 :            :                  */
     947                 :            : 
     948                 :          0 :                 runtime->num_sprites[PIPE_A] = 2;
     949                 :          0 :                 runtime->num_sprites[PIPE_B] = 2;
     950                 :          0 :                 runtime->num_sprites[PIPE_C] = 1;
     951   [ #  #  #  # ]:          0 :         } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
     952   [ #  #  #  # ]:          0 :                 for_each_pipe(dev_priv, pipe)
     953                 :          0 :                         runtime->num_sprites[pipe] = 2;
     954   [ #  #  #  #  :          0 :         } else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) {
                   #  # ]
     955   [ #  #  #  # ]:          0 :                 for_each_pipe(dev_priv, pipe)
     956                 :          0 :                         runtime->num_sprites[pipe] = 1;
     957                 :            :         }
     958                 :            : 
     959   [ #  #  #  # ]:          0 :         if (HAS_DISPLAY(dev_priv) && IS_GEN_RANGE(dev_priv, 7, 8) &&
     960         [ #  # ]:          0 :             HAS_PCH_SPLIT(dev_priv)) {
     961                 :          0 :                 u32 fuse_strap = I915_READ(FUSE_STRAP);
     962                 :          0 :                 u32 sfuse_strap = I915_READ(SFUSE_STRAP);
     963                 :            : 
     964                 :            :                 /*
     965                 :            :                  * SFUSE_STRAP is supposed to have a bit signalling the display
     966                 :            :                  * is fused off. Unfortunately it seems that, at least in
     967                 :            :                  * certain cases, fused off display means that PCH display
     968                 :            :                  * reads don't land anywhere. In that case, we read 0s.
     969                 :            :                  *
     970                 :            :                  * On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK
     971                 :            :                  * should be set when taking over after the firmware.
     972                 :            :                  */
     973         [ #  # ]:          0 :                 if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE ||
     974         [ #  # ]:          0 :                     sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED ||
     975         [ #  # ]:          0 :                     (HAS_PCH_CPT(dev_priv) &&
     976         [ #  # ]:          0 :                      !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) {
     977                 :          0 :                         DRM_INFO("Display fused off, disabling\n");
     978                 :          0 :                         info->pipe_mask = 0;
     979         [ #  # ]:          0 :                 } else if (fuse_strap & IVB_PIPE_C_DISABLE) {
     980                 :          0 :                         DRM_INFO("PipeC fused off\n");
     981                 :          0 :                         info->pipe_mask &= ~BIT(PIPE_C);
     982                 :            :                 }
     983   [ #  #  #  # ]:          0 :         } else if (HAS_DISPLAY(dev_priv) && INTEL_GEN(dev_priv) >= 9) {
     984                 :          0 :                 u32 dfsm = I915_READ(SKL_DFSM);
     985                 :          0 :                 u8 enabled_mask = info->pipe_mask;
     986                 :            : 
     987         [ #  # ]:          0 :                 if (dfsm & SKL_DFSM_PIPE_A_DISABLE)
     988                 :          0 :                         enabled_mask &= ~BIT(PIPE_A);
     989         [ #  # ]:          0 :                 if (dfsm & SKL_DFSM_PIPE_B_DISABLE)
     990                 :          0 :                         enabled_mask &= ~BIT(PIPE_B);
     991         [ #  # ]:          0 :                 if (dfsm & SKL_DFSM_PIPE_C_DISABLE)
     992                 :          0 :                         enabled_mask &= ~BIT(PIPE_C);
     993         [ #  # ]:          0 :                 if (INTEL_GEN(dev_priv) >= 12 &&
     994         [ #  # ]:          0 :                     (dfsm & TGL_DFSM_PIPE_D_DISABLE))
     995                 :          0 :                         enabled_mask &= ~BIT(PIPE_D);
     996                 :            : 
     997                 :            :                 /*
     998                 :            :                  * At least one pipe should be enabled and if there are
     999                 :            :                  * disabled pipes, they should be the last ones, with no holes
    1000                 :            :                  * in the mask.
    1001                 :            :                  */
    1002   [ #  #  #  #  :          0 :                 if (enabled_mask == 0 || !is_power_of_2(enabled_mask + 1))
                   #  # ]
    1003                 :          0 :                         DRM_ERROR("invalid pipe fuse configuration: enabled_mask=0x%x\n",
    1004                 :            :                                   enabled_mask);
    1005                 :            :                 else
    1006                 :          0 :                         info->pipe_mask = enabled_mask;
    1007                 :            : 
    1008         [ #  # ]:          0 :                 if (dfsm & SKL_DFSM_DISPLAY_HDCP_DISABLE)
    1009                 :          0 :                         info->display.has_hdcp = 0;
    1010                 :            : 
    1011         [ #  # ]:          0 :                 if (dfsm & SKL_DFSM_DISPLAY_PM_DISABLE)
    1012                 :          0 :                         info->display.has_fbc = 0;
    1013                 :            : 
    1014   [ #  #  #  # ]:          0 :                 if (INTEL_GEN(dev_priv) >= 11 && (dfsm & ICL_DFSM_DMC_DISABLE))
    1015                 :          0 :                         info->display.has_csr = 0;
    1016                 :            : 
    1017         [ #  # ]:          0 :                 if (INTEL_GEN(dev_priv) >= 10 &&
    1018         [ #  # ]:          0 :                     (dfsm & CNL_DFSM_DISPLAY_DSC_DISABLE))
    1019                 :          0 :                         info->display.has_dsc = 0;
    1020                 :            :         }
    1021                 :            : 
    1022                 :            :         /* Initialize slice/subslice/EU info */
    1023         [ #  # ]:          0 :         if (IS_HASWELL(dev_priv))
    1024                 :          0 :                 hsw_sseu_info_init(dev_priv);
    1025         [ #  # ]:          0 :         else if (IS_CHERRYVIEW(dev_priv))
    1026                 :          0 :                 cherryview_sseu_info_init(dev_priv);
    1027         [ #  # ]:          0 :         else if (IS_BROADWELL(dev_priv))
    1028                 :          0 :                 bdw_sseu_info_init(dev_priv);
    1029         [ #  # ]:          0 :         else if (IS_GEN(dev_priv, 9))
    1030                 :          0 :                 gen9_sseu_info_init(dev_priv);
    1031         [ #  # ]:          0 :         else if (IS_GEN(dev_priv, 10))
    1032                 :          0 :                 gen10_sseu_info_init(dev_priv);
    1033         [ #  # ]:          0 :         else if (IS_GEN(dev_priv, 11))
    1034                 :          0 :                 gen11_sseu_info_init(dev_priv);
    1035         [ #  # ]:          0 :         else if (INTEL_GEN(dev_priv) >= 12)
    1036                 :          0 :                 gen12_sseu_info_init(dev_priv);
    1037                 :            : 
    1038         [ #  # ]:          0 :         if (IS_GEN(dev_priv, 6) && intel_vtd_active()) {
    1039                 :          0 :                 DRM_INFO("Disabling ppGTT for VT-d support\n");
    1040                 :          0 :                 info->ppgtt_type = INTEL_PPGTT_NONE;
    1041                 :            :         }
    1042                 :            : 
    1043                 :            :         /* Initialize command stream timestamp frequency */
    1044                 :          0 :         runtime->cs_timestamp_frequency_khz = read_timestamp_frequency(dev_priv);
    1045                 :          0 : }
    1046                 :            : 
    1047                 :          0 : void intel_driver_caps_print(const struct intel_driver_caps *caps,
    1048                 :            :                              struct drm_printer *p)
    1049                 :            : {
    1050                 :          0 :         drm_printf(p, "Has logical contexts? %s\n",
    1051         [ #  # ]:          0 :                    yesno(caps->has_logical_contexts));
    1052                 :          0 :         drm_printf(p, "scheduler: %x\n", caps->scheduler);
    1053                 :          0 : }
    1054                 :            : 
    1055                 :            : /*
    1056                 :            :  * Determine which engines are fused off in our particular hardware. Since the
    1057                 :            :  * fuse register is in the blitter powerwell, we need forcewake to be ready at
    1058                 :            :  * this point (but later we need to prune the forcewake domains for engines that
    1059                 :            :  * are indeed fused off).
    1060                 :            :  */
    1061                 :          0 : void intel_device_info_init_mmio(struct drm_i915_private *dev_priv)
    1062                 :            : {
    1063         [ #  # ]:          0 :         struct intel_device_info *info = mkwrite_device_info(dev_priv);
    1064                 :          0 :         unsigned int logical_vdbox = 0;
    1065                 :          0 :         unsigned int i;
    1066                 :          0 :         u32 media_fuse;
    1067                 :          0 :         u16 vdbox_mask;
    1068                 :          0 :         u16 vebox_mask;
    1069                 :            : 
    1070         [ #  # ]:          0 :         if (INTEL_GEN(dev_priv) < 11)
    1071                 :            :                 return;
    1072                 :            : 
    1073                 :          0 :         media_fuse = ~I915_READ(GEN11_GT_VEBOX_VDBOX_DISABLE);
    1074                 :            : 
    1075                 :          0 :         vdbox_mask = media_fuse & GEN11_GT_VDBOX_DISABLE_MASK;
    1076                 :          0 :         vebox_mask = (media_fuse & GEN11_GT_VEBOX_DISABLE_MASK) >>
    1077                 :            :                       GEN11_GT_VEBOX_DISABLE_SHIFT;
    1078                 :            : 
    1079         [ #  # ]:          0 :         for (i = 0; i < I915_MAX_VCS; i++) {
    1080         [ #  # ]:          0 :                 if (!HAS_ENGINE(dev_priv, _VCS(i))) {
    1081                 :          0 :                         vdbox_mask &= ~BIT(i);
    1082                 :          0 :                         continue;
    1083                 :            :                 }
    1084                 :            : 
    1085         [ #  # ]:          0 :                 if (!(BIT(i) & vdbox_mask)) {
    1086                 :          0 :                         info->engine_mask &= ~BIT(_VCS(i));
    1087                 :          0 :                         DRM_DEBUG_DRIVER("vcs%u fused off\n", i);
    1088                 :          0 :                         continue;
    1089                 :            :                 }
    1090                 :            : 
    1091                 :            :                 /*
    1092                 :            :                  * In Gen11, only even numbered logical VDBOXes are
    1093                 :            :                  * hooked up to an SFC (Scaler & Format Converter) unit.
    1094                 :            :                  * In TGL each VDBOX has access to an SFC.
    1095                 :            :                  */
    1096   [ #  #  #  # ]:          0 :                 if (INTEL_GEN(dev_priv) >= 12 || logical_vdbox++ % 2 == 0)
    1097                 :          0 :                         RUNTIME_INFO(dev_priv)->vdbox_sfc_access |= BIT(i);
    1098                 :            :         }
    1099                 :          0 :         DRM_DEBUG_DRIVER("vdbox enable: %04x, instances: %04lx\n",
    1100                 :            :                          vdbox_mask, VDBOX_MASK(dev_priv));
    1101                 :          0 :         GEM_BUG_ON(vdbox_mask != VDBOX_MASK(dev_priv));
    1102                 :            : 
    1103         [ #  # ]:          0 :         for (i = 0; i < I915_MAX_VECS; i++) {
    1104         [ #  # ]:          0 :                 if (!HAS_ENGINE(dev_priv, _VECS(i))) {
    1105                 :          0 :                         vebox_mask &= ~BIT(i);
    1106                 :          0 :                         continue;
    1107                 :            :                 }
    1108                 :            : 
    1109         [ #  # ]:          0 :                 if (!(BIT(i) & vebox_mask)) {
    1110                 :          0 :                         info->engine_mask &= ~BIT(_VECS(i));
    1111                 :          0 :                         DRM_DEBUG_DRIVER("vecs%u fused off\n", i);
    1112                 :            :                 }
    1113                 :            :         }
    1114                 :          0 :         DRM_DEBUG_DRIVER("vebox enable: %04x, instances: %04lx\n",
    1115                 :            :                          vebox_mask, VEBOX_MASK(dev_priv));
    1116                 :          0 :         GEM_BUG_ON(vebox_mask != VEBOX_MASK(dev_priv));
    1117                 :            : }

Generated by: LCOV version 1.14