1 /* SPDX-License-Identifier: MIT */ 2 /* 3 * Copyright © 2019 Intel Corporation 4 */ 5 6 #ifndef __INTEL_SSEU_H__ 7 #define __INTEL_SSEU_H__ 8 9 #include <linux/types.h> 10 #include <linux/kernel.h> 11 12 #include "i915_gem.h" 13 14 struct drm_i915_private; 15 struct intel_gt; 16 struct drm_printer; 17 18 #define GEN_MAX_SLICES (3) /* SKL upper bound */ 19 #define GEN_MAX_SUBSLICES (32) /* XEHPSDV upper bound */ 20 #define GEN_SSEU_STRIDE(max_entries) DIV_ROUND_UP(max_entries, BITS_PER_BYTE) 21 #define GEN_MAX_SUBSLICE_STRIDE GEN_SSEU_STRIDE(GEN_MAX_SUBSLICES) 22 #define GEN_MAX_EUS (16) /* TGL upper bound */ 23 #define GEN_MAX_EU_STRIDE GEN_SSEU_STRIDE(GEN_MAX_EUS) 24 25 #define GEN_DSS_PER_GSLICE 4 26 #define GEN_DSS_PER_CSLICE 8 27 #define GEN_DSS_PER_MSLICE 8 28 29 #define GEN_MAX_GSLICES (GEN_MAX_SUBSLICES / GEN_DSS_PER_GSLICE) 30 #define GEN_MAX_CSLICES (GEN_MAX_SUBSLICES / GEN_DSS_PER_CSLICE) 31 32 struct sseu_dev_info { 33 u8 slice_mask; 34 u8 subslice_mask[GEN_MAX_SLICES * GEN_MAX_SUBSLICE_STRIDE]; 35 u8 geometry_subslice_mask[GEN_MAX_SLICES * GEN_MAX_SUBSLICE_STRIDE]; 36 u8 compute_subslice_mask[GEN_MAX_SLICES * GEN_MAX_SUBSLICE_STRIDE]; 37 u8 eu_mask[GEN_MAX_SLICES * GEN_MAX_SUBSLICES * GEN_MAX_EU_STRIDE]; 38 u16 eu_total; 39 u8 eu_per_subslice; 40 u8 min_eu_in_pool; 41 /* For each slice, which subslice(s) has(have) 7 EUs (bitfield)? */ 42 u8 subslice_7eu[3]; 43 u8 has_slice_pg:1; 44 u8 has_subslice_pg:1; 45 u8 has_eu_pg:1; 46 47 /* Topology fields */ 48 u8 max_slices; 49 u8 max_subslices; 50 u8 max_eus_per_subslice; 51 52 u8 ss_stride; 53 u8 eu_stride; 54 }; 55 56 /* 57 * Powergating configuration for a particular (context,engine). 58 */ 59 struct intel_sseu { 60 u8 slice_mask; 61 u8 subslice_mask; 62 u8 min_eus_per_subslice; 63 u8 max_eus_per_subslice; 64 }; 65 66 static inline struct intel_sseu 67 intel_sseu_from_device_info(const struct sseu_dev_info *sseu) 68 { 69 struct intel_sseu value = { 70 .slice_mask = sseu->slice_mask, 71 .subslice_mask = sseu->subslice_mask[0], 72 .min_eus_per_subslice = sseu->max_eus_per_subslice, 73 .max_eus_per_subslice = sseu->max_eus_per_subslice, 74 }; 75 76 return value; 77 } 78 79 static inline bool 80 intel_sseu_has_subslice(const struct sseu_dev_info *sseu, int slice, 81 int subslice) 82 { 83 u8 mask; 84 int ss_idx = subslice / BITS_PER_BYTE; 85 86 if (slice >= sseu->max_slices || 87 subslice >= sseu->max_subslices) 88 return false; 89 90 GEM_BUG_ON(ss_idx >= sseu->ss_stride); 91 92 mask = sseu->subslice_mask[slice * sseu->ss_stride + ss_idx]; 93 94 return mask & BIT(subslice % BITS_PER_BYTE); 95 } 96 97 void intel_sseu_set_info(struct sseu_dev_info *sseu, u8 max_slices, 98 u8 max_subslices, u8 max_eus_per_subslice); 99 100 unsigned int 101 intel_sseu_subslice_total(const struct sseu_dev_info *sseu); 102 103 unsigned int 104 intel_sseu_subslices_per_slice(const struct sseu_dev_info *sseu, u8 slice); 105 106 u32 intel_sseu_get_subslices(const struct sseu_dev_info *sseu, u8 slice); 107 108 u32 intel_sseu_get_compute_subslices(const struct sseu_dev_info *sseu); 109 110 void intel_sseu_set_subslices(struct sseu_dev_info *sseu, int slice, 111 u8 *subslice_mask, u32 ss_mask); 112 113 void intel_sseu_info_init(struct intel_gt *gt); 114 115 u32 intel_sseu_make_rpcs(struct intel_gt *gt, 116 const struct intel_sseu *req_sseu); 117 118 void intel_sseu_dump(const struct sseu_dev_info *sseu, struct drm_printer *p); 119 void intel_sseu_print_topology(const struct sseu_dev_info *sseu, 120 struct drm_printer *p); 121 122 u16 intel_slicemask_from_dssmask(u64 dss_mask, int dss_per_slice); 123 124 #endif /* __INTEL_SSEU_H__ */ 125