Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: MIT */
0002 /*
0003  * Copyright © 2019 Intel Corporation
0004  */
0005 
0006 #ifndef __INTEL_SSEU_H__
0007 #define __INTEL_SSEU_H__
0008 
0009 #include <linux/types.h>
0010 #include <linux/kernel.h>
0011 
0012 #include "i915_gem.h"
0013 
0014 struct drm_i915_private;
0015 struct intel_gt;
0016 struct drm_printer;
0017 
0018 /*
0019  * Maximum number of slices on older platforms.  Slices no longer exist
0020  * starting on Xe_HP ("gslices," "cslices," etc. are a different concept and
0021  * are not expressed through fusing).
0022  */
0023 #define GEN_MAX_HSW_SLICES      3
0024 
0025 /*
0026  * Maximum number of subslices that can exist within a HSW-style slice.  This
0027  * is only relevant to pre-Xe_HP platforms (Xe_HP and beyond use the
0028  * I915_MAX_SS_FUSE_BITS value below).
0029  */
0030 #define GEN_MAX_SS_PER_HSW_SLICE    6
0031 
0032 /*
0033  * Maximum number of 32-bit registers used by hardware to express the
0034  * enabled/disabled subslices.
0035  */
0036 #define I915_MAX_SS_FUSE_REGS   2
0037 #define I915_MAX_SS_FUSE_BITS   (I915_MAX_SS_FUSE_REGS * 32)
0038 
0039 /* Maximum number of EUs that can exist within a subslice or DSS. */
0040 #define GEN_MAX_EUS_PER_SS      16
0041 
0042 #define SSEU_MAX(a, b)          ((a) > (b) ? (a) : (b))
0043 
0044 /* The maximum number of bits needed to express each subslice/DSS independently */
0045 #define GEN_SS_MASK_SIZE        SSEU_MAX(I915_MAX_SS_FUSE_BITS, \
0046                          GEN_MAX_HSW_SLICES * GEN_MAX_SS_PER_HSW_SLICE)
0047 
0048 #define GEN_SSEU_STRIDE(max_entries)    DIV_ROUND_UP(max_entries, BITS_PER_BYTE)
0049 #define GEN_MAX_SUBSLICE_STRIDE     GEN_SSEU_STRIDE(GEN_SS_MASK_SIZE)
0050 #define GEN_MAX_EU_STRIDE       GEN_SSEU_STRIDE(GEN_MAX_EUS_PER_SS)
0051 
0052 #define GEN_DSS_PER_GSLICE  4
0053 #define GEN_DSS_PER_CSLICE  8
0054 #define GEN_DSS_PER_MSLICE  8
0055 
0056 #define GEN_MAX_GSLICES     (I915_MAX_SS_FUSE_BITS / GEN_DSS_PER_GSLICE)
0057 #define GEN_MAX_CSLICES     (I915_MAX_SS_FUSE_BITS / GEN_DSS_PER_CSLICE)
0058 
0059 typedef union {
0060     u8 hsw[GEN_MAX_HSW_SLICES];
0061 
0062     /* Bitmap compatible with linux/bitmap.h; may exceed size of u64 */
0063     unsigned long xehp[BITS_TO_LONGS(I915_MAX_SS_FUSE_BITS)];
0064 } intel_sseu_ss_mask_t;
0065 
0066 #define XEHP_BITMAP_BITS(mask)  ((int)BITS_PER_TYPE(typeof(mask.xehp)))
0067 
0068 struct sseu_dev_info {
0069     u8 slice_mask;
0070     intel_sseu_ss_mask_t subslice_mask;
0071     intel_sseu_ss_mask_t geometry_subslice_mask;
0072     intel_sseu_ss_mask_t compute_subslice_mask;
0073     union {
0074         u16 hsw[GEN_MAX_HSW_SLICES][GEN_MAX_SS_PER_HSW_SLICE];
0075         u16 xehp[I915_MAX_SS_FUSE_BITS];
0076     } eu_mask;
0077 
0078     u16 eu_total;
0079     u8 eu_per_subslice;
0080     u8 min_eu_in_pool;
0081     /* For each slice, which subslice(s) has(have) 7 EUs (bitfield)? */
0082     u8 subslice_7eu[3];
0083     u8 has_slice_pg:1;
0084     u8 has_subslice_pg:1;
0085     u8 has_eu_pg:1;
0086     /*
0087      * For Xe_HP and beyond, the hardware no longer has traditional slices
0088      * so we just report the entire DSS pool under a fake "slice 0."
0089      */
0090     u8 has_xehp_dss:1;
0091 
0092     /* Topology fields */
0093     u8 max_slices;
0094     u8 max_subslices;
0095     u8 max_eus_per_subslice;
0096 };
0097 
0098 /*
0099  * Powergating configuration for a particular (context,engine).
0100  */
0101 struct intel_sseu {
0102     u8 slice_mask;
0103     u8 subslice_mask;
0104     u8 min_eus_per_subslice;
0105     u8 max_eus_per_subslice;
0106 };
0107 
0108 static inline struct intel_sseu
0109 intel_sseu_from_device_info(const struct sseu_dev_info *sseu)
0110 {
0111     struct intel_sseu value = {
0112         .slice_mask = sseu->slice_mask,
0113         .subslice_mask = sseu->subslice_mask.hsw[0],
0114         .min_eus_per_subslice = sseu->max_eus_per_subslice,
0115         .max_eus_per_subslice = sseu->max_eus_per_subslice,
0116     };
0117 
0118     return value;
0119 }
0120 
0121 static inline bool
0122 intel_sseu_has_subslice(const struct sseu_dev_info *sseu, int slice,
0123             int subslice)
0124 {
0125     if (slice >= sseu->max_slices ||
0126         subslice >= sseu->max_subslices)
0127         return false;
0128 
0129     if (sseu->has_xehp_dss)
0130         return test_bit(subslice, sseu->subslice_mask.xehp);
0131     else
0132         return sseu->subslice_mask.hsw[slice] & BIT(subslice);
0133 }
0134 
0135 /*
0136  * Used to obtain the index of the first DSS.  Can start searching from the
0137  * beginning of a specific dss group (e.g., gslice, cslice, etc.) if
0138  * groupsize and groupnum are non-zero.
0139  */
0140 static inline unsigned int
0141 intel_sseu_find_first_xehp_dss(const struct sseu_dev_info *sseu, int groupsize,
0142                    int groupnum)
0143 {
0144     return find_next_bit(sseu->subslice_mask.xehp,
0145                  XEHP_BITMAP_BITS(sseu->subslice_mask),
0146                  groupnum * groupsize);
0147 }
0148 
0149 void intel_sseu_set_info(struct sseu_dev_info *sseu, u8 max_slices,
0150              u8 max_subslices, u8 max_eus_per_subslice);
0151 
0152 unsigned int
0153 intel_sseu_subslice_total(const struct sseu_dev_info *sseu);
0154 
0155 unsigned int
0156 intel_sseu_get_hsw_subslices(const struct sseu_dev_info *sseu, u8 slice);
0157 
0158 intel_sseu_ss_mask_t
0159 intel_sseu_get_compute_subslices(const struct sseu_dev_info *sseu);
0160 
0161 void intel_sseu_info_init(struct intel_gt *gt);
0162 
0163 u32 intel_sseu_make_rpcs(struct intel_gt *gt,
0164              const struct intel_sseu *req_sseu);
0165 
0166 void intel_sseu_dump(const struct sseu_dev_info *sseu, struct drm_printer *p);
0167 void intel_sseu_print_topology(struct drm_i915_private *i915,
0168                    const struct sseu_dev_info *sseu,
0169                    struct drm_printer *p);
0170 
0171 u16 intel_slicemask_from_xehp_dssmask(intel_sseu_ss_mask_t dss_mask, int dss_per_slice);
0172 
0173 int intel_sseu_copy_eumask_to_user(void __user *to,
0174                    const struct sseu_dev_info *sseu);
0175 int intel_sseu_copy_ssmask_to_user(void __user *to,
0176                    const struct sseu_dev_info *sseu);
0177 
0178 void intel_sseu_print_ss_info(const char *type,
0179                   const struct sseu_dev_info *sseu,
0180                   struct seq_file *m);
0181 
0182 #endif /* __INTEL_SSEU_H__ */