162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2020-2023 Intel Corporation 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <drm/drm_debugfs.h> 762306a36Sopenharmony_ci#include <drm/drm_file.h> 862306a36Sopenharmony_ci#include <drm/drm_print.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <uapi/drm/ivpu_accel.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include "ivpu_debugfs.h" 1362306a36Sopenharmony_ci#include "ivpu_drv.h" 1462306a36Sopenharmony_ci#include "ivpu_fw.h" 1562306a36Sopenharmony_ci#include "ivpu_fw_log.h" 1662306a36Sopenharmony_ci#include "ivpu_gem.h" 1762306a36Sopenharmony_ci#include "ivpu_jsm_msg.h" 1862306a36Sopenharmony_ci#include "ivpu_pm.h" 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistatic int bo_list_show(struct seq_file *s, void *v) 2162306a36Sopenharmony_ci{ 2262306a36Sopenharmony_ci struct drm_info_node *node = (struct drm_info_node *)s->private; 2362306a36Sopenharmony_ci struct drm_printer p = drm_seq_file_printer(s); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci ivpu_bo_list(node->minor->dev, &p); 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci return 0; 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistatic int fw_name_show(struct seq_file *s, void *v) 3162306a36Sopenharmony_ci{ 3262306a36Sopenharmony_ci struct drm_info_node *node = (struct drm_info_node *)s->private; 3362306a36Sopenharmony_ci struct ivpu_device *vdev = to_ivpu_device(node->minor->dev); 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci seq_printf(s, "%s\n", vdev->fw->name); 3662306a36Sopenharmony_ci return 0; 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic int fw_trace_capability_show(struct seq_file *s, void *v) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci struct drm_info_node *node = (struct drm_info_node *)s->private; 4262306a36Sopenharmony_ci struct ivpu_device *vdev = to_ivpu_device(node->minor->dev); 4362306a36Sopenharmony_ci u64 trace_hw_component_mask; 4462306a36Sopenharmony_ci u32 trace_destination_mask; 4562306a36Sopenharmony_ci int ret; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci ret = ivpu_jsm_trace_get_capability(vdev, &trace_destination_mask, 4862306a36Sopenharmony_ci &trace_hw_component_mask); 4962306a36Sopenharmony_ci if (!ret) { 5062306a36Sopenharmony_ci seq_printf(s, 5162306a36Sopenharmony_ci "trace_destination_mask: %#18x\n" 5262306a36Sopenharmony_ci "trace_hw_component_mask: %#18llx\n", 5362306a36Sopenharmony_ci trace_destination_mask, trace_hw_component_mask); 5462306a36Sopenharmony_ci } 5562306a36Sopenharmony_ci return 0; 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistatic int fw_trace_config_show(struct seq_file *s, void *v) 5962306a36Sopenharmony_ci{ 6062306a36Sopenharmony_ci struct drm_info_node *node = (struct drm_info_node *)s->private; 6162306a36Sopenharmony_ci struct ivpu_device *vdev = to_ivpu_device(node->minor->dev); 6262306a36Sopenharmony_ci /** 6362306a36Sopenharmony_ci * WA: VPU_JSM_MSG_TRACE_GET_CONFIG command is not working yet, 6462306a36Sopenharmony_ci * so we use values from vdev->fw instead of calling ivpu_jsm_trace_get_config() 6562306a36Sopenharmony_ci */ 6662306a36Sopenharmony_ci u32 trace_level = vdev->fw->trace_level; 6762306a36Sopenharmony_ci u32 trace_destination_mask = vdev->fw->trace_destination_mask; 6862306a36Sopenharmony_ci u64 trace_hw_component_mask = vdev->fw->trace_hw_component_mask; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci seq_printf(s, 7162306a36Sopenharmony_ci "trace_level: %#18x\n" 7262306a36Sopenharmony_ci "trace_destination_mask: %#18x\n" 7362306a36Sopenharmony_ci "trace_hw_component_mask: %#18llx\n", 7462306a36Sopenharmony_ci trace_level, trace_destination_mask, trace_hw_component_mask); 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci return 0; 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic int last_bootmode_show(struct seq_file *s, void *v) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci struct drm_info_node *node = (struct drm_info_node *)s->private; 8262306a36Sopenharmony_ci struct ivpu_device *vdev = to_ivpu_device(node->minor->dev); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci seq_printf(s, "%s\n", (vdev->pm->is_warmboot) ? "warmboot" : "coldboot"); 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci return 0; 8762306a36Sopenharmony_ci} 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistatic int reset_counter_show(struct seq_file *s, void *v) 9062306a36Sopenharmony_ci{ 9162306a36Sopenharmony_ci struct drm_info_node *node = (struct drm_info_node *)s->private; 9262306a36Sopenharmony_ci struct ivpu_device *vdev = to_ivpu_device(node->minor->dev); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci seq_printf(s, "%d\n", atomic_read(&vdev->pm->reset_counter)); 9562306a36Sopenharmony_ci return 0; 9662306a36Sopenharmony_ci} 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistatic int reset_pending_show(struct seq_file *s, void *v) 9962306a36Sopenharmony_ci{ 10062306a36Sopenharmony_ci struct drm_info_node *node = (struct drm_info_node *)s->private; 10162306a36Sopenharmony_ci struct ivpu_device *vdev = to_ivpu_device(node->minor->dev); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci seq_printf(s, "%d\n", atomic_read(&vdev->pm->in_reset)); 10462306a36Sopenharmony_ci return 0; 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cistatic const struct drm_info_list vdev_debugfs_list[] = { 10862306a36Sopenharmony_ci {"bo_list", bo_list_show, 0}, 10962306a36Sopenharmony_ci {"fw_name", fw_name_show, 0}, 11062306a36Sopenharmony_ci {"fw_trace_capability", fw_trace_capability_show, 0}, 11162306a36Sopenharmony_ci {"fw_trace_config", fw_trace_config_show, 0}, 11262306a36Sopenharmony_ci {"last_bootmode", last_bootmode_show, 0}, 11362306a36Sopenharmony_ci {"reset_counter", reset_counter_show, 0}, 11462306a36Sopenharmony_ci {"reset_pending", reset_pending_show, 0}, 11562306a36Sopenharmony_ci}; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_cistatic int fw_log_show(struct seq_file *s, void *v) 11862306a36Sopenharmony_ci{ 11962306a36Sopenharmony_ci struct ivpu_device *vdev = s->private; 12062306a36Sopenharmony_ci struct drm_printer p = drm_seq_file_printer(s); 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci ivpu_fw_log_print(vdev, true, &p); 12362306a36Sopenharmony_ci return 0; 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistatic int fw_log_fops_open(struct inode *inode, struct file *file) 12762306a36Sopenharmony_ci{ 12862306a36Sopenharmony_ci return single_open(file, fw_log_show, inode->i_private); 12962306a36Sopenharmony_ci} 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cistatic ssize_t 13262306a36Sopenharmony_cifw_log_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci struct seq_file *s = file->private_data; 13562306a36Sopenharmony_ci struct ivpu_device *vdev = s->private; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci if (!size) 13862306a36Sopenharmony_ci return -EINVAL; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci ivpu_fw_log_clear(vdev); 14162306a36Sopenharmony_ci return size; 14262306a36Sopenharmony_ci} 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_cistatic const struct file_operations fw_log_fops = { 14562306a36Sopenharmony_ci .owner = THIS_MODULE, 14662306a36Sopenharmony_ci .open = fw_log_fops_open, 14762306a36Sopenharmony_ci .write = fw_log_fops_write, 14862306a36Sopenharmony_ci .read = seq_read, 14962306a36Sopenharmony_ci .llseek = seq_lseek, 15062306a36Sopenharmony_ci .release = single_release, 15162306a36Sopenharmony_ci}; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cistatic ssize_t 15462306a36Sopenharmony_cifw_trace_destination_mask_fops_write(struct file *file, const char __user *user_buf, 15562306a36Sopenharmony_ci size_t size, loff_t *pos) 15662306a36Sopenharmony_ci{ 15762306a36Sopenharmony_ci struct ivpu_device *vdev = file->private_data; 15862306a36Sopenharmony_ci struct ivpu_fw_info *fw = vdev->fw; 15962306a36Sopenharmony_ci u32 trace_destination_mask; 16062306a36Sopenharmony_ci int ret; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci ret = kstrtou32_from_user(user_buf, size, 0, &trace_destination_mask); 16362306a36Sopenharmony_ci if (ret < 0) 16462306a36Sopenharmony_ci return ret; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci fw->trace_destination_mask = trace_destination_mask; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci ivpu_jsm_trace_set_config(vdev, fw->trace_level, trace_destination_mask, 16962306a36Sopenharmony_ci fw->trace_hw_component_mask); 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci return size; 17262306a36Sopenharmony_ci} 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_cistatic const struct file_operations fw_trace_destination_mask_fops = { 17562306a36Sopenharmony_ci .owner = THIS_MODULE, 17662306a36Sopenharmony_ci .open = simple_open, 17762306a36Sopenharmony_ci .write = fw_trace_destination_mask_fops_write, 17862306a36Sopenharmony_ci}; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_cistatic ssize_t 18162306a36Sopenharmony_cifw_trace_hw_comp_mask_fops_write(struct file *file, const char __user *user_buf, 18262306a36Sopenharmony_ci size_t size, loff_t *pos) 18362306a36Sopenharmony_ci{ 18462306a36Sopenharmony_ci struct ivpu_device *vdev = file->private_data; 18562306a36Sopenharmony_ci struct ivpu_fw_info *fw = vdev->fw; 18662306a36Sopenharmony_ci u64 trace_hw_component_mask; 18762306a36Sopenharmony_ci int ret; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci ret = kstrtou64_from_user(user_buf, size, 0, &trace_hw_component_mask); 19062306a36Sopenharmony_ci if (ret < 0) 19162306a36Sopenharmony_ci return ret; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci fw->trace_hw_component_mask = trace_hw_component_mask; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci ivpu_jsm_trace_set_config(vdev, fw->trace_level, fw->trace_destination_mask, 19662306a36Sopenharmony_ci trace_hw_component_mask); 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci return size; 19962306a36Sopenharmony_ci} 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_cistatic const struct file_operations fw_trace_hw_comp_mask_fops = { 20262306a36Sopenharmony_ci .owner = THIS_MODULE, 20362306a36Sopenharmony_ci .open = simple_open, 20462306a36Sopenharmony_ci .write = fw_trace_hw_comp_mask_fops_write, 20562306a36Sopenharmony_ci}; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_cistatic ssize_t 20862306a36Sopenharmony_cifw_trace_level_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) 20962306a36Sopenharmony_ci{ 21062306a36Sopenharmony_ci struct ivpu_device *vdev = file->private_data; 21162306a36Sopenharmony_ci struct ivpu_fw_info *fw = vdev->fw; 21262306a36Sopenharmony_ci u32 trace_level; 21362306a36Sopenharmony_ci int ret; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci ret = kstrtou32_from_user(user_buf, size, 0, &trace_level); 21662306a36Sopenharmony_ci if (ret < 0) 21762306a36Sopenharmony_ci return ret; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci fw->trace_level = trace_level; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci ivpu_jsm_trace_set_config(vdev, trace_level, fw->trace_destination_mask, 22262306a36Sopenharmony_ci fw->trace_hw_component_mask); 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci return size; 22562306a36Sopenharmony_ci} 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_cistatic const struct file_operations fw_trace_level_fops = { 22862306a36Sopenharmony_ci .owner = THIS_MODULE, 22962306a36Sopenharmony_ci .open = simple_open, 23062306a36Sopenharmony_ci .write = fw_trace_level_fops_write, 23162306a36Sopenharmony_ci}; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_cistatic ssize_t 23462306a36Sopenharmony_ciivpu_reset_engine_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) 23562306a36Sopenharmony_ci{ 23662306a36Sopenharmony_ci struct ivpu_device *vdev = file->private_data; 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci if (!size) 23962306a36Sopenharmony_ci return -EINVAL; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci if (ivpu_jsm_reset_engine(vdev, DRM_IVPU_ENGINE_COMPUTE)) 24262306a36Sopenharmony_ci return -ENODEV; 24362306a36Sopenharmony_ci if (ivpu_jsm_reset_engine(vdev, DRM_IVPU_ENGINE_COPY)) 24462306a36Sopenharmony_ci return -ENODEV; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci return size; 24762306a36Sopenharmony_ci} 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_cistatic ssize_t 25062306a36Sopenharmony_ciivpu_force_recovery_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos) 25162306a36Sopenharmony_ci{ 25262306a36Sopenharmony_ci struct ivpu_device *vdev = file->private_data; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci if (!size) 25562306a36Sopenharmony_ci return -EINVAL; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci ivpu_pm_schedule_recovery(vdev); 25862306a36Sopenharmony_ci return size; 25962306a36Sopenharmony_ci} 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_cistatic const struct file_operations ivpu_force_recovery_fops = { 26262306a36Sopenharmony_ci .owner = THIS_MODULE, 26362306a36Sopenharmony_ci .open = simple_open, 26462306a36Sopenharmony_ci .write = ivpu_force_recovery_fn, 26562306a36Sopenharmony_ci}; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_cistatic const struct file_operations ivpu_reset_engine_fops = { 26862306a36Sopenharmony_ci .owner = THIS_MODULE, 26962306a36Sopenharmony_ci .open = simple_open, 27062306a36Sopenharmony_ci .write = ivpu_reset_engine_fn, 27162306a36Sopenharmony_ci}; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_civoid ivpu_debugfs_init(struct drm_minor *minor) 27462306a36Sopenharmony_ci{ 27562306a36Sopenharmony_ci struct ivpu_device *vdev = to_ivpu_device(minor->dev); 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci drm_debugfs_create_files(vdev_debugfs_list, ARRAY_SIZE(vdev_debugfs_list), 27862306a36Sopenharmony_ci minor->debugfs_root, minor); 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci debugfs_create_file("force_recovery", 0200, minor->debugfs_root, vdev, 28162306a36Sopenharmony_ci &ivpu_force_recovery_fops); 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci debugfs_create_file("fw_log", 0644, minor->debugfs_root, vdev, 28462306a36Sopenharmony_ci &fw_log_fops); 28562306a36Sopenharmony_ci debugfs_create_file("fw_trace_destination_mask", 0200, minor->debugfs_root, vdev, 28662306a36Sopenharmony_ci &fw_trace_destination_mask_fops); 28762306a36Sopenharmony_ci debugfs_create_file("fw_trace_hw_comp_mask", 0200, minor->debugfs_root, vdev, 28862306a36Sopenharmony_ci &fw_trace_hw_comp_mask_fops); 28962306a36Sopenharmony_ci debugfs_create_file("fw_trace_level", 0200, minor->debugfs_root, vdev, 29062306a36Sopenharmony_ci &fw_trace_level_fops); 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci debugfs_create_file("reset_engine", 0200, minor->debugfs_root, vdev, 29362306a36Sopenharmony_ci &ivpu_reset_engine_fops); 29462306a36Sopenharmony_ci} 295