blob: 386c56cd7581a186068b643f64a47a5885d963d1 [file] [log] [blame]
Samantha Tran2d1ed732017-07-31 17:30:14 -07001/*
Narender Ankamb067def2020-01-06 15:06:10 +05302 * Copyright (c) 2017-2020, 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,
Narender Ankamb067def2020-01-06 15:06:10 +0530536 "%d %s %d %d %d %d %d 0x%x\n",
537 mode->vic_id, mode->name, mode->vrefresh,
538 mode->picture_aspect_ratio, mode->htotal, mode->vtotal,
539 mode->clock, mode->flags);
Padmanabhan Komanduru682ef582017-12-20 16:26:46 +0530540 if (dp_debug_check_buffer_overflow(ret, &max_size, &len))
541 break;
Samantha Tran2d1ed732017-07-31 17:30:14 -0700542 }
Lloyd Atkinsonc34a6ff2017-11-06 14:00:16 -0500543 mutex_unlock(&connector->dev->mode_config.mutex);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700544
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530545 len = min_t(size_t, count, len);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700546 if (copy_to_user(user_buff, buf, len)) {
547 kfree(buf);
548 rc = -EFAULT;
549 goto error;
550 }
551
552 *ppos += len;
553 kfree(buf);
554
555 return len;
556error:
557 return rc;
558}
559
Samantha Tran2d1ed732017-07-31 17:30:14 -0700560static ssize_t dp_debug_read_info(struct file *file, char __user *user_buff,
561 size_t count, loff_t *ppos)
562{
563 struct dp_debug_private *debug = file->private_data;
564 char *buf;
565 u32 len = 0, rc = 0;
Samantha Tran2d1ed732017-07-31 17:30:14 -0700566 u32 max_size = SZ_4K;
567
568 if (!debug)
569 return -ENODEV;
570
571 if (*ppos)
572 return 0;
573
574 buf = kzalloc(SZ_4K, GFP_KERNEL);
Aravind Venkateswaranc140b8f2018-07-19 14:53:41 -0700575 if (ZERO_OR_NULL_PTR(buf))
Samantha Tran2d1ed732017-07-31 17:30:14 -0700576 return -ENOMEM;
577
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800578 rc = snprintf(buf + len, max_size, "\tstate=0x%x\n", debug->aux->state);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700579 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
580 goto error;
581
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800582 rc = snprintf(buf + len, max_size, "\tlink_rate=%u\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700583 debug->panel->link_info.rate);
584 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
585 goto error;
586
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800587 rc = snprintf(buf + len, max_size, "\tnum_lanes=%u\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700588 debug->panel->link_info.num_lanes);
589 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
590 goto error;
591
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800592 rc = snprintf(buf + len, max_size, "\tresolution=%dx%d@%dHz\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700593 debug->panel->pinfo.h_active,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800594 debug->panel->pinfo.v_active,
Samantha Tran2d1ed732017-07-31 17:30:14 -0700595 debug->panel->pinfo.refresh_rate);
596 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
597 goto error;
598
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800599 rc = snprintf(buf + len, max_size, "\tpclock=%dKHz\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700600 debug->panel->pinfo.pixel_clk_khz);
601 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
602 goto error;
603
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800604 rc = snprintf(buf + len, max_size, "\tbpp=%d\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700605 debug->panel->pinfo.bpp);
606 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
607 goto error;
608
609 /* Link Information */
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800610 rc = snprintf(buf + len, max_size, "\ttest_req=%s\n",
611 dp_link_get_test_name(debug->link->sink_request));
Samantha Tran2d1ed732017-07-31 17:30:14 -0700612 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
613 goto error;
614
615 rc = snprintf(buf + len, max_size,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800616 "\tlane_count=%d\n", debug->link->link_params.lane_count);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700617 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
618 goto error;
619
620 rc = snprintf(buf + len, max_size,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800621 "\tbw_code=%d\n", debug->link->link_params.bw_code);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700622 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
623 goto error;
624
625 rc = snprintf(buf + len, max_size,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800626 "\tv_level=%d\n", debug->link->phy_params.v_level);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700627 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
628 goto error;
629
630 rc = snprintf(buf + len, max_size,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800631 "\tp_level=%d\n", debug->link->phy_params.p_level);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700632 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
633 goto error;
634
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530635 len = min_t(size_t, count, len);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700636 if (copy_to_user(user_buff, buf, len))
637 goto error;
638
639 *ppos += len;
640
641 kfree(buf);
642 return len;
643error:
644 kfree(buf);
645 return -EINVAL;
646}
647
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +0530648static ssize_t dp_debug_bw_code_read(struct file *file,
649 char __user *user_buff, size_t count, loff_t *ppos)
650{
651 struct dp_debug_private *debug = file->private_data;
652 char *buf;
653 u32 len = 0;
654
655 if (!debug)
656 return -ENODEV;
657
658 if (*ppos)
659 return 0;
660
661 buf = kzalloc(SZ_4K, GFP_KERNEL);
Aravind Venkateswaranc140b8f2018-07-19 14:53:41 -0700662 if (ZERO_OR_NULL_PTR(buf))
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +0530663 return -ENOMEM;
664
665 len += snprintf(buf + len, (SZ_4K - len),
666 "max_bw_code = %d\n", debug->panel->max_bw_code);
667
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530668 len = min_t(size_t, count, len);
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +0530669 if (copy_to_user(user_buff, buf, len)) {
670 kfree(buf);
671 return -EFAULT;
672 }
673
674 *ppos += len;
675 kfree(buf);
676 return len;
677}
678
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +0530679static ssize_t dp_debug_tpg_read(struct file *file,
680 char __user *user_buff, size_t count, loff_t *ppos)
681{
682 struct dp_debug_private *debug = file->private_data;
683 char buf[SZ_8];
684 u32 len = 0;
685
686 if (!debug)
687 return -ENODEV;
688
689 if (*ppos)
690 return 0;
691
692 len += snprintf(buf, SZ_8, "%d\n", debug->dp_debug.tpg_state);
693
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530694 len = min_t(size_t, count, len);
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +0530695 if (copy_to_user(user_buff, buf, len))
696 return -EFAULT;
697
698 *ppos += len;
699 return len;
700}
701
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800702static ssize_t dp_debug_write_hdr(struct file *file,
703 const char __user *user_buff, size_t count, loff_t *ppos)
704{
705 struct drm_connector *connector;
706 struct sde_connector *c_conn;
707 struct sde_connector_state *c_state;
708 struct dp_debug_private *debug = file->private_data;
Jayant Shekhar82e3c882018-06-22 18:04:09 +0530709 char buf[SZ_512];
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800710 size_t len = 0;
711
712 if (!debug)
713 return -ENODEV;
714
715 if (*ppos)
716 return 0;
717
718 connector = *debug->connector;
719 c_conn = to_sde_connector(connector);
720 c_state = to_sde_connector_state(connector->state);
721
722 /* Leave room for termination char */
Jayant Shekhar82e3c882018-06-22 18:04:09 +0530723 len = min_t(size_t, count, SZ_512 - 1);
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800724 if (copy_from_user(buf, user_buff, len))
725 goto end;
726
727 buf[len] = '\0';
728
729 if (sscanf(buf, "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
730 &c_state->hdr_meta.hdr_supported,
731 &c_state->hdr_meta.hdr_state,
732 &c_state->hdr_meta.eotf,
733 &c_state->hdr_meta.display_primaries_x[0],
734 &c_state->hdr_meta.display_primaries_x[1],
735 &c_state->hdr_meta.display_primaries_x[2],
736 &c_state->hdr_meta.display_primaries_y[0],
737 &c_state->hdr_meta.display_primaries_y[1],
738 &c_state->hdr_meta.display_primaries_y[2],
739 &c_state->hdr_meta.white_point_x,
740 &c_state->hdr_meta.white_point_y,
741 &c_state->hdr_meta.max_luminance,
742 &c_state->hdr_meta.min_luminance,
743 &c_state->hdr_meta.max_content_light_level,
744 &c_state->hdr_meta.max_average_light_level) != 15) {
745 pr_err("invalid input\n");
746 len = -EINVAL;
747 }
Ajay Singh Parmar87af50b2017-12-22 22:22:55 -0800748
749 debug->panel->setup_hdr(debug->panel, &c_state->hdr_meta);
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800750end:
751 return len;
752}
753
754static ssize_t dp_debug_read_hdr(struct file *file,
755 char __user *user_buff, size_t count, loff_t *ppos)
756{
757 struct dp_debug_private *debug = file->private_data;
758 char *buf;
759 u32 len = 0, i;
760 u32 max_size = SZ_4K;
761 int rc = 0;
762 struct drm_connector *connector;
763 struct sde_connector *c_conn;
764 struct sde_connector_state *c_state;
765 struct drm_msm_ext_hdr_metadata *hdr;
766
767 if (!debug) {
768 pr_err("invalid data\n");
769 rc = -ENODEV;
770 goto error;
771 }
772
773 connector = *debug->connector;
774
775 if (!connector) {
776 pr_err("connector is NULL\n");
777 rc = -EINVAL;
778 goto error;
779 }
780
781 if (*ppos)
782 goto error;
783
784 buf = kzalloc(SZ_4K, GFP_KERNEL);
Aravind Venkateswaranc140b8f2018-07-19 14:53:41 -0700785 if (ZERO_OR_NULL_PTR(buf)) {
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800786 rc = -ENOMEM;
787 goto error;
788 }
789
790 c_conn = to_sde_connector(connector);
791 c_state = to_sde_connector_state(connector->state);
792
793 hdr = &c_state->hdr_meta;
794
795 rc = snprintf(buf + len, max_size,
796 "============SINK HDR PARAMETERS===========\n");
797 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
798 goto error;
799
800 rc = snprintf(buf + len, max_size, "eotf = %d\n",
801 connector->hdr_eotf);
802 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
803 goto error;
804
805 rc = snprintf(buf + len, max_size, "type_one = %d\n",
806 connector->hdr_metadata_type_one);
807 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
808 goto error;
809
810 rc = snprintf(buf + len, max_size, "max_luminance = %d\n",
811 connector->hdr_max_luminance);
812 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
813 goto error;
814
815 rc = snprintf(buf + len, max_size, "avg_luminance = %d\n",
816 connector->hdr_avg_luminance);
817 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
818 goto error;
819
820 rc = snprintf(buf + len, max_size, "min_luminance = %d\n",
821 connector->hdr_min_luminance);
822 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
823 goto error;
824
825 rc = snprintf(buf + len, max_size,
826 "============VIDEO HDR PARAMETERS===========\n");
827 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
828 goto error;
829
830 rc = snprintf(buf + len, max_size, "hdr_state = %d\n", hdr->hdr_state);
831 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
832 goto error;
833
834 rc = snprintf(buf + len, max_size, "hdr_supported = %d\n",
835 hdr->hdr_supported);
836 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
837 goto error;
838
839 rc = snprintf(buf + len, max_size, "eotf = %d\n", hdr->eotf);
840 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
841 goto error;
842
843 rc = snprintf(buf + len, max_size, "white_point_x = %d\n",
844 hdr->white_point_x);
845 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
846 goto error;
847
848 rc = snprintf(buf + len, max_size, "white_point_y = %d\n",
849 hdr->white_point_y);
850 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
851 goto error;
852
853 rc = snprintf(buf + len, max_size, "max_luminance = %d\n",
854 hdr->max_luminance);
855 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
856 goto error;
857
858 rc = snprintf(buf + len, max_size, "min_luminance = %d\n",
859 hdr->min_luminance);
860 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
861 goto error;
862
863 rc = snprintf(buf + len, max_size, "max_content_light_level = %d\n",
864 hdr->max_content_light_level);
865 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
866 goto error;
867
868 rc = snprintf(buf + len, max_size, "min_content_light_level = %d\n",
869 hdr->max_average_light_level);
870 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
871 goto error;
872
873 for (i = 0; i < HDR_PRIMARIES_COUNT; i++) {
874 rc = snprintf(buf + len, max_size, "primaries_x[%d] = %d\n",
875 i, hdr->display_primaries_x[i]);
876 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
877 goto error;
878
879 rc = snprintf(buf + len, max_size, "primaries_y[%d] = %d\n",
880 i, hdr->display_primaries_y[i]);
881 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
882 goto error;
883 }
884
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +0530885 len = min_t(size_t, count, len);
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800886 if (copy_to_user(user_buff, buf, len)) {
887 kfree(buf);
888 rc = -EFAULT;
889 goto error;
890 }
891
892 *ppos += len;
893 kfree(buf);
894
895 return len;
896error:
897 return rc;
898}
899
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800900static ssize_t dp_debug_write_sim(struct file *file,
901 const char __user *user_buff, size_t count, loff_t *ppos)
902{
903 struct dp_debug_private *debug = file->private_data;
904 char buf[SZ_8];
905 size_t len = 0;
906 int sim;
907
908 if (!debug)
909 return -ENODEV;
910
911 if (*ppos)
912 return 0;
913
Ajay Singh Parmar668ca742019-01-16 21:50:19 -0800914 mutex_lock(&debug->lock);
915
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800916 /* Leave room for termination char */
917 len = min_t(size_t, count, SZ_8 - 1);
918 if (copy_from_user(buf, user_buff, len))
919 goto end;
920
921 buf[len] = '\0';
922
923 if (kstrtoint(buf, 10, &sim) != 0)
924 goto end;
925
926 if (sim) {
927 if (dp_debug_get_edid_buf(debug))
928 goto end;
929
930 if (dp_debug_get_dpcd_buf(debug))
931 goto error;
932 } else {
933 if (debug->edid) {
934 devm_kfree(debug->dev, debug->edid);
935 debug->edid = NULL;
936 }
937
938 if (debug->dpcd) {
939 devm_kfree(debug->dev, debug->dpcd);
940 debug->dpcd = NULL;
941 }
942 }
943
944 debug->dp_debug.sim_mode = !!sim;
945
946 debug->aux->set_sim_mode(debug->aux, debug->dp_debug.sim_mode,
947 debug->edid, debug->dpcd);
948end:
Ajay Singh Parmar668ca742019-01-16 21:50:19 -0800949 mutex_unlock(&debug->lock);
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800950 return len;
951error:
952 devm_kfree(debug->dev, debug->edid);
Ajay Singh Parmar668ca742019-01-16 21:50:19 -0800953 mutex_unlock(&debug->lock);
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800954 return len;
955}
956
957static ssize_t dp_debug_write_attention(struct file *file,
958 const char __user *user_buff, size_t count, loff_t *ppos)
959{
960 struct dp_debug_private *debug = file->private_data;
961 char buf[SZ_8];
962 size_t len = 0;
963 int vdo;
964
965 if (!debug)
966 return -ENODEV;
967
968 if (*ppos)
969 return 0;
970
971 /* Leave room for termination char */
972 len = min_t(size_t, count, SZ_8 - 1);
973 if (copy_from_user(buf, user_buff, len))
974 goto end;
975
976 buf[len] = '\0';
977
978 if (kstrtoint(buf, 10, &vdo) != 0)
979 goto end;
980
981 debug->vdo = vdo;
982
983 schedule_work(&debug->sim_work);
984end:
985 return len;
986}
987
Samantha Tranb6a5cd82018-02-01 14:47:16 -0800988static ssize_t dp_debug_write_dump(struct file *file,
989 const char __user *user_buff, size_t count, loff_t *ppos)
990{
991 struct dp_debug_private *debug = file->private_data;
992 char buf[SZ_32];
993 size_t len = 0;
994
995 if (!debug)
996 return -ENODEV;
997
998 if (*ppos)
999 return 0;
1000
1001 /* Leave room for termination char */
1002 len = min_t(size_t, count, SZ_32 - 1);
1003 if (copy_from_user(buf, user_buff, len))
1004 goto end;
1005
1006 buf[len] = '\0';
1007
1008 if (sscanf(buf, "%31s", debug->reg_dump) != 1)
1009 goto end;
1010
1011 /* qfprom register dump not supported */
1012 if (!strcmp(debug->reg_dump, "qfprom_physical"))
1013 strlcpy(debug->reg_dump, "clear", sizeof(debug->reg_dump));
1014end:
1015 return len;
1016}
1017
1018static ssize_t dp_debug_read_dump(struct file *file,
1019 char __user *user_buff, size_t count, loff_t *ppos)
1020{
1021 int rc = 0;
1022 struct dp_debug_private *debug = file->private_data;
1023 u8 *buf = NULL;
1024 u32 len = 0;
1025 char prefix[SZ_32];
1026
1027 if (!debug)
1028 return -ENODEV;
1029
1030 if (*ppos)
1031 return 0;
1032
1033 if (!debug->usbpd->hpd_high || !strlen(debug->reg_dump))
1034 goto end;
1035
1036 rc = debug->catalog->get_reg_dump(debug->catalog,
1037 debug->reg_dump, &buf, &len);
1038 if (rc)
1039 goto end;
1040
1041 snprintf(prefix, sizeof(prefix), "%s: ", debug->reg_dump);
1042 print_hex_dump(KERN_DEBUG, prefix, DUMP_PREFIX_NONE,
1043 16, 4, buf, len, false);
1044
Sankeerth Billakantidf847fe2019-07-11 11:49:48 +05301045 len = min_t(size_t, count, len);
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001046 if (copy_to_user(user_buff, buf, len))
1047 return -EFAULT;
1048
1049 *ppos += len;
1050end:
1051 return len;
1052}
1053
Samantha Tran2d1ed732017-07-31 17:30:14 -07001054static const struct file_operations dp_debug_fops = {
1055 .open = simple_open,
1056 .read = dp_debug_read_info,
1057};
1058
1059static const struct file_operations edid_modes_fops = {
1060 .open = simple_open,
1061 .read = dp_debug_read_edid_modes,
1062 .write = dp_debug_write_edid_modes,
1063};
1064
1065static const struct file_operations hpd_fops = {
1066 .open = simple_open,
1067 .write = dp_debug_write_hpd,
1068};
1069
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001070static const struct file_operations edid_fops = {
1071 .open = simple_open,
1072 .write = dp_debug_write_edid,
1073};
1074
Ajay Singh Parmard937eb22017-10-17 19:58:19 -07001075static const struct file_operations dpcd_fops = {
1076 .open = simple_open,
1077 .write = dp_debug_write_dpcd,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001078 .read = dp_debug_read_dpcd,
Ajay Singh Parmard937eb22017-10-17 19:58:19 -07001079};
1080
Samantha Tran2d1ed732017-07-31 17:30:14 -07001081static const struct file_operations connected_fops = {
1082 .open = simple_open,
1083 .read = dp_debug_read_connected,
1084};
1085
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301086static const struct file_operations bw_code_fops = {
1087 .open = simple_open,
1088 .read = dp_debug_bw_code_read,
1089 .write = dp_debug_bw_code_write,
1090};
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001091static const struct file_operations exe_mode_fops = {
1092 .open = simple_open,
1093 .write = dp_debug_write_exe_mode,
1094};
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301095
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +05301096static const struct file_operations tpg_fops = {
1097 .open = simple_open,
1098 .read = dp_debug_tpg_read,
1099 .write = dp_debug_tpg_write,
1100};
1101
Ajay Singh Parmar973cab12017-11-15 15:33:33 -08001102static const struct file_operations hdr_fops = {
1103 .open = simple_open,
1104 .write = dp_debug_write_hdr,
1105 .read = dp_debug_read_hdr,
1106};
1107
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001108static const struct file_operations sim_fops = {
1109 .open = simple_open,
1110 .write = dp_debug_write_sim,
1111};
1112
1113static const struct file_operations attention_fops = {
1114 .open = simple_open,
1115 .write = dp_debug_write_attention,
1116};
1117
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001118static const struct file_operations dump_fops = {
1119 .open = simple_open,
1120 .write = dp_debug_write_dump,
1121 .read = dp_debug_read_dump,
1122};
1123
Samantha Tran2d1ed732017-07-31 17:30:14 -07001124static int dp_debug_init(struct dp_debug *dp_debug)
1125{
1126 int rc = 0;
1127 struct dp_debug_private *debug = container_of(dp_debug,
1128 struct dp_debug_private, dp_debug);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001129 struct dentry *dir, *file;
Samantha Tran2d1ed732017-07-31 17:30:14 -07001130
1131 dir = debugfs_create_dir(DEBUG_NAME, NULL);
1132 if (IS_ERR_OR_NULL(dir)) {
Padmanabhan Komandurue5034142017-11-13 16:50:19 +05301133 if (!dir)
1134 rc = -EINVAL;
1135 else
1136 rc = PTR_ERR(dir);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001137 pr_err("[%s] debugfs create dir failed, rc = %d\n",
1138 DEBUG_NAME, rc);
1139 goto error;
1140 }
1141
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001142 debug->root = dir;
1143
Samantha Tran2d1ed732017-07-31 17:30:14 -07001144 file = debugfs_create_file("dp_debug", 0444, dir,
1145 debug, &dp_debug_fops);
1146 if (IS_ERR_OR_NULL(file)) {
1147 rc = PTR_ERR(file);
1148 pr_err("[%s] debugfs create file failed, rc=%d\n",
1149 DEBUG_NAME, rc);
1150 goto error_remove_dir;
1151 }
1152
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001153 file = debugfs_create_file("edid_modes", 0644, dir,
Samantha Tran2d1ed732017-07-31 17:30:14 -07001154 debug, &edid_modes_fops);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001155 if (IS_ERR_OR_NULL(file)) {
1156 rc = PTR_ERR(file);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001157 pr_err("[%s] debugfs create edid_modes failed, rc=%d\n",
1158 DEBUG_NAME, rc);
1159 goto error_remove_dir;
1160 }
1161
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001162 file = debugfs_create_file("hpd", 0644, dir,
Samantha Tran2d1ed732017-07-31 17:30:14 -07001163 debug, &hpd_fops);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001164 if (IS_ERR_OR_NULL(file)) {
1165 rc = PTR_ERR(file);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001166 pr_err("[%s] debugfs hpd failed, rc=%d\n",
1167 DEBUG_NAME, rc);
1168 goto error_remove_dir;
1169 }
1170
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001171 file = debugfs_create_file("connected", 0444, dir,
Samantha Tran2d1ed732017-07-31 17:30:14 -07001172 debug, &connected_fops);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001173 if (IS_ERR_OR_NULL(file)) {
1174 rc = PTR_ERR(file);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001175 pr_err("[%s] debugfs connected failed, rc=%d\n",
1176 DEBUG_NAME, rc);
1177 goto error_remove_dir;
1178 }
1179
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001180 file = debugfs_create_file("max_bw_code", 0644, dir,
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301181 debug, &bw_code_fops);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001182 if (IS_ERR_OR_NULL(file)) {
1183 rc = PTR_ERR(file);
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301184 pr_err("[%s] debugfs max_bw_code failed, rc=%d\n",
1185 DEBUG_NAME, rc);
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001186 }
1187
1188 file = debugfs_create_file("exe_mode", 0644, dir,
1189 debug, &exe_mode_fops);
1190 if (IS_ERR_OR_NULL(file)) {
1191 rc = PTR_ERR(file);
1192 pr_err("[%s] debugfs register failed, rc=%d\n",
1193 DEBUG_NAME, rc);
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301194 }
1195
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001196 file = debugfs_create_file("edid", 0644, dir,
1197 debug, &edid_fops);
1198 if (IS_ERR_OR_NULL(file)) {
1199 rc = PTR_ERR(file);
1200 pr_err("[%s] debugfs edid failed, rc=%d\n",
1201 DEBUG_NAME, rc);
1202 goto error_remove_dir;
1203 }
1204
Ajay Singh Parmard937eb22017-10-17 19:58:19 -07001205 file = debugfs_create_file("dpcd", 0644, dir,
1206 debug, &dpcd_fops);
1207 if (IS_ERR_OR_NULL(file)) {
1208 rc = PTR_ERR(file);
1209 pr_err("[%s] debugfs dpcd failed, rc=%d\n",
1210 DEBUG_NAME, rc);
1211 goto error_remove_dir;
1212 }
1213
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +05301214 file = debugfs_create_file("tpg_ctrl", 0644, dir,
1215 debug, &tpg_fops);
1216 if (IS_ERR_OR_NULL(file)) {
1217 rc = PTR_ERR(file);
1218 pr_err("[%s] debugfs tpg failed, rc=%d\n",
1219 DEBUG_NAME, rc);
1220 goto error_remove_dir;
1221 }
1222
Ajay Singh Parmar973cab12017-11-15 15:33:33 -08001223 file = debugfs_create_file("hdr", 0644, dir,
1224 debug, &hdr_fops);
1225
1226 if (IS_ERR_OR_NULL(file)) {
1227 rc = PTR_ERR(file);
1228 pr_err("[%s] debugfs hdr failed, rc=%d\n",
1229 DEBUG_NAME, rc);
1230 goto error_remove_dir;
1231 }
1232
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001233 file = debugfs_create_file("sim", 0644, dir,
1234 debug, &sim_fops);
1235
1236 if (IS_ERR_OR_NULL(file)) {
1237 rc = PTR_ERR(file);
1238 pr_err("[%s] debugfs sim failed, rc=%d\n",
1239 DEBUG_NAME, rc);
1240 goto error_remove_dir;
1241 }
1242
1243 file = debugfs_create_file("attention", 0644, dir,
1244 debug, &attention_fops);
1245
1246 if (IS_ERR_OR_NULL(file)) {
1247 rc = PTR_ERR(file);
1248 pr_err("[%s] debugfs attention failed, rc=%d\n",
1249 DEBUG_NAME, rc);
1250 goto error_remove_dir;
1251 }
1252
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001253 file = debugfs_create_file("dump", 0644, dir,
1254 debug, &dump_fops);
1255
1256 if (IS_ERR_OR_NULL(file)) {
1257 rc = PTR_ERR(file);
1258 pr_err("[%s] debugfs dump failed, rc=%d\n",
1259 DEBUG_NAME, rc);
1260 goto error_remove_dir;
1261 }
1262
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001263 return 0;
1264
Samantha Tran2d1ed732017-07-31 17:30:14 -07001265error_remove_dir:
Padmanabhan Komandurue5034142017-11-13 16:50:19 +05301266 if (!file)
1267 rc = -EINVAL;
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001268 debugfs_remove_recursive(dir);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001269error:
1270 return rc;
1271}
1272
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001273static void dp_debug_sim_work(struct work_struct *work)
1274{
1275 struct dp_debug_private *debug =
1276 container_of(work, typeof(*debug), sim_work);
1277
1278 debug->usbpd->simulate_attention(debug->usbpd, debug->vdo);
1279}
1280
Samantha Tran2d1ed732017-07-31 17:30:14 -07001281struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,
1282 struct dp_usbpd *usbpd, struct dp_link *link,
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001283 struct dp_aux *aux, struct drm_connector **connector,
1284 struct dp_catalog *catalog)
Samantha Tran2d1ed732017-07-31 17:30:14 -07001285{
1286 int rc = 0;
1287 struct dp_debug_private *debug;
1288 struct dp_debug *dp_debug;
1289
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001290 if (!dev || !panel || !usbpd || !link || !catalog) {
Samantha Tran2d1ed732017-07-31 17:30:14 -07001291 pr_err("invalid input\n");
1292 rc = -EINVAL;
1293 goto error;
1294 }
1295
1296 debug = devm_kzalloc(dev, sizeof(*debug), GFP_KERNEL);
1297 if (!debug) {
1298 rc = -ENOMEM;
1299 goto error;
1300 }
1301
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001302 INIT_WORK(&debug->sim_work, dp_debug_sim_work);
Ajay Singh Parmard937eb22017-10-17 19:58:19 -07001303
Samantha Tran2d1ed732017-07-31 17:30:14 -07001304 debug->dp_debug.debug_en = false;
1305 debug->usbpd = usbpd;
1306 debug->link = link;
1307 debug->panel = panel;
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001308 debug->aux = aux;
Samantha Tran2d1ed732017-07-31 17:30:14 -07001309 debug->dev = dev;
1310 debug->connector = connector;
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001311 debug->catalog = catalog;
Samantha Tran2d1ed732017-07-31 17:30:14 -07001312
1313 dp_debug = &debug->dp_debug;
1314 dp_debug->vdisplay = 0;
1315 dp_debug->hdisplay = 0;
1316 dp_debug->vrefresh = 0;
1317
Ajay Singh Parmar668ca742019-01-16 21:50:19 -08001318 mutex_init(&debug->lock);
1319
Tatenda Chipeperekwa47ddbcd2017-08-30 13:43:21 -07001320 rc = dp_debug_init(dp_debug);
1321 if (rc) {
1322 devm_kfree(dev, debug);
1323 goto error;
1324 }
Samantha Tran2d1ed732017-07-31 17:30:14 -07001325
1326 return dp_debug;
1327error:
1328 return ERR_PTR(rc);
1329}
1330
1331static int dp_debug_deinit(struct dp_debug *dp_debug)
1332{
1333 struct dp_debug_private *debug;
1334
1335 if (!dp_debug)
1336 return -EINVAL;
1337
1338 debug = container_of(dp_debug, struct dp_debug_private, dp_debug);
1339
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001340 debugfs_remove_recursive(debug->root);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001341
1342 return 0;
1343}
1344
1345void dp_debug_put(struct dp_debug *dp_debug)
1346{
1347 struct dp_debug_private *debug;
1348
1349 if (!dp_debug)
1350 return;
1351
1352 debug = container_of(dp_debug, struct dp_debug_private, dp_debug);
1353
1354 dp_debug_deinit(dp_debug);
1355
Ajay Singh Parmar668ca742019-01-16 21:50:19 -08001356 mutex_destroy(&debug->lock);
1357
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001358 if (debug->edid)
1359 devm_kfree(debug->dev, debug->edid);
1360
1361 if (debug->dpcd)
1362 devm_kfree(debug->dev, debug->dpcd);
1363
Tatenda Chipeperekwa47ddbcd2017-08-30 13:43:21 -07001364 devm_kfree(debug->dev, debug);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001365}