18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#define pr_fmt(fmt)"[drm-dp] %s: " fmt, __func__ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/debugfs.h> 98c2ecf20Sopenharmony_ci#include <drm/drm_connector.h> 108c2ecf20Sopenharmony_ci#include <drm/drm_file.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include "dp_parser.h" 138c2ecf20Sopenharmony_ci#include "dp_catalog.h" 148c2ecf20Sopenharmony_ci#include "dp_aux.h" 158c2ecf20Sopenharmony_ci#include "dp_ctrl.h" 168c2ecf20Sopenharmony_ci#include "dp_debug.h" 178c2ecf20Sopenharmony_ci#include "dp_display.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define DEBUG_NAME "msm_dp" 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cistruct dp_debug_private { 228c2ecf20Sopenharmony_ci struct dentry *root; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci struct dp_usbpd *usbpd; 258c2ecf20Sopenharmony_ci struct dp_link *link; 268c2ecf20Sopenharmony_ci struct dp_panel *panel; 278c2ecf20Sopenharmony_ci struct drm_connector **connector; 288c2ecf20Sopenharmony_ci struct device *dev; 298c2ecf20Sopenharmony_ci struct drm_device *drm_dev; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci struct dp_debug dp_debug; 328c2ecf20Sopenharmony_ci}; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic int dp_debug_check_buffer_overflow(int rc, int *max_size, int *len) 358c2ecf20Sopenharmony_ci{ 368c2ecf20Sopenharmony_ci if (rc >= *max_size) { 378c2ecf20Sopenharmony_ci DRM_ERROR("buffer overflow\n"); 388c2ecf20Sopenharmony_ci return -EINVAL; 398c2ecf20Sopenharmony_ci } 408c2ecf20Sopenharmony_ci *len += rc; 418c2ecf20Sopenharmony_ci *max_size = SZ_4K - *len; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci return 0; 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic ssize_t dp_debug_read_info(struct file *file, char __user *user_buff, 478c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci struct dp_debug_private *debug = file->private_data; 508c2ecf20Sopenharmony_ci char *buf; 518c2ecf20Sopenharmony_ci u32 len = 0, rc = 0; 528c2ecf20Sopenharmony_ci u64 lclk = 0; 538c2ecf20Sopenharmony_ci u32 max_size = SZ_4K; 548c2ecf20Sopenharmony_ci u32 link_params_rate; 558c2ecf20Sopenharmony_ci struct drm_display_mode *drm_mode; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci if (!debug) 588c2ecf20Sopenharmony_ci return -ENODEV; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci if (*ppos) 618c2ecf20Sopenharmony_ci return 0; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci buf = kzalloc(SZ_4K, GFP_KERNEL); 648c2ecf20Sopenharmony_ci if (!buf) 658c2ecf20Sopenharmony_ci return -ENOMEM; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci drm_mode = &debug->panel->dp_mode.drm_mode; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, "\tname = %s\n", DEBUG_NAME); 708c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 718c2ecf20Sopenharmony_ci goto error; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 748c2ecf20Sopenharmony_ci "\tdp_panel\n\t\tmax_pclk_khz = %d\n", 758c2ecf20Sopenharmony_ci debug->panel->max_pclk_khz); 768c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 778c2ecf20Sopenharmony_ci goto error; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 808c2ecf20Sopenharmony_ci "\tdrm_dp_link\n\t\trate = %u\n", 818c2ecf20Sopenharmony_ci debug->panel->link_info.rate); 828c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 838c2ecf20Sopenharmony_ci goto error; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 868c2ecf20Sopenharmony_ci "\t\tnum_lanes = %u\n", 878c2ecf20Sopenharmony_ci debug->panel->link_info.num_lanes); 888c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 898c2ecf20Sopenharmony_ci goto error; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 928c2ecf20Sopenharmony_ci "\t\tcapabilities = %lu\n", 938c2ecf20Sopenharmony_ci debug->panel->link_info.capabilities); 948c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 958c2ecf20Sopenharmony_ci goto error; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 988c2ecf20Sopenharmony_ci "\tdp_panel_info:\n\t\tactive = %dx%d\n", 998c2ecf20Sopenharmony_ci drm_mode->hdisplay, 1008c2ecf20Sopenharmony_ci drm_mode->vdisplay); 1018c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1028c2ecf20Sopenharmony_ci goto error; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 1058c2ecf20Sopenharmony_ci "\t\tback_porch = %dx%d\n", 1068c2ecf20Sopenharmony_ci drm_mode->htotal - drm_mode->hsync_end, 1078c2ecf20Sopenharmony_ci drm_mode->vtotal - drm_mode->vsync_end); 1088c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1098c2ecf20Sopenharmony_ci goto error; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 1128c2ecf20Sopenharmony_ci "\t\tfront_porch = %dx%d\n", 1138c2ecf20Sopenharmony_ci drm_mode->hsync_start - drm_mode->hdisplay, 1148c2ecf20Sopenharmony_ci drm_mode->vsync_start - drm_mode->vdisplay); 1158c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1168c2ecf20Sopenharmony_ci goto error; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 1198c2ecf20Sopenharmony_ci "\t\tsync_width = %dx%d\n", 1208c2ecf20Sopenharmony_ci drm_mode->hsync_end - drm_mode->hsync_start, 1218c2ecf20Sopenharmony_ci drm_mode->vsync_end - drm_mode->vsync_start); 1228c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1238c2ecf20Sopenharmony_ci goto error; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 1268c2ecf20Sopenharmony_ci "\t\tactive_low = %dx%d\n", 1278c2ecf20Sopenharmony_ci debug->panel->dp_mode.h_active_low, 1288c2ecf20Sopenharmony_ci debug->panel->dp_mode.v_active_low); 1298c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1308c2ecf20Sopenharmony_ci goto error; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 1338c2ecf20Sopenharmony_ci "\t\th_skew = %d\n", 1348c2ecf20Sopenharmony_ci drm_mode->hskew); 1358c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1368c2ecf20Sopenharmony_ci goto error; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 1398c2ecf20Sopenharmony_ci "\t\trefresh rate = %d\n", 1408c2ecf20Sopenharmony_ci drm_mode_vrefresh(drm_mode)); 1418c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1428c2ecf20Sopenharmony_ci goto error; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 1458c2ecf20Sopenharmony_ci "\t\tpixel clock khz = %d\n", 1468c2ecf20Sopenharmony_ci drm_mode->clock); 1478c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1488c2ecf20Sopenharmony_ci goto error; 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 1518c2ecf20Sopenharmony_ci "\t\tbpp = %d\n", 1528c2ecf20Sopenharmony_ci debug->panel->dp_mode.bpp); 1538c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1548c2ecf20Sopenharmony_ci goto error; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci /* Link Information */ 1578c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 1588c2ecf20Sopenharmony_ci "\tdp_link:\n\t\ttest_requested = %d\n", 1598c2ecf20Sopenharmony_ci debug->link->sink_request); 1608c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1618c2ecf20Sopenharmony_ci goto error; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 1648c2ecf20Sopenharmony_ci "\t\tnum_lanes = %d\n", 1658c2ecf20Sopenharmony_ci debug->link->link_params.num_lanes); 1668c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1678c2ecf20Sopenharmony_ci goto error; 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci link_params_rate = debug->link->link_params.rate; 1708c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 1718c2ecf20Sopenharmony_ci "\t\tbw_code = %d\n", 1728c2ecf20Sopenharmony_ci drm_dp_link_rate_to_bw_code(link_params_rate)); 1738c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1748c2ecf20Sopenharmony_ci goto error; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci lclk = debug->link->link_params.rate * 1000; 1778c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 1788c2ecf20Sopenharmony_ci "\t\tlclk = %lld\n", lclk); 1798c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1808c2ecf20Sopenharmony_ci goto error; 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 1838c2ecf20Sopenharmony_ci "\t\tv_level = %d\n", 1848c2ecf20Sopenharmony_ci debug->link->phy_params.v_level); 1858c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1868c2ecf20Sopenharmony_ci goto error; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci rc = snprintf(buf + len, max_size, 1898c2ecf20Sopenharmony_ci "\t\tp_level = %d\n", 1908c2ecf20Sopenharmony_ci debug->link->phy_params.p_level); 1918c2ecf20Sopenharmony_ci if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 1928c2ecf20Sopenharmony_ci goto error; 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci if (copy_to_user(user_buff, buf, len)) 1958c2ecf20Sopenharmony_ci goto error; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci *ppos += len; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci kfree(buf); 2008c2ecf20Sopenharmony_ci return len; 2018c2ecf20Sopenharmony_ci error: 2028c2ecf20Sopenharmony_ci kfree(buf); 2038c2ecf20Sopenharmony_ci return -EINVAL; 2048c2ecf20Sopenharmony_ci} 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_cistatic int dp_test_data_show(struct seq_file *m, void *data) 2078c2ecf20Sopenharmony_ci{ 2088c2ecf20Sopenharmony_ci struct drm_device *dev; 2098c2ecf20Sopenharmony_ci struct dp_debug_private *debug; 2108c2ecf20Sopenharmony_ci struct drm_connector *connector; 2118c2ecf20Sopenharmony_ci struct drm_connector_list_iter conn_iter; 2128c2ecf20Sopenharmony_ci u32 bpc; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci debug = m->private; 2158c2ecf20Sopenharmony_ci dev = debug->drm_dev; 2168c2ecf20Sopenharmony_ci drm_connector_list_iter_begin(dev, &conn_iter); 2178c2ecf20Sopenharmony_ci drm_for_each_connector_iter(connector, &conn_iter) { 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci if (connector->connector_type != 2208c2ecf20Sopenharmony_ci DRM_MODE_CONNECTOR_DisplayPort) 2218c2ecf20Sopenharmony_ci continue; 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci if (connector->status == connector_status_connected) { 2248c2ecf20Sopenharmony_ci bpc = debug->link->test_video.test_bit_depth; 2258c2ecf20Sopenharmony_ci seq_printf(m, "hdisplay: %d\n", 2268c2ecf20Sopenharmony_ci debug->link->test_video.test_h_width); 2278c2ecf20Sopenharmony_ci seq_printf(m, "vdisplay: %d\n", 2288c2ecf20Sopenharmony_ci debug->link->test_video.test_v_height); 2298c2ecf20Sopenharmony_ci seq_printf(m, "bpc: %u\n", 2308c2ecf20Sopenharmony_ci dp_link_bit_depth_to_bpc(bpc)); 2318c2ecf20Sopenharmony_ci } else 2328c2ecf20Sopenharmony_ci seq_puts(m, "0"); 2338c2ecf20Sopenharmony_ci } 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci drm_connector_list_iter_end(&conn_iter); 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci return 0; 2388c2ecf20Sopenharmony_ci} 2398c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(dp_test_data); 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_cistatic int dp_test_type_show(struct seq_file *m, void *data) 2428c2ecf20Sopenharmony_ci{ 2438c2ecf20Sopenharmony_ci struct dp_debug_private *debug = m->private; 2448c2ecf20Sopenharmony_ci struct drm_device *dev = debug->drm_dev; 2458c2ecf20Sopenharmony_ci struct drm_connector *connector; 2468c2ecf20Sopenharmony_ci struct drm_connector_list_iter conn_iter; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci drm_connector_list_iter_begin(dev, &conn_iter); 2498c2ecf20Sopenharmony_ci drm_for_each_connector_iter(connector, &conn_iter) { 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci if (connector->connector_type != 2528c2ecf20Sopenharmony_ci DRM_MODE_CONNECTOR_DisplayPort) 2538c2ecf20Sopenharmony_ci continue; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci if (connector->status == connector_status_connected) 2568c2ecf20Sopenharmony_ci seq_printf(m, "%02x", DP_TEST_LINK_VIDEO_PATTERN); 2578c2ecf20Sopenharmony_ci else 2588c2ecf20Sopenharmony_ci seq_puts(m, "0"); 2598c2ecf20Sopenharmony_ci } 2608c2ecf20Sopenharmony_ci drm_connector_list_iter_end(&conn_iter); 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci return 0; 2638c2ecf20Sopenharmony_ci} 2648c2ecf20Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(dp_test_type); 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_cistatic ssize_t dp_test_active_write(struct file *file, 2678c2ecf20Sopenharmony_ci const char __user *ubuf, 2688c2ecf20Sopenharmony_ci size_t len, loff_t *offp) 2698c2ecf20Sopenharmony_ci{ 2708c2ecf20Sopenharmony_ci char *input_buffer; 2718c2ecf20Sopenharmony_ci int status = 0; 2728c2ecf20Sopenharmony_ci struct dp_debug_private *debug; 2738c2ecf20Sopenharmony_ci struct drm_device *dev; 2748c2ecf20Sopenharmony_ci struct drm_connector *connector; 2758c2ecf20Sopenharmony_ci struct drm_connector_list_iter conn_iter; 2768c2ecf20Sopenharmony_ci int val = 0; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci debug = ((struct seq_file *)file->private_data)->private; 2798c2ecf20Sopenharmony_ci dev = debug->drm_dev; 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci if (len == 0) 2828c2ecf20Sopenharmony_ci return 0; 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci input_buffer = memdup_user_nul(ubuf, len); 2858c2ecf20Sopenharmony_ci if (IS_ERR(input_buffer)) 2868c2ecf20Sopenharmony_ci return PTR_ERR(input_buffer); 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci DRM_DEBUG_DRIVER("Copied %d bytes from user\n", (unsigned int)len); 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci drm_connector_list_iter_begin(dev, &conn_iter); 2918c2ecf20Sopenharmony_ci drm_for_each_connector_iter(connector, &conn_iter) { 2928c2ecf20Sopenharmony_ci if (connector->connector_type != 2938c2ecf20Sopenharmony_ci DRM_MODE_CONNECTOR_DisplayPort) 2948c2ecf20Sopenharmony_ci continue; 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci if (connector->status == connector_status_connected) { 2978c2ecf20Sopenharmony_ci status = kstrtoint(input_buffer, 10, &val); 2988c2ecf20Sopenharmony_ci if (status < 0) 2998c2ecf20Sopenharmony_ci break; 3008c2ecf20Sopenharmony_ci DRM_DEBUG_DRIVER("Got %d for test active\n", val); 3018c2ecf20Sopenharmony_ci /* To prevent erroneous activation of the compliance 3028c2ecf20Sopenharmony_ci * testing code, only accept an actual value of 1 here 3038c2ecf20Sopenharmony_ci */ 3048c2ecf20Sopenharmony_ci if (val == 1) 3058c2ecf20Sopenharmony_ci debug->panel->video_test = true; 3068c2ecf20Sopenharmony_ci else 3078c2ecf20Sopenharmony_ci debug->panel->video_test = false; 3088c2ecf20Sopenharmony_ci } 3098c2ecf20Sopenharmony_ci } 3108c2ecf20Sopenharmony_ci drm_connector_list_iter_end(&conn_iter); 3118c2ecf20Sopenharmony_ci kfree(input_buffer); 3128c2ecf20Sopenharmony_ci if (status < 0) 3138c2ecf20Sopenharmony_ci return status; 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci *offp += len; 3168c2ecf20Sopenharmony_ci return len; 3178c2ecf20Sopenharmony_ci} 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_cistatic int dp_test_active_show(struct seq_file *m, void *data) 3208c2ecf20Sopenharmony_ci{ 3218c2ecf20Sopenharmony_ci struct dp_debug_private *debug = m->private; 3228c2ecf20Sopenharmony_ci struct drm_device *dev = debug->drm_dev; 3238c2ecf20Sopenharmony_ci struct drm_connector *connector; 3248c2ecf20Sopenharmony_ci struct drm_connector_list_iter conn_iter; 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci drm_connector_list_iter_begin(dev, &conn_iter); 3278c2ecf20Sopenharmony_ci drm_for_each_connector_iter(connector, &conn_iter) { 3288c2ecf20Sopenharmony_ci if (connector->connector_type != 3298c2ecf20Sopenharmony_ci DRM_MODE_CONNECTOR_DisplayPort) 3308c2ecf20Sopenharmony_ci continue; 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci if (connector->status == connector_status_connected) { 3338c2ecf20Sopenharmony_ci if (debug->panel->video_test) 3348c2ecf20Sopenharmony_ci seq_puts(m, "1"); 3358c2ecf20Sopenharmony_ci else 3368c2ecf20Sopenharmony_ci seq_puts(m, "0"); 3378c2ecf20Sopenharmony_ci } else 3388c2ecf20Sopenharmony_ci seq_puts(m, "0"); 3398c2ecf20Sopenharmony_ci } 3408c2ecf20Sopenharmony_ci drm_connector_list_iter_end(&conn_iter); 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci return 0; 3438c2ecf20Sopenharmony_ci} 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_cistatic int dp_test_active_open(struct inode *inode, 3468c2ecf20Sopenharmony_ci struct file *file) 3478c2ecf20Sopenharmony_ci{ 3488c2ecf20Sopenharmony_ci return single_open(file, dp_test_active_show, 3498c2ecf20Sopenharmony_ci inode->i_private); 3508c2ecf20Sopenharmony_ci} 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_cistatic const struct file_operations dp_debug_fops = { 3538c2ecf20Sopenharmony_ci .open = simple_open, 3548c2ecf20Sopenharmony_ci .read = dp_debug_read_info, 3558c2ecf20Sopenharmony_ci}; 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_cistatic const struct file_operations test_active_fops = { 3588c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 3598c2ecf20Sopenharmony_ci .open = dp_test_active_open, 3608c2ecf20Sopenharmony_ci .read = seq_read, 3618c2ecf20Sopenharmony_ci .llseek = seq_lseek, 3628c2ecf20Sopenharmony_ci .release = single_release, 3638c2ecf20Sopenharmony_ci .write = dp_test_active_write 3648c2ecf20Sopenharmony_ci}; 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_cistatic int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor) 3678c2ecf20Sopenharmony_ci{ 3688c2ecf20Sopenharmony_ci int rc = 0; 3698c2ecf20Sopenharmony_ci struct dp_debug_private *debug = container_of(dp_debug, 3708c2ecf20Sopenharmony_ci struct dp_debug_private, dp_debug); 3718c2ecf20Sopenharmony_ci struct dentry *file; 3728c2ecf20Sopenharmony_ci struct dentry *test_active; 3738c2ecf20Sopenharmony_ci struct dentry *test_data, *test_type; 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci file = debugfs_create_file("dp_debug", 0444, minor->debugfs_root, 3768c2ecf20Sopenharmony_ci debug, &dp_debug_fops); 3778c2ecf20Sopenharmony_ci if (IS_ERR_OR_NULL(file)) { 3788c2ecf20Sopenharmony_ci rc = PTR_ERR(file); 3798c2ecf20Sopenharmony_ci DRM_ERROR("[%s] debugfs create file failed, rc=%d\n", 3808c2ecf20Sopenharmony_ci DEBUG_NAME, rc); 3818c2ecf20Sopenharmony_ci } 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci test_active = debugfs_create_file("msm_dp_test_active", 0444, 3848c2ecf20Sopenharmony_ci minor->debugfs_root, 3858c2ecf20Sopenharmony_ci debug, &test_active_fops); 3868c2ecf20Sopenharmony_ci if (IS_ERR_OR_NULL(test_active)) { 3878c2ecf20Sopenharmony_ci rc = PTR_ERR(test_active); 3888c2ecf20Sopenharmony_ci DRM_ERROR("[%s] debugfs test_active failed, rc=%d\n", 3898c2ecf20Sopenharmony_ci DEBUG_NAME, rc); 3908c2ecf20Sopenharmony_ci } 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci test_data = debugfs_create_file("msm_dp_test_data", 0444, 3938c2ecf20Sopenharmony_ci minor->debugfs_root, 3948c2ecf20Sopenharmony_ci debug, &dp_test_data_fops); 3958c2ecf20Sopenharmony_ci if (IS_ERR_OR_NULL(test_data)) { 3968c2ecf20Sopenharmony_ci rc = PTR_ERR(test_data); 3978c2ecf20Sopenharmony_ci DRM_ERROR("[%s] debugfs test_data failed, rc=%d\n", 3988c2ecf20Sopenharmony_ci DEBUG_NAME, rc); 3998c2ecf20Sopenharmony_ci } 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci test_type = debugfs_create_file("msm_dp_test_type", 0444, 4028c2ecf20Sopenharmony_ci minor->debugfs_root, 4038c2ecf20Sopenharmony_ci debug, &dp_test_type_fops); 4048c2ecf20Sopenharmony_ci if (IS_ERR_OR_NULL(test_type)) { 4058c2ecf20Sopenharmony_ci rc = PTR_ERR(test_type); 4068c2ecf20Sopenharmony_ci DRM_ERROR("[%s] debugfs test_type failed, rc=%d\n", 4078c2ecf20Sopenharmony_ci DEBUG_NAME, rc); 4088c2ecf20Sopenharmony_ci } 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci debug->root = minor->debugfs_root; 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci return rc; 4138c2ecf20Sopenharmony_ci} 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_cistruct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, 4168c2ecf20Sopenharmony_ci struct dp_usbpd *usbpd, struct dp_link *link, 4178c2ecf20Sopenharmony_ci struct drm_connector **connector, struct drm_minor *minor) 4188c2ecf20Sopenharmony_ci{ 4198c2ecf20Sopenharmony_ci int rc = 0; 4208c2ecf20Sopenharmony_ci struct dp_debug_private *debug; 4218c2ecf20Sopenharmony_ci struct dp_debug *dp_debug; 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci if (!dev || !panel || !usbpd || !link) { 4248c2ecf20Sopenharmony_ci DRM_ERROR("invalid input\n"); 4258c2ecf20Sopenharmony_ci rc = -EINVAL; 4268c2ecf20Sopenharmony_ci goto error; 4278c2ecf20Sopenharmony_ci } 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci debug = devm_kzalloc(dev, sizeof(*debug), GFP_KERNEL); 4308c2ecf20Sopenharmony_ci if (!debug) { 4318c2ecf20Sopenharmony_ci rc = -ENOMEM; 4328c2ecf20Sopenharmony_ci goto error; 4338c2ecf20Sopenharmony_ci } 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_ci debug->dp_debug.debug_en = false; 4368c2ecf20Sopenharmony_ci debug->usbpd = usbpd; 4378c2ecf20Sopenharmony_ci debug->link = link; 4388c2ecf20Sopenharmony_ci debug->panel = panel; 4398c2ecf20Sopenharmony_ci debug->dev = dev; 4408c2ecf20Sopenharmony_ci debug->drm_dev = minor->dev; 4418c2ecf20Sopenharmony_ci debug->connector = connector; 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci dp_debug = &debug->dp_debug; 4448c2ecf20Sopenharmony_ci dp_debug->vdisplay = 0; 4458c2ecf20Sopenharmony_ci dp_debug->hdisplay = 0; 4468c2ecf20Sopenharmony_ci dp_debug->vrefresh = 0; 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_ci rc = dp_debug_init(dp_debug, minor); 4498c2ecf20Sopenharmony_ci if (rc) { 4508c2ecf20Sopenharmony_ci devm_kfree(dev, debug); 4518c2ecf20Sopenharmony_ci goto error; 4528c2ecf20Sopenharmony_ci } 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci return dp_debug; 4558c2ecf20Sopenharmony_ci error: 4568c2ecf20Sopenharmony_ci return ERR_PTR(rc); 4578c2ecf20Sopenharmony_ci} 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_cistatic int dp_debug_deinit(struct dp_debug *dp_debug) 4608c2ecf20Sopenharmony_ci{ 4618c2ecf20Sopenharmony_ci struct dp_debug_private *debug; 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci if (!dp_debug) 4648c2ecf20Sopenharmony_ci return -EINVAL; 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_ci debug = container_of(dp_debug, struct dp_debug_private, dp_debug); 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_ci debugfs_remove_recursive(debug->root); 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci return 0; 4718c2ecf20Sopenharmony_ci} 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_civoid dp_debug_put(struct dp_debug *dp_debug) 4748c2ecf20Sopenharmony_ci{ 4758c2ecf20Sopenharmony_ci struct dp_debug_private *debug; 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_ci if (!dp_debug) 4788c2ecf20Sopenharmony_ci return; 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ci debug = container_of(dp_debug, struct dp_debug_private, dp_debug); 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_ci dp_debug_deinit(dp_debug); 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci devm_kfree(debug->dev, debug); 4858c2ecf20Sopenharmony_ci} 486