blob: d023f64178e5a005ada43890773ffc49084fbd2c [file] [log] [blame]
Samantha Tran2d1ed732017-07-31 17:30:14 -07001/*
Ajay Singh Parmar668ca742019-01-16 21:50:19 -08002 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
Samantha Tran2d1ed732017-07-31 17:30:14 -07003 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__
16
17#include <linux/debugfs.h>
18
Samantha Tran2d1ed732017-07-31 17:30:14 -070019#include "dp_power.h"
20#include "dp_catalog.h"
21#include "dp_aux.h"
22#include "dp_ctrl.h"
23#include "dp_debug.h"
24#include "drm_connector.h"
Ajay Singh Parmar973cab12017-11-15 15:33:33 -080025#include "sde_connector.h"
Samantha Tran2d1ed732017-07-31 17:30:14 -070026#include "dp_display.h"
27
28#define DEBUG_NAME "drm_dp"
29
30struct dp_debug_private {
31 struct dentry *root;
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -070032 u8 *edid;
33 u32 edid_size;
Samantha Tran2d1ed732017-07-31 17:30:14 -070034
Ajay Singh Parmard937eb22017-10-17 19:58:19 -070035 u8 *dpcd;
36 u32 dpcd_size;
37
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -080038 int vdo;
39
Samantha Tranb6a5cd82018-02-01 14:47:16 -080040 char exe_mode[SZ_32];
41 char reg_dump[SZ_32];
42
Samantha Tran2d1ed732017-07-31 17:30:14 -070043 struct dp_usbpd *usbpd;
44 struct dp_link *link;
45 struct dp_panel *panel;
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -080046 struct dp_aux *aux;
Samantha Tranb6a5cd82018-02-01 14:47:16 -080047 struct dp_catalog *catalog;
Samantha Tran2d1ed732017-07-31 17:30:14 -070048 struct drm_connector **connector;
49 struct device *dev;
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -080050 struct work_struct sim_work;
Samantha Tran2d1ed732017-07-31 17:30:14 -070051 struct dp_debug dp_debug;
Ajay Singh Parmar668ca742019-01-16 21:50:19 -080052 struct mutex lock;
Samantha Tran2d1ed732017-07-31 17:30:14 -070053};
54
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -080055static int dp_debug_get_edid_buf(struct dp_debug_private *debug)
56{
57 int rc = 0;
58
59 if (!debug->edid) {
60 debug->edid = devm_kzalloc(debug->dev, SZ_256, GFP_KERNEL);
61 if (!debug->edid) {
62 rc = -ENOMEM;
63 goto end;
64 }
65
66 debug->edid_size = SZ_256;
67 }
68end:
69 return rc;
70}
71
72static int dp_debug_get_dpcd_buf(struct dp_debug_private *debug)
73{
74 int rc = 0;
75
76 if (!debug->dpcd) {
77 debug->dpcd = devm_kzalloc(debug->dev, SZ_1K, GFP_KERNEL);
78 if (!debug->dpcd) {
79 rc = -ENOMEM;
80 goto end;
81 }
82
83 debug->dpcd_size = SZ_1K;
84 }
85end:
86 return rc;
87}
88
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -070089static ssize_t dp_debug_write_edid(struct file *file,
90 const char __user *user_buff, size_t count, loff_t *ppos)
91{
92 struct dp_debug_private *debug = file->private_data;
93 u8 *buf = NULL, *buf_t = NULL, *edid = NULL;
94 const int char_to_nib = 2;
95 size_t edid_size = 0;
96 size_t size = 0, edid_buf_index = 0;
97 ssize_t rc = count;
98
99 if (!debug)
100 return -ENODEV;
101
Ajay Singh Parmar668ca742019-01-16 21:50:19 -0800102 mutex_lock(&debug->lock);
103
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -0700104 if (*ppos)
105 goto bail;
106
107 size = min_t(size_t, count, SZ_1K);
108
109 buf = kzalloc(size, GFP_KERNEL);
Aravind Venkateswaranc140b8f2018-07-19 14:53:41 -0700110 if (ZERO_OR_NULL_PTR(buf)) {
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -0700111 rc = -ENOMEM;
112 goto bail;
113 }
114
115 if (copy_from_user(buf, user_buff, size))
116 goto bail;
117
118 edid_size = size / char_to_nib;
119 buf_t = buf;
120
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800121 if (dp_debug_get_edid_buf(debug))
122 goto bail;
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -0700123
124 if (edid_size != debug->edid_size) {
Ray Zhang18b469da2018-08-24 16:50:13 +0800125 pr_debug("realloc debug edid\n");
126
127 if (debug->edid) {
128 devm_kfree(debug->dev, debug->edid);
129
130 debug->edid = devm_kzalloc(debug->dev,
131 edid_size, GFP_KERNEL);
132 if (!debug->edid) {
133 rc = -ENOMEM;
134 goto bail;
135 }
136
137 debug->edid_size = edid_size;
138
139 debug->aux->set_sim_mode(debug->aux,
140 debug->dp_debug.sim_mode,
141 debug->edid, debug->dpcd);
142 }
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -0700143 }
144
145 while (edid_size--) {
146 char t[3];
147 int d;
148
149 memcpy(t, buf_t, sizeof(char) * char_to_nib);
150 t[char_to_nib] = '\0';
151
152 if (kstrtoint(t, 16, &d)) {
153 pr_err("kstrtoint error\n");
154 goto bail;
155 }
156
157 if (edid_buf_index < debug->edid_size)
158 debug->edid[edid_buf_index++] = d;
159
160 buf_t += char_to_nib;
161 }
162
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -0700163 edid = debug->edid;
164bail:
165 kfree(buf);
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800166
167 if (!debug->dp_debug.sim_mode)
168 debug->panel->set_edid(debug->panel, edid);
169
Ajay Singh Parmar668ca742019-01-16 21:50:19 -0800170 mutex_unlock(&debug->lock);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -0700171 return rc;
172}
173
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700174static ssize_t dp_debug_write_dpcd(struct file *file,
175 const char __user *user_buff, size_t count, loff_t *ppos)
176{
177 struct dp_debug_private *debug = file->private_data;
178 u8 *buf = NULL, *buf_t = NULL, *dpcd = NULL;
179 const int char_to_nib = 2;
180 size_t dpcd_size = 0;
181 size_t size = 0, dpcd_buf_index = 0;
182 ssize_t rc = count;
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800183 char offset_ch[5];
184 u32 offset;
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700185
186 if (!debug)
187 return -ENODEV;
188
Ajay Singh Parmar668ca742019-01-16 21:50:19 -0800189 mutex_lock(&debug->lock);
190
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700191 if (*ppos)
192 goto bail;
193
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800194 size = min_t(size_t, count, SZ_2K);
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530195 if (size < 4)
196 goto bail;
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700197
198 buf = kzalloc(size, GFP_KERNEL);
Aravind Venkateswaranc140b8f2018-07-19 14:53:41 -0700199 if (ZERO_OR_NULL_PTR(buf)) {
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700200 rc = -ENOMEM;
201 goto bail;
202 }
203
204 if (copy_from_user(buf, user_buff, size))
205 goto bail;
206
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800207 memcpy(offset_ch, buf, 4);
208 offset_ch[4] = '\0';
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700209
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800210 if (kstrtoint(offset_ch, 16, &offset)) {
211 pr_err("offset kstrtoint error\n");
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700212 goto bail;
213 }
214
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800215 if (dp_debug_get_dpcd_buf(debug))
216 goto bail;
217
218 if (offset == 0xFFFF) {
219 pr_err("clearing dpcd\n");
220 memset(debug->dpcd, 0, debug->dpcd_size);
221 goto bail;
222 }
223
224 size -= 4;
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530225 if (size == 0)
226 goto bail;
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800227
228 dpcd_size = size / char_to_nib;
229 buf_t = buf + 4;
230
231 dpcd_buf_index = offset;
232
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700233 while (dpcd_size--) {
234 char t[3];
235 int d;
236
237 memcpy(t, buf_t, sizeof(char) * char_to_nib);
238 t[char_to_nib] = '\0';
239
240 if (kstrtoint(t, 16, &d)) {
241 pr_err("kstrtoint error\n");
242 goto bail;
243 }
244
245 if (dpcd_buf_index < debug->dpcd_size)
246 debug->dpcd[dpcd_buf_index++] = d;
247
248 buf_t += char_to_nib;
249 }
250
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700251 dpcd = debug->dpcd;
252bail:
253 kfree(buf);
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800254 if (debug->dp_debug.sim_mode)
255 debug->aux->dpcd_updated(debug->aux);
256 else
257 debug->panel->set_dpcd(debug->panel, dpcd);
258
Ajay Singh Parmar668ca742019-01-16 21:50:19 -0800259 mutex_unlock(&debug->lock);
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700260 return rc;
261}
262
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800263static ssize_t dp_debug_read_dpcd(struct file *file,
264 char __user *user_buff, size_t count, loff_t *ppos)
265{
266 struct dp_debug_private *debug = file->private_data;
267 char buf[SZ_8];
268 u32 len = 0;
269
270 if (!debug)
271 return -ENODEV;
272
273 if (*ppos)
274 return 0;
275
276 len += snprintf(buf, SZ_8, "0x%x\n", debug->aux->reg);
277
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530278 len = min_t(size_t, count, len);
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800279 if (copy_to_user(user_buff, buf, len))
280 return -EFAULT;
281
282 *ppos += len;
283 return len;
284}
285
Samantha Tran2d1ed732017-07-31 17:30:14 -0700286static ssize_t dp_debug_write_hpd(struct file *file,
287 const char __user *user_buff, size_t count, loff_t *ppos)
288{
289 struct dp_debug_private *debug = file->private_data;
290 char buf[SZ_8];
291 size_t len = 0;
292 int hpd;
293
294 if (!debug)
295 return -ENODEV;
296
297 if (*ppos)
298 return 0;
299
300 /* Leave room for termination char */
301 len = min_t(size_t, count, SZ_8 - 1);
302 if (copy_from_user(buf, user_buff, len))
303 goto end;
304
305 buf[len] = '\0';
306
307 if (kstrtoint(buf, 10, &hpd) != 0)
308 goto end;
309
Ajay Singh Parmar25e2ee52017-10-20 23:50:53 -0700310 hpd &= 0x3;
311
312 debug->dp_debug.psm_enabled = !!(hpd & BIT(1));
313
314 debug->usbpd->simulate_connect(debug->usbpd, !!(hpd & BIT(0)));
Samantha Tran2d1ed732017-07-31 17:30:14 -0700315end:
Ajay Singh Parmar25e2ee52017-10-20 23:50:53 -0700316 return len;
Samantha Tran2d1ed732017-07-31 17:30:14 -0700317}
318
319static ssize_t dp_debug_write_edid_modes(struct file *file,
320 const char __user *user_buff, size_t count, loff_t *ppos)
321{
322 struct dp_debug_private *debug = file->private_data;
323 char buf[SZ_32];
324 size_t len = 0;
Tatenda Chipeperekwa59510402017-09-28 12:50:58 -0700325 int hdisplay = 0, vdisplay = 0, vrefresh = 0, aspect_ratio;
Samantha Tran2d1ed732017-07-31 17:30:14 -0700326
327 if (!debug)
328 return -ENODEV;
329
330 if (*ppos)
331 goto end;
332
333 /* Leave room for termination char */
334 len = min_t(size_t, count, SZ_32 - 1);
335 if (copy_from_user(buf, user_buff, len))
336 goto clear;
337
338 buf[len] = '\0';
339
Tatenda Chipeperekwa59510402017-09-28 12:50:58 -0700340 if (sscanf(buf, "%d %d %d %d", &hdisplay, &vdisplay, &vrefresh,
341 &aspect_ratio) != 4)
Samantha Tran2d1ed732017-07-31 17:30:14 -0700342 goto clear;
343
344 if (!hdisplay || !vdisplay || !vrefresh)
345 goto clear;
346
347 debug->dp_debug.debug_en = true;
348 debug->dp_debug.hdisplay = hdisplay;
349 debug->dp_debug.vdisplay = vdisplay;
350 debug->dp_debug.vrefresh = vrefresh;
Tatenda Chipeperekwa59510402017-09-28 12:50:58 -0700351 debug->dp_debug.aspect_ratio = aspect_ratio;
Samantha Tran2d1ed732017-07-31 17:30:14 -0700352 goto end;
353clear:
354 pr_debug("clearing debug modes\n");
355 debug->dp_debug.debug_en = false;
356end:
357 return len;
358}
359
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +0530360static ssize_t dp_debug_bw_code_write(struct file *file,
361 const char __user *user_buff, size_t count, loff_t *ppos)
362{
363 struct dp_debug_private *debug = file->private_data;
364 char buf[SZ_8];
365 size_t len = 0;
366 u32 max_bw_code = 0;
367
368 if (!debug)
369 return -ENODEV;
370
371 if (*ppos)
372 return 0;
373
374 /* Leave room for termination char */
375 len = min_t(size_t, count, SZ_8 - 1);
376 if (copy_from_user(buf, user_buff, len))
377 return 0;
378
379 buf[len] = '\0';
380
381 if (kstrtoint(buf, 10, &max_bw_code) != 0)
382 return 0;
383
384 if (!is_link_rate_valid(max_bw_code)) {
385 pr_err("Unsupported bw code %d\n", max_bw_code);
386 return len;
387 }
388 debug->panel->max_bw_code = max_bw_code;
389 pr_debug("max_bw_code: %d\n", max_bw_code);
390
391 return len;
392}
393
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +0530394static ssize_t dp_debug_tpg_write(struct file *file,
395 const char __user *user_buff, size_t count, loff_t *ppos)
396{
397 struct dp_debug_private *debug = file->private_data;
398 char buf[SZ_8];
399 size_t len = 0;
400 u32 tpg_state = 0;
401
402 if (!debug)
403 return -ENODEV;
404
405 if (*ppos)
406 return 0;
407
408 /* Leave room for termination char */
409 len = min_t(size_t, count, SZ_8 - 1);
410 if (copy_from_user(buf, user_buff, len))
411 goto bail;
412
413 buf[len] = '\0';
414
415 if (kstrtoint(buf, 10, &tpg_state) != 0)
416 goto bail;
417
418 tpg_state &= 0x1;
419 pr_debug("tpg_state: %d\n", tpg_state);
420
421 if (tpg_state == debug->dp_debug.tpg_state)
422 goto bail;
423
424 if (debug->panel)
425 debug->panel->tpg_config(debug->panel, tpg_state);
426
427 debug->dp_debug.tpg_state = tpg_state;
428bail:
429 return len;
430}
431
Samantha Tranb6a5cd82018-02-01 14:47:16 -0800432static ssize_t dp_debug_write_exe_mode(struct file *file,
433 const char __user *user_buff, size_t count, loff_t *ppos)
434{
435 struct dp_debug_private *debug = file->private_data;
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530436 char buf[SZ_32];
Samantha Tranb6a5cd82018-02-01 14:47:16 -0800437 size_t len = 0;
438
439 if (!debug)
440 return -ENODEV;
441
442 if (*ppos)
443 return 0;
444
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530445 /* Leave room for termination char */
Samantha Tranb6a5cd82018-02-01 14:47:16 -0800446 len = min_t(size_t, count, SZ_32 - 1);
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530447 if (copy_from_user(buf, user_buff, len))
448 goto end;
449
Samantha Tranb6a5cd82018-02-01 14:47:16 -0800450 buf[len] = '\0';
451
452 if (sscanf(buf, "%3s", debug->exe_mode) != 1)
453 goto end;
454
455 if (strcmp(debug->exe_mode, "hw") &&
456 strcmp(debug->exe_mode, "sw") &&
457 strcmp(debug->exe_mode, "all"))
458 goto end;
459
460 debug->catalog->set_exe_mode(debug->catalog, debug->exe_mode);
461end:
462 return len;
463}
464
Samantha Tran2d1ed732017-07-31 17:30:14 -0700465static ssize_t dp_debug_read_connected(struct file *file,
466 char __user *user_buff, size_t count, loff_t *ppos)
467{
468 struct dp_debug_private *debug = file->private_data;
469 char buf[SZ_8];
470 u32 len = 0;
471
472 if (!debug)
473 return -ENODEV;
474
475 if (*ppos)
476 return 0;
477
478 len += snprintf(buf, SZ_8, "%d\n", debug->usbpd->hpd_high);
479
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530480 len = min_t(size_t, count, len);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700481 if (copy_to_user(user_buff, buf, len))
482 return -EFAULT;
483
484 *ppos += len;
485 return len;
486}
487
Padmanabhan Komanduru682ef582017-12-20 16:26:46 +0530488static int dp_debug_check_buffer_overflow(int rc, int *max_size, int *len)
489{
490 if (rc >= *max_size) {
491 pr_err("buffer overflow\n");
492 return -EINVAL;
493 }
494 *len += rc;
495 *max_size = SZ_4K - *len;
496
497 return 0;
498}
499
Samantha Tran2d1ed732017-07-31 17:30:14 -0700500static ssize_t dp_debug_read_edid_modes(struct file *file,
501 char __user *user_buff, size_t count, loff_t *ppos)
502{
503 struct dp_debug_private *debug = file->private_data;
504 char *buf;
Padmanabhan Komanduru682ef582017-12-20 16:26:46 +0530505 u32 len = 0, ret = 0, max_size = SZ_4K;
Samantha Tran2d1ed732017-07-31 17:30:14 -0700506 int rc = 0;
507 struct drm_connector *connector;
508 struct drm_display_mode *mode;
509
510 if (!debug) {
511 pr_err("invalid data\n");
512 rc = -ENODEV;
513 goto error;
514 }
515
516 connector = *debug->connector;
517
518 if (!connector) {
519 pr_err("connector is NULL\n");
520 rc = -EINVAL;
521 goto error;
522 }
523
524 if (*ppos)
525 goto error;
526
527 buf = kzalloc(SZ_4K, GFP_KERNEL);
Aravind Venkateswaranc140b8f2018-07-19 14:53:41 -0700528 if (ZERO_OR_NULL_PTR(buf)) {
Samantha Tran2d1ed732017-07-31 17:30:14 -0700529 rc = -ENOMEM;
530 goto error;
531 }
532
Lloyd Atkinsonc34a6ff2017-11-06 14:00:16 -0500533 mutex_lock(&connector->dev->mode_config.mutex);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700534 list_for_each_entry(mode, &connector->modes, head) {
Padmanabhan Komanduru682ef582017-12-20 16:26:46 +0530535 ret = snprintf(buf + len, max_size,
536 "%s %d %d %d %d %d 0x%x\n",
Tatenda Chipeperekwa59510402017-09-28 12:50:58 -0700537 mode->name, mode->vrefresh, mode->picture_aspect_ratio,
Padmanabhan Komanduru682ef582017-12-20 16:26:46 +0530538 mode->htotal, mode->vtotal, mode->clock, mode->flags);
539 if (dp_debug_check_buffer_overflow(ret, &max_size, &len))
540 break;
Samantha Tran2d1ed732017-07-31 17:30:14 -0700541 }
Lloyd Atkinsonc34a6ff2017-11-06 14:00:16 -0500542 mutex_unlock(&connector->dev->mode_config.mutex);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700543
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530544 len = min_t(size_t, count, len);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700545 if (copy_to_user(user_buff, buf, len)) {
546 kfree(buf);
547 rc = -EFAULT;
548 goto error;
549 }
550
551 *ppos += len;
552 kfree(buf);
553
554 return len;
555error:
556 return rc;
557}
558
Samantha Tran2d1ed732017-07-31 17:30:14 -0700559static ssize_t dp_debug_read_info(struct file *file, char __user *user_buff,
560 size_t count, loff_t *ppos)
561{
562 struct dp_debug_private *debug = file->private_data;
563 char *buf;
564 u32 len = 0, rc = 0;
Samantha Tran2d1ed732017-07-31 17:30:14 -0700565 u32 max_size = SZ_4K;
566
567 if (!debug)
568 return -ENODEV;
569
570 if (*ppos)
571 return 0;
572
573 buf = kzalloc(SZ_4K, GFP_KERNEL);
Aravind Venkateswaranc140b8f2018-07-19 14:53:41 -0700574 if (ZERO_OR_NULL_PTR(buf))
Samantha Tran2d1ed732017-07-31 17:30:14 -0700575 return -ENOMEM;
576
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800577 rc = snprintf(buf + len, max_size, "\tstate=0x%x\n", debug->aux->state);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700578 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
579 goto error;
580
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800581 rc = snprintf(buf + len, max_size, "\tlink_rate=%u\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700582 debug->panel->link_info.rate);
583 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
584 goto error;
585
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800586 rc = snprintf(buf + len, max_size, "\tnum_lanes=%u\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700587 debug->panel->link_info.num_lanes);
588 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
589 goto error;
590
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800591 rc = snprintf(buf + len, max_size, "\tresolution=%dx%d@%dHz\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700592 debug->panel->pinfo.h_active,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800593 debug->panel->pinfo.v_active,
Samantha Tran2d1ed732017-07-31 17:30:14 -0700594 debug->panel->pinfo.refresh_rate);
595 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
596 goto error;
597
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800598 rc = snprintf(buf + len, max_size, "\tpclock=%dKHz\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700599 debug->panel->pinfo.pixel_clk_khz);
600 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
601 goto error;
602
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800603 rc = snprintf(buf + len, max_size, "\tbpp=%d\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700604 debug->panel->pinfo.bpp);
605 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
606 goto error;
607
608 /* Link Information */
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800609 rc = snprintf(buf + len, max_size, "\ttest_req=%s\n",
610 dp_link_get_test_name(debug->link->sink_request));
Samantha Tran2d1ed732017-07-31 17:30:14 -0700611 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
612 goto error;
613
614 rc = snprintf(buf + len, max_size,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800615 "\tlane_count=%d\n", debug->link->link_params.lane_count);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700616 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
617 goto error;
618
619 rc = snprintf(buf + len, max_size,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800620 "\tbw_code=%d\n", debug->link->link_params.bw_code);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700621 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
622 goto error;
623
624 rc = snprintf(buf + len, max_size,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800625 "\tv_level=%d\n", debug->link->phy_params.v_level);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700626 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
627 goto error;
628
629 rc = snprintf(buf + len, max_size,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800630 "\tp_level=%d\n", debug->link->phy_params.p_level);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700631 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
632 goto error;
633
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530634 len = min_t(size_t, count, len);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700635 if (copy_to_user(user_buff, buf, len))
636 goto error;
637
638 *ppos += len;
639
640 kfree(buf);
641 return len;
642error:
643 kfree(buf);
644 return -EINVAL;
645}
646
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +0530647static ssize_t dp_debug_bw_code_read(struct file *file,
648 char __user *user_buff, size_t count, loff_t *ppos)
649{
650 struct dp_debug_private *debug = file->private_data;
651 char *buf;
652 u32 len = 0;
653
654 if (!debug)
655 return -ENODEV;
656
657 if (*ppos)
658 return 0;
659
660 buf = kzalloc(SZ_4K, GFP_KERNEL);
Aravind Venkateswaranc140b8f2018-07-19 14:53:41 -0700661 if (ZERO_OR_NULL_PTR(buf))
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +0530662 return -ENOMEM;
663
664 len += snprintf(buf + len, (SZ_4K - len),
665 "max_bw_code = %d\n", debug->panel->max_bw_code);
666
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530667 len = min_t(size_t, count, len);
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +0530668 if (copy_to_user(user_buff, buf, len)) {
669 kfree(buf);
670 return -EFAULT;
671 }
672
673 *ppos += len;
674 kfree(buf);
675 return len;
676}
677
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +0530678static ssize_t dp_debug_tpg_read(struct file *file,
679 char __user *user_buff, size_t count, loff_t *ppos)
680{
681 struct dp_debug_private *debug = file->private_data;
682 char buf[SZ_8];
683 u32 len = 0;
684
685 if (!debug)
686 return -ENODEV;
687
688 if (*ppos)
689 return 0;
690
691 len += snprintf(buf, SZ_8, "%d\n", debug->dp_debug.tpg_state);
692
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530693 len = min_t(size_t, count, len);
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +0530694 if (copy_to_user(user_buff, buf, len))
695 return -EFAULT;
696
697 *ppos += len;
698 return len;
699}
700
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800701static ssize_t dp_debug_write_hdr(struct file *file,
702 const char __user *user_buff, size_t count, loff_t *ppos)
703{
704 struct drm_connector *connector;
705 struct sde_connector *c_conn;
706 struct sde_connector_state *c_state;
707 struct dp_debug_private *debug = file->private_data;
Jayant Shekhar82e3c882018-06-22 18:04:09 +0530708 char buf[SZ_512];
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800709 size_t len = 0;
710
711 if (!debug)
712 return -ENODEV;
713
714 if (*ppos)
715 return 0;
716
717 connector = *debug->connector;
718 c_conn = to_sde_connector(connector);
719 c_state = to_sde_connector_state(connector->state);
720
721 /* Leave room for termination char */
Jayant Shekhar82e3c882018-06-22 18:04:09 +0530722 len = min_t(size_t, count, SZ_512 - 1);
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800723 if (copy_from_user(buf, user_buff, len))
724 goto end;
725
726 buf[len] = '\0';
727
728 if (sscanf(buf, "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
729 &c_state->hdr_meta.hdr_supported,
730 &c_state->hdr_meta.hdr_state,
731 &c_state->hdr_meta.eotf,
732 &c_state->hdr_meta.display_primaries_x[0],
733 &c_state->hdr_meta.display_primaries_x[1],
734 &c_state->hdr_meta.display_primaries_x[2],
735 &c_state->hdr_meta.display_primaries_y[0],
736 &c_state->hdr_meta.display_primaries_y[1],
737 &c_state->hdr_meta.display_primaries_y[2],
738 &c_state->hdr_meta.white_point_x,
739 &c_state->hdr_meta.white_point_y,
740 &c_state->hdr_meta.max_luminance,
741 &c_state->hdr_meta.min_luminance,
742 &c_state->hdr_meta.max_content_light_level,
743 &c_state->hdr_meta.max_average_light_level) != 15) {
744 pr_err("invalid input\n");
745 len = -EINVAL;
746 }
Ajay Singh Parmar87af50b2017-12-22 22:22:55 -0800747
748 debug->panel->setup_hdr(debug->panel, &c_state->hdr_meta);
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800749end:
750 return len;
751}
752
753static ssize_t dp_debug_read_hdr(struct file *file,
754 char __user *user_buff, size_t count, loff_t *ppos)
755{
756 struct dp_debug_private *debug = file->private_data;
757 char *buf;
758 u32 len = 0, i;
759 u32 max_size = SZ_4K;
760 int rc = 0;
761 struct drm_connector *connector;
762 struct sde_connector *c_conn;
763 struct sde_connector_state *c_state;
764 struct drm_msm_ext_hdr_metadata *hdr;
765
766 if (!debug) {
767 pr_err("invalid data\n");
768 rc = -ENODEV;
769 goto error;
770 }
771
772 connector = *debug->connector;
773
774 if (!connector) {
775 pr_err("connector is NULL\n");
776 rc = -EINVAL;
777 goto error;
778 }
779
780 if (*ppos)
781 goto error;
782
783 buf = kzalloc(SZ_4K, GFP_KERNEL);
Aravind Venkateswaranc140b8f2018-07-19 14:53:41 -0700784 if (ZERO_OR_NULL_PTR(buf)) {
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800785 rc = -ENOMEM;
786 goto error;
787 }
788
789 c_conn = to_sde_connector(connector);
790 c_state = to_sde_connector_state(connector->state);
791
792 hdr = &c_state->hdr_meta;
793
794 rc = snprintf(buf + len, max_size,
795 "============SINK HDR PARAMETERS===========\n");
796 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
797 goto error;
798
799 rc = snprintf(buf + len, max_size, "eotf = %d\n",
800 connector->hdr_eotf);
801 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
802 goto error;
803
804 rc = snprintf(buf + len, max_size, "type_one = %d\n",
805 connector->hdr_metadata_type_one);
806 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
807 goto error;
808
809 rc = snprintf(buf + len, max_size, "max_luminance = %d\n",
810 connector->hdr_max_luminance);
811 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
812 goto error;
813
814 rc = snprintf(buf + len, max_size, "avg_luminance = %d\n",
815 connector->hdr_avg_luminance);
816 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
817 goto error;
818
819 rc = snprintf(buf + len, max_size, "min_luminance = %d\n",
820 connector->hdr_min_luminance);
821 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
822 goto error;
823
824 rc = snprintf(buf + len, max_size,
825 "============VIDEO HDR PARAMETERS===========\n");
826 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
827 goto error;
828
829 rc = snprintf(buf + len, max_size, "hdr_state = %d\n", hdr->hdr_state);
830 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
831 goto error;
832
833 rc = snprintf(buf + len, max_size, "hdr_supported = %d\n",
834 hdr->hdr_supported);
835 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
836 goto error;
837
838 rc = snprintf(buf + len, max_size, "eotf = %d\n", hdr->eotf);
839 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
840 goto error;
841
842 rc = snprintf(buf + len, max_size, "white_point_x = %d\n",
843 hdr->white_point_x);
844 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
845 goto error;
846
847 rc = snprintf(buf + len, max_size, "white_point_y = %d\n",
848 hdr->white_point_y);
849 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
850 goto error;
851
852 rc = snprintf(buf + len, max_size, "max_luminance = %d\n",
853 hdr->max_luminance);
854 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
855 goto error;
856
857 rc = snprintf(buf + len, max_size, "min_luminance = %d\n",
858 hdr->min_luminance);
859 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
860 goto error;
861
862 rc = snprintf(buf + len, max_size, "max_content_light_level = %d\n",
863 hdr->max_content_light_level);
864 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
865 goto error;
866
867 rc = snprintf(buf + len, max_size, "min_content_light_level = %d\n",
868 hdr->max_average_light_level);
869 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
870 goto error;
871
872 for (i = 0; i < HDR_PRIMARIES_COUNT; i++) {
873 rc = snprintf(buf + len, max_size, "primaries_x[%d] = %d\n",
874 i, hdr->display_primaries_x[i]);
875 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
876 goto error;
877
878 rc = snprintf(buf + len, max_size, "primaries_y[%d] = %d\n",
879 i, hdr->display_primaries_y[i]);
880 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
881 goto error;
882 }
883
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530884 len = min_t(size_t, count, len);
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800885 if (copy_to_user(user_buff, buf, len)) {
886 kfree(buf);
887 rc = -EFAULT;
888 goto error;
889 }
890
891 *ppos += len;
892 kfree(buf);
893
894 return len;
895error:
896 return rc;
897}
898
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800899static ssize_t dp_debug_write_sim(struct file *file,
900 const char __user *user_buff, size_t count, loff_t *ppos)
901{
902 struct dp_debug_private *debug = file->private_data;
903 char buf[SZ_8];
904 size_t len = 0;
905 int sim;
906
907 if (!debug)
908 return -ENODEV;
909
910 if (*ppos)
911 return 0;
912
Ajay Singh Parmar668ca742019-01-16 21:50:19 -0800913 mutex_lock(&debug->lock);
914
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800915 /* Leave room for termination char */
916 len = min_t(size_t, count, SZ_8 - 1);
917 if (copy_from_user(buf, user_buff, len))
918 goto end;
919
920 buf[len] = '\0';
921
922 if (kstrtoint(buf, 10, &sim) != 0)
923 goto end;
924
925 if (sim) {
926 if (dp_debug_get_edid_buf(debug))
927 goto end;
928
929 if (dp_debug_get_dpcd_buf(debug))
930 goto error;
931 } else {
932 if (debug->edid) {
933 devm_kfree(debug->dev, debug->edid);
934 debug->edid = NULL;
935 }
936
937 if (debug->dpcd) {
938 devm_kfree(debug->dev, debug->dpcd);
939 debug->dpcd = NULL;
940 }
941 }
942
943 debug->dp_debug.sim_mode = !!sim;
944
945 debug->aux->set_sim_mode(debug->aux, debug->dp_debug.sim_mode,
946 debug->edid, debug->dpcd);
947end:
Ajay Singh Parmar668ca742019-01-16 21:50:19 -0800948 mutex_unlock(&debug->lock);
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800949 return len;
950error:
951 devm_kfree(debug->dev, debug->edid);
Ajay Singh Parmar668ca742019-01-16 21:50:19 -0800952 mutex_unlock(&debug->lock);
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800953 return len;
954}
955
956static ssize_t dp_debug_write_attention(struct file *file,
957 const char __user *user_buff, size_t count, loff_t *ppos)
958{
959 struct dp_debug_private *debug = file->private_data;
960 char buf[SZ_8];
961 size_t len = 0;
962 int vdo;
963
964 if (!debug)
965 return -ENODEV;
966
967 if (*ppos)
968 return 0;
969
970 /* Leave room for termination char */
971 len = min_t(size_t, count, SZ_8 - 1);
972 if (copy_from_user(buf, user_buff, len))
973 goto end;
974
975 buf[len] = '\0';
976
977 if (kstrtoint(buf, 10, &vdo) != 0)
978 goto end;
979
980 debug->vdo = vdo;
981
982 schedule_work(&debug->sim_work);
983end:
984 return len;
985}
986
Samantha Tranb6a5cd82018-02-01 14:47:16 -0800987static ssize_t dp_debug_write_dump(struct file *file,
988 const char __user *user_buff, size_t count, loff_t *ppos)
989{
990 struct dp_debug_private *debug = file->private_data;
991 char buf[SZ_32];
992 size_t len = 0;
993
994 if (!debug)
995 return -ENODEV;
996
997 if (*ppos)
998 return 0;
999
1000 /* Leave room for termination char */
1001 len = min_t(size_t, count, SZ_32 - 1);
1002 if (copy_from_user(buf, user_buff, len))
1003 goto end;
1004
1005 buf[len] = '\0';
1006
1007 if (sscanf(buf, "%31s", debug->reg_dump) != 1)
1008 goto end;
1009
1010 /* qfprom register dump not supported */
1011 if (!strcmp(debug->reg_dump, "qfprom_physical"))
1012 strlcpy(debug->reg_dump, "clear", sizeof(debug->reg_dump));
1013end:
1014 return len;
1015}
1016
1017static ssize_t dp_debug_read_dump(struct file *file,
1018 char __user *user_buff, size_t count, loff_t *ppos)
1019{
1020 int rc = 0;
1021 struct dp_debug_private *debug = file->private_data;
1022 u8 *buf = NULL;
1023 u32 len = 0;
1024 char prefix[SZ_32];
1025
1026 if (!debug)
1027 return -ENODEV;
1028
1029 if (*ppos)
1030 return 0;
1031
1032 if (!debug->usbpd->hpd_high || !strlen(debug->reg_dump))
1033 goto end;
1034
1035 rc = debug->catalog->get_reg_dump(debug->catalog,
1036 debug->reg_dump, &buf, &len);
1037 if (rc)
1038 goto end;
1039
1040 snprintf(prefix, sizeof(prefix), "%s: ", debug->reg_dump);
1041 print_hex_dump(KERN_DEBUG, prefix, DUMP_PREFIX_NONE,
1042 16, 4, buf, len, false);
1043
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +05301044 len = min_t(size_t, count, len);
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001045 if (copy_to_user(user_buff, buf, len))
1046 return -EFAULT;
1047
1048 *ppos += len;
1049end:
1050 return len;
1051}
1052
Samantha Tran2d1ed732017-07-31 17:30:14 -07001053static const struct file_operations dp_debug_fops = {
1054 .open = simple_open,
1055 .read = dp_debug_read_info,
1056};
1057
1058static const struct file_operations edid_modes_fops = {
1059 .open = simple_open,
1060 .read = dp_debug_read_edid_modes,
1061 .write = dp_debug_write_edid_modes,
1062};
1063
1064static const struct file_operations hpd_fops = {
1065 .open = simple_open,
1066 .write = dp_debug_write_hpd,
1067};
1068
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001069static const struct file_operations edid_fops = {
1070 .open = simple_open,
1071 .write = dp_debug_write_edid,
1072};
1073
Ajay Singh Parmard937eb22017-10-17 19:58:19 -07001074static const struct file_operations dpcd_fops = {
1075 .open = simple_open,
1076 .write = dp_debug_write_dpcd,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001077 .read = dp_debug_read_dpcd,
Ajay Singh Parmard937eb22017-10-17 19:58:19 -07001078};
1079
Samantha Tran2d1ed732017-07-31 17:30:14 -07001080static const struct file_operations connected_fops = {
1081 .open = simple_open,
1082 .read = dp_debug_read_connected,
1083};
1084
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301085static const struct file_operations bw_code_fops = {
1086 .open = simple_open,
1087 .read = dp_debug_bw_code_read,
1088 .write = dp_debug_bw_code_write,
1089};
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001090static const struct file_operations exe_mode_fops = {
1091 .open = simple_open,
1092 .write = dp_debug_write_exe_mode,
1093};
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301094
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +05301095static const struct file_operations tpg_fops = {
1096 .open = simple_open,
1097 .read = dp_debug_tpg_read,
1098 .write = dp_debug_tpg_write,
1099};
1100
Ajay Singh Parmar973cab12017-11-15 15:33:33 -08001101static const struct file_operations hdr_fops = {
1102 .open = simple_open,
1103 .write = dp_debug_write_hdr,
1104 .read = dp_debug_read_hdr,
1105};
1106
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001107static const struct file_operations sim_fops = {
1108 .open = simple_open,
1109 .write = dp_debug_write_sim,
1110};
1111
1112static const struct file_operations attention_fops = {
1113 .open = simple_open,
1114 .write = dp_debug_write_attention,
1115};
1116
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001117static const struct file_operations dump_fops = {
1118 .open = simple_open,
1119 .write = dp_debug_write_dump,
1120 .read = dp_debug_read_dump,
1121};
1122
Samantha Tran2d1ed732017-07-31 17:30:14 -07001123static int dp_debug_init(struct dp_debug *dp_debug)
1124{
1125 int rc = 0;
1126 struct dp_debug_private *debug = container_of(dp_debug,
1127 struct dp_debug_private, dp_debug);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001128 struct dentry *dir, *file;
Samantha Tran2d1ed732017-07-31 17:30:14 -07001129
1130 dir = debugfs_create_dir(DEBUG_NAME, NULL);
1131 if (IS_ERR_OR_NULL(dir)) {
Padmanabhan Komandurue5034142017-11-13 16:50:19 +05301132 if (!dir)
1133 rc = -EINVAL;
1134 else
1135 rc = PTR_ERR(dir);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001136 pr_err("[%s] debugfs create dir failed, rc = %d\n",
1137 DEBUG_NAME, rc);
1138 goto error;
1139 }
1140
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001141 debug->root = dir;
1142
Samantha Tran2d1ed732017-07-31 17:30:14 -07001143 file = debugfs_create_file("dp_debug", 0444, dir,
1144 debug, &dp_debug_fops);
1145 if (IS_ERR_OR_NULL(file)) {
1146 rc = PTR_ERR(file);
1147 pr_err("[%s] debugfs create file failed, rc=%d\n",
1148 DEBUG_NAME, rc);
1149 goto error_remove_dir;
1150 }
1151
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001152 file = debugfs_create_file("edid_modes", 0644, dir,
Samantha Tran2d1ed732017-07-31 17:30:14 -07001153 debug, &edid_modes_fops);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001154 if (IS_ERR_OR_NULL(file)) {
1155 rc = PTR_ERR(file);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001156 pr_err("[%s] debugfs create edid_modes failed, rc=%d\n",
1157 DEBUG_NAME, rc);
1158 goto error_remove_dir;
1159 }
1160
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001161 file = debugfs_create_file("hpd", 0644, dir,
Samantha Tran2d1ed732017-07-31 17:30:14 -07001162 debug, &hpd_fops);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001163 if (IS_ERR_OR_NULL(file)) {
1164 rc = PTR_ERR(file);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001165 pr_err("[%s] debugfs hpd failed, rc=%d\n",
1166 DEBUG_NAME, rc);
1167 goto error_remove_dir;
1168 }
1169
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001170 file = debugfs_create_file("connected", 0444, dir,
Samantha Tran2d1ed732017-07-31 17:30:14 -07001171 debug, &connected_fops);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001172 if (IS_ERR_OR_NULL(file)) {
1173 rc = PTR_ERR(file);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001174 pr_err("[%s] debugfs connected failed, rc=%d\n",
1175 DEBUG_NAME, rc);
1176 goto error_remove_dir;
1177 }
1178
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001179 file = debugfs_create_file("max_bw_code", 0644, dir,
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301180 debug, &bw_code_fops);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001181 if (IS_ERR_OR_NULL(file)) {
1182 rc = PTR_ERR(file);
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301183 pr_err("[%s] debugfs max_bw_code failed, rc=%d\n",
1184 DEBUG_NAME, rc);
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001185 }
1186
1187 file = debugfs_create_file("exe_mode", 0644, dir,
1188 debug, &exe_mode_fops);
1189 if (IS_ERR_OR_NULL(file)) {
1190 rc = PTR_ERR(file);
1191 pr_err("[%s] debugfs register failed, rc=%d\n",
1192 DEBUG_NAME, rc);
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301193 }
1194
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001195 file = debugfs_create_file("edid", 0644, dir,
1196 debug, &edid_fops);
1197 if (IS_ERR_OR_NULL(file)) {
1198 rc = PTR_ERR(file);
1199 pr_err("[%s] debugfs edid failed, rc=%d\n",
1200 DEBUG_NAME, rc);
1201 goto error_remove_dir;
1202 }
1203
Ajay Singh Parmard937eb22017-10-17 19:58:19 -07001204 file = debugfs_create_file("dpcd", 0644, dir,
1205 debug, &dpcd_fops);
1206 if (IS_ERR_OR_NULL(file)) {
1207 rc = PTR_ERR(file);
1208 pr_err("[%s] debugfs dpcd failed, rc=%d\n",
1209 DEBUG_NAME, rc);
1210 goto error_remove_dir;
1211 }
1212
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +05301213 file = debugfs_create_file("tpg_ctrl", 0644, dir,
1214 debug, &tpg_fops);
1215 if (IS_ERR_OR_NULL(file)) {
1216 rc = PTR_ERR(file);
1217 pr_err("[%s] debugfs tpg failed, rc=%d\n",
1218 DEBUG_NAME, rc);
1219 goto error_remove_dir;
1220 }
1221
Ajay Singh Parmar973cab12017-11-15 15:33:33 -08001222 file = debugfs_create_file("hdr", 0644, dir,
1223 debug, &hdr_fops);
1224
1225 if (IS_ERR_OR_NULL(file)) {
1226 rc = PTR_ERR(file);
1227 pr_err("[%s] debugfs hdr failed, rc=%d\n",
1228 DEBUG_NAME, rc);
1229 goto error_remove_dir;
1230 }
1231
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001232 file = debugfs_create_file("sim", 0644, dir,
1233 debug, &sim_fops);
1234
1235 if (IS_ERR_OR_NULL(file)) {
1236 rc = PTR_ERR(file);
1237 pr_err("[%s] debugfs sim failed, rc=%d\n",
1238 DEBUG_NAME, rc);
1239 goto error_remove_dir;
1240 }
1241
1242 file = debugfs_create_file("attention", 0644, dir,
1243 debug, &attention_fops);
1244
1245 if (IS_ERR_OR_NULL(file)) {
1246 rc = PTR_ERR(file);
1247 pr_err("[%s] debugfs attention failed, rc=%d\n",
1248 DEBUG_NAME, rc);
1249 goto error_remove_dir;
1250 }
1251
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001252 file = debugfs_create_file("dump", 0644, dir,
1253 debug, &dump_fops);
1254
1255 if (IS_ERR_OR_NULL(file)) {
1256 rc = PTR_ERR(file);
1257 pr_err("[%s] debugfs dump failed, rc=%d\n",
1258 DEBUG_NAME, rc);
1259 goto error_remove_dir;
1260 }
1261
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001262 return 0;
1263
Samantha Tran2d1ed732017-07-31 17:30:14 -07001264error_remove_dir:
Padmanabhan Komandurue5034142017-11-13 16:50:19 +05301265 if (!file)
1266 rc = -EINVAL;
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001267 debugfs_remove_recursive(dir);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001268error:
1269 return rc;
1270}
1271
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001272static void dp_debug_sim_work(struct work_struct *work)
1273{
1274 struct dp_debug_private *debug =
1275 container_of(work, typeof(*debug), sim_work);
1276
1277 debug->usbpd->simulate_attention(debug->usbpd, debug->vdo);
1278}
1279
Samantha Tran2d1ed732017-07-31 17:30:14 -07001280struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,
1281 struct dp_usbpd *usbpd, struct dp_link *link,
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001282 struct dp_aux *aux, struct drm_connector **connector,
1283 struct dp_catalog *catalog)
Samantha Tran2d1ed732017-07-31 17:30:14 -07001284{
1285 int rc = 0;
1286 struct dp_debug_private *debug;
1287 struct dp_debug *dp_debug;
1288
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001289 if (!dev || !panel || !usbpd || !link || !catalog) {
Samantha Tran2d1ed732017-07-31 17:30:14 -07001290 pr_err("invalid input\n");
1291 rc = -EINVAL;
1292 goto error;
1293 }
1294
1295 debug = devm_kzalloc(dev, sizeof(*debug), GFP_KERNEL);
1296 if (!debug) {
1297 rc = -ENOMEM;
1298 goto error;
1299 }
1300
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001301 INIT_WORK(&debug->sim_work, dp_debug_sim_work);
Ajay Singh Parmard937eb22017-10-17 19:58:19 -07001302
Samantha Tran2d1ed732017-07-31 17:30:14 -07001303 debug->dp_debug.debug_en = false;
1304 debug->usbpd = usbpd;
1305 debug->link = link;
1306 debug->panel = panel;
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001307 debug->aux = aux;
Samantha Tran2d1ed732017-07-31 17:30:14 -07001308 debug->dev = dev;
1309 debug->connector = connector;
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001310 debug->catalog = catalog;
Samantha Tran2d1ed732017-07-31 17:30:14 -07001311
1312 dp_debug = &debug->dp_debug;
1313 dp_debug->vdisplay = 0;
1314 dp_debug->hdisplay = 0;
1315 dp_debug->vrefresh = 0;
1316
Ajay Singh Parmar668ca742019-01-16 21:50:19 -08001317 mutex_init(&debug->lock);
1318
Tatenda Chipeperekwa47ddbcd2017-08-30 13:43:21 -07001319 rc = dp_debug_init(dp_debug);
1320 if (rc) {
1321 devm_kfree(dev, debug);
1322 goto error;
1323 }
Samantha Tran2d1ed732017-07-31 17:30:14 -07001324
1325 return dp_debug;
1326error:
1327 return ERR_PTR(rc);
1328}
1329
1330static int dp_debug_deinit(struct dp_debug *dp_debug)
1331{
1332 struct dp_debug_private *debug;
1333
1334 if (!dp_debug)
1335 return -EINVAL;
1336
1337 debug = container_of(dp_debug, struct dp_debug_private, dp_debug);
1338
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001339 debugfs_remove_recursive(debug->root);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001340
1341 return 0;
1342}
1343
1344void dp_debug_put(struct dp_debug *dp_debug)
1345{
1346 struct dp_debug_private *debug;
1347
1348 if (!dp_debug)
1349 return;
1350
1351 debug = container_of(dp_debug, struct dp_debug_private, dp_debug);
1352
1353 dp_debug_deinit(dp_debug);
1354
Ajay Singh Parmar668ca742019-01-16 21:50:19 -08001355 mutex_destroy(&debug->lock);
1356
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001357 if (debug->edid)
1358 devm_kfree(debug->dev, debug->edid);
1359
1360 if (debug->dpcd)
1361 devm_kfree(debug->dev, debug->dpcd);
1362
Tatenda Chipeperekwa47ddbcd2017-08-30 13:43:21 -07001363 devm_kfree(debug->dev, debug);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001364}