Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: Move sseu debugfs under gt/

In line with what happened for other gt-related features, move the sseu
debugfs files under gt/.

The sseu_status debugfs has also been kept at the top level as we do
have tests that use it; it will be removed once we teach the tests to
look into the new path.

Suggested-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: Andi Shyti <andi.shyti@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20200708003952.21831-10-daniele.ceraolospurio@intel.com

authored by

Daniele Ceraolo Spurio and committed by
Chris Wilson
a00eda7d 5df79ff1

+328 -267
+1
drivers/gpu/drm/i915/Makefile
··· 112 112 gt/intel_ring_submission.o \ 113 113 gt/intel_rps.o \ 114 114 gt/intel_sseu.o \ 115 + gt/intel_sseu_debugfs.o \ 115 116 gt/intel_timeline.o \ 116 117 gt/intel_workarounds.o \ 117 118 gt/shmem_utils.o \
+2
drivers/gpu/drm/i915/gt/debugfs_gt.c
··· 9 9 #include "debugfs_engines.h" 10 10 #include "debugfs_gt.h" 11 11 #include "debugfs_gt_pm.h" 12 + #include "intel_sseu_debugfs.h" 12 13 #include "uc/intel_uc_debugfs.h" 13 14 #include "i915_drv.h" 14 15 ··· 26 25 27 26 debugfs_engines_register(gt, root); 28 27 debugfs_gt_pm_register(gt, root); 28 + intel_sseu_debugfs_register(gt, root); 29 29 30 30 intel_uc_debugfs_register(&gt->uc, root); 31 31 }
+306
drivers/gpu/drm/i915/gt/intel_sseu_debugfs.c
··· 1 + // SPDX-License-Identifier: MIT 2 + 3 + /* 4 + * Copyright © 2020 Intel Corporation 5 + */ 6 + 7 + #include "debugfs_gt.h" 8 + #include "intel_sseu_debugfs.h" 9 + #include "i915_drv.h" 10 + 11 + static void sseu_copy_subslices(const struct sseu_dev_info *sseu, 12 + int slice, u8 *to_mask) 13 + { 14 + int offset = slice * sseu->ss_stride; 15 + 16 + memcpy(&to_mask[offset], &sseu->subslice_mask[offset], sseu->ss_stride); 17 + } 18 + 19 + static void cherryview_sseu_device_status(struct intel_gt *gt, 20 + struct sseu_dev_info *sseu) 21 + { 22 + #define SS_MAX 2 23 + struct intel_uncore *uncore = gt->uncore; 24 + const int ss_max = SS_MAX; 25 + u32 sig1[SS_MAX], sig2[SS_MAX]; 26 + int ss; 27 + 28 + sig1[0] = intel_uncore_read(uncore, CHV_POWER_SS0_SIG1); 29 + sig1[1] = intel_uncore_read(uncore, CHV_POWER_SS1_SIG1); 30 + sig2[0] = intel_uncore_read(uncore, CHV_POWER_SS0_SIG2); 31 + sig2[1] = intel_uncore_read(uncore, CHV_POWER_SS1_SIG2); 32 + 33 + for (ss = 0; ss < ss_max; ss++) { 34 + unsigned int eu_cnt; 35 + 36 + if (sig1[ss] & CHV_SS_PG_ENABLE) 37 + /* skip disabled subslice */ 38 + continue; 39 + 40 + sseu->slice_mask = BIT(0); 41 + sseu->subslice_mask[0] |= BIT(ss); 42 + eu_cnt = ((sig1[ss] & CHV_EU08_PG_ENABLE) ? 0 : 2) + 43 + ((sig1[ss] & CHV_EU19_PG_ENABLE) ? 0 : 2) + 44 + ((sig1[ss] & CHV_EU210_PG_ENABLE) ? 0 : 2) + 45 + ((sig2[ss] & CHV_EU311_PG_ENABLE) ? 0 : 2); 46 + sseu->eu_total += eu_cnt; 47 + sseu->eu_per_subslice = max_t(unsigned int, 48 + sseu->eu_per_subslice, eu_cnt); 49 + } 50 + #undef SS_MAX 51 + } 52 + 53 + static void gen10_sseu_device_status(struct intel_gt *gt, 54 + struct sseu_dev_info *sseu) 55 + { 56 + #define SS_MAX 6 57 + struct intel_uncore *uncore = gt->uncore; 58 + const struct intel_gt_info *info = &gt->info; 59 + u32 s_reg[SS_MAX], eu_reg[2 * SS_MAX], eu_mask[2]; 60 + int s, ss; 61 + 62 + for (s = 0; s < info->sseu.max_slices; s++) { 63 + /* 64 + * FIXME: Valid SS Mask respects the spec and read 65 + * only valid bits for those registers, excluding reserved 66 + * although this seems wrong because it would leave many 67 + * subslices without ACK. 68 + */ 69 + s_reg[s] = intel_uncore_read(uncore, GEN10_SLICE_PGCTL_ACK(s)) & 70 + GEN10_PGCTL_VALID_SS_MASK(s); 71 + eu_reg[2 * s] = intel_uncore_read(uncore, 72 + GEN10_SS01_EU_PGCTL_ACK(s)); 73 + eu_reg[2 * s + 1] = intel_uncore_read(uncore, 74 + GEN10_SS23_EU_PGCTL_ACK(s)); 75 + } 76 + 77 + eu_mask[0] = GEN9_PGCTL_SSA_EU08_ACK | 78 + GEN9_PGCTL_SSA_EU19_ACK | 79 + GEN9_PGCTL_SSA_EU210_ACK | 80 + GEN9_PGCTL_SSA_EU311_ACK; 81 + eu_mask[1] = GEN9_PGCTL_SSB_EU08_ACK | 82 + GEN9_PGCTL_SSB_EU19_ACK | 83 + GEN9_PGCTL_SSB_EU210_ACK | 84 + GEN9_PGCTL_SSB_EU311_ACK; 85 + 86 + for (s = 0; s < info->sseu.max_slices; s++) { 87 + if ((s_reg[s] & GEN9_PGCTL_SLICE_ACK) == 0) 88 + /* skip disabled slice */ 89 + continue; 90 + 91 + sseu->slice_mask |= BIT(s); 92 + sseu_copy_subslices(&info->sseu, s, sseu->subslice_mask); 93 + 94 + for (ss = 0; ss < info->sseu.max_subslices; ss++) { 95 + unsigned int eu_cnt; 96 + 97 + if (info->sseu.has_subslice_pg && 98 + !(s_reg[s] & (GEN9_PGCTL_SS_ACK(ss)))) 99 + /* skip disabled subslice */ 100 + continue; 101 + 102 + eu_cnt = 2 * hweight32(eu_reg[2 * s + ss / 2] & 103 + eu_mask[ss % 2]); 104 + sseu->eu_total += eu_cnt; 105 + sseu->eu_per_subslice = max_t(unsigned int, 106 + sseu->eu_per_subslice, 107 + eu_cnt); 108 + } 109 + } 110 + #undef SS_MAX 111 + } 112 + 113 + static void gen9_sseu_device_status(struct intel_gt *gt, 114 + struct sseu_dev_info *sseu) 115 + { 116 + #define SS_MAX 3 117 + struct intel_uncore *uncore = gt->uncore; 118 + const struct intel_gt_info *info = &gt->info; 119 + u32 s_reg[SS_MAX], eu_reg[2 * SS_MAX], eu_mask[2]; 120 + int s, ss; 121 + 122 + for (s = 0; s < info->sseu.max_slices; s++) { 123 + s_reg[s] = intel_uncore_read(uncore, GEN9_SLICE_PGCTL_ACK(s)); 124 + eu_reg[2 * s] = 125 + intel_uncore_read(uncore, GEN9_SS01_EU_PGCTL_ACK(s)); 126 + eu_reg[2 * s + 1] = 127 + intel_uncore_read(uncore, GEN9_SS23_EU_PGCTL_ACK(s)); 128 + } 129 + 130 + eu_mask[0] = GEN9_PGCTL_SSA_EU08_ACK | 131 + GEN9_PGCTL_SSA_EU19_ACK | 132 + GEN9_PGCTL_SSA_EU210_ACK | 133 + GEN9_PGCTL_SSA_EU311_ACK; 134 + eu_mask[1] = GEN9_PGCTL_SSB_EU08_ACK | 135 + GEN9_PGCTL_SSB_EU19_ACK | 136 + GEN9_PGCTL_SSB_EU210_ACK | 137 + GEN9_PGCTL_SSB_EU311_ACK; 138 + 139 + for (s = 0; s < info->sseu.max_slices; s++) { 140 + if ((s_reg[s] & GEN9_PGCTL_SLICE_ACK) == 0) 141 + /* skip disabled slice */ 142 + continue; 143 + 144 + sseu->slice_mask |= BIT(s); 145 + 146 + if (IS_GEN9_BC(gt->i915)) 147 + sseu_copy_subslices(&info->sseu, s, 148 + sseu->subslice_mask); 149 + 150 + for (ss = 0; ss < info->sseu.max_subslices; ss++) { 151 + unsigned int eu_cnt; 152 + u8 ss_idx = s * info->sseu.ss_stride + 153 + ss / BITS_PER_BYTE; 154 + 155 + if (IS_GEN9_LP(gt->i915)) { 156 + if (!(s_reg[s] & (GEN9_PGCTL_SS_ACK(ss)))) 157 + /* skip disabled subslice */ 158 + continue; 159 + 160 + sseu->subslice_mask[ss_idx] |= 161 + BIT(ss % BITS_PER_BYTE); 162 + } 163 + 164 + eu_cnt = eu_reg[2 * s + ss / 2] & eu_mask[ss % 2]; 165 + eu_cnt = 2 * hweight32(eu_cnt); 166 + 167 + sseu->eu_total += eu_cnt; 168 + sseu->eu_per_subslice = max_t(unsigned int, 169 + sseu->eu_per_subslice, 170 + eu_cnt); 171 + } 172 + } 173 + #undef SS_MAX 174 + } 175 + 176 + static void bdw_sseu_device_status(struct intel_gt *gt, 177 + struct sseu_dev_info *sseu) 178 + { 179 + const struct intel_gt_info *info = &gt->info; 180 + u32 slice_info = intel_uncore_read(gt->uncore, GEN8_GT_SLICE_INFO); 181 + int s; 182 + 183 + sseu->slice_mask = slice_info & GEN8_LSLICESTAT_MASK; 184 + 185 + if (sseu->slice_mask) { 186 + sseu->eu_per_subslice = info->sseu.eu_per_subslice; 187 + for (s = 0; s < fls(sseu->slice_mask); s++) 188 + sseu_copy_subslices(&info->sseu, s, 189 + sseu->subslice_mask); 190 + sseu->eu_total = sseu->eu_per_subslice * 191 + intel_sseu_subslice_total(sseu); 192 + 193 + /* subtract fused off EU(s) from enabled slice(s) */ 194 + for (s = 0; s < fls(sseu->slice_mask); s++) { 195 + u8 subslice_7eu = info->sseu.subslice_7eu[s]; 196 + 197 + sseu->eu_total -= hweight8(subslice_7eu); 198 + } 199 + } 200 + } 201 + 202 + static void i915_print_sseu_info(struct seq_file *m, 203 + bool is_available_info, 204 + bool has_pooled_eu, 205 + const struct sseu_dev_info *sseu) 206 + { 207 + const char *type = is_available_info ? "Available" : "Enabled"; 208 + int s; 209 + 210 + seq_printf(m, " %s Slice Mask: %04x\n", type, 211 + sseu->slice_mask); 212 + seq_printf(m, " %s Slice Total: %u\n", type, 213 + hweight8(sseu->slice_mask)); 214 + seq_printf(m, " %s Subslice Total: %u\n", type, 215 + intel_sseu_subslice_total(sseu)); 216 + for (s = 0; s < fls(sseu->slice_mask); s++) { 217 + seq_printf(m, " %s Slice%i subslices: %u\n", type, 218 + s, intel_sseu_subslices_per_slice(sseu, s)); 219 + } 220 + seq_printf(m, " %s EU Total: %u\n", type, 221 + sseu->eu_total); 222 + seq_printf(m, " %s EU Per Subslice: %u\n", type, 223 + sseu->eu_per_subslice); 224 + 225 + if (!is_available_info) 226 + return; 227 + 228 + seq_printf(m, " Has Pooled EU: %s\n", yesno(has_pooled_eu)); 229 + if (has_pooled_eu) 230 + seq_printf(m, " Min EU in pool: %u\n", sseu->min_eu_in_pool); 231 + 232 + seq_printf(m, " Has Slice Power Gating: %s\n", 233 + yesno(sseu->has_slice_pg)); 234 + seq_printf(m, " Has Subslice Power Gating: %s\n", 235 + yesno(sseu->has_subslice_pg)); 236 + seq_printf(m, " Has EU Power Gating: %s\n", 237 + yesno(sseu->has_eu_pg)); 238 + } 239 + 240 + /* 241 + * this is called from top-level debugfs as well, so we can't get the gt from 242 + * the seq_file. 243 + */ 244 + int intel_sseu_status(struct seq_file *m, struct intel_gt *gt) 245 + { 246 + struct drm_i915_private *i915 = gt->i915; 247 + const struct intel_gt_info *info = &gt->info; 248 + struct sseu_dev_info sseu; 249 + intel_wakeref_t wakeref; 250 + 251 + if (INTEL_GEN(i915) < 8) 252 + return -ENODEV; 253 + 254 + seq_puts(m, "SSEU Device Info\n"); 255 + i915_print_sseu_info(m, true, HAS_POOLED_EU(i915), &info->sseu); 256 + 257 + seq_puts(m, "SSEU Device Status\n"); 258 + memset(&sseu, 0, sizeof(sseu)); 259 + intel_sseu_set_info(&sseu, info->sseu.max_slices, 260 + info->sseu.max_subslices, 261 + info->sseu.max_eus_per_subslice); 262 + 263 + with_intel_runtime_pm(&i915->runtime_pm, wakeref) { 264 + if (IS_CHERRYVIEW(i915)) 265 + cherryview_sseu_device_status(gt, &sseu); 266 + else if (IS_BROADWELL(i915)) 267 + bdw_sseu_device_status(gt, &sseu); 268 + else if (IS_GEN(i915, 9)) 269 + gen9_sseu_device_status(gt, &sseu); 270 + else if (INTEL_GEN(i915) >= 10) 271 + gen10_sseu_device_status(gt, &sseu); 272 + } 273 + 274 + i915_print_sseu_info(m, false, HAS_POOLED_EU(i915), &sseu); 275 + 276 + return 0; 277 + } 278 + 279 + static int sseu_status_show(struct seq_file *m, void *unused) 280 + { 281 + struct intel_gt *gt = m->private; 282 + 283 + return intel_sseu_status(m, gt); 284 + } 285 + DEFINE_GT_DEBUGFS_ATTRIBUTE(sseu_status); 286 + 287 + static int rcs_topology_show(struct seq_file *m, void *unused) 288 + { 289 + struct intel_gt *gt = m->private; 290 + struct drm_printer p = drm_seq_file_printer(m); 291 + 292 + intel_sseu_print_topology(&gt->info.sseu, &p); 293 + 294 + return 0; 295 + } 296 + DEFINE_GT_DEBUGFS_ATTRIBUTE(rcs_topology); 297 + 298 + void intel_sseu_debugfs_register(struct intel_gt *gt, struct dentry *root) 299 + { 300 + static const struct debugfs_gt_file files[] = { 301 + { "sseu_status", &sseu_status_fops, NULL }, 302 + { "rcs_topology", &rcs_topology_fops, NULL }, 303 + }; 304 + 305 + intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), gt); 306 + }
+17
drivers/gpu/drm/i915/gt/intel_sseu_debugfs.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + 3 + /* 4 + * Copyright © 2020 Intel Corporation 5 + */ 6 + 7 + #ifndef INTEL_SSEU_DEBUGFS_H 8 + #define INTEL_SSEU_DEBUGFS_H 9 + 10 + struct intel_gt; 11 + struct dentry; 12 + struct seq_file; 13 + 14 + int intel_sseu_status(struct seq_file *m, struct intel_gt *gt); 15 + void intel_sseu_debugfs_register(struct intel_gt *gt, struct dentry *root); 16 + 17 + #endif /* INTEL_SSEU_DEBUGFS_H */
+2 -267
drivers/gpu/drm/i915/i915_debugfs.c
··· 40 40 #include "gt/intel_reset.h" 41 41 #include "gt/intel_rc6.h" 42 42 #include "gt/intel_rps.h" 43 + #include "gt/intel_sseu_debugfs.h" 43 44 44 45 #include "i915_debugfs.h" 45 46 #include "i915_debugfs_params.h" ··· 1323 1322 return 0; 1324 1323 } 1325 1324 1326 - static int i915_rcs_topology(struct seq_file *m, void *unused) 1327 - { 1328 - struct drm_i915_private *dev_priv = node_to_i915(m->private); 1329 - struct drm_printer p = drm_seq_file_printer(m); 1330 - 1331 - intel_sseu_print_topology(&dev_priv->gt.info.sseu, &p); 1332 - 1333 - return 0; 1334 - } 1335 - 1336 1325 static int i915_shrinker_info(struct seq_file *m, void *unused) 1337 1326 { 1338 1327 struct drm_i915_private *i915 = node_to_i915(m->private); ··· 1573 1582 i915_cache_sharing_get, i915_cache_sharing_set, 1574 1583 "%llu\n"); 1575 1584 1576 - static void sseu_copy_subslices(const struct sseu_dev_info *sseu, 1577 - int slice, u8 *to_mask) 1578 - { 1579 - int offset = slice * sseu->ss_stride; 1580 - 1581 - memcpy(&to_mask[offset], &sseu->subslice_mask[offset], sseu->ss_stride); 1582 - } 1583 - 1584 - static void cherryview_sseu_device_status(struct intel_gt *gt, 1585 - struct sseu_dev_info *sseu) 1586 - { 1587 - #define SS_MAX 2 1588 - struct intel_uncore *uncore = gt->uncore; 1589 - const int ss_max = SS_MAX; 1590 - u32 sig1[SS_MAX], sig2[SS_MAX]; 1591 - int ss; 1592 - 1593 - sig1[0] = intel_uncore_read(uncore, CHV_POWER_SS0_SIG1); 1594 - sig1[1] = intel_uncore_read(uncore, CHV_POWER_SS1_SIG1); 1595 - sig2[0] = intel_uncore_read(uncore, CHV_POWER_SS0_SIG2); 1596 - sig2[1] = intel_uncore_read(uncore, CHV_POWER_SS1_SIG2); 1597 - 1598 - for (ss = 0; ss < ss_max; ss++) { 1599 - unsigned int eu_cnt; 1600 - 1601 - if (sig1[ss] & CHV_SS_PG_ENABLE) 1602 - /* skip disabled subslice */ 1603 - continue; 1604 - 1605 - sseu->slice_mask = BIT(0); 1606 - sseu->subslice_mask[0] |= BIT(ss); 1607 - eu_cnt = ((sig1[ss] & CHV_EU08_PG_ENABLE) ? 0 : 2) + 1608 - ((sig1[ss] & CHV_EU19_PG_ENABLE) ? 0 : 2) + 1609 - ((sig1[ss] & CHV_EU210_PG_ENABLE) ? 0 : 2) + 1610 - ((sig2[ss] & CHV_EU311_PG_ENABLE) ? 0 : 2); 1611 - sseu->eu_total += eu_cnt; 1612 - sseu->eu_per_subslice = max_t(unsigned int, 1613 - sseu->eu_per_subslice, eu_cnt); 1614 - } 1615 - #undef SS_MAX 1616 - } 1617 - 1618 - static void gen10_sseu_device_status(struct intel_gt *gt, 1619 - struct sseu_dev_info *sseu) 1620 - { 1621 - #define SS_MAX 6 1622 - struct intel_uncore *uncore = gt->uncore; 1623 - const struct intel_gt_info *info = &gt->info; 1624 - u32 s_reg[SS_MAX], eu_reg[2 * SS_MAX], eu_mask[2]; 1625 - int s, ss; 1626 - 1627 - for (s = 0; s < info->sseu.max_slices; s++) { 1628 - /* 1629 - * FIXME: Valid SS Mask respects the spec and read 1630 - * only valid bits for those registers, excluding reserved 1631 - * although this seems wrong because it would leave many 1632 - * subslices without ACK. 1633 - */ 1634 - s_reg[s] = intel_uncore_read(uncore, GEN10_SLICE_PGCTL_ACK(s)) & 1635 - GEN10_PGCTL_VALID_SS_MASK(s); 1636 - eu_reg[2 * s] = intel_uncore_read(uncore, 1637 - GEN10_SS01_EU_PGCTL_ACK(s)); 1638 - eu_reg[2 * s + 1] = intel_uncore_read(uncore, 1639 - GEN10_SS23_EU_PGCTL_ACK(s)); 1640 - } 1641 - 1642 - eu_mask[0] = GEN9_PGCTL_SSA_EU08_ACK | 1643 - GEN9_PGCTL_SSA_EU19_ACK | 1644 - GEN9_PGCTL_SSA_EU210_ACK | 1645 - GEN9_PGCTL_SSA_EU311_ACK; 1646 - eu_mask[1] = GEN9_PGCTL_SSB_EU08_ACK | 1647 - GEN9_PGCTL_SSB_EU19_ACK | 1648 - GEN9_PGCTL_SSB_EU210_ACK | 1649 - GEN9_PGCTL_SSB_EU311_ACK; 1650 - 1651 - for (s = 0; s < info->sseu.max_slices; s++) { 1652 - if ((s_reg[s] & GEN9_PGCTL_SLICE_ACK) == 0) 1653 - /* skip disabled slice */ 1654 - continue; 1655 - 1656 - sseu->slice_mask |= BIT(s); 1657 - sseu_copy_subslices(&info->sseu, s, sseu->subslice_mask); 1658 - 1659 - for (ss = 0; ss < info->sseu.max_subslices; ss++) { 1660 - unsigned int eu_cnt; 1661 - 1662 - if (info->sseu.has_subslice_pg && 1663 - !(s_reg[s] & (GEN9_PGCTL_SS_ACK(ss)))) 1664 - /* skip disabled subslice */ 1665 - continue; 1666 - 1667 - eu_cnt = 2 * hweight32(eu_reg[2 * s + ss / 2] & 1668 - eu_mask[ss % 2]); 1669 - sseu->eu_total += eu_cnt; 1670 - sseu->eu_per_subslice = max_t(unsigned int, 1671 - sseu->eu_per_subslice, 1672 - eu_cnt); 1673 - } 1674 - } 1675 - #undef SS_MAX 1676 - } 1677 - 1678 - static void gen9_sseu_device_status(struct intel_gt *gt, 1679 - struct sseu_dev_info *sseu) 1680 - { 1681 - #define SS_MAX 3 1682 - struct intel_uncore *uncore = gt->uncore; 1683 - const struct intel_gt_info *info = &gt->info; 1684 - u32 s_reg[SS_MAX], eu_reg[2 * SS_MAX], eu_mask[2]; 1685 - int s, ss; 1686 - 1687 - for (s = 0; s < info->sseu.max_slices; s++) { 1688 - s_reg[s] = intel_uncore_read(uncore, GEN9_SLICE_PGCTL_ACK(s)); 1689 - eu_reg[2 * s] = 1690 - intel_uncore_read(uncore, GEN9_SS01_EU_PGCTL_ACK(s)); 1691 - eu_reg[2 * s + 1] = 1692 - intel_uncore_read(uncore, GEN9_SS23_EU_PGCTL_ACK(s)); 1693 - } 1694 - 1695 - eu_mask[0] = GEN9_PGCTL_SSA_EU08_ACK | 1696 - GEN9_PGCTL_SSA_EU19_ACK | 1697 - GEN9_PGCTL_SSA_EU210_ACK | 1698 - GEN9_PGCTL_SSA_EU311_ACK; 1699 - eu_mask[1] = GEN9_PGCTL_SSB_EU08_ACK | 1700 - GEN9_PGCTL_SSB_EU19_ACK | 1701 - GEN9_PGCTL_SSB_EU210_ACK | 1702 - GEN9_PGCTL_SSB_EU311_ACK; 1703 - 1704 - for (s = 0; s < info->sseu.max_slices; s++) { 1705 - if ((s_reg[s] & GEN9_PGCTL_SLICE_ACK) == 0) 1706 - /* skip disabled slice */ 1707 - continue; 1708 - 1709 - sseu->slice_mask |= BIT(s); 1710 - 1711 - if (IS_GEN9_BC(gt->i915)) 1712 - sseu_copy_subslices(&info->sseu, s, 1713 - sseu->subslice_mask); 1714 - 1715 - for (ss = 0; ss < info->sseu.max_subslices; ss++) { 1716 - unsigned int eu_cnt; 1717 - u8 ss_idx = s * info->sseu.ss_stride + 1718 - ss / BITS_PER_BYTE; 1719 - 1720 - if (IS_GEN9_LP(gt->i915)) { 1721 - if (!(s_reg[s] & (GEN9_PGCTL_SS_ACK(ss)))) 1722 - /* skip disabled subslice */ 1723 - continue; 1724 - 1725 - sseu->subslice_mask[ss_idx] |= 1726 - BIT(ss % BITS_PER_BYTE); 1727 - } 1728 - 1729 - eu_cnt = 2 * hweight32(eu_reg[2*s + ss/2] & 1730 - eu_mask[ss%2]); 1731 - sseu->eu_total += eu_cnt; 1732 - sseu->eu_per_subslice = max_t(unsigned int, 1733 - sseu->eu_per_subslice, 1734 - eu_cnt); 1735 - } 1736 - } 1737 - #undef SS_MAX 1738 - } 1739 - 1740 - static void bdw_sseu_device_status(struct intel_gt *gt, 1741 - struct sseu_dev_info *sseu) 1742 - { 1743 - const struct intel_gt_info *info = &gt->info; 1744 - u32 slice_info = intel_uncore_read(gt->uncore, GEN8_GT_SLICE_INFO); 1745 - int s; 1746 - 1747 - sseu->slice_mask = slice_info & GEN8_LSLICESTAT_MASK; 1748 - 1749 - if (sseu->slice_mask) { 1750 - sseu->eu_per_subslice = info->sseu.eu_per_subslice; 1751 - for (s = 0; s < fls(sseu->slice_mask); s++) 1752 - sseu_copy_subslices(&info->sseu, s, 1753 - sseu->subslice_mask); 1754 - sseu->eu_total = sseu->eu_per_subslice * 1755 - intel_sseu_subslice_total(sseu); 1756 - 1757 - /* subtract fused off EU(s) from enabled slice(s) */ 1758 - for (s = 0; s < fls(sseu->slice_mask); s++) { 1759 - u8 subslice_7eu = info->sseu.subslice_7eu[s]; 1760 - 1761 - sseu->eu_total -= hweight8(subslice_7eu); 1762 - } 1763 - } 1764 - } 1765 - 1766 - static void i915_print_sseu_info(struct seq_file *m, bool is_available_info, 1767 - const struct sseu_dev_info *sseu) 1768 - { 1769 - struct drm_i915_private *dev_priv = node_to_i915(m->private); 1770 - const char *type = is_available_info ? "Available" : "Enabled"; 1771 - int s; 1772 - 1773 - seq_printf(m, " %s Slice Mask: %04x\n", type, 1774 - sseu->slice_mask); 1775 - seq_printf(m, " %s Slice Total: %u\n", type, 1776 - hweight8(sseu->slice_mask)); 1777 - seq_printf(m, " %s Subslice Total: %u\n", type, 1778 - intel_sseu_subslice_total(sseu)); 1779 - for (s = 0; s < fls(sseu->slice_mask); s++) { 1780 - seq_printf(m, " %s Slice%i subslices: %u\n", type, 1781 - s, intel_sseu_subslices_per_slice(sseu, s)); 1782 - } 1783 - seq_printf(m, " %s EU Total: %u\n", type, 1784 - sseu->eu_total); 1785 - seq_printf(m, " %s EU Per Subslice: %u\n", type, 1786 - sseu->eu_per_subslice); 1787 - 1788 - if (!is_available_info) 1789 - return; 1790 - 1791 - seq_printf(m, " Has Pooled EU: %s\n", yesno(HAS_POOLED_EU(dev_priv))); 1792 - if (HAS_POOLED_EU(dev_priv)) 1793 - seq_printf(m, " Min EU in pool: %u\n", sseu->min_eu_in_pool); 1794 - 1795 - seq_printf(m, " Has Slice Power Gating: %s\n", 1796 - yesno(sseu->has_slice_pg)); 1797 - seq_printf(m, " Has Subslice Power Gating: %s\n", 1798 - yesno(sseu->has_subslice_pg)); 1799 - seq_printf(m, " Has EU Power Gating: %s\n", 1800 - yesno(sseu->has_eu_pg)); 1801 - } 1802 - 1803 1585 static int i915_sseu_status(struct seq_file *m, void *unused) 1804 1586 { 1805 1587 struct drm_i915_private *i915 = node_to_i915(m->private); 1806 1588 struct intel_gt *gt = &i915->gt; 1807 - const struct intel_gt_info *info = &gt->info; 1808 - struct sseu_dev_info sseu; 1809 - intel_wakeref_t wakeref; 1810 1589 1811 - if (INTEL_GEN(i915) < 8) 1812 - return -ENODEV; 1813 - 1814 - seq_puts(m, "SSEU Device Info\n"); 1815 - i915_print_sseu_info(m, true, &info->sseu); 1816 - 1817 - seq_puts(m, "SSEU Device Status\n"); 1818 - memset(&sseu, 0, sizeof(sseu)); 1819 - intel_sseu_set_info(&sseu, info->sseu.max_slices, 1820 - info->sseu.max_subslices, 1821 - info->sseu.max_eus_per_subslice); 1822 - 1823 - with_intel_runtime_pm(&i915->runtime_pm, wakeref) { 1824 - if (IS_CHERRYVIEW(i915)) 1825 - cherryview_sseu_device_status(gt, &sseu); 1826 - else if (IS_BROADWELL(i915)) 1827 - bdw_sseu_device_status(gt, &sseu); 1828 - else if (IS_GEN(i915, 9)) 1829 - gen9_sseu_device_status(gt, &sseu); 1830 - else if (INTEL_GEN(i915) >= 10) 1831 - gen10_sseu_device_status(gt, &sseu); 1832 - } 1833 - 1834 - i915_print_sseu_info(m, false, &sseu); 1835 - 1836 - return 0; 1590 + return intel_sseu_status(m, gt); 1837 1591 } 1838 1592 1839 1593 static int i915_forcewake_open(struct inode *inode, struct file *file) ··· 1625 1889 {"i915_llc", i915_llc, 0}, 1626 1890 {"i915_runtime_pm_status", i915_runtime_pm_status, 0}, 1627 1891 {"i915_engine_info", i915_engine_info, 0}, 1628 - {"i915_rcs_topology", i915_rcs_topology, 0}, 1629 1892 {"i915_shrinker_info", i915_shrinker_info, 0}, 1630 1893 {"i915_wa_registers", i915_wa_registers, 0}, 1631 1894 {"i915_sseu_status", i915_sseu_status, 0},