15489e7d4SMichal Wajdeczko // SPDX-License-Identifier: MIT 25489e7d4SMichal Wajdeczko /* 35489e7d4SMichal Wajdeczko * Copyright © 2025 Intel Corporation 45489e7d4SMichal Wajdeczko */ 55489e7d4SMichal Wajdeczko 65489e7d4SMichal Wajdeczko #include <linux/debugfs.h> 75489e7d4SMichal Wajdeczko #include <drm/drm_debugfs.h> 85489e7d4SMichal Wajdeczko 99a719bbfSMichal Wajdeczko #include "xe_device.h" 105489e7d4SMichal Wajdeczko #include "xe_device_types.h" 11486d7f1bSMichal Wajdeczko #include "xe_gt_sriov_pf_config.h" 129a719bbfSMichal Wajdeczko #include "xe_gt_sriov_pf_debugfs.h" 13486d7f1bSMichal Wajdeczko #include "xe_pm.h" 14486d7f1bSMichal Wajdeczko #include "xe_tile_debugfs.h" 155489e7d4SMichal Wajdeczko #include "xe_tile_sriov_pf_debugfs.h" 165489e7d4SMichal Wajdeczko #include "xe_sriov.h" 17486d7f1bSMichal Wajdeczko #include "xe_sriov_pf.h" 18*b1767ca1SMichal Wajdeczko #include "xe_sriov_pf_provision.h" 195489e7d4SMichal Wajdeczko 205489e7d4SMichal Wajdeczko /* 215489e7d4SMichal Wajdeczko * /sys/kernel/debug/dri/BDF/ 225489e7d4SMichal Wajdeczko * ├── sriov # d_inode->i_private = (xe_device*) 235489e7d4SMichal Wajdeczko * │ ├── pf # d_inode->i_private = (xe_device*) 245489e7d4SMichal Wajdeczko * │ │ ├── tile0 # d_inode->i_private = (xe_tile*) 255489e7d4SMichal Wajdeczko * │ │ ├── tile1 265489e7d4SMichal Wajdeczko * │ │ : : 275489e7d4SMichal Wajdeczko * │ ├── vf1 # d_inode->i_private = VFID(1) 285489e7d4SMichal Wajdeczko * │ │ ├── tile0 # d_inode->i_private = (xe_tile*) 295489e7d4SMichal Wajdeczko * │ │ ├── tile1 305489e7d4SMichal Wajdeczko * │ │ : : 315489e7d4SMichal Wajdeczko * │ ├── vfN # d_inode->i_private = VFID(N) 325489e7d4SMichal Wajdeczko * │ │ ├── tile0 # d_inode->i_private = (xe_tile*) 335489e7d4SMichal Wajdeczko * │ │ ├── tile1 345489e7d4SMichal Wajdeczko * : : : : 355489e7d4SMichal Wajdeczko */ 365489e7d4SMichal Wajdeczko 375489e7d4SMichal Wajdeczko static void *extract_priv(struct dentry *d) 385489e7d4SMichal Wajdeczko { 395489e7d4SMichal Wajdeczko return d->d_inode->i_private; 405489e7d4SMichal Wajdeczko } 415489e7d4SMichal Wajdeczko 425489e7d4SMichal Wajdeczko __maybe_unused 435489e7d4SMichal Wajdeczko static struct xe_tile *extract_tile(struct dentry *d) 445489e7d4SMichal Wajdeczko { 455489e7d4SMichal Wajdeczko return extract_priv(d); 465489e7d4SMichal Wajdeczko } 475489e7d4SMichal Wajdeczko 485489e7d4SMichal Wajdeczko static struct xe_device *extract_xe(struct dentry *d) 495489e7d4SMichal Wajdeczko { 505489e7d4SMichal Wajdeczko return extract_priv(d->d_parent->d_parent); 515489e7d4SMichal Wajdeczko } 525489e7d4SMichal Wajdeczko 535489e7d4SMichal Wajdeczko __maybe_unused 545489e7d4SMichal Wajdeczko static unsigned int extract_vfid(struct dentry *d) 555489e7d4SMichal Wajdeczko { 565489e7d4SMichal Wajdeczko void *pp = extract_priv(d->d_parent); 575489e7d4SMichal Wajdeczko 585489e7d4SMichal Wajdeczko return pp == extract_xe(d) ? PFID : (uintptr_t)pp; 595489e7d4SMichal Wajdeczko } 605489e7d4SMichal Wajdeczko 61486d7f1bSMichal Wajdeczko /* 62486d7f1bSMichal Wajdeczko * /sys/kernel/debug/dri/BDF/ 63486d7f1bSMichal Wajdeczko * ├── sriov 64486d7f1bSMichal Wajdeczko * : ├── pf 65486d7f1bSMichal Wajdeczko * : ├── tile0 66486d7f1bSMichal Wajdeczko * : ├── ggtt_available 67486d7f1bSMichal Wajdeczko * ├── ggtt_provisioned 68486d7f1bSMichal Wajdeczko */ 69486d7f1bSMichal Wajdeczko 70486d7f1bSMichal Wajdeczko static int pf_config_print_available_ggtt(struct xe_tile *tile, struct drm_printer *p) 71486d7f1bSMichal Wajdeczko { 72486d7f1bSMichal Wajdeczko return xe_gt_sriov_pf_config_print_available_ggtt(tile->primary_gt, p); 73486d7f1bSMichal Wajdeczko } 74486d7f1bSMichal Wajdeczko 75486d7f1bSMichal Wajdeczko static int pf_config_print_ggtt(struct xe_tile *tile, struct drm_printer *p) 76486d7f1bSMichal Wajdeczko { 77486d7f1bSMichal Wajdeczko return xe_gt_sriov_pf_config_print_ggtt(tile->primary_gt, p); 78486d7f1bSMichal Wajdeczko } 79486d7f1bSMichal Wajdeczko 80486d7f1bSMichal Wajdeczko static const struct drm_info_list pf_ggtt_info[] = { 81486d7f1bSMichal Wajdeczko { 82486d7f1bSMichal Wajdeczko "ggtt_available", 83486d7f1bSMichal Wajdeczko .show = xe_tile_debugfs_simple_show, 84486d7f1bSMichal Wajdeczko .data = pf_config_print_available_ggtt, 85486d7f1bSMichal Wajdeczko }, 86486d7f1bSMichal Wajdeczko { 87486d7f1bSMichal Wajdeczko "ggtt_provisioned", 88486d7f1bSMichal Wajdeczko .show = xe_tile_debugfs_simple_show, 89486d7f1bSMichal Wajdeczko .data = pf_config_print_ggtt, 90486d7f1bSMichal Wajdeczko }, 91486d7f1bSMichal Wajdeczko }; 92486d7f1bSMichal Wajdeczko 93486d7f1bSMichal Wajdeczko /* 94486d7f1bSMichal Wajdeczko * /sys/kernel/debug/dri/BDF/ 95486d7f1bSMichal Wajdeczko * ├── sriov 96486d7f1bSMichal Wajdeczko * : ├── pf 97486d7f1bSMichal Wajdeczko * : ├── tile0 98486d7f1bSMichal Wajdeczko * : ├── vram_provisioned 99486d7f1bSMichal Wajdeczko */ 100486d7f1bSMichal Wajdeczko 101486d7f1bSMichal Wajdeczko static int pf_config_print_vram(struct xe_tile *tile, struct drm_printer *p) 102486d7f1bSMichal Wajdeczko { 103486d7f1bSMichal Wajdeczko return xe_gt_sriov_pf_config_print_lmem(tile->primary_gt, p); 104486d7f1bSMichal Wajdeczko } 105486d7f1bSMichal Wajdeczko 106486d7f1bSMichal Wajdeczko static const struct drm_info_list pf_vram_info[] = { 107486d7f1bSMichal Wajdeczko { 108486d7f1bSMichal Wajdeczko "vram_provisioned", 109486d7f1bSMichal Wajdeczko .show = xe_tile_debugfs_simple_show, 110486d7f1bSMichal Wajdeczko .data = pf_config_print_vram, 111486d7f1bSMichal Wajdeczko }, 112486d7f1bSMichal Wajdeczko }; 113486d7f1bSMichal Wajdeczko 114486d7f1bSMichal Wajdeczko /* 115486d7f1bSMichal Wajdeczko * /sys/kernel/debug/dri/BDF/ 116486d7f1bSMichal Wajdeczko * ├── sriov 117486d7f1bSMichal Wajdeczko * │ ├── pf 118486d7f1bSMichal Wajdeczko * │ │ ├── tile0 119486d7f1bSMichal Wajdeczko * │ │ │ ├── ggtt_spare 120486d7f1bSMichal Wajdeczko * │ │ │ ├── vram_spare 121486d7f1bSMichal Wajdeczko * │ │ ├── tile1 122486d7f1bSMichal Wajdeczko * │ │ : : 123486d7f1bSMichal Wajdeczko * │ ├── vf1 124486d7f1bSMichal Wajdeczko * │ : ├── tile0 125486d7f1bSMichal Wajdeczko * │ │ ├── ggtt_quota 126486d7f1bSMichal Wajdeczko * │ │ ├── vram_quota 127486d7f1bSMichal Wajdeczko * │ ├── tile1 128486d7f1bSMichal Wajdeczko * │ : : 129486d7f1bSMichal Wajdeczko */ 130486d7f1bSMichal Wajdeczko 131486d7f1bSMichal Wajdeczko #define DEFINE_SRIOV_TILE_CONFIG_DEBUGFS_ATTRIBUTE(NAME, CONFIG, TYPE, FORMAT) \ 132486d7f1bSMichal Wajdeczko \ 133486d7f1bSMichal Wajdeczko static int NAME##_set(void *data, u64 val) \ 134486d7f1bSMichal Wajdeczko { \ 135486d7f1bSMichal Wajdeczko struct xe_tile *tile = extract_tile(data); \ 136486d7f1bSMichal Wajdeczko unsigned int vfid = extract_vfid(data); \ 137486d7f1bSMichal Wajdeczko struct xe_gt *gt = tile->primary_gt; \ 138486d7f1bSMichal Wajdeczko struct xe_device *xe = tile->xe; \ 139486d7f1bSMichal Wajdeczko int err; \ 140486d7f1bSMichal Wajdeczko \ 141486d7f1bSMichal Wajdeczko if (val > (TYPE)~0ull) \ 142486d7f1bSMichal Wajdeczko return -EOVERFLOW; \ 143486d7f1bSMichal Wajdeczko \ 144486d7f1bSMichal Wajdeczko xe_pm_runtime_get(xe); \ 145486d7f1bSMichal Wajdeczko err = xe_sriov_pf_wait_ready(xe) ?: \ 146486d7f1bSMichal Wajdeczko xe_gt_sriov_pf_config_set_##CONFIG(gt, vfid, val); \ 147*b1767ca1SMichal Wajdeczko if (!err) \ 148*b1767ca1SMichal Wajdeczko xe_sriov_pf_provision_set_custom_mode(xe); \ 149486d7f1bSMichal Wajdeczko xe_pm_runtime_put(xe); \ 150486d7f1bSMichal Wajdeczko \ 151486d7f1bSMichal Wajdeczko return err; \ 152486d7f1bSMichal Wajdeczko } \ 153486d7f1bSMichal Wajdeczko \ 154486d7f1bSMichal Wajdeczko static int NAME##_get(void *data, u64 *val) \ 155486d7f1bSMichal Wajdeczko { \ 156486d7f1bSMichal Wajdeczko struct xe_tile *tile = extract_tile(data); \ 157486d7f1bSMichal Wajdeczko unsigned int vfid = extract_vfid(data); \ 158486d7f1bSMichal Wajdeczko struct xe_gt *gt = tile->primary_gt; \ 159486d7f1bSMichal Wajdeczko \ 160486d7f1bSMichal Wajdeczko *val = xe_gt_sriov_pf_config_get_##CONFIG(gt, vfid); \ 161486d7f1bSMichal Wajdeczko return 0; \ 162486d7f1bSMichal Wajdeczko } \ 163486d7f1bSMichal Wajdeczko \ 164486d7f1bSMichal Wajdeczko DEFINE_DEBUGFS_ATTRIBUTE(NAME##_fops, NAME##_get, NAME##_set, FORMAT) 165486d7f1bSMichal Wajdeczko 166486d7f1bSMichal Wajdeczko DEFINE_SRIOV_TILE_CONFIG_DEBUGFS_ATTRIBUTE(ggtt, ggtt, u64, "%llu\n"); 167486d7f1bSMichal Wajdeczko DEFINE_SRIOV_TILE_CONFIG_DEBUGFS_ATTRIBUTE(vram, lmem, u64, "%llu\n"); 168486d7f1bSMichal Wajdeczko 169486d7f1bSMichal Wajdeczko static void pf_add_config_attrs(struct xe_tile *tile, struct dentry *dent, unsigned int vfid) 170486d7f1bSMichal Wajdeczko { 17137c8c8d9SLukasz Laguna struct xe_device *xe = tile->xe; 17237c8c8d9SLukasz Laguna 173486d7f1bSMichal Wajdeczko xe_tile_assert(tile, tile == extract_tile(dent)); 174486d7f1bSMichal Wajdeczko xe_tile_assert(tile, vfid == extract_vfid(dent)); 175486d7f1bSMichal Wajdeczko 176486d7f1bSMichal Wajdeczko debugfs_create_file_unsafe(vfid ? "ggtt_quota" : "ggtt_spare", 177486d7f1bSMichal Wajdeczko 0644, dent, dent, &ggtt_fops); 17837c8c8d9SLukasz Laguna if (IS_DGFX(xe)) 179486d7f1bSMichal Wajdeczko debugfs_create_file_unsafe(vfid ? "vram_quota" : "vram_spare", 18037c8c8d9SLukasz Laguna xe_device_has_lmtt(xe) ? 0644 : 0444, 18137c8c8d9SLukasz Laguna dent, dent, &vram_fops); 182486d7f1bSMichal Wajdeczko } 183486d7f1bSMichal Wajdeczko 1849a719bbfSMichal Wajdeczko static void pf_populate_tile(struct xe_tile *tile, struct dentry *dent, unsigned int vfid) 1859a719bbfSMichal Wajdeczko { 186486d7f1bSMichal Wajdeczko struct xe_device *xe = tile->xe; 187486d7f1bSMichal Wajdeczko struct drm_minor *minor = xe->drm.primary; 1889a719bbfSMichal Wajdeczko struct xe_gt *gt; 1899a719bbfSMichal Wajdeczko unsigned int id; 1909a719bbfSMichal Wajdeczko 191486d7f1bSMichal Wajdeczko pf_add_config_attrs(tile, dent, vfid); 192486d7f1bSMichal Wajdeczko 193486d7f1bSMichal Wajdeczko if (!vfid) { 194486d7f1bSMichal Wajdeczko drm_debugfs_create_files(pf_ggtt_info, 195486d7f1bSMichal Wajdeczko ARRAY_SIZE(pf_ggtt_info), 196486d7f1bSMichal Wajdeczko dent, minor); 19737c8c8d9SLukasz Laguna if (IS_DGFX(xe)) 198486d7f1bSMichal Wajdeczko drm_debugfs_create_files(pf_vram_info, 199486d7f1bSMichal Wajdeczko ARRAY_SIZE(pf_vram_info), 200486d7f1bSMichal Wajdeczko dent, minor); 201486d7f1bSMichal Wajdeczko } 202486d7f1bSMichal Wajdeczko 2039a719bbfSMichal Wajdeczko for_each_gt_on_tile(gt, tile, id) 2049a719bbfSMichal Wajdeczko xe_gt_sriov_pf_debugfs_populate(gt, dent, vfid); 2059a719bbfSMichal Wajdeczko } 2069a719bbfSMichal Wajdeczko 2075489e7d4SMichal Wajdeczko /** 2085489e7d4SMichal Wajdeczko * xe_tile_sriov_pf_debugfs_populate() - Populate SR-IOV debugfs tree with tile files. 2095489e7d4SMichal Wajdeczko * @tile: the &xe_tile to register 2105489e7d4SMichal Wajdeczko * @parent: the parent &dentry that represents the SR-IOV @vfid function 2115489e7d4SMichal Wajdeczko * @vfid: the VF identifier 2125489e7d4SMichal Wajdeczko * 2135489e7d4SMichal Wajdeczko * Add to the @parent directory new debugfs directory that will represent a @tile and 2145489e7d4SMichal Wajdeczko * populate it with files that are related to the SR-IOV @vfid function. 2155489e7d4SMichal Wajdeczko * 2165489e7d4SMichal Wajdeczko * This function can only be called on PF. 2175489e7d4SMichal Wajdeczko */ 2185489e7d4SMichal Wajdeczko void xe_tile_sriov_pf_debugfs_populate(struct xe_tile *tile, struct dentry *parent, 2195489e7d4SMichal Wajdeczko unsigned int vfid) 2205489e7d4SMichal Wajdeczko { 2215489e7d4SMichal Wajdeczko struct xe_device *xe = tile->xe; 2225489e7d4SMichal Wajdeczko struct dentry *dent; 2235489e7d4SMichal Wajdeczko char name[10]; /* should be enough up to "tile%u\0" for 2^16 - 1 */ 2245489e7d4SMichal Wajdeczko 2255489e7d4SMichal Wajdeczko xe_tile_assert(tile, IS_SRIOV_PF(xe)); 2265489e7d4SMichal Wajdeczko xe_tile_assert(tile, extract_priv(parent->d_parent) == xe); 2275489e7d4SMichal Wajdeczko xe_tile_assert(tile, extract_priv(parent) == tile->xe || 2285489e7d4SMichal Wajdeczko (uintptr_t)extract_priv(parent) == vfid); 2295489e7d4SMichal Wajdeczko 2305489e7d4SMichal Wajdeczko /* 2315489e7d4SMichal Wajdeczko * /sys/kernel/debug/dri/BDF/ 2325489e7d4SMichal Wajdeczko * ├── sriov 2335489e7d4SMichal Wajdeczko * │ ├── pf # parent, d_inode->i_private = (xe_device*) 2345489e7d4SMichal Wajdeczko * │ │ ├── tile0 # d_inode->i_private = (xe_tile*) 2355489e7d4SMichal Wajdeczko * │ │ ├── tile1 2365489e7d4SMichal Wajdeczko * │ │ : : 2375489e7d4SMichal Wajdeczko * │ ├── vf1 # parent, d_inode->i_private = VFID(1) 2385489e7d4SMichal Wajdeczko * │ │ ├── tile0 # d_inode->i_private = (xe_tile*) 2395489e7d4SMichal Wajdeczko * │ │ ├── tile1 2405489e7d4SMichal Wajdeczko * : : : : 2415489e7d4SMichal Wajdeczko */ 2425489e7d4SMichal Wajdeczko snprintf(name, sizeof(name), "tile%u", tile->id); 2435489e7d4SMichal Wajdeczko dent = debugfs_create_dir(name, parent); 2445489e7d4SMichal Wajdeczko if (IS_ERR(dent)) 2455489e7d4SMichal Wajdeczko return; 2465489e7d4SMichal Wajdeczko dent->d_inode->i_private = tile; 2475489e7d4SMichal Wajdeczko 2485489e7d4SMichal Wajdeczko xe_tile_assert(tile, extract_tile(dent) == tile); 2495489e7d4SMichal Wajdeczko xe_tile_assert(tile, extract_vfid(dent) == vfid); 2505489e7d4SMichal Wajdeczko xe_tile_assert(tile, extract_xe(dent) == xe); 2519a719bbfSMichal Wajdeczko 2529a719bbfSMichal Wajdeczko pf_populate_tile(tile, dent, vfid); 2535489e7d4SMichal Wajdeczko } 254