at v6.7 294 lines 7.5 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2020-2023 Intel Corporation 4 */ 5 6#include <drm/drm_debugfs.h> 7#include <drm/drm_file.h> 8#include <drm/drm_print.h> 9 10#include <uapi/drm/ivpu_accel.h> 11 12#include "ivpu_debugfs.h" 13#include "ivpu_drv.h" 14#include "ivpu_fw.h" 15#include "ivpu_fw_log.h" 16#include "ivpu_gem.h" 17#include "ivpu_jsm_msg.h" 18#include "ivpu_pm.h" 19 20static inline struct ivpu_device *seq_to_ivpu(struct seq_file *s) 21{ 22 struct drm_debugfs_entry *entry = s->private; 23 24 return to_ivpu_device(entry->dev); 25} 26 27static int bo_list_show(struct seq_file *s, void *v) 28{ 29 struct drm_printer p = drm_seq_file_printer(s); 30 struct ivpu_device *vdev = seq_to_ivpu(s); 31 32 ivpu_bo_list(&vdev->drm, &p); 33 34 return 0; 35} 36 37static int fw_name_show(struct seq_file *s, void *v) 38{ 39 struct ivpu_device *vdev = seq_to_ivpu(s); 40 41 seq_printf(s, "%s\n", vdev->fw->name); 42 return 0; 43} 44 45static int fw_trace_capability_show(struct seq_file *s, void *v) 46{ 47 struct ivpu_device *vdev = seq_to_ivpu(s); 48 u64 trace_hw_component_mask; 49 u32 trace_destination_mask; 50 int ret; 51 52 ret = ivpu_jsm_trace_get_capability(vdev, &trace_destination_mask, 53 &trace_hw_component_mask); 54 if (!ret) { 55 seq_printf(s, 56 "trace_destination_mask: %#18x\n" 57 "trace_hw_component_mask: %#18llx\n", 58 trace_destination_mask, trace_hw_component_mask); 59 } 60 return 0; 61} 62 63static int fw_trace_config_show(struct seq_file *s, void *v) 64{ 65 struct ivpu_device *vdev = seq_to_ivpu(s); 66 /** 67 * WA: VPU_JSM_MSG_TRACE_GET_CONFIG command is not working yet, 68 * so we use values from vdev->fw instead of calling ivpu_jsm_trace_get_config() 69 */ 70 u32 trace_level = vdev->fw->trace_level; 71 u32 trace_destination_mask = vdev->fw->trace_destination_mask; 72 u64 trace_hw_component_mask = vdev->fw->trace_hw_component_mask; 73 74 seq_printf(s, 75 "trace_level: %#18x\n" 76 "trace_destination_mask: %#18x\n" 77 "trace_hw_component_mask: %#18llx\n", 78 trace_level, trace_destination_mask, trace_hw_component_mask); 79 80 return 0; 81} 82 83static int last_bootmode_show(struct seq_file *s, void *v) 84{ 85 struct ivpu_device *vdev = seq_to_ivpu(s); 86 87 seq_printf(s, "%s\n", (vdev->pm->is_warmboot) ? "warmboot" : "coldboot"); 88 89 return 0; 90} 91 92static int reset_counter_show(struct seq_file *s, void *v) 93{ 94 struct ivpu_device *vdev = seq_to_ivpu(s); 95 96 seq_printf(s, "%d\n", atomic_read(&vdev->pm->reset_counter)); 97 return 0; 98} 99 100static int reset_pending_show(struct seq_file *s, void *v) 101{ 102 struct ivpu_device *vdev = seq_to_ivpu(s); 103 104 seq_printf(s, "%d\n", atomic_read(&vdev->pm->in_reset)); 105 return 0; 106} 107 108static const struct drm_debugfs_info vdev_debugfs_list[] = { 109 {"bo_list", bo_list_show, 0}, 110 {"fw_name", fw_name_show, 0}, 111 {"fw_trace_capability", fw_trace_capability_show, 0}, 112 {"fw_trace_config", fw_trace_config_show, 0}, 113 {"last_bootmode", last_bootmode_show, 0}, 114 {"reset_counter", reset_counter_show, 0}, 115 {"reset_pending", reset_pending_show, 0}, 116}; 117 118static int fw_log_show(struct seq_file *s, void *v) 119{ 120 struct ivpu_device *vdev = s->private; 121 struct drm_printer p = drm_seq_file_printer(s); 122 123 ivpu_fw_log_print(vdev, true, &p); 124 return 0; 125} 126 127static int fw_log_fops_open(struct inode *inode, struct file *file) 128{ 129 return single_open(file, fw_log_show, inode->i_private); 130} 131 132static ssize_t 133fw_log_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) 134{ 135 struct seq_file *s = file->private_data; 136 struct ivpu_device *vdev = s->private; 137 138 if (!size) 139 return -EINVAL; 140 141 ivpu_fw_log_clear(vdev); 142 return size; 143} 144 145static const struct file_operations fw_log_fops = { 146 .owner = THIS_MODULE, 147 .open = fw_log_fops_open, 148 .write = fw_log_fops_write, 149 .read = seq_read, 150 .llseek = seq_lseek, 151 .release = single_release, 152}; 153 154static ssize_t 155fw_trace_destination_mask_fops_write(struct file *file, const char __user *user_buf, 156 size_t size, loff_t *pos) 157{ 158 struct ivpu_device *vdev = file->private_data; 159 struct ivpu_fw_info *fw = vdev->fw; 160 u32 trace_destination_mask; 161 int ret; 162 163 ret = kstrtou32_from_user(user_buf, size, 0, &trace_destination_mask); 164 if (ret < 0) 165 return ret; 166 167 fw->trace_destination_mask = trace_destination_mask; 168 169 ivpu_jsm_trace_set_config(vdev, fw->trace_level, trace_destination_mask, 170 fw->trace_hw_component_mask); 171 172 return size; 173} 174 175static const struct file_operations fw_trace_destination_mask_fops = { 176 .owner = THIS_MODULE, 177 .open = simple_open, 178 .write = fw_trace_destination_mask_fops_write, 179}; 180 181static ssize_t 182fw_trace_hw_comp_mask_fops_write(struct file *file, const char __user *user_buf, 183 size_t size, loff_t *pos) 184{ 185 struct ivpu_device *vdev = file->private_data; 186 struct ivpu_fw_info *fw = vdev->fw; 187 u64 trace_hw_component_mask; 188 int ret; 189 190 ret = kstrtou64_from_user(user_buf, size, 0, &trace_hw_component_mask); 191 if (ret < 0) 192 return ret; 193 194 fw->trace_hw_component_mask = trace_hw_component_mask; 195 196 ivpu_jsm_trace_set_config(vdev, fw->trace_level, fw->trace_destination_mask, 197 trace_hw_component_mask); 198 199 return size; 200} 201 202static const struct file_operations fw_trace_hw_comp_mask_fops = { 203 .owner = THIS_MODULE, 204 .open = simple_open, 205 .write = fw_trace_hw_comp_mask_fops_write, 206}; 207 208static ssize_t 209fw_trace_level_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) 210{ 211 struct ivpu_device *vdev = file->private_data; 212 struct ivpu_fw_info *fw = vdev->fw; 213 u32 trace_level; 214 int ret; 215 216 ret = kstrtou32_from_user(user_buf, size, 0, &trace_level); 217 if (ret < 0) 218 return ret; 219 220 fw->trace_level = trace_level; 221 222 ivpu_jsm_trace_set_config(vdev, trace_level, fw->trace_destination_mask, 223 fw->trace_hw_component_mask); 224 225 return size; 226} 227 228static const struct file_operations fw_trace_level_fops = { 229 .owner = THIS_MODULE, 230 .open = simple_open, 231 .write = fw_trace_level_fops_write, 232}; 233 234static ssize_t 235ivpu_reset_engine_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) 236{ 237 struct ivpu_device *vdev = file->private_data; 238 239 if (!size) 240 return -EINVAL; 241 242 if (ivpu_jsm_reset_engine(vdev, DRM_IVPU_ENGINE_COMPUTE)) 243 return -ENODEV; 244 if (ivpu_jsm_reset_engine(vdev, DRM_IVPU_ENGINE_COPY)) 245 return -ENODEV; 246 247 return size; 248} 249 250static ssize_t 251ivpu_force_recovery_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) 252{ 253 struct ivpu_device *vdev = file->private_data; 254 255 if (!size) 256 return -EINVAL; 257 258 ivpu_pm_schedule_recovery(vdev); 259 return size; 260} 261 262static const struct file_operations ivpu_force_recovery_fops = { 263 .owner = THIS_MODULE, 264 .open = simple_open, 265 .write = ivpu_force_recovery_fn, 266}; 267 268static const struct file_operations ivpu_reset_engine_fops = { 269 .owner = THIS_MODULE, 270 .open = simple_open, 271 .write = ivpu_reset_engine_fn, 272}; 273 274void ivpu_debugfs_init(struct ivpu_device *vdev) 275{ 276 struct dentry *debugfs_root = vdev->drm.debugfs_root; 277 278 drm_debugfs_add_files(&vdev->drm, vdev_debugfs_list, ARRAY_SIZE(vdev_debugfs_list)); 279 280 debugfs_create_file("force_recovery", 0200, debugfs_root, vdev, 281 &ivpu_force_recovery_fops); 282 283 debugfs_create_file("fw_log", 0644, debugfs_root, vdev, 284 &fw_log_fops); 285 debugfs_create_file("fw_trace_destination_mask", 0200, debugfs_root, vdev, 286 &fw_trace_destination_mask_fops); 287 debugfs_create_file("fw_trace_hw_comp_mask", 0200, debugfs_root, vdev, 288 &fw_trace_hw_comp_mask_fops); 289 debugfs_create_file("fw_trace_level", 0200, debugfs_root, vdev, 290 &fw_trace_level_fops); 291 292 debugfs_create_file("reset_engine", 0200, debugfs_root, vdev, 293 &ivpu_reset_engine_fops); 294}