1d11a9369SAbhinav Kumar // SPDX-License-Identifier: GPL-2.0-only 2d11a9369SAbhinav Kumar /* 3d11a9369SAbhinav Kumar * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. 4d11a9369SAbhinav Kumar */ 5d11a9369SAbhinav Kumar 6d11a9369SAbhinav Kumar #define pr_fmt(fmt)"[drm-dp] %s: " fmt, __func__ 7d11a9369SAbhinav Kumar 8d11a9369SAbhinav Kumar #include <linux/debugfs.h> 9d11a9369SAbhinav Kumar #include <drm/drm_connector.h> 10f913454aSAbhinav Kumar #include <drm/drm_file.h> 11d11a9369SAbhinav Kumar 12d11a9369SAbhinav Kumar #include "dp_parser.h" 13d11a9369SAbhinav Kumar #include "dp_catalog.h" 14d11a9369SAbhinav Kumar #include "dp_aux.h" 15d11a9369SAbhinav Kumar #include "dp_ctrl.h" 16d11a9369SAbhinav Kumar #include "dp_debug.h" 17d11a9369SAbhinav Kumar #include "dp_display.h" 18d11a9369SAbhinav Kumar 19f913454aSAbhinav Kumar #define DEBUG_NAME "msm_dp" 20d11a9369SAbhinav Kumar 21d11a9369SAbhinav Kumar struct dp_debug_private { 22d11a9369SAbhinav Kumar struct dentry *root; 23d11a9369SAbhinav Kumar 24d11a9369SAbhinav Kumar struct dp_usbpd *usbpd; 25d11a9369SAbhinav Kumar struct dp_link *link; 26d11a9369SAbhinav Kumar struct dp_panel *panel; 27d11a9369SAbhinav Kumar struct drm_connector **connector; 28d11a9369SAbhinav Kumar struct device *dev; 29f913454aSAbhinav Kumar struct drm_device *drm_dev; 30d11a9369SAbhinav Kumar 31d11a9369SAbhinav Kumar struct dp_debug dp_debug; 32d11a9369SAbhinav Kumar }; 33d11a9369SAbhinav Kumar 34d11a9369SAbhinav Kumar static int dp_debug_check_buffer_overflow(int rc, int *max_size, int *len) 35d11a9369SAbhinav Kumar { 36d11a9369SAbhinav Kumar if (rc >= *max_size) { 37d11a9369SAbhinav Kumar DRM_ERROR("buffer overflow\n"); 38d11a9369SAbhinav Kumar return -EINVAL; 39d11a9369SAbhinav Kumar } 40d11a9369SAbhinav Kumar *len += rc; 41d11a9369SAbhinav Kumar *max_size = SZ_4K - *len; 42d11a9369SAbhinav Kumar 43d11a9369SAbhinav Kumar return 0; 44d11a9369SAbhinav Kumar } 45d11a9369SAbhinav Kumar 46d11a9369SAbhinav Kumar static ssize_t dp_debug_read_info(struct file *file, char __user *user_buff, 47d11a9369SAbhinav Kumar size_t count, loff_t *ppos) 48d11a9369SAbhinav Kumar { 49d11a9369SAbhinav Kumar struct dp_debug_private *debug = file->private_data; 50d11a9369SAbhinav Kumar char *buf; 51d11a9369SAbhinav Kumar u32 len = 0, rc = 0; 52d11a9369SAbhinav Kumar u64 lclk = 0; 53d11a9369SAbhinav Kumar u32 max_size = SZ_4K; 54d11a9369SAbhinav Kumar u32 link_params_rate; 55d11a9369SAbhinav Kumar struct drm_display_mode *drm_mode; 56d11a9369SAbhinav Kumar 57d11a9369SAbhinav Kumar if (!debug) 58d11a9369SAbhinav Kumar return -ENODEV; 59d11a9369SAbhinav Kumar 60d11a9369SAbhinav Kumar if (*ppos) 61d11a9369SAbhinav Kumar return 0; 62d11a9369SAbhinav Kumar 63d11a9369SAbhinav Kumar buf = kzalloc(SZ_4K, GFP_KERNEL); 64d11a9369SAbhinav Kumar if (!buf) 65d11a9369SAbhinav Kumar return -ENOMEM; 66d11a9369SAbhinav Kumar 67d11a9369SAbhinav Kumar drm_mode = &debug->panel->dp_mode.drm_mode; 68d11a9369SAbhinav Kumar 69d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, "\tname = %s\n", DEBUG_NAME); 70d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 71d11a9369SAbhinav Kumar goto error; 72d11a9369SAbhinav Kumar 73d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 74d11a9369SAbhinav Kumar "\tdp_panel\n\t\tmax_pclk_khz = %d\n", 75d11a9369SAbhinav Kumar debug->panel->max_pclk_khz); 76d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 77d11a9369SAbhinav Kumar goto error; 78d11a9369SAbhinav Kumar 79d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 80d11a9369SAbhinav Kumar "\tdrm_dp_link\n\t\trate = %u\n", 81d11a9369SAbhinav Kumar debug->panel->link_info.rate); 82d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 83d11a9369SAbhinav Kumar goto error; 84d11a9369SAbhinav Kumar 85d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 86d11a9369SAbhinav Kumar "\t\tnum_lanes = %u\n", 87d11a9369SAbhinav Kumar debug->panel->link_info.num_lanes); 88d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 89d11a9369SAbhinav Kumar goto error; 90d11a9369SAbhinav Kumar 91d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 92d11a9369SAbhinav Kumar "\t\tcapabilities = %lu\n", 93d11a9369SAbhinav Kumar debug->panel->link_info.capabilities); 94d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 95d11a9369SAbhinav Kumar goto error; 96d11a9369SAbhinav Kumar 97d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 98d11a9369SAbhinav Kumar "\tdp_panel_info:\n\t\tactive = %dx%d\n", 99d11a9369SAbhinav Kumar drm_mode->hdisplay, 100d11a9369SAbhinav Kumar drm_mode->vdisplay); 101d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 102d11a9369SAbhinav Kumar goto error; 103d11a9369SAbhinav Kumar 104d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 105d11a9369SAbhinav Kumar "\t\tback_porch = %dx%d\n", 106d11a9369SAbhinav Kumar drm_mode->htotal - drm_mode->hsync_end, 107d11a9369SAbhinav Kumar drm_mode->vtotal - drm_mode->vsync_end); 108d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 109d11a9369SAbhinav Kumar goto error; 110d11a9369SAbhinav Kumar 111d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 112d11a9369SAbhinav Kumar "\t\tfront_porch = %dx%d\n", 113d11a9369SAbhinav Kumar drm_mode->hsync_start - drm_mode->hdisplay, 114d11a9369SAbhinav Kumar drm_mode->vsync_start - drm_mode->vdisplay); 115d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 116d11a9369SAbhinav Kumar goto error; 117d11a9369SAbhinav Kumar 118d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 119d11a9369SAbhinav Kumar "\t\tsync_width = %dx%d\n", 120d11a9369SAbhinav Kumar drm_mode->hsync_end - drm_mode->hsync_start, 121d11a9369SAbhinav Kumar drm_mode->vsync_end - drm_mode->vsync_start); 122d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 123d11a9369SAbhinav Kumar goto error; 124d11a9369SAbhinav Kumar 125d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 126d11a9369SAbhinav Kumar "\t\tactive_low = %dx%d\n", 127d11a9369SAbhinav Kumar debug->panel->dp_mode.h_active_low, 128d11a9369SAbhinav Kumar debug->panel->dp_mode.v_active_low); 129d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 130d11a9369SAbhinav Kumar goto error; 131d11a9369SAbhinav Kumar 132d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 133d11a9369SAbhinav Kumar "\t\th_skew = %d\n", 134d11a9369SAbhinav Kumar drm_mode->hskew); 135d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 136d11a9369SAbhinav Kumar goto error; 137d11a9369SAbhinav Kumar 138d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 139d11a9369SAbhinav Kumar "\t\trefresh rate = %d\n", 140d11a9369SAbhinav Kumar drm_mode_vrefresh(drm_mode)); 141d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 142d11a9369SAbhinav Kumar goto error; 143d11a9369SAbhinav Kumar 144d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 145d11a9369SAbhinav Kumar "\t\tpixel clock khz = %d\n", 146d11a9369SAbhinav Kumar drm_mode->clock); 147d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 148d11a9369SAbhinav Kumar goto error; 149d11a9369SAbhinav Kumar 150d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 151d11a9369SAbhinav Kumar "\t\tbpp = %d\n", 152d11a9369SAbhinav Kumar debug->panel->dp_mode.bpp); 153d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 154d11a9369SAbhinav Kumar goto error; 155d11a9369SAbhinav Kumar 156d11a9369SAbhinav Kumar /* Link Information */ 157d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 158d11a9369SAbhinav Kumar "\tdp_link:\n\t\ttest_requested = %d\n", 159d11a9369SAbhinav Kumar debug->link->sink_request); 160d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 161d11a9369SAbhinav Kumar goto error; 162d11a9369SAbhinav Kumar 163d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 164d11a9369SAbhinav Kumar "\t\tnum_lanes = %d\n", 165d11a9369SAbhinav Kumar debug->link->link_params.num_lanes); 166d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 167d11a9369SAbhinav Kumar goto error; 168d11a9369SAbhinav Kumar 169d11a9369SAbhinav Kumar link_params_rate = debug->link->link_params.rate; 170d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 171d11a9369SAbhinav Kumar "\t\tbw_code = %d\n", 172d11a9369SAbhinav Kumar drm_dp_link_rate_to_bw_code(link_params_rate)); 173d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 174d11a9369SAbhinav Kumar goto error; 175d11a9369SAbhinav Kumar 176d11a9369SAbhinav Kumar lclk = debug->link->link_params.rate * 1000; 177d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 178d11a9369SAbhinav Kumar "\t\tlclk = %lld\n", lclk); 179d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 180d11a9369SAbhinav Kumar goto error; 181d11a9369SAbhinav Kumar 182d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 183d11a9369SAbhinav Kumar "\t\tv_level = %d\n", 184d11a9369SAbhinav Kumar debug->link->phy_params.v_level); 185d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 186d11a9369SAbhinav Kumar goto error; 187d11a9369SAbhinav Kumar 188d11a9369SAbhinav Kumar rc = snprintf(buf + len, max_size, 189d11a9369SAbhinav Kumar "\t\tp_level = %d\n", 190d11a9369SAbhinav Kumar debug->link->phy_params.p_level); 191d11a9369SAbhinav Kumar if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 192d11a9369SAbhinav Kumar goto error; 193d11a9369SAbhinav Kumar 194d11a9369SAbhinav Kumar if (copy_to_user(user_buff, buf, len)) 195d11a9369SAbhinav Kumar goto error; 196d11a9369SAbhinav Kumar 197d11a9369SAbhinav Kumar *ppos += len; 198d11a9369SAbhinav Kumar 199d11a9369SAbhinav Kumar kfree(buf); 200d11a9369SAbhinav Kumar return len; 201d11a9369SAbhinav Kumar error: 202d11a9369SAbhinav Kumar kfree(buf); 203d11a9369SAbhinav Kumar return -EINVAL; 204d11a9369SAbhinav Kumar } 205d11a9369SAbhinav Kumar 206*de3ee254SAbhinav Kumar static int dp_test_data_show(struct seq_file *m, void *data) 207*de3ee254SAbhinav Kumar { 208*de3ee254SAbhinav Kumar struct drm_device *dev; 209*de3ee254SAbhinav Kumar struct dp_debug_private *debug; 210*de3ee254SAbhinav Kumar struct drm_connector *connector; 211*de3ee254SAbhinav Kumar struct drm_connector_list_iter conn_iter; 212*de3ee254SAbhinav Kumar u32 bpc; 213*de3ee254SAbhinav Kumar 214*de3ee254SAbhinav Kumar debug = m->private; 215*de3ee254SAbhinav Kumar dev = debug->drm_dev; 216*de3ee254SAbhinav Kumar drm_connector_list_iter_begin(dev, &conn_iter); 217*de3ee254SAbhinav Kumar drm_for_each_connector_iter(connector, &conn_iter) { 218*de3ee254SAbhinav Kumar 219*de3ee254SAbhinav Kumar if (connector->connector_type != 220*de3ee254SAbhinav Kumar DRM_MODE_CONNECTOR_DisplayPort) 221*de3ee254SAbhinav Kumar continue; 222*de3ee254SAbhinav Kumar 223*de3ee254SAbhinav Kumar if (connector->status == connector_status_connected) { 224*de3ee254SAbhinav Kumar bpc = debug->link->test_video.test_bit_depth; 225*de3ee254SAbhinav Kumar seq_printf(m, "hdisplay: %d\n", 226*de3ee254SAbhinav Kumar debug->link->test_video.test_h_width); 227*de3ee254SAbhinav Kumar seq_printf(m, "vdisplay: %d\n", 228*de3ee254SAbhinav Kumar debug->link->test_video.test_v_height); 229*de3ee254SAbhinav Kumar seq_printf(m, "bpc: %u\n", 230*de3ee254SAbhinav Kumar dp_link_bit_depth_to_bpc(bpc)); 231*de3ee254SAbhinav Kumar } else 232*de3ee254SAbhinav Kumar seq_puts(m, "0"); 233*de3ee254SAbhinav Kumar } 234*de3ee254SAbhinav Kumar 235*de3ee254SAbhinav Kumar drm_connector_list_iter_end(&conn_iter); 236*de3ee254SAbhinav Kumar 237*de3ee254SAbhinav Kumar return 0; 238*de3ee254SAbhinav Kumar } 239*de3ee254SAbhinav Kumar DEFINE_SHOW_ATTRIBUTE(dp_test_data); 240*de3ee254SAbhinav Kumar 241*de3ee254SAbhinav Kumar static int dp_test_type_show(struct seq_file *m, void *data) 242*de3ee254SAbhinav Kumar { 243*de3ee254SAbhinav Kumar struct dp_debug_private *debug = m->private; 244*de3ee254SAbhinav Kumar struct drm_device *dev = debug->drm_dev; 245*de3ee254SAbhinav Kumar struct drm_connector *connector; 246*de3ee254SAbhinav Kumar struct drm_connector_list_iter conn_iter; 247*de3ee254SAbhinav Kumar 248*de3ee254SAbhinav Kumar drm_connector_list_iter_begin(dev, &conn_iter); 249*de3ee254SAbhinav Kumar drm_for_each_connector_iter(connector, &conn_iter) { 250*de3ee254SAbhinav Kumar 251*de3ee254SAbhinav Kumar if (connector->connector_type != 252*de3ee254SAbhinav Kumar DRM_MODE_CONNECTOR_DisplayPort) 253*de3ee254SAbhinav Kumar continue; 254*de3ee254SAbhinav Kumar 255*de3ee254SAbhinav Kumar if (connector->status == connector_status_connected) 256*de3ee254SAbhinav Kumar seq_printf(m, "%02x", DP_TEST_LINK_VIDEO_PATTERN); 257*de3ee254SAbhinav Kumar else 258*de3ee254SAbhinav Kumar seq_puts(m, "0"); 259*de3ee254SAbhinav Kumar } 260*de3ee254SAbhinav Kumar drm_connector_list_iter_end(&conn_iter); 261*de3ee254SAbhinav Kumar 262*de3ee254SAbhinav Kumar return 0; 263*de3ee254SAbhinav Kumar } 264*de3ee254SAbhinav Kumar DEFINE_SHOW_ATTRIBUTE(dp_test_type); 265*de3ee254SAbhinav Kumar 266*de3ee254SAbhinav Kumar static ssize_t dp_test_active_write(struct file *file, 267*de3ee254SAbhinav Kumar const char __user *ubuf, 268*de3ee254SAbhinav Kumar size_t len, loff_t *offp) 269*de3ee254SAbhinav Kumar { 270*de3ee254SAbhinav Kumar char *input_buffer; 271*de3ee254SAbhinav Kumar int status = 0; 272*de3ee254SAbhinav Kumar struct dp_debug_private *debug; 273*de3ee254SAbhinav Kumar struct drm_device *dev; 274*de3ee254SAbhinav Kumar struct drm_connector *connector; 275*de3ee254SAbhinav Kumar struct drm_connector_list_iter conn_iter; 276*de3ee254SAbhinav Kumar int val = 0; 277*de3ee254SAbhinav Kumar 278*de3ee254SAbhinav Kumar debug = ((struct seq_file *)file->private_data)->private; 279*de3ee254SAbhinav Kumar dev = debug->drm_dev; 280*de3ee254SAbhinav Kumar 281*de3ee254SAbhinav Kumar if (len == 0) 282*de3ee254SAbhinav Kumar return 0; 283*de3ee254SAbhinav Kumar 284*de3ee254SAbhinav Kumar input_buffer = memdup_user_nul(ubuf, len); 285*de3ee254SAbhinav Kumar if (IS_ERR(input_buffer)) 286*de3ee254SAbhinav Kumar return PTR_ERR(input_buffer); 287*de3ee254SAbhinav Kumar 288*de3ee254SAbhinav Kumar DRM_DEBUG_DRIVER("Copied %d bytes from user\n", (unsigned int)len); 289*de3ee254SAbhinav Kumar 290*de3ee254SAbhinav Kumar drm_connector_list_iter_begin(dev, &conn_iter); 291*de3ee254SAbhinav Kumar drm_for_each_connector_iter(connector, &conn_iter) { 292*de3ee254SAbhinav Kumar if (connector->connector_type != 293*de3ee254SAbhinav Kumar DRM_MODE_CONNECTOR_DisplayPort) 294*de3ee254SAbhinav Kumar continue; 295*de3ee254SAbhinav Kumar 296*de3ee254SAbhinav Kumar if (connector->status == connector_status_connected) { 297*de3ee254SAbhinav Kumar status = kstrtoint(input_buffer, 10, &val); 298*de3ee254SAbhinav Kumar if (status < 0) 299*de3ee254SAbhinav Kumar break; 300*de3ee254SAbhinav Kumar DRM_DEBUG_DRIVER("Got %d for test active\n", val); 301*de3ee254SAbhinav Kumar /* To prevent erroneous activation of the compliance 302*de3ee254SAbhinav Kumar * testing code, only accept an actual value of 1 here 303*de3ee254SAbhinav Kumar */ 304*de3ee254SAbhinav Kumar if (val == 1) 305*de3ee254SAbhinav Kumar debug->panel->video_test = true; 306*de3ee254SAbhinav Kumar else 307*de3ee254SAbhinav Kumar debug->panel->video_test = false; 308*de3ee254SAbhinav Kumar } 309*de3ee254SAbhinav Kumar } 310*de3ee254SAbhinav Kumar drm_connector_list_iter_end(&conn_iter); 311*de3ee254SAbhinav Kumar kfree(input_buffer); 312*de3ee254SAbhinav Kumar if (status < 0) 313*de3ee254SAbhinav Kumar return status; 314*de3ee254SAbhinav Kumar 315*de3ee254SAbhinav Kumar *offp += len; 316*de3ee254SAbhinav Kumar return len; 317*de3ee254SAbhinav Kumar } 318*de3ee254SAbhinav Kumar 319*de3ee254SAbhinav Kumar static int dp_test_active_show(struct seq_file *m, void *data) 320*de3ee254SAbhinav Kumar { 321*de3ee254SAbhinav Kumar struct dp_debug_private *debug = m->private; 322*de3ee254SAbhinav Kumar struct drm_device *dev = debug->drm_dev; 323*de3ee254SAbhinav Kumar struct drm_connector *connector; 324*de3ee254SAbhinav Kumar struct drm_connector_list_iter conn_iter; 325*de3ee254SAbhinav Kumar 326*de3ee254SAbhinav Kumar drm_connector_list_iter_begin(dev, &conn_iter); 327*de3ee254SAbhinav Kumar drm_for_each_connector_iter(connector, &conn_iter) { 328*de3ee254SAbhinav Kumar if (connector->connector_type != 329*de3ee254SAbhinav Kumar DRM_MODE_CONNECTOR_DisplayPort) 330*de3ee254SAbhinav Kumar continue; 331*de3ee254SAbhinav Kumar 332*de3ee254SAbhinav Kumar if (connector->status == connector_status_connected) { 333*de3ee254SAbhinav Kumar if (debug->panel->video_test) 334*de3ee254SAbhinav Kumar seq_puts(m, "1"); 335*de3ee254SAbhinav Kumar else 336*de3ee254SAbhinav Kumar seq_puts(m, "0"); 337*de3ee254SAbhinav Kumar } else 338*de3ee254SAbhinav Kumar seq_puts(m, "0"); 339*de3ee254SAbhinav Kumar } 340*de3ee254SAbhinav Kumar drm_connector_list_iter_end(&conn_iter); 341*de3ee254SAbhinav Kumar 342*de3ee254SAbhinav Kumar return 0; 343*de3ee254SAbhinav Kumar } 344*de3ee254SAbhinav Kumar 345*de3ee254SAbhinav Kumar static int dp_test_active_open(struct inode *inode, 346*de3ee254SAbhinav Kumar struct file *file) 347*de3ee254SAbhinav Kumar { 348*de3ee254SAbhinav Kumar return single_open(file, dp_test_active_show, 349*de3ee254SAbhinav Kumar inode->i_private); 350*de3ee254SAbhinav Kumar } 351*de3ee254SAbhinav Kumar 352d11a9369SAbhinav Kumar static const struct file_operations dp_debug_fops = { 353d11a9369SAbhinav Kumar .open = simple_open, 354d11a9369SAbhinav Kumar .read = dp_debug_read_info, 355d11a9369SAbhinav Kumar }; 356d11a9369SAbhinav Kumar 357*de3ee254SAbhinav Kumar static const struct file_operations test_active_fops = { 358*de3ee254SAbhinav Kumar .owner = THIS_MODULE, 359*de3ee254SAbhinav Kumar .open = dp_test_active_open, 360*de3ee254SAbhinav Kumar .read = seq_read, 361*de3ee254SAbhinav Kumar .llseek = seq_lseek, 362*de3ee254SAbhinav Kumar .release = single_release, 363*de3ee254SAbhinav Kumar .write = dp_test_active_write 364*de3ee254SAbhinav Kumar }; 365*de3ee254SAbhinav Kumar 366f913454aSAbhinav Kumar static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor) 367d11a9369SAbhinav Kumar { 368d11a9369SAbhinav Kumar int rc = 0; 369d11a9369SAbhinav Kumar struct dp_debug_private *debug = container_of(dp_debug, 370d11a9369SAbhinav Kumar struct dp_debug_private, dp_debug); 371f913454aSAbhinav Kumar struct dentry *file; 372*de3ee254SAbhinav Kumar struct dentry *test_active; 373*de3ee254SAbhinav Kumar struct dentry *test_data, *test_type; 374d11a9369SAbhinav Kumar 375f913454aSAbhinav Kumar file = debugfs_create_file("dp_debug", 0444, minor->debugfs_root, 376d11a9369SAbhinav Kumar debug, &dp_debug_fops); 377d11a9369SAbhinav Kumar if (IS_ERR_OR_NULL(file)) { 378d11a9369SAbhinav Kumar rc = PTR_ERR(file); 379d11a9369SAbhinav Kumar DRM_ERROR("[%s] debugfs create file failed, rc=%d\n", 380d11a9369SAbhinav Kumar DEBUG_NAME, rc); 381d11a9369SAbhinav Kumar } 382d11a9369SAbhinav Kumar 383*de3ee254SAbhinav Kumar test_active = debugfs_create_file("msm_dp_test_active", 0444, 384*de3ee254SAbhinav Kumar minor->debugfs_root, 385*de3ee254SAbhinav Kumar debug, &test_active_fops); 386*de3ee254SAbhinav Kumar if (IS_ERR_OR_NULL(test_active)) { 387*de3ee254SAbhinav Kumar rc = PTR_ERR(test_active); 388*de3ee254SAbhinav Kumar DRM_ERROR("[%s] debugfs test_active failed, rc=%d\n", 389*de3ee254SAbhinav Kumar DEBUG_NAME, rc); 390*de3ee254SAbhinav Kumar } 391*de3ee254SAbhinav Kumar 392*de3ee254SAbhinav Kumar test_data = debugfs_create_file("msm_dp_test_data", 0444, 393*de3ee254SAbhinav Kumar minor->debugfs_root, 394*de3ee254SAbhinav Kumar debug, &dp_test_data_fops); 395*de3ee254SAbhinav Kumar if (IS_ERR_OR_NULL(test_data)) { 396*de3ee254SAbhinav Kumar rc = PTR_ERR(test_data); 397*de3ee254SAbhinav Kumar DRM_ERROR("[%s] debugfs test_data failed, rc=%d\n", 398*de3ee254SAbhinav Kumar DEBUG_NAME, rc); 399*de3ee254SAbhinav Kumar } 400*de3ee254SAbhinav Kumar 401*de3ee254SAbhinav Kumar test_type = debugfs_create_file("msm_dp_test_type", 0444, 402*de3ee254SAbhinav Kumar minor->debugfs_root, 403*de3ee254SAbhinav Kumar debug, &dp_test_type_fops); 404*de3ee254SAbhinav Kumar if (IS_ERR_OR_NULL(test_type)) { 405*de3ee254SAbhinav Kumar rc = PTR_ERR(test_type); 406*de3ee254SAbhinav Kumar DRM_ERROR("[%s] debugfs test_type failed, rc=%d\n", 407*de3ee254SAbhinav Kumar DEBUG_NAME, rc); 408*de3ee254SAbhinav Kumar } 409*de3ee254SAbhinav Kumar 410f913454aSAbhinav Kumar debug->root = minor->debugfs_root; 411f913454aSAbhinav Kumar 412d11a9369SAbhinav Kumar return rc; 413d11a9369SAbhinav Kumar } 414d11a9369SAbhinav Kumar 415d11a9369SAbhinav Kumar struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, 416d11a9369SAbhinav Kumar struct dp_usbpd *usbpd, struct dp_link *link, 417f913454aSAbhinav Kumar struct drm_connector **connector, struct drm_minor *minor) 418d11a9369SAbhinav Kumar { 419d11a9369SAbhinav Kumar int rc = 0; 420d11a9369SAbhinav Kumar struct dp_debug_private *debug; 421d11a9369SAbhinav Kumar struct dp_debug *dp_debug; 422d11a9369SAbhinav Kumar 423d11a9369SAbhinav Kumar if (!dev || !panel || !usbpd || !link) { 424d11a9369SAbhinav Kumar DRM_ERROR("invalid input\n"); 425d11a9369SAbhinav Kumar rc = -EINVAL; 426d11a9369SAbhinav Kumar goto error; 427d11a9369SAbhinav Kumar } 428d11a9369SAbhinav Kumar 429d11a9369SAbhinav Kumar debug = devm_kzalloc(dev, sizeof(*debug), GFP_KERNEL); 430d11a9369SAbhinav Kumar if (!debug) { 431d11a9369SAbhinav Kumar rc = -ENOMEM; 432d11a9369SAbhinav Kumar goto error; 433d11a9369SAbhinav Kumar } 434d11a9369SAbhinav Kumar 435d11a9369SAbhinav Kumar debug->dp_debug.debug_en = false; 436d11a9369SAbhinav Kumar debug->usbpd = usbpd; 437d11a9369SAbhinav Kumar debug->link = link; 438d11a9369SAbhinav Kumar debug->panel = panel; 439d11a9369SAbhinav Kumar debug->dev = dev; 440f913454aSAbhinav Kumar debug->drm_dev = minor->dev; 441d11a9369SAbhinav Kumar debug->connector = connector; 442d11a9369SAbhinav Kumar 443d11a9369SAbhinav Kumar dp_debug = &debug->dp_debug; 444d11a9369SAbhinav Kumar dp_debug->vdisplay = 0; 445d11a9369SAbhinav Kumar dp_debug->hdisplay = 0; 446d11a9369SAbhinav Kumar dp_debug->vrefresh = 0; 447d11a9369SAbhinav Kumar 448f913454aSAbhinav Kumar rc = dp_debug_init(dp_debug, minor); 449d11a9369SAbhinav Kumar if (rc) { 450d11a9369SAbhinav Kumar devm_kfree(dev, debug); 451d11a9369SAbhinav Kumar goto error; 452d11a9369SAbhinav Kumar } 453d11a9369SAbhinav Kumar 454d11a9369SAbhinav Kumar return dp_debug; 455d11a9369SAbhinav Kumar error: 456d11a9369SAbhinav Kumar return ERR_PTR(rc); 457d11a9369SAbhinav Kumar } 458d11a9369SAbhinav Kumar 459d11a9369SAbhinav Kumar static int dp_debug_deinit(struct dp_debug *dp_debug) 460d11a9369SAbhinav Kumar { 461d11a9369SAbhinav Kumar struct dp_debug_private *debug; 462d11a9369SAbhinav Kumar 463d11a9369SAbhinav Kumar if (!dp_debug) 464d11a9369SAbhinav Kumar return -EINVAL; 465d11a9369SAbhinav Kumar 466d11a9369SAbhinav Kumar debug = container_of(dp_debug, struct dp_debug_private, dp_debug); 467d11a9369SAbhinav Kumar 468d11a9369SAbhinav Kumar debugfs_remove_recursive(debug->root); 469d11a9369SAbhinav Kumar 470d11a9369SAbhinav Kumar return 0; 471d11a9369SAbhinav Kumar } 472d11a9369SAbhinav Kumar 473d11a9369SAbhinav Kumar void dp_debug_put(struct dp_debug *dp_debug) 474d11a9369SAbhinav Kumar { 475d11a9369SAbhinav Kumar struct dp_debug_private *debug; 476d11a9369SAbhinav Kumar 477d11a9369SAbhinav Kumar if (!dp_debug) 478d11a9369SAbhinav Kumar return; 479d11a9369SAbhinav Kumar 480d11a9369SAbhinav Kumar debug = container_of(dp_debug, struct dp_debug_private, dp_debug); 481d11a9369SAbhinav Kumar 482d11a9369SAbhinav Kumar dp_debug_deinit(dp_debug); 483d11a9369SAbhinav Kumar 484d11a9369SAbhinav Kumar devm_kfree(debug->dev, debug); 485d11a9369SAbhinav Kumar } 486