1d11a9369SAbhinav Kumar // SPDX-License-Identifier: GPL-2.0-only
2d11a9369SAbhinav Kumar /*
3d11a9369SAbhinav Kumar * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
4d11a9369SAbhinav Kumar */
5d11a9369SAbhinav Kumar
6d11a9369SAbhinav Kumar #define pr_fmt(fmt)"[drm-dp] %s: " fmt, __func__
7d11a9369SAbhinav Kumar
8d11a9369SAbhinav Kumar #include <linux/debugfs.h>
9d11a9369SAbhinav Kumar #include <drm/drm_connector.h>
10f913454aSAbhinav Kumar #include <drm/drm_file.h>
11d11a9369SAbhinav Kumar
12d11a9369SAbhinav Kumar #include "dp_catalog.h"
13d11a9369SAbhinav Kumar #include "dp_aux.h"
14d11a9369SAbhinav Kumar #include "dp_ctrl.h"
15d11a9369SAbhinav Kumar #include "dp_debug.h"
16d11a9369SAbhinav Kumar #include "dp_display.h"
17d11a9369SAbhinav Kumar
18f913454aSAbhinav Kumar #define DEBUG_NAME "msm_dp"
19d11a9369SAbhinav Kumar
20d11a9369SAbhinav Kumar struct dp_debug_private {
21d11a9369SAbhinav Kumar struct dp_link *link;
22d11a9369SAbhinav Kumar struct dp_panel *panel;
23899b2608SBjorn Andersson struct drm_connector *connector;
24d11a9369SAbhinav Kumar };
25d11a9369SAbhinav Kumar
dp_debug_show(struct seq_file * seq,void * p)26eea8f024SBjorn Andersson static int dp_debug_show(struct seq_file *seq, void *p)
27d11a9369SAbhinav Kumar {
28eea8f024SBjorn Andersson struct dp_debug_private *debug = seq->private;
29d11a9369SAbhinav Kumar u64 lclk = 0;
30d11a9369SAbhinav Kumar u32 link_params_rate;
31eea8f024SBjorn Andersson const struct drm_display_mode *drm_mode;
32d11a9369SAbhinav Kumar
33d11a9369SAbhinav Kumar if (!debug)
34d11a9369SAbhinav Kumar return -ENODEV;
35d11a9369SAbhinav Kumar
36d11a9369SAbhinav Kumar drm_mode = &debug->panel->dp_mode.drm_mode;
37d11a9369SAbhinav Kumar
38eea8f024SBjorn Andersson seq_printf(seq, "\tname = %s\n", DEBUG_NAME);
39eea8f024SBjorn Andersson seq_printf(seq, "\tdrm_dp_link\n\t\trate = %u\n",
40d11a9369SAbhinav Kumar debug->panel->link_info.rate);
41eea8f024SBjorn Andersson seq_printf(seq, "\t\tnum_lanes = %u\n",
42d11a9369SAbhinav Kumar debug->panel->link_info.num_lanes);
43eea8f024SBjorn Andersson seq_printf(seq, "\t\tcapabilities = %lu\n",
44d11a9369SAbhinav Kumar debug->panel->link_info.capabilities);
45eea8f024SBjorn Andersson seq_printf(seq, "\tdp_panel_info:\n\t\tactive = %dx%d\n",
46d11a9369SAbhinav Kumar drm_mode->hdisplay,
47d11a9369SAbhinav Kumar drm_mode->vdisplay);
48eea8f024SBjorn Andersson seq_printf(seq, "\t\tback_porch = %dx%d\n",
49d11a9369SAbhinav Kumar drm_mode->htotal - drm_mode->hsync_end,
50d11a9369SAbhinav Kumar drm_mode->vtotal - drm_mode->vsync_end);
51eea8f024SBjorn Andersson seq_printf(seq, "\t\tfront_porch = %dx%d\n",
52d11a9369SAbhinav Kumar drm_mode->hsync_start - drm_mode->hdisplay,
53d11a9369SAbhinav Kumar drm_mode->vsync_start - drm_mode->vdisplay);
54eea8f024SBjorn Andersson seq_printf(seq, "\t\tsync_width = %dx%d\n",
55d11a9369SAbhinav Kumar drm_mode->hsync_end - drm_mode->hsync_start,
56d11a9369SAbhinav Kumar drm_mode->vsync_end - drm_mode->vsync_start);
57eea8f024SBjorn Andersson seq_printf(seq, "\t\tactive_low = %dx%d\n",
58d11a9369SAbhinav Kumar debug->panel->dp_mode.h_active_low,
59d11a9369SAbhinav Kumar debug->panel->dp_mode.v_active_low);
60eea8f024SBjorn Andersson seq_printf(seq, "\t\th_skew = %d\n",
61d11a9369SAbhinav Kumar drm_mode->hskew);
62eea8f024SBjorn Andersson seq_printf(seq, "\t\trefresh rate = %d\n",
63d11a9369SAbhinav Kumar drm_mode_vrefresh(drm_mode));
64eea8f024SBjorn Andersson seq_printf(seq, "\t\tpixel clock khz = %d\n",
65d11a9369SAbhinav Kumar drm_mode->clock);
66eea8f024SBjorn Andersson seq_printf(seq, "\t\tbpp = %d\n",
67d11a9369SAbhinav Kumar debug->panel->dp_mode.bpp);
68d11a9369SAbhinav Kumar
69d11a9369SAbhinav Kumar /* Link Information */
70eea8f024SBjorn Andersson seq_printf(seq, "\tdp_link:\n\t\ttest_requested = %d\n",
71d11a9369SAbhinav Kumar debug->link->sink_request);
72eea8f024SBjorn Andersson seq_printf(seq, "\t\tnum_lanes = %d\n",
73d11a9369SAbhinav Kumar debug->link->link_params.num_lanes);
74d11a9369SAbhinav Kumar link_params_rate = debug->link->link_params.rate;
75eea8f024SBjorn Andersson seq_printf(seq, "\t\tbw_code = %d\n",
76d11a9369SAbhinav Kumar drm_dp_link_rate_to_bw_code(link_params_rate));
77d11a9369SAbhinav Kumar lclk = debug->link->link_params.rate * 1000;
78eea8f024SBjorn Andersson seq_printf(seq, "\t\tlclk = %lld\n", lclk);
79eea8f024SBjorn Andersson seq_printf(seq, "\t\tv_level = %d\n",
80d11a9369SAbhinav Kumar debug->link->phy_params.v_level);
81eea8f024SBjorn Andersson seq_printf(seq, "\t\tp_level = %d\n",
82d11a9369SAbhinav Kumar debug->link->phy_params.p_level);
83d11a9369SAbhinav Kumar
84eea8f024SBjorn Andersson return 0;
85d11a9369SAbhinav Kumar }
86eea8f024SBjorn Andersson DEFINE_SHOW_ATTRIBUTE(dp_debug);
87d11a9369SAbhinav Kumar
dp_test_data_show(struct seq_file * m,void * data)88de3ee254SAbhinav Kumar static int dp_test_data_show(struct seq_file *m, void *data)
89de3ee254SAbhinav Kumar {
90899b2608SBjorn Andersson const struct dp_debug_private *debug = m->private;
91899b2608SBjorn Andersson const struct drm_connector *connector = debug->connector;
92de3ee254SAbhinav Kumar u32 bpc;
93de3ee254SAbhinav Kumar
94de3ee254SAbhinav Kumar if (connector->status == connector_status_connected) {
95de3ee254SAbhinav Kumar bpc = debug->link->test_video.test_bit_depth;
96de3ee254SAbhinav Kumar seq_printf(m, "hdisplay: %d\n",
97de3ee254SAbhinav Kumar debug->link->test_video.test_h_width);
98de3ee254SAbhinav Kumar seq_printf(m, "vdisplay: %d\n",
99de3ee254SAbhinav Kumar debug->link->test_video.test_v_height);
100de3ee254SAbhinav Kumar seq_printf(m, "bpc: %u\n",
10172b557c1SKuogee Hsieh dp_link_bit_depth_to_bpp(bpc) / 3);
102899b2608SBjorn Andersson } else {
103de3ee254SAbhinav Kumar seq_puts(m, "0");
104de3ee254SAbhinav Kumar }
105de3ee254SAbhinav Kumar
106de3ee254SAbhinav Kumar return 0;
107de3ee254SAbhinav Kumar }
108de3ee254SAbhinav Kumar DEFINE_SHOW_ATTRIBUTE(dp_test_data);
109de3ee254SAbhinav Kumar
dp_test_type_show(struct seq_file * m,void * data)110de3ee254SAbhinav Kumar static int dp_test_type_show(struct seq_file *m, void *data)
111de3ee254SAbhinav Kumar {
112899b2608SBjorn Andersson const struct dp_debug_private *debug = m->private;
113899b2608SBjorn Andersson const struct drm_connector *connector = debug->connector;
114de3ee254SAbhinav Kumar
115de3ee254SAbhinav Kumar if (connector->status == connector_status_connected)
116de3ee254SAbhinav Kumar seq_printf(m, "%02x", DP_TEST_LINK_VIDEO_PATTERN);
117de3ee254SAbhinav Kumar else
118de3ee254SAbhinav Kumar seq_puts(m, "0");
119de3ee254SAbhinav Kumar
120de3ee254SAbhinav Kumar return 0;
121de3ee254SAbhinav Kumar }
122de3ee254SAbhinav Kumar DEFINE_SHOW_ATTRIBUTE(dp_test_type);
123de3ee254SAbhinav Kumar
dp_test_active_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)124de3ee254SAbhinav Kumar static ssize_t dp_test_active_write(struct file *file,
125de3ee254SAbhinav Kumar const char __user *ubuf,
126de3ee254SAbhinav Kumar size_t len, loff_t *offp)
127de3ee254SAbhinav Kumar {
128de3ee254SAbhinav Kumar char *input_buffer;
129de3ee254SAbhinav Kumar int status = 0;
130899b2608SBjorn Andersson const struct dp_debug_private *debug;
131899b2608SBjorn Andersson const struct drm_connector *connector;
132de3ee254SAbhinav Kumar int val = 0;
133de3ee254SAbhinav Kumar
134de3ee254SAbhinav Kumar debug = ((struct seq_file *)file->private_data)->private;
135899b2608SBjorn Andersson connector = debug->connector;
136de3ee254SAbhinav Kumar
137de3ee254SAbhinav Kumar if (len == 0)
138de3ee254SAbhinav Kumar return 0;
139de3ee254SAbhinav Kumar
140de3ee254SAbhinav Kumar input_buffer = memdup_user_nul(ubuf, len);
141de3ee254SAbhinav Kumar if (IS_ERR(input_buffer))
142de3ee254SAbhinav Kumar return PTR_ERR(input_buffer);
143de3ee254SAbhinav Kumar
144de3ee254SAbhinav Kumar DRM_DEBUG_DRIVER("Copied %d bytes from user\n", (unsigned int)len);
145de3ee254SAbhinav Kumar
146de3ee254SAbhinav Kumar if (connector->status == connector_status_connected) {
147de3ee254SAbhinav Kumar status = kstrtoint(input_buffer, 10, &val);
148899b2608SBjorn Andersson if (status < 0) {
149899b2608SBjorn Andersson kfree(input_buffer);
150899b2608SBjorn Andersson return status;
151899b2608SBjorn Andersson }
152de3ee254SAbhinav Kumar DRM_DEBUG_DRIVER("Got %d for test active\n", val);
153de3ee254SAbhinav Kumar /* To prevent erroneous activation of the compliance
154de3ee254SAbhinav Kumar * testing code, only accept an actual value of 1 here
155de3ee254SAbhinav Kumar */
156de3ee254SAbhinav Kumar if (val == 1)
157de3ee254SAbhinav Kumar debug->panel->video_test = true;
158de3ee254SAbhinav Kumar else
159de3ee254SAbhinav Kumar debug->panel->video_test = false;
160de3ee254SAbhinav Kumar }
161de3ee254SAbhinav Kumar kfree(input_buffer);
162de3ee254SAbhinav Kumar
163de3ee254SAbhinav Kumar *offp += len;
164de3ee254SAbhinav Kumar return len;
165de3ee254SAbhinav Kumar }
166de3ee254SAbhinav Kumar
dp_test_active_show(struct seq_file * m,void * data)167de3ee254SAbhinav Kumar static int dp_test_active_show(struct seq_file *m, void *data)
168de3ee254SAbhinav Kumar {
169de3ee254SAbhinav Kumar struct dp_debug_private *debug = m->private;
170899b2608SBjorn Andersson struct drm_connector *connector = debug->connector;
171de3ee254SAbhinav Kumar
172de3ee254SAbhinav Kumar if (connector->status == connector_status_connected) {
173de3ee254SAbhinav Kumar if (debug->panel->video_test)
174de3ee254SAbhinav Kumar seq_puts(m, "1");
175de3ee254SAbhinav Kumar else
176de3ee254SAbhinav Kumar seq_puts(m, "0");
177899b2608SBjorn Andersson } else {
178de3ee254SAbhinav Kumar seq_puts(m, "0");
179de3ee254SAbhinav Kumar }
180de3ee254SAbhinav Kumar
181de3ee254SAbhinav Kumar return 0;
182de3ee254SAbhinav Kumar }
183de3ee254SAbhinav Kumar
dp_test_active_open(struct inode * inode,struct file * file)184de3ee254SAbhinav Kumar static int dp_test_active_open(struct inode *inode,
185de3ee254SAbhinav Kumar struct file *file)
186de3ee254SAbhinav Kumar {
187de3ee254SAbhinav Kumar return single_open(file, dp_test_active_show,
188de3ee254SAbhinav Kumar inode->i_private);
189de3ee254SAbhinav Kumar }
190de3ee254SAbhinav Kumar
191de3ee254SAbhinav Kumar static const struct file_operations test_active_fops = {
192de3ee254SAbhinav Kumar .owner = THIS_MODULE,
193de3ee254SAbhinav Kumar .open = dp_test_active_open,
194de3ee254SAbhinav Kumar .read = seq_read,
195de3ee254SAbhinav Kumar .llseek = seq_lseek,
196de3ee254SAbhinav Kumar .release = single_release,
197de3ee254SAbhinav Kumar .write = dp_test_active_write
198de3ee254SAbhinav Kumar };
199de3ee254SAbhinav Kumar
dp_debug_init(struct device * dev,struct dp_panel * panel,struct dp_link * link,struct drm_connector * connector,struct dentry * root,bool is_edp)200*3b76287cSBjorn Andersson int dp_debug_init(struct device *dev, struct dp_panel *panel,
201*3b76287cSBjorn Andersson struct dp_link *link,
202*3b76287cSBjorn Andersson struct drm_connector *connector,
203*3b76287cSBjorn Andersson struct dentry *root, bool is_edp)
204d11a9369SAbhinav Kumar {
205*3b76287cSBjorn Andersson struct dp_debug_private *debug;
206*3b76287cSBjorn Andersson
207*3b76287cSBjorn Andersson if (!dev || !panel || !link) {
208*3b76287cSBjorn Andersson DRM_ERROR("invalid input\n");
209*3b76287cSBjorn Andersson return -EINVAL;
210*3b76287cSBjorn Andersson }
211*3b76287cSBjorn Andersson
212*3b76287cSBjorn Andersson debug = devm_kzalloc(dev, sizeof(*debug), GFP_KERNEL);
213*3b76287cSBjorn Andersson if (!debug)
214*3b76287cSBjorn Andersson return -ENOMEM;
215*3b76287cSBjorn Andersson
216*3b76287cSBjorn Andersson debug->link = link;
217*3b76287cSBjorn Andersson debug->panel = panel;
218d11a9369SAbhinav Kumar
219ab842041SDmitry Baryshkov debugfs_create_file("dp_debug", 0444, root,
220d11a9369SAbhinav Kumar debug, &dp_debug_fops);
221d11a9369SAbhinav Kumar
222ab842041SDmitry Baryshkov if (!is_edp) {
223cb3fd74aSAbhinav Kumar debugfs_create_file("msm_dp_test_active", 0444,
224ab842041SDmitry Baryshkov root,
225de3ee254SAbhinav Kumar debug, &test_active_fops);
226de3ee254SAbhinav Kumar
227cb3fd74aSAbhinav Kumar debugfs_create_file("msm_dp_test_data", 0444,
228ab842041SDmitry Baryshkov root,
229de3ee254SAbhinav Kumar debug, &dp_test_data_fops);
230de3ee254SAbhinav Kumar
231cb3fd74aSAbhinav Kumar debugfs_create_file("msm_dp_test_type", 0444,
232ab842041SDmitry Baryshkov root,
233de3ee254SAbhinav Kumar debug, &dp_test_type_fops);
234d11a9369SAbhinav Kumar }
235d11a9369SAbhinav Kumar
236*3b76287cSBjorn Andersson return 0;
237d11a9369SAbhinav Kumar }
238