blob: 78bea02955fb0ec1cf9a08bc0839e7ebc70f6b16 [file] [log] [blame]
Samantha Tran2d1ed732017-07-31 17:30:14 -07001/*
Ajay Singh Parmar87af50b2017-12-22 22:22:55 -08002 * Copyright (c) 2017-2018, 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;
52};
53
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -080054static int dp_debug_get_edid_buf(struct dp_debug_private *debug)
55{
56 int rc = 0;
57
58 if (!debug->edid) {
59 debug->edid = devm_kzalloc(debug->dev, SZ_256, GFP_KERNEL);
60 if (!debug->edid) {
61 rc = -ENOMEM;
62 goto end;
63 }
64
65 debug->edid_size = SZ_256;
66 }
67end:
68 return rc;
69}
70
71static int dp_debug_get_dpcd_buf(struct dp_debug_private *debug)
72{
73 int rc = 0;
74
75 if (!debug->dpcd) {
76 debug->dpcd = devm_kzalloc(debug->dev, SZ_1K, GFP_KERNEL);
77 if (!debug->dpcd) {
78 rc = -ENOMEM;
79 goto end;
80 }
81
82 debug->dpcd_size = SZ_1K;
83 }
84end:
85 return rc;
86}
87
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -070088static ssize_t dp_debug_write_edid(struct file *file,
89 const char __user *user_buff, size_t count, loff_t *ppos)
90{
91 struct dp_debug_private *debug = file->private_data;
92 u8 *buf = NULL, *buf_t = NULL, *edid = NULL;
93 const int char_to_nib = 2;
94 size_t edid_size = 0;
95 size_t size = 0, edid_buf_index = 0;
96 ssize_t rc = count;
97
98 if (!debug)
99 return -ENODEV;
100
101 if (*ppos)
102 goto bail;
103
104 size = min_t(size_t, count, SZ_1K);
105
106 buf = kzalloc(size, GFP_KERNEL);
107 if (!buf) {
108 rc = -ENOMEM;
109 goto bail;
110 }
111
112 if (copy_from_user(buf, user_buff, size))
113 goto bail;
114
115 edid_size = size / char_to_nib;
116 buf_t = buf;
117
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800118 if (dp_debug_get_edid_buf(debug))
119 goto bail;
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -0700120
121 if (edid_size != debug->edid_size) {
122 pr_debug("clearing debug edid\n");
123 goto bail;
124 }
125
126 while (edid_size--) {
127 char t[3];
128 int d;
129
130 memcpy(t, buf_t, sizeof(char) * char_to_nib);
131 t[char_to_nib] = '\0';
132
133 if (kstrtoint(t, 16, &d)) {
134 pr_err("kstrtoint error\n");
135 goto bail;
136 }
137
138 if (edid_buf_index < debug->edid_size)
139 debug->edid[edid_buf_index++] = d;
140
141 buf_t += char_to_nib;
142 }
143
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -0700144 edid = debug->edid;
145bail:
146 kfree(buf);
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800147
148 if (!debug->dp_debug.sim_mode)
149 debug->panel->set_edid(debug->panel, edid);
150
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -0700151 return rc;
152}
153
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700154static ssize_t dp_debug_write_dpcd(struct file *file,
155 const char __user *user_buff, size_t count, loff_t *ppos)
156{
157 struct dp_debug_private *debug = file->private_data;
158 u8 *buf = NULL, *buf_t = NULL, *dpcd = NULL;
159 const int char_to_nib = 2;
160 size_t dpcd_size = 0;
161 size_t size = 0, dpcd_buf_index = 0;
162 ssize_t rc = count;
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800163 char offset_ch[5];
164 u32 offset;
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700165
166 if (!debug)
167 return -ENODEV;
168
169 if (*ppos)
170 goto bail;
171
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800172 size = min_t(size_t, count, SZ_2K);
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700173
174 buf = kzalloc(size, GFP_KERNEL);
175 if (!buf) {
176 rc = -ENOMEM;
177 goto bail;
178 }
179
180 if (copy_from_user(buf, user_buff, size))
181 goto bail;
182
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800183 memcpy(offset_ch, buf, 4);
184 offset_ch[4] = '\0';
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700185
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800186 if (kstrtoint(offset_ch, 16, &offset)) {
187 pr_err("offset kstrtoint error\n");
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700188 goto bail;
189 }
190
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800191 if (dp_debug_get_dpcd_buf(debug))
192 goto bail;
193
194 if (offset == 0xFFFF) {
195 pr_err("clearing dpcd\n");
196 memset(debug->dpcd, 0, debug->dpcd_size);
197 goto bail;
198 }
199
200 size -= 4;
201
202 dpcd_size = size / char_to_nib;
203 buf_t = buf + 4;
204
205 dpcd_buf_index = offset;
206
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700207 while (dpcd_size--) {
208 char t[3];
209 int d;
210
211 memcpy(t, buf_t, sizeof(char) * char_to_nib);
212 t[char_to_nib] = '\0';
213
214 if (kstrtoint(t, 16, &d)) {
215 pr_err("kstrtoint error\n");
216 goto bail;
217 }
218
219 if (dpcd_buf_index < debug->dpcd_size)
220 debug->dpcd[dpcd_buf_index++] = d;
221
222 buf_t += char_to_nib;
223 }
224
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700225 dpcd = debug->dpcd;
226bail:
227 kfree(buf);
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800228 if (debug->dp_debug.sim_mode)
229 debug->aux->dpcd_updated(debug->aux);
230 else
231 debug->panel->set_dpcd(debug->panel, dpcd);
232
Ajay Singh Parmard937eb22017-10-17 19:58:19 -0700233 return rc;
234}
235
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800236static ssize_t dp_debug_read_dpcd(struct file *file,
237 char __user *user_buff, size_t count, loff_t *ppos)
238{
239 struct dp_debug_private *debug = file->private_data;
240 char buf[SZ_8];
241 u32 len = 0;
242
243 if (!debug)
244 return -ENODEV;
245
246 if (*ppos)
247 return 0;
248
249 len += snprintf(buf, SZ_8, "0x%x\n", debug->aux->reg);
250
251 if (copy_to_user(user_buff, buf, len))
252 return -EFAULT;
253
254 *ppos += len;
255 return len;
256}
257
Samantha Tran2d1ed732017-07-31 17:30:14 -0700258static ssize_t dp_debug_write_hpd(struct file *file,
259 const char __user *user_buff, size_t count, loff_t *ppos)
260{
261 struct dp_debug_private *debug = file->private_data;
262 char buf[SZ_8];
263 size_t len = 0;
264 int hpd;
265
266 if (!debug)
267 return -ENODEV;
268
269 if (*ppos)
270 return 0;
271
272 /* Leave room for termination char */
273 len = min_t(size_t, count, SZ_8 - 1);
274 if (copy_from_user(buf, user_buff, len))
275 goto end;
276
277 buf[len] = '\0';
278
279 if (kstrtoint(buf, 10, &hpd) != 0)
280 goto end;
281
Ajay Singh Parmar25e2ee52017-10-20 23:50:53 -0700282 hpd &= 0x3;
283
284 debug->dp_debug.psm_enabled = !!(hpd & BIT(1));
285
286 debug->usbpd->simulate_connect(debug->usbpd, !!(hpd & BIT(0)));
Samantha Tran2d1ed732017-07-31 17:30:14 -0700287end:
Ajay Singh Parmar25e2ee52017-10-20 23:50:53 -0700288 return len;
Samantha Tran2d1ed732017-07-31 17:30:14 -0700289}
290
291static ssize_t dp_debug_write_edid_modes(struct file *file,
292 const char __user *user_buff, size_t count, loff_t *ppos)
293{
294 struct dp_debug_private *debug = file->private_data;
295 char buf[SZ_32];
296 size_t len = 0;
Tatenda Chipeperekwa59510402017-09-28 12:50:58 -0700297 int hdisplay = 0, vdisplay = 0, vrefresh = 0, aspect_ratio;
Samantha Tran2d1ed732017-07-31 17:30:14 -0700298
299 if (!debug)
300 return -ENODEV;
301
302 if (*ppos)
303 goto end;
304
305 /* Leave room for termination char */
306 len = min_t(size_t, count, SZ_32 - 1);
307 if (copy_from_user(buf, user_buff, len))
308 goto clear;
309
310 buf[len] = '\0';
311
Tatenda Chipeperekwa59510402017-09-28 12:50:58 -0700312 if (sscanf(buf, "%d %d %d %d", &hdisplay, &vdisplay, &vrefresh,
313 &aspect_ratio) != 4)
Samantha Tran2d1ed732017-07-31 17:30:14 -0700314 goto clear;
315
316 if (!hdisplay || !vdisplay || !vrefresh)
317 goto clear;
318
319 debug->dp_debug.debug_en = true;
320 debug->dp_debug.hdisplay = hdisplay;
321 debug->dp_debug.vdisplay = vdisplay;
322 debug->dp_debug.vrefresh = vrefresh;
Tatenda Chipeperekwa59510402017-09-28 12:50:58 -0700323 debug->dp_debug.aspect_ratio = aspect_ratio;
Samantha Tran2d1ed732017-07-31 17:30:14 -0700324 goto end;
325clear:
326 pr_debug("clearing debug modes\n");
327 debug->dp_debug.debug_en = false;
328end:
329 return len;
330}
331
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +0530332static ssize_t dp_debug_bw_code_write(struct file *file,
333 const char __user *user_buff, size_t count, loff_t *ppos)
334{
335 struct dp_debug_private *debug = file->private_data;
336 char buf[SZ_8];
337 size_t len = 0;
338 u32 max_bw_code = 0;
339
340 if (!debug)
341 return -ENODEV;
342
343 if (*ppos)
344 return 0;
345
346 /* Leave room for termination char */
347 len = min_t(size_t, count, SZ_8 - 1);
348 if (copy_from_user(buf, user_buff, len))
349 return 0;
350
351 buf[len] = '\0';
352
353 if (kstrtoint(buf, 10, &max_bw_code) != 0)
354 return 0;
355
356 if (!is_link_rate_valid(max_bw_code)) {
357 pr_err("Unsupported bw code %d\n", max_bw_code);
358 return len;
359 }
360 debug->panel->max_bw_code = max_bw_code;
361 pr_debug("max_bw_code: %d\n", max_bw_code);
362
363 return len;
364}
365
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +0530366static ssize_t dp_debug_tpg_write(struct file *file,
367 const char __user *user_buff, size_t count, loff_t *ppos)
368{
369 struct dp_debug_private *debug = file->private_data;
370 char buf[SZ_8];
371 size_t len = 0;
372 u32 tpg_state = 0;
373
374 if (!debug)
375 return -ENODEV;
376
377 if (*ppos)
378 return 0;
379
380 /* Leave room for termination char */
381 len = min_t(size_t, count, SZ_8 - 1);
382 if (copy_from_user(buf, user_buff, len))
383 goto bail;
384
385 buf[len] = '\0';
386
387 if (kstrtoint(buf, 10, &tpg_state) != 0)
388 goto bail;
389
390 tpg_state &= 0x1;
391 pr_debug("tpg_state: %d\n", tpg_state);
392
393 if (tpg_state == debug->dp_debug.tpg_state)
394 goto bail;
395
396 if (debug->panel)
397 debug->panel->tpg_config(debug->panel, tpg_state);
398
399 debug->dp_debug.tpg_state = tpg_state;
400bail:
401 return len;
402}
403
Samantha Tranb6a5cd82018-02-01 14:47:16 -0800404static ssize_t dp_debug_write_exe_mode(struct file *file,
405 const char __user *user_buff, size_t count, loff_t *ppos)
406{
407 struct dp_debug_private *debug = file->private_data;
408 char *buf;
409 size_t len = 0;
410
411 if (!debug)
412 return -ENODEV;
413
414 if (*ppos)
415 return 0;
416
417 len = min_t(size_t, count, SZ_32 - 1);
418 buf = memdup_user(user_buff, len);
419 buf[len] = '\0';
420
421 if (sscanf(buf, "%3s", debug->exe_mode) != 1)
422 goto end;
423
424 if (strcmp(debug->exe_mode, "hw") &&
425 strcmp(debug->exe_mode, "sw") &&
426 strcmp(debug->exe_mode, "all"))
427 goto end;
428
429 debug->catalog->set_exe_mode(debug->catalog, debug->exe_mode);
430end:
431 return len;
432}
433
Samantha Tran2d1ed732017-07-31 17:30:14 -0700434static ssize_t dp_debug_read_connected(struct file *file,
435 char __user *user_buff, size_t count, loff_t *ppos)
436{
437 struct dp_debug_private *debug = file->private_data;
438 char buf[SZ_8];
439 u32 len = 0;
440
441 if (!debug)
442 return -ENODEV;
443
444 if (*ppos)
445 return 0;
446
447 len += snprintf(buf, SZ_8, "%d\n", debug->usbpd->hpd_high);
448
449 if (copy_to_user(user_buff, buf, len))
450 return -EFAULT;
451
452 *ppos += len;
453 return len;
454}
455
Padmanabhan Komanduru682ef582017-12-20 16:26:46 +0530456static int dp_debug_check_buffer_overflow(int rc, int *max_size, int *len)
457{
458 if (rc >= *max_size) {
459 pr_err("buffer overflow\n");
460 return -EINVAL;
461 }
462 *len += rc;
463 *max_size = SZ_4K - *len;
464
465 return 0;
466}
467
Samantha Tran2d1ed732017-07-31 17:30:14 -0700468static ssize_t dp_debug_read_edid_modes(struct file *file,
469 char __user *user_buff, size_t count, loff_t *ppos)
470{
471 struct dp_debug_private *debug = file->private_data;
472 char *buf;
Padmanabhan Komanduru682ef582017-12-20 16:26:46 +0530473 u32 len = 0, ret = 0, max_size = SZ_4K;
Samantha Tran2d1ed732017-07-31 17:30:14 -0700474 int rc = 0;
475 struct drm_connector *connector;
476 struct drm_display_mode *mode;
477
478 if (!debug) {
479 pr_err("invalid data\n");
480 rc = -ENODEV;
481 goto error;
482 }
483
484 connector = *debug->connector;
485
486 if (!connector) {
487 pr_err("connector is NULL\n");
488 rc = -EINVAL;
489 goto error;
490 }
491
492 if (*ppos)
493 goto error;
494
495 buf = kzalloc(SZ_4K, GFP_KERNEL);
496 if (!buf) {
497 rc = -ENOMEM;
498 goto error;
499 }
500
Lloyd Atkinsonc34a6ff2017-11-06 14:00:16 -0500501 mutex_lock(&connector->dev->mode_config.mutex);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700502 list_for_each_entry(mode, &connector->modes, head) {
Padmanabhan Komanduru682ef582017-12-20 16:26:46 +0530503 ret = snprintf(buf + len, max_size,
504 "%s %d %d %d %d %d 0x%x\n",
Tatenda Chipeperekwa59510402017-09-28 12:50:58 -0700505 mode->name, mode->vrefresh, mode->picture_aspect_ratio,
Padmanabhan Komanduru682ef582017-12-20 16:26:46 +0530506 mode->htotal, mode->vtotal, mode->clock, mode->flags);
507 if (dp_debug_check_buffer_overflow(ret, &max_size, &len))
508 break;
Samantha Tran2d1ed732017-07-31 17:30:14 -0700509 }
Lloyd Atkinsonc34a6ff2017-11-06 14:00:16 -0500510 mutex_unlock(&connector->dev->mode_config.mutex);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700511
512 if (copy_to_user(user_buff, buf, len)) {
513 kfree(buf);
514 rc = -EFAULT;
515 goto error;
516 }
517
518 *ppos += len;
519 kfree(buf);
520
521 return len;
522error:
523 return rc;
524}
525
Samantha Tran2d1ed732017-07-31 17:30:14 -0700526static ssize_t dp_debug_read_info(struct file *file, char __user *user_buff,
527 size_t count, loff_t *ppos)
528{
529 struct dp_debug_private *debug = file->private_data;
530 char *buf;
531 u32 len = 0, rc = 0;
Samantha Tran2d1ed732017-07-31 17:30:14 -0700532 u32 max_size = SZ_4K;
533
534 if (!debug)
535 return -ENODEV;
536
537 if (*ppos)
538 return 0;
539
540 buf = kzalloc(SZ_4K, GFP_KERNEL);
541 if (!buf)
542 return -ENOMEM;
543
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800544 rc = snprintf(buf + len, max_size, "\tstate=0x%x\n", debug->aux->state);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700545 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
546 goto error;
547
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800548 rc = snprintf(buf + len, max_size, "\tlink_rate=%u\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700549 debug->panel->link_info.rate);
550 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
551 goto error;
552
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800553 rc = snprintf(buf + len, max_size, "\tnum_lanes=%u\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700554 debug->panel->link_info.num_lanes);
555 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
556 goto error;
557
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800558 rc = snprintf(buf + len, max_size, "\tresolution=%dx%d@%dHz\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700559 debug->panel->pinfo.h_active,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800560 debug->panel->pinfo.v_active,
Samantha Tran2d1ed732017-07-31 17:30:14 -0700561 debug->panel->pinfo.refresh_rate);
562 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
563 goto error;
564
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800565 rc = snprintf(buf + len, max_size, "\tpclock=%dKHz\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700566 debug->panel->pinfo.pixel_clk_khz);
567 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
568 goto error;
569
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800570 rc = snprintf(buf + len, max_size, "\tbpp=%d\n",
Samantha Tran2d1ed732017-07-31 17:30:14 -0700571 debug->panel->pinfo.bpp);
572 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
573 goto error;
574
575 /* Link Information */
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800576 rc = snprintf(buf + len, max_size, "\ttest_req=%s\n",
577 dp_link_get_test_name(debug->link->sink_request));
Samantha Tran2d1ed732017-07-31 17:30:14 -0700578 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
579 goto error;
580
581 rc = snprintf(buf + len, max_size,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800582 "\tlane_count=%d\n", debug->link->link_params.lane_count);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700583 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
584 goto error;
585
586 rc = snprintf(buf + len, max_size,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800587 "\tbw_code=%d\n", debug->link->link_params.bw_code);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700588 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
589 goto error;
590
591 rc = snprintf(buf + len, max_size,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800592 "\tv_level=%d\n", debug->link->phy_params.v_level);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700593 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
594 goto error;
595
596 rc = snprintf(buf + len, max_size,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800597 "\tp_level=%d\n", debug->link->phy_params.p_level);
Samantha Tran2d1ed732017-07-31 17:30:14 -0700598 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
599 goto error;
600
601 if (copy_to_user(user_buff, buf, len))
602 goto error;
603
604 *ppos += len;
605
606 kfree(buf);
607 return len;
608error:
609 kfree(buf);
610 return -EINVAL;
611}
612
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +0530613static ssize_t dp_debug_bw_code_read(struct file *file,
614 char __user *user_buff, size_t count, loff_t *ppos)
615{
616 struct dp_debug_private *debug = file->private_data;
617 char *buf;
618 u32 len = 0;
619
620 if (!debug)
621 return -ENODEV;
622
623 if (*ppos)
624 return 0;
625
626 buf = kzalloc(SZ_4K, GFP_KERNEL);
627 if (!buf)
628 return -ENOMEM;
629
630 len += snprintf(buf + len, (SZ_4K - len),
631 "max_bw_code = %d\n", debug->panel->max_bw_code);
632
633 if (copy_to_user(user_buff, buf, len)) {
634 kfree(buf);
635 return -EFAULT;
636 }
637
638 *ppos += len;
639 kfree(buf);
640 return len;
641}
642
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +0530643static ssize_t dp_debug_tpg_read(struct file *file,
644 char __user *user_buff, size_t count, loff_t *ppos)
645{
646 struct dp_debug_private *debug = file->private_data;
647 char buf[SZ_8];
648 u32 len = 0;
649
650 if (!debug)
651 return -ENODEV;
652
653 if (*ppos)
654 return 0;
655
656 len += snprintf(buf, SZ_8, "%d\n", debug->dp_debug.tpg_state);
657
658 if (copy_to_user(user_buff, buf, len))
659 return -EFAULT;
660
661 *ppos += len;
662 return len;
663}
664
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800665static ssize_t dp_debug_write_hdr(struct file *file,
666 const char __user *user_buff, size_t count, loff_t *ppos)
667{
668 struct drm_connector *connector;
669 struct sde_connector *c_conn;
670 struct sde_connector_state *c_state;
671 struct dp_debug_private *debug = file->private_data;
672 char buf[SZ_1K];
673 size_t len = 0;
674
675 if (!debug)
676 return -ENODEV;
677
678 if (*ppos)
679 return 0;
680
681 connector = *debug->connector;
682 c_conn = to_sde_connector(connector);
683 c_state = to_sde_connector_state(connector->state);
684
685 /* Leave room for termination char */
686 len = min_t(size_t, count, SZ_1K - 1);
687 if (copy_from_user(buf, user_buff, len))
688 goto end;
689
690 buf[len] = '\0';
691
692 if (sscanf(buf, "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
693 &c_state->hdr_meta.hdr_supported,
694 &c_state->hdr_meta.hdr_state,
695 &c_state->hdr_meta.eotf,
696 &c_state->hdr_meta.display_primaries_x[0],
697 &c_state->hdr_meta.display_primaries_x[1],
698 &c_state->hdr_meta.display_primaries_x[2],
699 &c_state->hdr_meta.display_primaries_y[0],
700 &c_state->hdr_meta.display_primaries_y[1],
701 &c_state->hdr_meta.display_primaries_y[2],
702 &c_state->hdr_meta.white_point_x,
703 &c_state->hdr_meta.white_point_y,
704 &c_state->hdr_meta.max_luminance,
705 &c_state->hdr_meta.min_luminance,
706 &c_state->hdr_meta.max_content_light_level,
707 &c_state->hdr_meta.max_average_light_level) != 15) {
708 pr_err("invalid input\n");
709 len = -EINVAL;
710 }
Ajay Singh Parmar87af50b2017-12-22 22:22:55 -0800711
712 debug->panel->setup_hdr(debug->panel, &c_state->hdr_meta);
Ajay Singh Parmar973cab12017-11-15 15:33:33 -0800713end:
714 return len;
715}
716
717static ssize_t dp_debug_read_hdr(struct file *file,
718 char __user *user_buff, size_t count, loff_t *ppos)
719{
720 struct dp_debug_private *debug = file->private_data;
721 char *buf;
722 u32 len = 0, i;
723 u32 max_size = SZ_4K;
724 int rc = 0;
725 struct drm_connector *connector;
726 struct sde_connector *c_conn;
727 struct sde_connector_state *c_state;
728 struct drm_msm_ext_hdr_metadata *hdr;
729
730 if (!debug) {
731 pr_err("invalid data\n");
732 rc = -ENODEV;
733 goto error;
734 }
735
736 connector = *debug->connector;
737
738 if (!connector) {
739 pr_err("connector is NULL\n");
740 rc = -EINVAL;
741 goto error;
742 }
743
744 if (*ppos)
745 goto error;
746
747 buf = kzalloc(SZ_4K, GFP_KERNEL);
748 if (!buf) {
749 rc = -ENOMEM;
750 goto error;
751 }
752
753 c_conn = to_sde_connector(connector);
754 c_state = to_sde_connector_state(connector->state);
755
756 hdr = &c_state->hdr_meta;
757
758 rc = snprintf(buf + len, max_size,
759 "============SINK HDR PARAMETERS===========\n");
760 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
761 goto error;
762
763 rc = snprintf(buf + len, max_size, "eotf = %d\n",
764 connector->hdr_eotf);
765 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
766 goto error;
767
768 rc = snprintf(buf + len, max_size, "type_one = %d\n",
769 connector->hdr_metadata_type_one);
770 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
771 goto error;
772
773 rc = snprintf(buf + len, max_size, "max_luminance = %d\n",
774 connector->hdr_max_luminance);
775 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
776 goto error;
777
778 rc = snprintf(buf + len, max_size, "avg_luminance = %d\n",
779 connector->hdr_avg_luminance);
780 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
781 goto error;
782
783 rc = snprintf(buf + len, max_size, "min_luminance = %d\n",
784 connector->hdr_min_luminance);
785 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
786 goto error;
787
788 rc = snprintf(buf + len, max_size,
789 "============VIDEO HDR PARAMETERS===========\n");
790 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
791 goto error;
792
793 rc = snprintf(buf + len, max_size, "hdr_state = %d\n", hdr->hdr_state);
794 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
795 goto error;
796
797 rc = snprintf(buf + len, max_size, "hdr_supported = %d\n",
798 hdr->hdr_supported);
799 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
800 goto error;
801
802 rc = snprintf(buf + len, max_size, "eotf = %d\n", hdr->eotf);
803 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
804 goto error;
805
806 rc = snprintf(buf + len, max_size, "white_point_x = %d\n",
807 hdr->white_point_x);
808 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
809 goto error;
810
811 rc = snprintf(buf + len, max_size, "white_point_y = %d\n",
812 hdr->white_point_y);
813 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
814 goto error;
815
816 rc = snprintf(buf + len, max_size, "max_luminance = %d\n",
817 hdr->max_luminance);
818 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
819 goto error;
820
821 rc = snprintf(buf + len, max_size, "min_luminance = %d\n",
822 hdr->min_luminance);
823 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
824 goto error;
825
826 rc = snprintf(buf + len, max_size, "max_content_light_level = %d\n",
827 hdr->max_content_light_level);
828 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
829 goto error;
830
831 rc = snprintf(buf + len, max_size, "min_content_light_level = %d\n",
832 hdr->max_average_light_level);
833 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
834 goto error;
835
836 for (i = 0; i < HDR_PRIMARIES_COUNT; i++) {
837 rc = snprintf(buf + len, max_size, "primaries_x[%d] = %d\n",
838 i, hdr->display_primaries_x[i]);
839 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
840 goto error;
841
842 rc = snprintf(buf + len, max_size, "primaries_y[%d] = %d\n",
843 i, hdr->display_primaries_y[i]);
844 if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
845 goto error;
846 }
847
848 if (copy_to_user(user_buff, buf, len)) {
849 kfree(buf);
850 rc = -EFAULT;
851 goto error;
852 }
853
854 *ppos += len;
855 kfree(buf);
856
857 return len;
858error:
859 return rc;
860}
861
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -0800862static ssize_t dp_debug_write_sim(struct file *file,
863 const char __user *user_buff, size_t count, loff_t *ppos)
864{
865 struct dp_debug_private *debug = file->private_data;
866 char buf[SZ_8];
867 size_t len = 0;
868 int sim;
869
870 if (!debug)
871 return -ENODEV;
872
873 if (*ppos)
874 return 0;
875
876 /* Leave room for termination char */
877 len = min_t(size_t, count, SZ_8 - 1);
878 if (copy_from_user(buf, user_buff, len))
879 goto end;
880
881 buf[len] = '\0';
882
883 if (kstrtoint(buf, 10, &sim) != 0)
884 goto end;
885
886 if (sim) {
887 if (dp_debug_get_edid_buf(debug))
888 goto end;
889
890 if (dp_debug_get_dpcd_buf(debug))
891 goto error;
892 } else {
893 if (debug->edid) {
894 devm_kfree(debug->dev, debug->edid);
895 debug->edid = NULL;
896 }
897
898 if (debug->dpcd) {
899 devm_kfree(debug->dev, debug->dpcd);
900 debug->dpcd = NULL;
901 }
902 }
903
904 debug->dp_debug.sim_mode = !!sim;
905
906 debug->aux->set_sim_mode(debug->aux, debug->dp_debug.sim_mode,
907 debug->edid, debug->dpcd);
908end:
909 return len;
910error:
911 devm_kfree(debug->dev, debug->edid);
912 return len;
913}
914
915static ssize_t dp_debug_write_attention(struct file *file,
916 const char __user *user_buff, size_t count, loff_t *ppos)
917{
918 struct dp_debug_private *debug = file->private_data;
919 char buf[SZ_8];
920 size_t len = 0;
921 int vdo;
922
923 if (!debug)
924 return -ENODEV;
925
926 if (*ppos)
927 return 0;
928
929 /* Leave room for termination char */
930 len = min_t(size_t, count, SZ_8 - 1);
931 if (copy_from_user(buf, user_buff, len))
932 goto end;
933
934 buf[len] = '\0';
935
936 if (kstrtoint(buf, 10, &vdo) != 0)
937 goto end;
938
939 debug->vdo = vdo;
940
941 schedule_work(&debug->sim_work);
942end:
943 return len;
944}
945
Samantha Tranb6a5cd82018-02-01 14:47:16 -0800946static ssize_t dp_debug_write_dump(struct file *file,
947 const char __user *user_buff, size_t count, loff_t *ppos)
948{
949 struct dp_debug_private *debug = file->private_data;
950 char buf[SZ_32];
951 size_t len = 0;
952
953 if (!debug)
954 return -ENODEV;
955
956 if (*ppos)
957 return 0;
958
959 /* Leave room for termination char */
960 len = min_t(size_t, count, SZ_32 - 1);
961 if (copy_from_user(buf, user_buff, len))
962 goto end;
963
964 buf[len] = '\0';
965
966 if (sscanf(buf, "%31s", debug->reg_dump) != 1)
967 goto end;
968
969 /* qfprom register dump not supported */
970 if (!strcmp(debug->reg_dump, "qfprom_physical"))
971 strlcpy(debug->reg_dump, "clear", sizeof(debug->reg_dump));
972end:
973 return len;
974}
975
976static ssize_t dp_debug_read_dump(struct file *file,
977 char __user *user_buff, size_t count, loff_t *ppos)
978{
979 int rc = 0;
980 struct dp_debug_private *debug = file->private_data;
981 u8 *buf = NULL;
982 u32 len = 0;
983 char prefix[SZ_32];
984
985 if (!debug)
986 return -ENODEV;
987
988 if (*ppos)
989 return 0;
990
991 if (!debug->usbpd->hpd_high || !strlen(debug->reg_dump))
992 goto end;
993
994 rc = debug->catalog->get_reg_dump(debug->catalog,
995 debug->reg_dump, &buf, &len);
996 if (rc)
997 goto end;
998
999 snprintf(prefix, sizeof(prefix), "%s: ", debug->reg_dump);
1000 print_hex_dump(KERN_DEBUG, prefix, DUMP_PREFIX_NONE,
1001 16, 4, buf, len, false);
1002
1003 if (copy_to_user(user_buff, buf, len))
1004 return -EFAULT;
1005
1006 *ppos += len;
1007end:
1008 return len;
1009}
1010
Samantha Tran2d1ed732017-07-31 17:30:14 -07001011static const struct file_operations dp_debug_fops = {
1012 .open = simple_open,
1013 .read = dp_debug_read_info,
1014};
1015
1016static const struct file_operations edid_modes_fops = {
1017 .open = simple_open,
1018 .read = dp_debug_read_edid_modes,
1019 .write = dp_debug_write_edid_modes,
1020};
1021
1022static const struct file_operations hpd_fops = {
1023 .open = simple_open,
1024 .write = dp_debug_write_hpd,
1025};
1026
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001027static const struct file_operations edid_fops = {
1028 .open = simple_open,
1029 .write = dp_debug_write_edid,
1030};
1031
Ajay Singh Parmard937eb22017-10-17 19:58:19 -07001032static const struct file_operations dpcd_fops = {
1033 .open = simple_open,
1034 .write = dp_debug_write_dpcd,
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001035 .read = dp_debug_read_dpcd,
Ajay Singh Parmard937eb22017-10-17 19:58:19 -07001036};
1037
Samantha Tran2d1ed732017-07-31 17:30:14 -07001038static const struct file_operations connected_fops = {
1039 .open = simple_open,
1040 .read = dp_debug_read_connected,
1041};
1042
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301043static const struct file_operations bw_code_fops = {
1044 .open = simple_open,
1045 .read = dp_debug_bw_code_read,
1046 .write = dp_debug_bw_code_write,
1047};
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001048static const struct file_operations exe_mode_fops = {
1049 .open = simple_open,
1050 .write = dp_debug_write_exe_mode,
1051};
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301052
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +05301053static const struct file_operations tpg_fops = {
1054 .open = simple_open,
1055 .read = dp_debug_tpg_read,
1056 .write = dp_debug_tpg_write,
1057};
1058
Ajay Singh Parmar973cab12017-11-15 15:33:33 -08001059static const struct file_operations hdr_fops = {
1060 .open = simple_open,
1061 .write = dp_debug_write_hdr,
1062 .read = dp_debug_read_hdr,
1063};
1064
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001065static const struct file_operations sim_fops = {
1066 .open = simple_open,
1067 .write = dp_debug_write_sim,
1068};
1069
1070static const struct file_operations attention_fops = {
1071 .open = simple_open,
1072 .write = dp_debug_write_attention,
1073};
1074
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001075static const struct file_operations dump_fops = {
1076 .open = simple_open,
1077 .write = dp_debug_write_dump,
1078 .read = dp_debug_read_dump,
1079};
1080
Samantha Tran2d1ed732017-07-31 17:30:14 -07001081static int dp_debug_init(struct dp_debug *dp_debug)
1082{
1083 int rc = 0;
1084 struct dp_debug_private *debug = container_of(dp_debug,
1085 struct dp_debug_private, dp_debug);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001086 struct dentry *dir, *file;
Samantha Tran2d1ed732017-07-31 17:30:14 -07001087
1088 dir = debugfs_create_dir(DEBUG_NAME, NULL);
1089 if (IS_ERR_OR_NULL(dir)) {
Padmanabhan Komandurue5034142017-11-13 16:50:19 +05301090 if (!dir)
1091 rc = -EINVAL;
1092 else
1093 rc = PTR_ERR(dir);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001094 pr_err("[%s] debugfs create dir failed, rc = %d\n",
1095 DEBUG_NAME, rc);
1096 goto error;
1097 }
1098
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001099 debug->root = dir;
1100
Samantha Tran2d1ed732017-07-31 17:30:14 -07001101 file = debugfs_create_file("dp_debug", 0444, dir,
1102 debug, &dp_debug_fops);
1103 if (IS_ERR_OR_NULL(file)) {
1104 rc = PTR_ERR(file);
1105 pr_err("[%s] debugfs create file failed, rc=%d\n",
1106 DEBUG_NAME, rc);
1107 goto error_remove_dir;
1108 }
1109
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001110 file = debugfs_create_file("edid_modes", 0644, dir,
Samantha Tran2d1ed732017-07-31 17:30:14 -07001111 debug, &edid_modes_fops);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001112 if (IS_ERR_OR_NULL(file)) {
1113 rc = PTR_ERR(file);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001114 pr_err("[%s] debugfs create edid_modes failed, rc=%d\n",
1115 DEBUG_NAME, rc);
1116 goto error_remove_dir;
1117 }
1118
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001119 file = debugfs_create_file("hpd", 0644, dir,
Samantha Tran2d1ed732017-07-31 17:30:14 -07001120 debug, &hpd_fops);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001121 if (IS_ERR_OR_NULL(file)) {
1122 rc = PTR_ERR(file);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001123 pr_err("[%s] debugfs hpd failed, rc=%d\n",
1124 DEBUG_NAME, rc);
1125 goto error_remove_dir;
1126 }
1127
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001128 file = debugfs_create_file("connected", 0444, dir,
Samantha Tran2d1ed732017-07-31 17:30:14 -07001129 debug, &connected_fops);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001130 if (IS_ERR_OR_NULL(file)) {
1131 rc = PTR_ERR(file);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001132 pr_err("[%s] debugfs connected failed, rc=%d\n",
1133 DEBUG_NAME, rc);
1134 goto error_remove_dir;
1135 }
1136
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001137 file = debugfs_create_file("max_bw_code", 0644, dir,
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301138 debug, &bw_code_fops);
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001139 if (IS_ERR_OR_NULL(file)) {
1140 rc = PTR_ERR(file);
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301141 pr_err("[%s] debugfs max_bw_code failed, rc=%d\n",
1142 DEBUG_NAME, rc);
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001143 }
1144
1145 file = debugfs_create_file("exe_mode", 0644, dir,
1146 debug, &exe_mode_fops);
1147 if (IS_ERR_OR_NULL(file)) {
1148 rc = PTR_ERR(file);
1149 pr_err("[%s] debugfs register failed, rc=%d\n",
1150 DEBUG_NAME, rc);
Padmanabhan Komanduru87222e72017-09-21 18:27:25 +05301151 }
1152
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001153 file = debugfs_create_file("edid", 0644, dir,
1154 debug, &edid_fops);
1155 if (IS_ERR_OR_NULL(file)) {
1156 rc = PTR_ERR(file);
1157 pr_err("[%s] debugfs edid failed, rc=%d\n",
1158 DEBUG_NAME, rc);
1159 goto error_remove_dir;
1160 }
1161
Ajay Singh Parmard937eb22017-10-17 19:58:19 -07001162 file = debugfs_create_file("dpcd", 0644, dir,
1163 debug, &dpcd_fops);
1164 if (IS_ERR_OR_NULL(file)) {
1165 rc = PTR_ERR(file);
1166 pr_err("[%s] debugfs dpcd failed, rc=%d\n",
1167 DEBUG_NAME, rc);
1168 goto error_remove_dir;
1169 }
1170
Padmanabhan Komanduru04aa2a72017-11-06 17:59:24 +05301171 file = debugfs_create_file("tpg_ctrl", 0644, dir,
1172 debug, &tpg_fops);
1173 if (IS_ERR_OR_NULL(file)) {
1174 rc = PTR_ERR(file);
1175 pr_err("[%s] debugfs tpg failed, rc=%d\n",
1176 DEBUG_NAME, rc);
1177 goto error_remove_dir;
1178 }
1179
Ajay Singh Parmar973cab12017-11-15 15:33:33 -08001180 file = debugfs_create_file("hdr", 0644, dir,
1181 debug, &hdr_fops);
1182
1183 if (IS_ERR_OR_NULL(file)) {
1184 rc = PTR_ERR(file);
1185 pr_err("[%s] debugfs hdr failed, rc=%d\n",
1186 DEBUG_NAME, rc);
1187 goto error_remove_dir;
1188 }
1189
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001190 file = debugfs_create_file("sim", 0644, dir,
1191 debug, &sim_fops);
1192
1193 if (IS_ERR_OR_NULL(file)) {
1194 rc = PTR_ERR(file);
1195 pr_err("[%s] debugfs sim failed, rc=%d\n",
1196 DEBUG_NAME, rc);
1197 goto error_remove_dir;
1198 }
1199
1200 file = debugfs_create_file("attention", 0644, dir,
1201 debug, &attention_fops);
1202
1203 if (IS_ERR_OR_NULL(file)) {
1204 rc = PTR_ERR(file);
1205 pr_err("[%s] debugfs attention failed, rc=%d\n",
1206 DEBUG_NAME, rc);
1207 goto error_remove_dir;
1208 }
1209
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001210 file = debugfs_create_file("dump", 0644, dir,
1211 debug, &dump_fops);
1212
1213 if (IS_ERR_OR_NULL(file)) {
1214 rc = PTR_ERR(file);
1215 pr_err("[%s] debugfs dump failed, rc=%d\n",
1216 DEBUG_NAME, rc);
1217 goto error_remove_dir;
1218 }
1219
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001220 return 0;
1221
Samantha Tran2d1ed732017-07-31 17:30:14 -07001222error_remove_dir:
Padmanabhan Komandurue5034142017-11-13 16:50:19 +05301223 if (!file)
1224 rc = -EINVAL;
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001225 debugfs_remove_recursive(dir);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001226error:
1227 return rc;
1228}
1229
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001230static void dp_debug_sim_work(struct work_struct *work)
1231{
1232 struct dp_debug_private *debug =
1233 container_of(work, typeof(*debug), sim_work);
1234
1235 debug->usbpd->simulate_attention(debug->usbpd, debug->vdo);
1236}
1237
Samantha Tran2d1ed732017-07-31 17:30:14 -07001238struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,
1239 struct dp_usbpd *usbpd, struct dp_link *link,
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001240 struct dp_aux *aux, struct drm_connector **connector,
1241 struct dp_catalog *catalog)
Samantha Tran2d1ed732017-07-31 17:30:14 -07001242{
1243 int rc = 0;
1244 struct dp_debug_private *debug;
1245 struct dp_debug *dp_debug;
1246
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001247 if (!dev || !panel || !usbpd || !link || !catalog) {
Samantha Tran2d1ed732017-07-31 17:30:14 -07001248 pr_err("invalid input\n");
1249 rc = -EINVAL;
1250 goto error;
1251 }
1252
1253 debug = devm_kzalloc(dev, sizeof(*debug), GFP_KERNEL);
1254 if (!debug) {
1255 rc = -ENOMEM;
1256 goto error;
1257 }
1258
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001259 INIT_WORK(&debug->sim_work, dp_debug_sim_work);
Ajay Singh Parmard937eb22017-10-17 19:58:19 -07001260
Samantha Tran2d1ed732017-07-31 17:30:14 -07001261 debug->dp_debug.debug_en = false;
1262 debug->usbpd = usbpd;
1263 debug->link = link;
1264 debug->panel = panel;
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001265 debug->aux = aux;
Samantha Tran2d1ed732017-07-31 17:30:14 -07001266 debug->dev = dev;
1267 debug->connector = connector;
Samantha Tranb6a5cd82018-02-01 14:47:16 -08001268 debug->catalog = catalog;
Samantha Tran2d1ed732017-07-31 17:30:14 -07001269
1270 dp_debug = &debug->dp_debug;
1271 dp_debug->vdisplay = 0;
1272 dp_debug->hdisplay = 0;
1273 dp_debug->vrefresh = 0;
1274
Tatenda Chipeperekwa47ddbcd2017-08-30 13:43:21 -07001275 rc = dp_debug_init(dp_debug);
1276 if (rc) {
1277 devm_kfree(dev, debug);
1278 goto error;
1279 }
Samantha Tran2d1ed732017-07-31 17:30:14 -07001280
1281 return dp_debug;
1282error:
1283 return ERR_PTR(rc);
1284}
1285
1286static int dp_debug_deinit(struct dp_debug *dp_debug)
1287{
1288 struct dp_debug_private *debug;
1289
1290 if (!dp_debug)
1291 return -EINVAL;
1292
1293 debug = container_of(dp_debug, struct dp_debug_private, dp_debug);
1294
Ajay Singh Parmar4c92d392017-08-30 22:51:10 -07001295 debugfs_remove_recursive(debug->root);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001296
1297 return 0;
1298}
1299
1300void dp_debug_put(struct dp_debug *dp_debug)
1301{
1302 struct dp_debug_private *debug;
1303
1304 if (!dp_debug)
1305 return;
1306
1307 debug = container_of(dp_debug, struct dp_debug_private, dp_debug);
1308
1309 dp_debug_deinit(dp_debug);
1310
Ajay Singh Parmar09e6af62018-01-19 17:56:21 -08001311 if (debug->edid)
1312 devm_kfree(debug->dev, debug->edid);
1313
1314 if (debug->dpcd)
1315 devm_kfree(debug->dev, debug->dpcd);
1316
Tatenda Chipeperekwa47ddbcd2017-08-30 13:43:21 -07001317 devm_kfree(debug->dev, debug);
Samantha Tran2d1ed732017-07-31 17:30:14 -07001318}