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