1 /* 2 * Created: Sun Dec 21 13:08:50 2008 by bgamari@gmail.com 3 * 4 * Copyright 2008 Ben Gamari <bgamari@gmail.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 #include <linux/debugfs.h> 27 #include <linux/export.h> 28 #include <linux/seq_file.h> 29 #include <linux/slab.h> 30 #include <linux/uaccess.h> 31 32 #include <drm/drm_atomic.h> 33 #include <drm/drm_auth.h> 34 #include <drm/drm_bridge.h> 35 #include <drm/drm_debugfs.h> 36 #include <drm/drm_device.h> 37 #include <drm/drm_drv.h> 38 #include <drm/drm_edid.h> 39 #include <drm/drm_file.h> 40 #include <drm/drm_gem.h> 41 #include <drm/drm_managed.h> 42 #include <drm/drm_gpuvm.h> 43 44 #include "drm_crtc_internal.h" 45 #include "drm_internal.h" 46 47 static struct dentry *accel_debugfs_root; 48 static struct dentry *drm_debugfs_root; 49 50 /*************************************************** 51 * Initialization, etc. 52 **************************************************/ 53 54 static int drm_name_info(struct seq_file *m, void *data) 55 { 56 struct drm_debugfs_entry *entry = m->private; 57 struct drm_device *dev = entry->dev; 58 struct drm_master *master; 59 60 mutex_lock(&dev->master_mutex); 61 master = dev->master; 62 seq_printf(m, "%s", dev->driver->name); 63 if (dev->dev) 64 seq_printf(m, " dev=%s", dev_name(dev->dev)); 65 if (master && master->unique) 66 seq_printf(m, " master=%s", master->unique); 67 if (dev->unique) 68 seq_printf(m, " unique=%s", dev->unique); 69 seq_printf(m, "\n"); 70 mutex_unlock(&dev->master_mutex); 71 72 return 0; 73 } 74 75 static int drm_clients_info(struct seq_file *m, void *data) 76 { 77 struct drm_debugfs_entry *entry = m->private; 78 struct drm_device *dev = entry->dev; 79 struct drm_file *priv; 80 kuid_t uid; 81 82 seq_printf(m, 83 "%20s %5s %3s master a %5s %10s %*s %20s\n", 84 "command", 85 "tgid", 86 "dev", 87 "uid", 88 "magic", 89 DRM_CLIENT_NAME_MAX_LEN, 90 "name", 91 "id"); 92 93 /* dev->filelist is sorted youngest first, but we want to present 94 * oldest first (i.e. kernel, servers, clients), so walk backwardss. 95 */ 96 mutex_lock(&dev->filelist_mutex); 97 list_for_each_entry_reverse(priv, &dev->filelist, lhead) { 98 bool is_current_master = drm_is_current_master(priv); 99 struct task_struct *task; 100 struct pid *pid; 101 102 mutex_lock(&priv->client_name_lock); 103 rcu_read_lock(); /* Locks priv->pid and pid_task()->comm! */ 104 pid = rcu_dereference(priv->pid); 105 task = pid_task(pid, PIDTYPE_TGID); 106 uid = task ? __task_cred(task)->euid : GLOBAL_ROOT_UID; 107 seq_printf(m, "%20s %5d %3d %c %c %5d %10u %*s %20llu\n", 108 task ? task->comm : "<unknown>", 109 pid_vnr(pid), 110 priv->minor->index, 111 is_current_master ? 'y' : 'n', 112 priv->authenticated ? 'y' : 'n', 113 from_kuid_munged(seq_user_ns(m), uid), 114 priv->magic, 115 DRM_CLIENT_NAME_MAX_LEN, 116 priv->client_name ? priv->client_name : "<unset>", 117 priv->client_id); 118 rcu_read_unlock(); 119 mutex_unlock(&priv->client_name_lock); 120 } 121 mutex_unlock(&dev->filelist_mutex); 122 return 0; 123 } 124 125 static int drm_gem_one_name_info(int id, void *ptr, void *data) 126 { 127 struct drm_gem_object *obj = ptr; 128 struct seq_file *m = data; 129 130 seq_printf(m, "%6d %8zd %7d %8d\n", 131 obj->name, obj->size, 132 obj->handle_count, 133 kref_read(&obj->refcount)); 134 return 0; 135 } 136 137 static int drm_gem_name_info(struct seq_file *m, void *data) 138 { 139 struct drm_debugfs_entry *entry = m->private; 140 struct drm_device *dev = entry->dev; 141 142 seq_printf(m, " name size handles refcount\n"); 143 144 mutex_lock(&dev->object_name_lock); 145 idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, m); 146 mutex_unlock(&dev->object_name_lock); 147 148 return 0; 149 } 150 151 static const struct drm_debugfs_info drm_debugfs_list[] = { 152 {"name", drm_name_info, 0}, 153 {"clients", drm_clients_info, 0}, 154 {"gem_names", drm_gem_name_info, DRIVER_GEM}, 155 }; 156 #define DRM_DEBUGFS_ENTRIES ARRAY_SIZE(drm_debugfs_list) 157 158 159 static int drm_debugfs_open(struct inode *inode, struct file *file) 160 { 161 struct drm_info_node *node = inode->i_private; 162 163 if (!device_is_registered(node->minor->kdev)) 164 return -ENODEV; 165 166 return single_open(file, node->info_ent->show, node); 167 } 168 169 static int drm_debugfs_entry_open(struct inode *inode, struct file *file) 170 { 171 struct drm_debugfs_entry *entry = inode->i_private; 172 struct drm_debugfs_info *node = &entry->file; 173 struct drm_minor *minor = entry->dev->primary ?: entry->dev->accel; 174 175 if (!device_is_registered(minor->kdev)) 176 return -ENODEV; 177 178 return single_open(file, node->show, entry); 179 } 180 181 static const struct file_operations drm_debugfs_entry_fops = { 182 .owner = THIS_MODULE, 183 .open = drm_debugfs_entry_open, 184 .read = seq_read, 185 .llseek = seq_lseek, 186 .release = single_release, 187 }; 188 189 static const struct file_operations drm_debugfs_fops = { 190 .owner = THIS_MODULE, 191 .open = drm_debugfs_open, 192 .read = seq_read, 193 .llseek = seq_lseek, 194 .release = single_release, 195 }; 196 197 /** 198 * drm_debugfs_gpuva_info - dump the given DRM GPU VA space 199 * @m: pointer to the &seq_file to write 200 * @gpuvm: the &drm_gpuvm representing the GPU VA space 201 * 202 * Dumps the GPU VA mappings of a given DRM GPU VA manager. 203 * 204 * For each DRM GPU VA space drivers should call this function from their 205 * &drm_info_list's show callback. 206 * 207 * Returns: 0 on success, -ENODEV if the &gpuvm is not initialized 208 */ 209 int drm_debugfs_gpuva_info(struct seq_file *m, 210 struct drm_gpuvm *gpuvm) 211 { 212 struct drm_gpuva *va, *kva = &gpuvm->kernel_alloc_node; 213 214 if (!gpuvm->name) 215 return -ENODEV; 216 217 seq_printf(m, "DRM GPU VA space (%s) [0x%016llx;0x%016llx]\n", 218 gpuvm->name, gpuvm->mm_start, gpuvm->mm_start + gpuvm->mm_range); 219 seq_printf(m, "Kernel reserved node [0x%016llx;0x%016llx]\n", 220 kva->va.addr, kva->va.addr + kva->va.range); 221 seq_puts(m, "\n"); 222 seq_puts(m, " VAs | start | range | end | object | object offset\n"); 223 seq_puts(m, "-------------------------------------------------------------------------------------------------------------\n"); 224 drm_gpuvm_for_each_va(va, gpuvm) { 225 if (unlikely(va == kva)) 226 continue; 227 228 seq_printf(m, " | 0x%016llx | 0x%016llx | 0x%016llx | 0x%016llx | 0x%016llx\n", 229 va->va.addr, va->va.range, va->va.addr + va->va.range, 230 (u64)(uintptr_t)va->gem.obj, va->gem.offset); 231 } 232 233 return 0; 234 } 235 EXPORT_SYMBOL(drm_debugfs_gpuva_info); 236 237 /** 238 * drm_debugfs_create_files - Initialize a given set of debugfs files for DRM 239 * minor 240 * @files: The array of files to create 241 * @count: The number of files given 242 * @root: DRI debugfs dir entry. 243 * @minor: device minor number 244 * 245 * Create a given set of debugfs files represented by an array of 246 * &struct drm_info_list in the given root directory. These files will be removed 247 * automatically on drm_debugfs_dev_fini(). 248 */ 249 void drm_debugfs_create_files(const struct drm_info_list *files, int count, 250 struct dentry *root, struct drm_minor *minor) 251 { 252 struct drm_device *dev = minor->dev; 253 struct drm_info_node *tmp; 254 int i; 255 256 for (i = 0; i < count; i++) { 257 u32 features = files[i].driver_features; 258 259 if (features && !drm_core_check_all_features(dev, features)) 260 continue; 261 262 tmp = drmm_kzalloc(dev, sizeof(*tmp), GFP_KERNEL); 263 if (tmp == NULL) 264 continue; 265 266 tmp->minor = minor; 267 tmp->dent = debugfs_create_file(files[i].name, 268 0444, root, tmp, 269 &drm_debugfs_fops); 270 tmp->info_ent = &files[i]; 271 } 272 } 273 EXPORT_SYMBOL(drm_debugfs_create_files); 274 275 int drm_debugfs_remove_files(const struct drm_info_list *files, int count, 276 struct dentry *root, struct drm_minor *minor) 277 { 278 int i; 279 280 for (i = 0; i < count; i++) { 281 struct dentry *dent = debugfs_lookup(files[i].name, root); 282 283 if (!dent) 284 continue; 285 286 drmm_kfree(minor->dev, d_inode(dent)->i_private); 287 debugfs_remove(dent); 288 } 289 return 0; 290 } 291 EXPORT_SYMBOL(drm_debugfs_remove_files); 292 293 void drm_debugfs_bridge_params(void) 294 { 295 drm_bridge_debugfs_params(drm_debugfs_root); 296 } 297 298 void drm_debugfs_init_root(void) 299 { 300 drm_debugfs_root = debugfs_create_dir("dri", NULL); 301 #if IS_ENABLED(CONFIG_DRM_ACCEL) 302 accel_debugfs_root = debugfs_create_dir("accel", NULL); 303 #endif 304 } 305 306 void drm_debugfs_remove_root(void) 307 { 308 #if IS_ENABLED(CONFIG_DRM_ACCEL) 309 debugfs_remove(accel_debugfs_root); 310 #endif 311 debugfs_remove(drm_debugfs_root); 312 } 313 314 static int drm_debugfs_proc_info_show(struct seq_file *m, void *unused) 315 { 316 struct pid *pid; 317 struct task_struct *task; 318 struct drm_file *file = m->private; 319 320 if (!file) 321 return -EINVAL; 322 323 rcu_read_lock(); 324 pid = rcu_dereference(file->pid); 325 task = pid_task(pid, PIDTYPE_TGID); 326 327 seq_printf(m, "pid: %d\n", task ? task->pid : 0); 328 seq_printf(m, "comm: %s\n", task ? task->comm : "Unset"); 329 rcu_read_unlock(); 330 return 0; 331 } 332 333 static int drm_debufs_proc_info_open(struct inode *inode, struct file *file) 334 { 335 return single_open(file, drm_debugfs_proc_info_show, inode->i_private); 336 } 337 338 static const struct file_operations drm_debugfs_proc_info_fops = { 339 .owner = THIS_MODULE, 340 .open = drm_debufs_proc_info_open, 341 .read = seq_read, 342 .llseek = seq_lseek, 343 .release = single_release, 344 }; 345 346 /** 347 * drm_debugfs_clients_add - Add a per client debugfs directory 348 * @file: drm_file for a client 349 * 350 * Create the debugfs directory for each client. This will be used to populate 351 * driver specific data for each client. 352 * 353 * Also add the process information debugfs file for each client to tag 354 * which client belongs to which process. 355 */ 356 void drm_debugfs_clients_add(struct drm_file *file) 357 { 358 char *client; 359 360 client = kasprintf(GFP_KERNEL, "client-%llu", file->client_id); 361 if (!client) 362 return; 363 364 /* Create a debugfs directory for the client in root on drm debugfs */ 365 file->debugfs_client = debugfs_create_dir(client, drm_debugfs_root); 366 kfree(client); 367 368 debugfs_create_file("proc_info", 0444, file->debugfs_client, file, 369 &drm_debugfs_proc_info_fops); 370 371 client = kasprintf(GFP_KERNEL, "../%s", file->minor->dev->unique); 372 if (!client) 373 return; 374 375 /* Create a link from client_id to the drm device this client id belongs to */ 376 debugfs_create_symlink("device", file->debugfs_client, client); 377 kfree(client); 378 } 379 380 /** 381 * drm_debugfs_clients_remove - removes all debugfs directories and files 382 * @file: drm_file for a client 383 * 384 * Removes the debugfs directories recursively from the client directory. 385 * 386 * There is also a possibility that debugfs files are open while the drm_file 387 * is released. 388 */ 389 void drm_debugfs_clients_remove(struct drm_file *file) 390 { 391 debugfs_remove_recursive(file->debugfs_client); 392 file->debugfs_client = NULL; 393 } 394 395 /** 396 * drm_debugfs_dev_init - create debugfs directory for the device 397 * @dev: the device which we want to create the directory for 398 * 399 * Creates the debugfs directory for the device under the given root directory. 400 */ 401 void drm_debugfs_dev_init(struct drm_device *dev) 402 { 403 if (drm_core_check_feature(dev, DRIVER_COMPUTE_ACCEL)) 404 dev->debugfs_root = debugfs_create_dir(dev->unique, accel_debugfs_root); 405 else 406 dev->debugfs_root = debugfs_create_dir(dev->unique, drm_debugfs_root); 407 } 408 409 /** 410 * drm_debugfs_dev_fini - cleanup debugfs directory 411 * @dev: the device to cleanup the debugfs stuff 412 * 413 * Remove the debugfs directory, might be called multiple times. 414 */ 415 void drm_debugfs_dev_fini(struct drm_device *dev) 416 { 417 debugfs_remove_recursive(dev->debugfs_root); 418 dev->debugfs_root = NULL; 419 } 420 421 void drm_debugfs_dev_register(struct drm_device *dev) 422 { 423 drm_debugfs_add_files(dev, drm_debugfs_list, DRM_DEBUGFS_ENTRIES); 424 425 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 426 drm_framebuffer_debugfs_init(dev); 427 drm_client_debugfs_init(dev); 428 } 429 if (drm_drv_uses_atomic_modeset(dev)) 430 drm_atomic_debugfs_init(dev); 431 } 432 433 int drm_debugfs_register(struct drm_minor *minor, int minor_id) 434 { 435 struct drm_device *dev = minor->dev; 436 char name[64]; 437 438 sprintf(name, "%d", minor_id); 439 minor->debugfs_symlink = debugfs_create_symlink(name, drm_debugfs_root, 440 dev->unique); 441 442 /* TODO: Only for compatibility with drivers */ 443 minor->debugfs_root = dev->debugfs_root; 444 445 if (dev->driver->debugfs_init && dev->render != minor) 446 dev->driver->debugfs_init(minor); 447 448 return 0; 449 } 450 451 void drm_debugfs_unregister(struct drm_minor *minor) 452 { 453 debugfs_remove(minor->debugfs_symlink); 454 minor->debugfs_symlink = NULL; 455 } 456 457 /** 458 * drm_debugfs_add_file - Add a given file to the DRM device debugfs file list 459 * @dev: drm device for the ioctl 460 * @name: debugfs file name 461 * @show: show callback 462 * @data: driver-private data, should not be device-specific 463 * 464 * Add a given file entry to the DRM device debugfs file list to be created on 465 * drm_debugfs_init. 466 */ 467 void drm_debugfs_add_file(struct drm_device *dev, const char *name, 468 int (*show)(struct seq_file*, void*), void *data) 469 { 470 struct drm_debugfs_entry *entry = drmm_kzalloc(dev, sizeof(*entry), GFP_KERNEL); 471 472 if (!entry) 473 return; 474 475 entry->file.name = name; 476 entry->file.show = show; 477 entry->file.data = data; 478 entry->dev = dev; 479 480 debugfs_create_file(name, 0444, dev->debugfs_root, entry, 481 &drm_debugfs_entry_fops); 482 } 483 EXPORT_SYMBOL(drm_debugfs_add_file); 484 485 /** 486 * drm_debugfs_add_files - Add an array of files to the DRM device debugfs file list 487 * @dev: drm device for the ioctl 488 * @files: The array of files to create 489 * @count: The number of files given 490 * 491 * Add a given set of debugfs files represented by an array of 492 * &struct drm_debugfs_info in the DRM device debugfs file list. 493 */ 494 void drm_debugfs_add_files(struct drm_device *dev, const struct drm_debugfs_info *files, int count) 495 { 496 int i; 497 498 for (i = 0; i < count; i++) 499 drm_debugfs_add_file(dev, files[i].name, files[i].show, files[i].data); 500 } 501 EXPORT_SYMBOL(drm_debugfs_add_files); 502 503 static int connector_show(struct seq_file *m, void *data) 504 { 505 struct drm_connector *connector = m->private; 506 507 seq_printf(m, "%s\n", drm_get_connector_force_name(connector->force)); 508 509 return 0; 510 } 511 512 static int connector_open(struct inode *inode, struct file *file) 513 { 514 struct drm_connector *dev = inode->i_private; 515 516 return single_open(file, connector_show, dev); 517 } 518 519 static ssize_t connector_write(struct file *file, const char __user *ubuf, 520 size_t len, loff_t *offp) 521 { 522 struct seq_file *m = file->private_data; 523 struct drm_connector *connector = m->private; 524 char buf[12]; 525 526 if (len > sizeof(buf) - 1) 527 return -EINVAL; 528 529 if (copy_from_user(buf, ubuf, len)) 530 return -EFAULT; 531 532 buf[len] = '\0'; 533 534 if (sysfs_streq(buf, "on")) 535 connector->force = DRM_FORCE_ON; 536 else if (sysfs_streq(buf, "digital")) 537 connector->force = DRM_FORCE_ON_DIGITAL; 538 else if (sysfs_streq(buf, "off")) 539 connector->force = DRM_FORCE_OFF; 540 else if (sysfs_streq(buf, "unspecified")) 541 connector->force = DRM_FORCE_UNSPECIFIED; 542 else 543 return -EINVAL; 544 545 return len; 546 } 547 548 static int edid_show(struct seq_file *m, void *data) 549 { 550 return drm_edid_override_show(m->private, m); 551 } 552 553 static int edid_open(struct inode *inode, struct file *file) 554 { 555 struct drm_connector *dev = inode->i_private; 556 557 return single_open(file, edid_show, dev); 558 } 559 560 static ssize_t edid_write(struct file *file, const char __user *ubuf, 561 size_t len, loff_t *offp) 562 { 563 struct seq_file *m = file->private_data; 564 struct drm_connector *connector = m->private; 565 char *buf; 566 int ret; 567 568 buf = memdup_user(ubuf, len); 569 if (IS_ERR(buf)) 570 return PTR_ERR(buf); 571 572 if (len == 5 && !strncmp(buf, "reset", 5)) 573 ret = drm_edid_override_reset(connector); 574 else 575 ret = drm_edid_override_set(connector, buf, len); 576 577 kfree(buf); 578 579 return ret ? ret : len; 580 } 581 582 /* 583 * Returns the min and max vrr vfreq through the connector's debugfs file. 584 * Example usage: cat /sys/kernel/debug/dri/0/DP-1/vrr_range 585 */ 586 static int vrr_range_show(struct seq_file *m, void *data) 587 { 588 struct drm_connector *connector = m->private; 589 590 if (connector->status != connector_status_connected) 591 return -ENODEV; 592 593 seq_printf(m, "Min: %u\n", connector->display_info.monitor_range.min_vfreq); 594 seq_printf(m, "Max: %u\n", connector->display_info.monitor_range.max_vfreq); 595 596 return 0; 597 } 598 DEFINE_SHOW_ATTRIBUTE(vrr_range); 599 600 /* 601 * Returns Connector's max supported bpc through debugfs file. 602 * Example usage: cat /sys/kernel/debug/dri/0/DP-1/output_bpc 603 */ 604 static int output_bpc_show(struct seq_file *m, void *data) 605 { 606 struct drm_connector *connector = m->private; 607 608 if (connector->status != connector_status_connected) 609 return -ENODEV; 610 611 seq_printf(m, "Maximum: %u\n", connector->display_info.bpc); 612 613 return 0; 614 } 615 DEFINE_SHOW_ATTRIBUTE(output_bpc); 616 617 static const struct file_operations drm_edid_fops = { 618 .owner = THIS_MODULE, 619 .open = edid_open, 620 .read = seq_read, 621 .llseek = seq_lseek, 622 .release = single_release, 623 .write = edid_write 624 }; 625 626 627 static const struct file_operations drm_connector_fops = { 628 .owner = THIS_MODULE, 629 .open = connector_open, 630 .read = seq_read, 631 .llseek = seq_lseek, 632 .release = single_release, 633 .write = connector_write 634 }; 635 636 static ssize_t 637 audio_infoframe_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos) 638 { 639 struct drm_connector_hdmi_infoframe *infoframe; 640 struct drm_connector *connector; 641 union hdmi_infoframe *frame; 642 u8 buf[HDMI_INFOFRAME_SIZE(AUDIO)]; 643 ssize_t len = 0; 644 645 connector = filp->private_data; 646 mutex_lock(&connector->hdmi.infoframes.lock); 647 648 infoframe = &connector->hdmi.infoframes.audio; 649 if (!infoframe->set) 650 goto out; 651 652 frame = &infoframe->data; 653 len = hdmi_infoframe_pack(frame, buf, sizeof(buf)); 654 if (len < 0) 655 goto out; 656 657 len = simple_read_from_buffer(ubuf, count, ppos, buf, len); 658 659 out: 660 mutex_unlock(&connector->hdmi.infoframes.lock); 661 return len; 662 } 663 664 static const struct file_operations audio_infoframe_fops = { 665 .owner = THIS_MODULE, 666 .open = simple_open, 667 .read = audio_infoframe_read, 668 }; 669 670 static int create_hdmi_audio_infoframe_file(struct drm_connector *connector, 671 struct dentry *parent) 672 { 673 struct dentry *file; 674 675 file = debugfs_create_file("audio", 0400, parent, connector, &audio_infoframe_fops); 676 if (IS_ERR(file)) 677 return PTR_ERR(file); 678 679 return 0; 680 } 681 682 #define DEFINE_INFOFRAME_FILE(_f) \ 683 static ssize_t _f##_read_infoframe(struct file *filp, \ 684 char __user *ubuf, \ 685 size_t count, \ 686 loff_t *ppos) \ 687 { \ 688 struct drm_connector_hdmi_infoframe *infoframe; \ 689 struct drm_connector_state *conn_state; \ 690 struct drm_connector *connector; \ 691 union hdmi_infoframe *frame; \ 692 struct drm_device *dev; \ 693 u8 buf[HDMI_INFOFRAME_SIZE(MAX)]; \ 694 ssize_t len = 0; \ 695 \ 696 connector = filp->private_data; \ 697 dev = connector->dev; \ 698 \ 699 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); \ 700 \ 701 conn_state = connector->state; \ 702 infoframe = &conn_state->hdmi.infoframes._f; \ 703 if (!infoframe->set) \ 704 goto out; \ 705 \ 706 frame = &infoframe->data; \ 707 len = hdmi_infoframe_pack(frame, buf, sizeof(buf)); \ 708 if (len < 0) \ 709 goto out; \ 710 \ 711 len = simple_read_from_buffer(ubuf, count, ppos, buf, len); \ 712 \ 713 out: \ 714 drm_modeset_unlock(&dev->mode_config.connection_mutex); \ 715 return len; \ 716 } \ 717 \ 718 static const struct file_operations _f##_infoframe_fops = { \ 719 .owner = THIS_MODULE, \ 720 .open = simple_open, \ 721 .read = _f##_read_infoframe, \ 722 }; \ 723 \ 724 static int create_hdmi_## _f ## _infoframe_file(struct drm_connector *connector, \ 725 struct dentry *parent) \ 726 { \ 727 struct dentry *file; \ 728 \ 729 file = debugfs_create_file(#_f, 0400, parent, connector, &_f ## _infoframe_fops); \ 730 if (IS_ERR(file)) \ 731 return PTR_ERR(file); \ 732 \ 733 return 0; \ 734 } 735 736 DEFINE_INFOFRAME_FILE(avi); 737 DEFINE_INFOFRAME_FILE(hdmi); 738 DEFINE_INFOFRAME_FILE(hdr_drm); 739 DEFINE_INFOFRAME_FILE(spd); 740 741 static int create_hdmi_infoframe_files(struct drm_connector *connector, 742 struct dentry *parent) 743 { 744 int ret; 745 746 ret = create_hdmi_audio_infoframe_file(connector, parent); 747 if (ret) 748 return ret; 749 750 ret = create_hdmi_avi_infoframe_file(connector, parent); 751 if (ret) 752 return ret; 753 754 ret = create_hdmi_hdmi_infoframe_file(connector, parent); 755 if (ret) 756 return ret; 757 758 ret = create_hdmi_hdr_drm_infoframe_file(connector, parent); 759 if (ret) 760 return ret; 761 762 ret = create_hdmi_spd_infoframe_file(connector, parent); 763 if (ret) 764 return ret; 765 766 return 0; 767 } 768 769 static void hdmi_debugfs_add(struct drm_connector *connector) 770 { 771 struct dentry *dir; 772 773 if (!(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || 774 connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)) 775 return; 776 777 dir = debugfs_create_dir("infoframes", connector->debugfs_entry); 778 if (IS_ERR(dir)) 779 return; 780 781 create_hdmi_infoframe_files(connector, dir); 782 } 783 784 void drm_debugfs_connector_add(struct drm_connector *connector) 785 { 786 struct drm_device *dev = connector->dev; 787 struct dentry *root; 788 789 if (!dev->debugfs_root) 790 return; 791 792 root = debugfs_create_dir(connector->name, dev->debugfs_root); 793 connector->debugfs_entry = root; 794 795 /* force */ 796 debugfs_create_file("force", 0644, root, connector, 797 &drm_connector_fops); 798 799 /* edid */ 800 debugfs_create_file("edid_override", 0644, root, connector, 801 &drm_edid_fops); 802 803 /* vrr range */ 804 debugfs_create_file("vrr_range", 0444, root, connector, 805 &vrr_range_fops); 806 807 /* max bpc */ 808 debugfs_create_file("output_bpc", 0444, root, connector, 809 &output_bpc_fops); 810 811 hdmi_debugfs_add(connector); 812 813 if (connector->funcs->debugfs_init) 814 connector->funcs->debugfs_init(connector, root); 815 } 816 817 void drm_debugfs_connector_remove(struct drm_connector *connector) 818 { 819 if (!connector->debugfs_entry) 820 return; 821 822 debugfs_remove_recursive(connector->debugfs_entry); 823 824 connector->debugfs_entry = NULL; 825 } 826 827 void drm_debugfs_crtc_add(struct drm_crtc *crtc) 828 { 829 struct drm_device *dev = crtc->dev; 830 struct dentry *root; 831 char *name; 832 833 name = kasprintf(GFP_KERNEL, "crtc-%d", crtc->index); 834 if (!name) 835 return; 836 837 root = debugfs_create_dir(name, dev->debugfs_root); 838 kfree(name); 839 840 crtc->debugfs_entry = root; 841 842 drm_debugfs_crtc_crc_add(crtc); 843 } 844 845 void drm_debugfs_crtc_remove(struct drm_crtc *crtc) 846 { 847 debugfs_remove_recursive(crtc->debugfs_entry); 848 crtc->debugfs_entry = NULL; 849 } 850 851 void drm_debugfs_encoder_add(struct drm_encoder *encoder) 852 { 853 struct drm_minor *minor = encoder->dev->primary; 854 struct dentry *root; 855 char *name; 856 857 name = kasprintf(GFP_KERNEL, "encoder-%d", encoder->index); 858 if (!name) 859 return; 860 861 root = debugfs_create_dir(name, minor->debugfs_root); 862 kfree(name); 863 864 encoder->debugfs_entry = root; 865 866 drm_bridge_debugfs_encoder_params(root, encoder); 867 868 if (encoder->funcs && encoder->funcs->debugfs_init) 869 encoder->funcs->debugfs_init(encoder, root); 870 } 871 872 void drm_debugfs_encoder_remove(struct drm_encoder *encoder) 873 { 874 debugfs_remove_recursive(encoder->debugfs_entry); 875 encoder->debugfs_entry = NULL; 876 } 877