1 // SPDX-License-Identifier: GPL-2.0-or-later 2 // Copyright (c) 2024 Hisilicon Limited. 3 4 #include <linux/debugfs.h> 5 #include <linux/device.h> 6 #include <linux/seq_file.h> 7 #include <linux/pci.h> 8 9 #include <drm/drm_drv.h> 10 #include <drm/drm_file.h> 11 #include <drm/drm_debugfs.h> 12 #include <drm/drm_edid.h> 13 14 #include "hibmc_drm_drv.h" 15 16 #define MAX_BUF_SIZE 12 17 18 static ssize_t hibmc_control_write(struct file *file, const char __user *user_buf, 19 size_t count, loff_t *ppos) 20 { 21 struct hibmc_drm_private *priv = file_inode(file)->i_private; 22 struct hibmc_dp_cbar_cfg *cfg = &priv->dp.cfg; 23 int ret, idx; 24 u8 buf[MAX_BUF_SIZE]; 25 26 if (count >= MAX_BUF_SIZE) 27 return -EINVAL; 28 29 if (copy_from_user(buf, user_buf, count)) 30 return -EFAULT; 31 32 buf[count] = '\0'; 33 34 /* Only 4 parameters is allowed, the ranger are as follow: 35 * [0] enable/disable colorbar feature 36 0: enable colorbar, 1: disable colorbar 37 * [1] the timing source of colorbar displaying 38 0: timing follows XDP, 1: internal self timing 39 * [2] the movment of colorbar displaying 40 0: static colorbar image, 41 * 1~255: right shifting a type of color per (1~255)frames 42 * [3] the color type of colorbar displaying 43 0~9: color bar, white, red, orange, 44 * yellow, green, cyan, bule, pupper, black 45 */ 46 if (sscanf(buf, "%hhu %hhu %hhu %u", &cfg->enable, &cfg->self_timing, 47 &cfg->dynamic_rate, &cfg->pattern) != 4) { 48 return -EINVAL; 49 } 50 51 if (cfg->pattern > 9 || cfg->enable > 1 || cfg->self_timing > 1) 52 return -EINVAL; 53 54 ret = drm_dev_enter(&priv->dev, &idx); 55 if (!ret) 56 return -ENODEV; 57 58 hibmc_dp_set_cbar(&priv->dp, cfg); 59 60 drm_dev_exit(idx); 61 62 return count; 63 } 64 65 static int hibmc_dp_dbgfs_show(struct seq_file *m, void *arg) 66 { 67 struct hibmc_drm_private *priv = m->private; 68 struct hibmc_dp_cbar_cfg *cfg = &priv->dp.cfg; 69 int idx; 70 71 if (!drm_dev_enter(&priv->dev, &idx)) 72 return -ENODEV; 73 74 seq_printf(m, "hibmc dp colorbar cfg: %u %u %u %u\n", cfg->enable, cfg->self_timing, 75 cfg->dynamic_rate, cfg->pattern); 76 77 drm_dev_exit(idx); 78 79 return 0; 80 } 81 82 static int hibmc_open(struct inode *inode, struct file *filp) 83 { 84 return single_open(filp, hibmc_dp_dbgfs_show, inode->i_private); 85 } 86 87 static const struct file_operations hibmc_dbg_fops = { 88 .owner = THIS_MODULE, 89 .write = hibmc_control_write, 90 .read = seq_read, 91 .open = hibmc_open, 92 .llseek = seq_lseek, 93 .release = single_release, 94 }; 95 96 void hibmc_debugfs_init(struct drm_connector *connector, struct dentry *root) 97 { 98 struct drm_device *dev = connector->dev; 99 struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); 100 101 /* create the file in drm directory, so we don't need to remove manually */ 102 debugfs_create_file("colorbar-cfg", 0200, 103 root, priv, &hibmc_dbg_fops); 104 } 105