From 2469d5374745a2228f774adbca6fb95a79b9047f Mon Sep 17 00:00:00 2001 From: Yang Xu Date: Thu, 29 Oct 2015 17:46:15 +0800 Subject: msm: mdss: Add debugfs support for panel command data type Register debugfs node to read from and write to the panel command data type. The default data type is DCS_LONG_WRITE 0x39. Give following command in adb shell to read panel register: cat /sys/kernel/debug/mdp/panel_cmd_data_type To write panel command data type: echo "command_data_type" > /sys/kernel/debug/mdp/panel_cmd_data_type Change-Id: I6dbe5bccb3142e93400825eddf7f05180acfc710 Signed-off-by: Yang Xu --- drivers/video/msm/mdss/mdss_debug.c | 73 ++++++++++++++++++++++--------------- drivers/video/msm/mdss/mdss_debug.h | 3 +- 2 files changed, 46 insertions(+), 30 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index eaeccac..13d2b16 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2009-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -124,32 +124,22 @@ static ssize_t panel_debug_base_reg_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct mdss_debug_base *dbg = file->private_data; - - u32 cnt, tmp, i; - u32 len = 0; char buf[PANEL_TX_MAX_BUF] = {0x0}; - char *p = NULL; char reg[PANEL_TX_MAX_BUF] = {0x0}; + u32 len = 0, step = 0, value = 0; + char *bufp; struct mdss_data_type *mdata = mdss_res; - struct mdss_mdp_ctl *ctl = mdata->ctl_off + 0; - struct mdss_panel_data *panel_data = ctl->panel_data; - struct mdss_dsi_ctrl_pdata *ctrl_pdata = container_of(panel_data, - struct mdss_dsi_ctrl_pdata, panel_data); - + struct mdss_mdp_ctl *ctl; + struct mdss_dsi_ctrl_pdata *ctrl_pdata; struct dsi_cmd_desc dsi_write_cmd = { - {DTYPE_GEN_LWRITE, 1, 0, 0, 0, 0/*len*/}, reg}; + {0/*data type*/, 1, 0, 0, 0, 0/* len */}, reg}; struct dcs_cmd_req cmdreq; - cmdreq.cmds = &dsi_write_cmd; - cmdreq.cmds_cnt = 1; - cmdreq.flags = CMD_REQ_COMMIT; - cmdreq.rlen = 0; - cmdreq.cb = NULL; - if (!dbg || !mdata) return -ENODEV; + /* get command string from user */ if (count >= sizeof(buf)) return -EFAULT; @@ -158,26 +148,38 @@ static ssize_t panel_debug_base_reg_write(struct file *file, buf[count] = 0; /* end of string */ - len = count / 3; - + bufp = buf; + while (sscanf(bufp, "%x%n", &value, &step) > 0) { + reg[len++] = value; + if (len >= PANEL_TX_MAX_BUF) { + pr_err("wrong input reg len\n"); + return -EFAULT; + } + bufp += step; + } if (len < PANEL_CMD_MIN_TX_COUNT) { pr_err("wrong input reg len\n"); return -EFAULT; } - for (i = 0; i < len; i++) { - p = buf + i * 3; - p[2] = 0; - pr_debug("p[%d] = %p:%s\n", i, p, p); - cnt = sscanf(p, "%x", &tmp); - reg[i] = tmp; - pr_debug("reg[%d] = %x\n", i, (int)reg[i]); - } + /* put command to cmdlist */ + dsi_write_cmd.dchdr.dtype = dbg->cmd_data_type; + dsi_write_cmd.dchdr.dlen = len; + dsi_write_cmd.payload = reg; + + cmdreq.cmds = &dsi_write_cmd; + cmdreq.cmds_cnt = 1; + cmdreq.flags = CMD_REQ_COMMIT; + cmdreq.rlen = 0; + cmdreq.cb = NULL; + + ctl = mdata->ctl_off + 0; + ctrl_pdata = container_of(ctl->panel_data, + struct mdss_dsi_ctrl_pdata, panel_data); if (mdata->debug_inf.debug_enable_clock) mdata->debug_inf.debug_enable_clock(1); - dsi_write_cmd.dchdr.dlen = len; mdss_dsi_cmdlist_put(ctrl_pdata, &cmdreq); if (mdata->debug_inf.debug_enable_clock) @@ -262,7 +264,7 @@ int panel_debug_register_base(const char *name, void __iomem *base, struct mdss_data_type *mdata = mdss_res; struct mdss_debug_data *mdd; struct mdss_debug_base *dbg; - struct dentry *ent_off, *ent_reg; + struct dentry *ent_off, *ent_reg, *ent_type; char dn[PANEL_DATA_NODE_LEN] = ""; int prefix_len = 0; @@ -279,10 +281,20 @@ int panel_debug_register_base(const char *name, void __iomem *base, dbg->max_offset = max_offset; dbg->off = 0x0a; dbg->cnt = 0x01; + dbg->cmd_data_type = DTYPE_DCS_LWRITE; if (name) prefix_len = snprintf(dn, sizeof(dn), "%s_", name); + strlcpy(dn + prefix_len, "cmd_data_type", sizeof(dn) - prefix_len); + ent_type = debugfs_create_x8(dn, 0644, mdd->root, + (u8 *)&dbg->cmd_data_type); + + if (IS_ERR_OR_NULL(ent_type)) { + pr_err("debugfs_create_file: data_type fail\n"); + goto type_fail; + } + strlcpy(dn + prefix_len, "off", sizeof(dn) - prefix_len); ent_off = debugfs_create_file(dn, 0644, mdd->root, dbg, &panel_off_fops); @@ -303,9 +315,12 @@ int panel_debug_register_base(const char *name, void __iomem *base, list_add(&dbg->head, &mdd->base_list); return 0; + reg_fail: debugfs_remove(ent_off); off_fail: + debugfs_remove(ent_type); +type_fail: kfree(dbg); return -ENODEV; } diff --git a/drivers/video/msm/mdss/mdss_debug.h b/drivers/video/msm/mdss/mdss_debug.h index ef665e7..1bb54d2 100644 --- a/drivers/video/msm/mdss/mdss_debug.h +++ b/drivers/video/msm/mdss/mdss_debug.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -49,6 +49,7 @@ struct mdss_debug_base { void __iomem *base; size_t off; size_t cnt; + u8 cmd_data_type; size_t max_offset; char *buf; size_t buf_len; -- cgit v1.1