Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'drm-misc-next-2026-01-22' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next

drm-misc-next for 6.20:

Core Changes:
- buddy: Fix free_trees memory leak, prevent a BUG_ON
- dma-buf: Start to introduce cgroup memory accounting in heaps, Remove
sysfs stats, add new tracepoints
- hdmi: Limit infoframes exposure to userspace based on driver
capabilities
- property: Account for property blobs in memcg

Driver Changes:
- atmel-hlcdc: Switch to drmm resources, Support nomodeset parameter,
various patches to use newish helpers and fix memory safety bugs
- hisilicon: Fix various DisplayPort related bugs
- imagination: Introduce hardware version checks
- renesas: Fix kernel panic on reboot
- rockchip: Fix RK3576 HPD interrupt handling, Improve RK3588 HPD
interrupt handling
- v3d: Convert to drm logging helpers

- bridge:
- Continuation of the refcounting effort
- new bridge: Algoltek AG6311

- panel:
- new panel: Anbernic RG-DS

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Maxime Ripard <mripard@redhat.com>
Link: https://patch.msgid.link/20260122-antique-sexy-junglefowl-1bc5a8@houat

+3108 -1489
+3 -1
.mailmap
··· 373 373 Jesper Dangaard Brouer <hawk@kernel.org> <jbrouer@redhat.com> 374 374 Jesper Dangaard Brouer <hawk@kernel.org> <jdb@comx.dk> 375 375 Jesper Dangaard Brouer <hawk@kernel.org> <netoptimizer@brouer.com> 376 - Jessica Zhang <quic_jesszhan@quicinc.com> <jesszhan@codeaurora.org> 376 + Jessica Zhang <jesszhan0024@gmail.com> <jesszhan@codeaurora.org> 377 + Jessica Zhang <jesszhan0024@gmail.com> <quic_jesszhan@quicinc.com> 378 + Jessica Zhang <jesszhan0024@gmail.com> <jessica.zhang@oss.qualcomm.com> 377 379 Jilai Wang <quic_jilaiw@quicinc.com> <jilaiw@codeaurora.org> 378 380 Jiri Kosina <jikos@kernel.org> <jikos@jikos.cz> 379 381 Jiri Kosina <jikos@kernel.org> <jkosina@suse.cz>
-24
Documentation/ABI/testing/sysfs-kernel-dmabuf-buffers
··· 1 - What: /sys/kernel/dmabuf/buffers 2 - Date: May 2021 3 - KernelVersion: v5.13 4 - Contact: Hridya Valsaraju <hridya@google.com> 5 - Description: The /sys/kernel/dmabuf/buffers directory contains a 6 - snapshot of the internal state of every DMA-BUF. 7 - /sys/kernel/dmabuf/buffers/<inode_number> will contain the 8 - statistics for the DMA-BUF with the unique inode number 9 - <inode_number> 10 - Users: kernel memory tuning/debugging tools 11 - 12 - What: /sys/kernel/dmabuf/buffers/<inode_number>/exporter_name 13 - Date: May 2021 14 - KernelVersion: v5.13 15 - Contact: Hridya Valsaraju <hridya@google.com> 16 - Description: This file is read-only and contains the name of the exporter of 17 - the DMA-BUF. 18 - 19 - What: /sys/kernel/dmabuf/buffers/<inode_number>/size 20 - Date: May 2021 21 - KernelVersion: v5.13 22 - Contact: Hridya Valsaraju <hridya@google.com> 23 - Description: This file is read-only and specifies the size of the DMA-BUF in 24 - bytes.
+1
Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml
··· 27 27 - const: adi,adv7123 28 28 - enum: 29 29 - adi,adv7123 30 + - algoltek,ag6311 30 31 - asl-tek,cs5263 31 32 - dumb-vga-dac 32 33 - parade,ps185hdm
+2
Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml
··· 16 16 compatible: 17 17 items: 18 18 - enum: 19 + - anbernic,rg-ds-display-bottom 20 + - anbernic,rg-ds-display-top 19 21 - chongzhou,cz101b4001 20 22 - kingdisplay,kd101ne3-40ti 21 23 - melfas,lmfbx101117480
+2
Documentation/devicetree/bindings/vendor-prefixes.yaml
··· 86 86 description: Aldec, Inc. 87 87 "^alfa-network,.*": 88 88 description: ALFA Network Inc. 89 + "^algoltek,.*": 90 + description: AlgolTek, Inc. 89 91 "^allegro,.*": 90 92 description: Allegro DVT 91 93 "^allegromicro,.*":
-5
Documentation/driver-api/dma-buf.rst
··· 125 125 .. kernel-doc:: drivers/dma-buf/dma-buf.c 126 126 :doc: implicit fence polling 127 127 128 - DMA-BUF statistics 129 - ~~~~~~~~~~~~~~~~~~ 130 - .. kernel-doc:: drivers/dma-buf/dma-buf-sysfs-stats.c 131 - :doc: overview 132 - 133 128 DMA Buffer ioctls 134 129 ~~~~~~~~~~~~~~~~~ 135 130
-15
drivers/dma-buf/Kconfig
··· 75 75 allows userspace to allocate dma-bufs that can be shared 76 76 between drivers. 77 77 78 - menuconfig DMABUF_SYSFS_STATS 79 - bool "DMA-BUF sysfs statistics (DEPRECATED)" 80 - depends on DMA_SHARED_BUFFER 81 - help 82 - Choose this option to enable DMA-BUF sysfs statistics 83 - in location /sys/kernel/dmabuf/buffers. 84 - 85 - /sys/kernel/dmabuf/buffers/<inode_number> will contain 86 - statistics for the DMA-BUF with the unique inode number 87 - <inode_number>. 88 - 89 - This option is deprecated and should sooner or later be removed. 90 - Android is the only user of this and it turned out that this resulted 91 - in quite some performance problems. 92 - 93 78 source "drivers/dma-buf/heaps/Kconfig" 94 79 95 80 endmenu
-1
drivers/dma-buf/Makefile
··· 6 6 obj-$(CONFIG_SYNC_FILE) += sync_file.o 7 7 obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o 8 8 obj-$(CONFIG_UDMABUF) += udmabuf.o 9 - obj-$(CONFIG_DMABUF_SYSFS_STATS) += dma-buf-sysfs-stats.o 10 9 11 10 dmabuf_selftests-y := \ 12 11 selftest.o \
-202
drivers/dma-buf/dma-buf-sysfs-stats.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * DMA-BUF sysfs statistics. 4 - * 5 - * Copyright (C) 2021 Google LLC. 6 - */ 7 - 8 - #include <linux/dma-buf.h> 9 - #include <linux/dma-resv.h> 10 - #include <linux/kobject.h> 11 - #include <linux/printk.h> 12 - #include <linux/slab.h> 13 - #include <linux/sysfs.h> 14 - 15 - #include "dma-buf-sysfs-stats.h" 16 - 17 - #define to_dma_buf_entry_from_kobj(x) container_of(x, struct dma_buf_sysfs_entry, kobj) 18 - 19 - /** 20 - * DOC: overview 21 - * 22 - * ``/sys/kernel/debug/dma_buf/bufinfo`` provides an overview of every DMA-BUF 23 - * in the system. However, since debugfs is not safe to be mounted in 24 - * production, procfs and sysfs can be used to gather DMA-BUF statistics on 25 - * production systems. 26 - * 27 - * The ``/proc/<pid>/fdinfo/<fd>`` files in procfs can be used to gather 28 - * information about DMA-BUF fds. Detailed documentation about the interface 29 - * is present in Documentation/filesystems/proc.rst. 30 - * 31 - * Unfortunately, the existing procfs interfaces can only provide information 32 - * about the DMA-BUFs for which processes hold fds or have the buffers mmapped 33 - * into their address space. This necessitated the creation of the DMA-BUF sysfs 34 - * statistics interface to provide per-buffer information on production systems. 35 - * 36 - * The interface at ``/sys/kernel/dmabuf/buffers`` exposes information about 37 - * every DMA-BUF when ``CONFIG_DMABUF_SYSFS_STATS`` is enabled. 38 - * 39 - * The following stats are exposed by the interface: 40 - * 41 - * * ``/sys/kernel/dmabuf/buffers/<inode_number>/exporter_name`` 42 - * * ``/sys/kernel/dmabuf/buffers/<inode_number>/size`` 43 - * 44 - * The information in the interface can also be used to derive per-exporter 45 - * statistics. The data from the interface can be gathered on error conditions 46 - * or other important events to provide a snapshot of DMA-BUF usage. 47 - * It can also be collected periodically by telemetry to monitor various metrics. 48 - * 49 - * Detailed documentation about the interface is present in 50 - * Documentation/ABI/testing/sysfs-kernel-dmabuf-buffers. 51 - */ 52 - 53 - struct dma_buf_stats_attribute { 54 - struct attribute attr; 55 - ssize_t (*show)(struct dma_buf *dmabuf, 56 - struct dma_buf_stats_attribute *attr, char *buf); 57 - }; 58 - #define to_dma_buf_stats_attr(x) container_of(x, struct dma_buf_stats_attribute, attr) 59 - 60 - static ssize_t dma_buf_stats_attribute_show(struct kobject *kobj, 61 - struct attribute *attr, 62 - char *buf) 63 - { 64 - struct dma_buf_stats_attribute *attribute; 65 - struct dma_buf_sysfs_entry *sysfs_entry; 66 - struct dma_buf *dmabuf; 67 - 68 - attribute = to_dma_buf_stats_attr(attr); 69 - sysfs_entry = to_dma_buf_entry_from_kobj(kobj); 70 - dmabuf = sysfs_entry->dmabuf; 71 - 72 - if (!dmabuf || !attribute->show) 73 - return -EIO; 74 - 75 - return attribute->show(dmabuf, attribute, buf); 76 - } 77 - 78 - static const struct sysfs_ops dma_buf_stats_sysfs_ops = { 79 - .show = dma_buf_stats_attribute_show, 80 - }; 81 - 82 - static ssize_t exporter_name_show(struct dma_buf *dmabuf, 83 - struct dma_buf_stats_attribute *attr, 84 - char *buf) 85 - { 86 - return sysfs_emit(buf, "%s\n", dmabuf->exp_name); 87 - } 88 - 89 - static ssize_t size_show(struct dma_buf *dmabuf, 90 - struct dma_buf_stats_attribute *attr, 91 - char *buf) 92 - { 93 - return sysfs_emit(buf, "%zu\n", dmabuf->size); 94 - } 95 - 96 - static struct dma_buf_stats_attribute exporter_name_attribute = 97 - __ATTR_RO(exporter_name); 98 - static struct dma_buf_stats_attribute size_attribute = __ATTR_RO(size); 99 - 100 - static struct attribute *dma_buf_stats_default_attrs[] = { 101 - &exporter_name_attribute.attr, 102 - &size_attribute.attr, 103 - NULL, 104 - }; 105 - ATTRIBUTE_GROUPS(dma_buf_stats_default); 106 - 107 - static void dma_buf_sysfs_release(struct kobject *kobj) 108 - { 109 - struct dma_buf_sysfs_entry *sysfs_entry; 110 - 111 - sysfs_entry = to_dma_buf_entry_from_kobj(kobj); 112 - kfree(sysfs_entry); 113 - } 114 - 115 - static const struct kobj_type dma_buf_ktype = { 116 - .sysfs_ops = &dma_buf_stats_sysfs_ops, 117 - .release = dma_buf_sysfs_release, 118 - .default_groups = dma_buf_stats_default_groups, 119 - }; 120 - 121 - void dma_buf_stats_teardown(struct dma_buf *dmabuf) 122 - { 123 - struct dma_buf_sysfs_entry *sysfs_entry; 124 - 125 - sysfs_entry = dmabuf->sysfs_entry; 126 - if (!sysfs_entry) 127 - return; 128 - 129 - kobject_del(&sysfs_entry->kobj); 130 - kobject_put(&sysfs_entry->kobj); 131 - } 132 - 133 - 134 - /* Statistics files do not need to send uevents. */ 135 - static int dmabuf_sysfs_uevent_filter(const struct kobject *kobj) 136 - { 137 - return 0; 138 - } 139 - 140 - static const struct kset_uevent_ops dmabuf_sysfs_no_uevent_ops = { 141 - .filter = dmabuf_sysfs_uevent_filter, 142 - }; 143 - 144 - static struct kset *dma_buf_stats_kset; 145 - static struct kset *dma_buf_per_buffer_stats_kset; 146 - int dma_buf_init_sysfs_statistics(void) 147 - { 148 - dma_buf_stats_kset = kset_create_and_add("dmabuf", 149 - &dmabuf_sysfs_no_uevent_ops, 150 - kernel_kobj); 151 - if (!dma_buf_stats_kset) 152 - return -ENOMEM; 153 - 154 - dma_buf_per_buffer_stats_kset = kset_create_and_add("buffers", 155 - &dmabuf_sysfs_no_uevent_ops, 156 - &dma_buf_stats_kset->kobj); 157 - if (!dma_buf_per_buffer_stats_kset) { 158 - kset_unregister(dma_buf_stats_kset); 159 - return -ENOMEM; 160 - } 161 - 162 - return 0; 163 - } 164 - 165 - void dma_buf_uninit_sysfs_statistics(void) 166 - { 167 - kset_unregister(dma_buf_per_buffer_stats_kset); 168 - kset_unregister(dma_buf_stats_kset); 169 - } 170 - 171 - int dma_buf_stats_setup(struct dma_buf *dmabuf, struct file *file) 172 - { 173 - struct dma_buf_sysfs_entry *sysfs_entry; 174 - int ret; 175 - 176 - if (!dmabuf->exp_name) { 177 - pr_err("exporter name must not be empty if stats needed\n"); 178 - return -EINVAL; 179 - } 180 - 181 - sysfs_entry = kzalloc(sizeof(struct dma_buf_sysfs_entry), GFP_KERNEL); 182 - if (!sysfs_entry) 183 - return -ENOMEM; 184 - 185 - sysfs_entry->kobj.kset = dma_buf_per_buffer_stats_kset; 186 - sysfs_entry->dmabuf = dmabuf; 187 - 188 - dmabuf->sysfs_entry = sysfs_entry; 189 - 190 - /* create the directory for buffer stats */ 191 - ret = kobject_init_and_add(&sysfs_entry->kobj, &dma_buf_ktype, NULL, 192 - "%lu", file_inode(file)->i_ino); 193 - if (ret) 194 - goto err_sysfs_dmabuf; 195 - 196 - return 0; 197 - 198 - err_sysfs_dmabuf: 199 - kobject_put(&sysfs_entry->kobj); 200 - dmabuf->sysfs_entry = NULL; 201 - return ret; 202 - }
-35
drivers/dma-buf/dma-buf-sysfs-stats.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * DMA-BUF sysfs statistics. 4 - * 5 - * Copyright (C) 2021 Google LLC. 6 - */ 7 - 8 - #ifndef _DMA_BUF_SYSFS_STATS_H 9 - #define _DMA_BUF_SYSFS_STATS_H 10 - 11 - #ifdef CONFIG_DMABUF_SYSFS_STATS 12 - 13 - int dma_buf_init_sysfs_statistics(void); 14 - void dma_buf_uninit_sysfs_statistics(void); 15 - 16 - int dma_buf_stats_setup(struct dma_buf *dmabuf, struct file *file); 17 - 18 - void dma_buf_stats_teardown(struct dma_buf *dmabuf); 19 - #else 20 - 21 - static inline int dma_buf_init_sysfs_statistics(void) 22 - { 23 - return 0; 24 - } 25 - 26 - static inline void dma_buf_uninit_sysfs_statistics(void) {} 27 - 28 - static inline int dma_buf_stats_setup(struct dma_buf *dmabuf, struct file *file) 29 - { 30 - return 0; 31 - } 32 - 33 - static inline void dma_buf_stats_teardown(struct dma_buf *dmabuf) {} 34 - #endif 35 - #endif // _DMA_BUF_SYSFS_STATS_H
+3 -24
drivers/dma-buf/dma-buf.c
··· 33 33 #include <uapi/linux/dma-buf.h> 34 34 #include <uapi/linux/magic.h> 35 35 36 - #include "dma-buf-sysfs-stats.h" 37 - 38 36 #define CREATE_TRACE_POINTS 39 37 #include <trace/events/dma_buf.h> 40 38 ··· 46 48 */ 47 49 #define DMA_BUF_TRACE(FUNC, ...) \ 48 50 do { \ 49 - if (FUNC##_enabled()) { \ 51 + /* Always expose lock if lockdep is enabled */ \ 52 + if (IS_ENABLED(CONFIG_LOCKDEP) || FUNC##_enabled()) { \ 50 53 guard(spinlock)(&dmabuf->name_lock); \ 51 54 FUNC(__VA_ARGS__); \ 52 - } else if (IS_ENABLED(CONFIG_LOCKDEP)) { \ 53 - /* Expose this lock when lockdep is enabled */ \ 54 - guard(spinlock)(&dmabuf->name_lock); \ 55 55 } \ 56 56 } while (0) 57 57 ··· 180 184 */ 181 185 BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active); 182 186 183 - dma_buf_stats_teardown(dmabuf); 184 187 dmabuf->ops->release(dmabuf); 185 188 186 189 if (dmabuf->resv == (struct dma_resv *)&dmabuf[1]) ··· 760 765 dmabuf->resv = resv; 761 766 } 762 767 763 - ret = dma_buf_stats_setup(dmabuf, file); 764 - if (ret) 765 - goto err_dmabuf; 766 - 767 768 file->private_data = dmabuf; 768 769 file->f_path.dentry->d_fsdata = dmabuf; 769 770 dmabuf->file = file; ··· 770 779 771 780 return dmabuf; 772 781 773 - err_dmabuf: 774 - if (!resv) 775 - dma_resv_fini(dmabuf->resv); 776 - kfree(dmabuf); 777 782 err_file: 778 783 fput(file); 779 784 err_module: ··· 793 806 return -EINVAL; 794 807 795 808 fd = FD_ADD(flags, dmabuf->file); 796 - if (fd >= 0) 797 - DMA_BUF_TRACE(trace_dma_buf_fd, dmabuf, fd); 809 + DMA_BUF_TRACE(trace_dma_buf_fd, dmabuf, fd); 798 810 799 811 return fd; 800 812 } ··· 1788 1802 1789 1803 static int __init dma_buf_init(void) 1790 1804 { 1791 - int ret; 1792 - 1793 - ret = dma_buf_init_sysfs_statistics(); 1794 - if (ret) 1795 - return ret; 1796 - 1797 1805 dma_buf_mnt = kern_mount(&dma_buf_fs_type); 1798 1806 if (IS_ERR(dma_buf_mnt)) 1799 1807 return PTR_ERR(dma_buf_mnt); ··· 1801 1821 { 1802 1822 dma_buf_uninit_debugfs(); 1803 1823 kern_unmount(dma_buf_mnt); 1804 - dma_buf_uninit_sysfs_statistics(); 1805 1824 } 1806 1825 __exitcall(dma_buf_deinit);
+5
drivers/dma-buf/dma-heap.c
··· 49 49 static struct class *dma_heap_class; 50 50 static DEFINE_XARRAY_ALLOC(dma_heap_minors); 51 51 52 + bool __read_mostly mem_accounting; 53 + module_param(mem_accounting, bool, 0444); 54 + MODULE_PARM_DESC(mem_accounting, 55 + "Enable cgroup-based memory accounting for dma-buf heap allocations (default=false)."); 56 + 52 57 static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len, 53 58 u32 fd_flags, 54 59 u64 heap_flags)
+5 -2
drivers/dma-buf/heaps/system_heap.c
··· 320 320 { 321 321 struct page *page; 322 322 int i; 323 + gfp_t flags; 323 324 324 325 for (i = 0; i < NUM_ORDERS; i++) { 325 326 if (size < (PAGE_SIZE << orders[i])) 326 327 continue; 327 328 if (max_order < orders[i]) 328 329 continue; 329 - 330 - page = alloc_pages(order_flags[i], orders[i]); 330 + flags = order_flags[i]; 331 + if (mem_accounting) 332 + flags |= __GFP_ACCOUNT; 333 + page = alloc_pages(flags, orders[i]); 331 334 if (!page) 332 335 continue; 333 336 return page;
+6 -26
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
··· 509 509 .atomic_disable = atmel_hlcdc_crtc_atomic_disable, 510 510 }; 511 511 512 - static void atmel_hlcdc_crtc_destroy(struct drm_crtc *c) 513 - { 514 - struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c); 515 - 516 - drm_crtc_cleanup(c); 517 - kfree(crtc); 518 - } 519 - 520 512 static void atmel_hlcdc_crtc_finish_page_flip(struct atmel_hlcdc_crtc *crtc) 521 513 { 522 514 struct drm_device *dev = crtc->base.dev; ··· 599 607 static const struct drm_crtc_funcs atmel_hlcdc_crtc_funcs = { 600 608 .page_flip = drm_atomic_helper_page_flip, 601 609 .set_config = drm_atomic_helper_set_config, 602 - .destroy = atmel_hlcdc_crtc_destroy, 603 610 .reset = atmel_hlcdc_crtc_reset, 604 611 .atomic_duplicate_state = atmel_hlcdc_crtc_duplicate_state, 605 612 .atomic_destroy_state = atmel_hlcdc_crtc_destroy_state, ··· 611 620 struct atmel_hlcdc_plane *primary = NULL, *cursor = NULL; 612 621 struct atmel_hlcdc_dc *dc = dev->dev_private; 613 622 struct atmel_hlcdc_crtc *crtc; 614 - int ret; 615 623 int i; 616 - 617 - crtc = kzalloc(sizeof(*crtc), GFP_KERNEL); 618 - if (!crtc) 619 - return -ENOMEM; 620 - 621 - crtc->dc = dc; 622 624 623 625 for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) { 624 626 if (!dc->layers[i]) ··· 630 646 break; 631 647 } 632 648 } 649 + crtc = drmm_crtc_alloc_with_planes(dev, struct atmel_hlcdc_crtc, base, 650 + &primary->base, &cursor->base, &atmel_hlcdc_crtc_funcs, 651 + NULL); 652 + if (IS_ERR(crtc)) 653 + return PTR_ERR(crtc); 633 654 634 - ret = drm_crtc_init_with_planes(dev, &crtc->base, &primary->base, 635 - &cursor->base, &atmel_hlcdc_crtc_funcs, 636 - NULL); 637 - if (ret < 0) 638 - goto fail; 639 - 655 + crtc->dc = dc; 640 656 crtc->id = drm_crtc_index(&crtc->base); 641 657 642 658 for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) { ··· 658 674 dc->crtc = &crtc->base; 659 675 660 676 return 0; 661 - 662 - fail: 663 - atmel_hlcdc_crtc_destroy(&crtc->base); 664 - return ret; 665 677 }
+21 -19
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
··· 723 723 724 724 drm_mode_config_init(dev); 725 725 726 - ret = atmel_hlcdc_create_outputs(dev); 727 - if (ret) { 728 - drm_err(dev, "failed to create HLCDC outputs: %d\n", ret); 729 - return ret; 730 - } 731 - 732 726 ret = atmel_hlcdc_create_planes(dev); 733 727 if (ret) { 734 728 drm_err(dev, "failed to create planes: %d\n", ret); ··· 732 738 ret = atmel_hlcdc_crtc_create(dev); 733 739 if (ret) { 734 740 drm_err(dev, "failed to create crtc\n"); 741 + return ret; 742 + } 743 + 744 + ret = atmel_hlcdc_create_outputs(dev); 745 + if (ret) { 746 + drm_err(dev, "failed to create HLCDC outputs: %d\n", ret); 735 747 return ret; 736 748 } 737 749 ··· 751 751 return 0; 752 752 } 753 753 754 + static struct atmel_hlcdc_dc *atmel_hlcdc_dc_of_dev(struct drm_device *dev) 755 + { 756 + return container_of(dev, struct atmel_hlcdc_dc, dev); 757 + } 758 + 754 759 static int atmel_hlcdc_dc_load(struct drm_device *dev) 755 760 { 756 761 struct platform_device *pdev = to_platform_device(dev->dev); 757 762 const struct of_device_id *match; 758 - struct atmel_hlcdc_dc *dc; 763 + struct atmel_hlcdc_dc *dc = atmel_hlcdc_dc_of_dev(dev); 759 764 int ret; 760 765 761 766 match = of_match_node(atmel_hlcdc_of_match, dev->dev->parent->of_node); ··· 773 768 dev_err(&pdev->dev, "invalid hlcdc description\n"); 774 769 return -EINVAL; 775 770 } 776 - 777 - dc = devm_kzalloc(dev->dev, sizeof(*dc), GFP_KERNEL); 778 - if (!dc) 779 - return -ENOMEM; 780 771 781 772 dc->desc = match->data; 782 773 dc->hlcdc = dev_get_drvdata(dev->dev->parent); ··· 854 853 855 854 static int atmel_hlcdc_dc_drm_probe(struct platform_device *pdev) 856 855 { 856 + struct atmel_hlcdc_dc *dc; 857 857 struct drm_device *ddev; 858 858 int ret; 859 859 860 - ddev = drm_dev_alloc(&atmel_hlcdc_dc_driver, &pdev->dev); 861 - if (IS_ERR(ddev)) 862 - return PTR_ERR(ddev); 860 + if (drm_firmware_drivers_only()) 861 + return -ENODEV; 862 + 863 + dc = devm_drm_dev_alloc(&pdev->dev, &atmel_hlcdc_dc_driver, struct atmel_hlcdc_dc, dev); 864 + if (IS_ERR(dc)) 865 + return PTR_ERR(dc); 866 + ddev = &dc->dev; 863 867 864 868 ret = atmel_hlcdc_dc_load(ddev); 865 869 if (ret) 866 - goto err_put; 870 + return ret; 867 871 868 872 ret = drm_dev_register(ddev, 0); 869 873 if (ret) ··· 881 875 err_unload: 882 876 atmel_hlcdc_dc_unload(ddev); 883 877 884 - err_put: 885 - drm_dev_put(ddev); 886 - 887 878 return ret; 888 879 } 889 880 ··· 890 887 891 888 drm_dev_unregister(ddev); 892 889 atmel_hlcdc_dc_unload(ddev); 893 - drm_dev_put(ddev); 894 890 } 895 891 896 892 static void atmel_hlcdc_dc_drm_shutdown(struct platform_device *pdev)
+1
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
··· 350 350 struct dma_pool *dscrpool; 351 351 struct atmel_hlcdc *hlcdc; 352 352 struct drm_crtc *crtc; 353 + struct drm_device dev; 353 354 struct atmel_hlcdc_layer *layers[ATMEL_HLCDC_MAX_LAYERS]; 354 355 struct { 355 356 u32 imr;
+14 -36
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c
··· 69 69 { 70 70 struct atmel_hlcdc_rgb_output *output; 71 71 struct device_node *ep; 72 - struct drm_panel *panel; 73 72 struct drm_bridge *bridge; 74 - int ret; 73 + struct atmel_hlcdc_dc *dc = dev->dev_private; 74 + struct drm_crtc *crtc = dc->crtc; 75 + int ret = 0; 76 + 77 + bridge = devm_drm_of_get_bridge(dev->dev, dev->dev->of_node, 0, endpoint); 78 + if (IS_ERR(bridge)) 79 + return PTR_ERR(bridge); 80 + 81 + output = drmm_simple_encoder_alloc(dev, struct atmel_hlcdc_rgb_output, 82 + encoder, DRM_MODE_ENCODER_NONE); 83 + if (IS_ERR(output)) 84 + return PTR_ERR(output); 75 85 76 86 ep = of_graph_get_endpoint_by_regs(dev->dev->of_node, 0, endpoint); 77 87 if (!ep) 78 88 return -ENODEV; 79 - 80 - ret = drm_of_find_panel_or_bridge(dev->dev->of_node, 0, endpoint, 81 - &panel, &bridge); 82 - if (ret) { 83 - of_node_put(ep); 84 - return ret; 85 - } 86 - 87 - output = devm_kzalloc(dev->dev, sizeof(*output), GFP_KERNEL); 88 - if (!output) { 89 - of_node_put(ep); 90 - return -ENOMEM; 91 - } 92 89 93 90 output->bus_fmt = atmel_hlcdc_of_bus_fmt(ep); 94 91 of_node_put(ep); ··· 94 97 return -EINVAL; 95 98 } 96 99 97 - ret = drm_simple_encoder_init(dev, &output->encoder, 98 - DRM_MODE_ENCODER_NONE); 99 - if (ret) 100 - return ret; 101 100 102 - output->encoder.possible_crtcs = 0x1; 101 + output->encoder.possible_crtcs = drm_crtc_mask(crtc); 103 102 104 - if (panel) { 105 - bridge = drm_panel_bridge_add_typed(panel, 106 - DRM_MODE_CONNECTOR_Unknown); 107 - if (IS_ERR(bridge)) 108 - return PTR_ERR(bridge); 109 - } 110 - 111 - if (bridge) { 103 + if (bridge) 112 104 ret = drm_bridge_attach(&output->encoder, bridge, NULL, 0); 113 - if (!ret) 114 - return 0; 115 - 116 - if (panel) 117 - drm_panel_bridge_remove(bridge); 118 - } 119 - 120 - drm_encoder_cleanup(&output->encoder); 121 105 122 106 return ret; 123 107 }
+39 -59
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
··· 79 79 return container_of(s, struct atmel_hlcdc_plane_state, base); 80 80 } 81 81 82 - #define SUBPIXEL_MASK 0xffff 83 - 84 82 static uint32_t rgb_formats[] = { 85 83 DRM_FORMAT_C8, 86 84 DRM_FORMAT_XRGB4444, ··· 743 745 if (ret || !s->visible) 744 746 return ret; 745 747 746 - hstate->src_x = s->src.x1; 747 - hstate->src_y = s->src.y1; 748 - hstate->src_w = drm_rect_width(&s->src); 749 - hstate->src_h = drm_rect_height(&s->src); 748 + hstate->src_x = s->src.x1 >> 16; 749 + hstate->src_y = s->src.y1 >> 16; 750 + hstate->src_w = drm_rect_width(&s->src) >> 16; 751 + hstate->src_h = drm_rect_height(&s->src) >> 16; 750 752 hstate->crtc_x = s->dst.x1; 751 753 hstate->crtc_y = s->dst.y1; 752 754 hstate->crtc_w = drm_rect_width(&s->dst); 753 755 hstate->crtc_h = drm_rect_height(&s->dst); 754 - 755 - if ((hstate->src_x | hstate->src_y | hstate->src_w | hstate->src_h) & 756 - SUBPIXEL_MASK) 757 - return -EINVAL; 758 - 759 - hstate->src_x >>= 16; 760 - hstate->src_y >>= 16; 761 - hstate->src_w >>= 16; 762 - hstate->src_h >>= 16; 763 756 764 757 hstate->nplanes = fb->format->num_planes; 765 758 if (hstate->nplanes > ATMEL_HLCDC_LAYER_MAX_PLANES) ··· 1144 1155 return -ENOMEM; 1145 1156 } 1146 1157 1147 - static void atmel_hlcdc_plane_reset(struct drm_plane *p) 1148 - { 1149 - struct atmel_hlcdc_plane_state *state; 1150 - 1151 - if (p->state) { 1152 - state = drm_plane_state_to_atmel_hlcdc_plane_state(p->state); 1153 - 1154 - if (state->base.fb) 1155 - drm_framebuffer_put(state->base.fb); 1156 - 1157 - kfree(state); 1158 - p->state = NULL; 1159 - } 1160 - 1161 - state = kzalloc(sizeof(*state), GFP_KERNEL); 1162 - if (state) { 1163 - if (atmel_hlcdc_plane_alloc_dscrs(p, state)) { 1164 - kfree(state); 1165 - drm_err(p->dev, 1166 - "Failed to allocate initial plane state\n"); 1167 - return; 1168 - } 1169 - __drm_atomic_helper_plane_reset(p, &state->base); 1170 - } 1171 - } 1172 - 1173 1158 static struct drm_plane_state * 1174 1159 atmel_hlcdc_plane_atomic_duplicate_state(struct drm_plane *p) 1175 1160 { ··· 1160 1197 return NULL; 1161 1198 } 1162 1199 1163 - if (copy->base.fb) 1164 - drm_framebuffer_get(copy->base.fb); 1200 + __drm_atomic_helper_plane_duplicate_state(p, &copy->base); 1165 1201 1166 1202 return &copy->base; 1167 1203 } ··· 1178 1216 state->dscrs[i]->self); 1179 1217 } 1180 1218 1181 - if (s->fb) 1182 - drm_framebuffer_put(s->fb); 1219 + __drm_atomic_helper_plane_destroy_state(s); 1183 1220 1184 1221 kfree(state); 1222 + } 1223 + 1224 + static void atmel_hlcdc_plane_reset(struct drm_plane *p) 1225 + { 1226 + struct atmel_hlcdc_plane_state *state; 1227 + struct atmel_hlcdc_dc *dc = p->dev->dev_private; 1228 + struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); 1229 + 1230 + if (p->state) { 1231 + atmel_hlcdc_plane_atomic_destroy_state(p, p->state); 1232 + p->state = NULL; 1233 + } 1234 + 1235 + state = kzalloc(sizeof(*state), GFP_KERNEL); 1236 + if (state) { 1237 + if (atmel_hlcdc_plane_alloc_dscrs(p, state)) { 1238 + kfree(state); 1239 + drm_err(p->dev, 1240 + "Failed to allocate initial plane state\n"); 1241 + return; 1242 + } 1243 + __drm_atomic_helper_plane_reset(p, &state->base); 1244 + } 1245 + 1246 + if (plane->layer.desc->layout.csc) 1247 + dc->desc->ops->lcdc_csc_init(plane, plane->layer.desc); 1185 1248 } 1186 1249 1187 1250 static const struct drm_plane_funcs layer_plane_funcs = { 1188 1251 .update_plane = drm_atomic_helper_update_plane, 1189 1252 .disable_plane = drm_atomic_helper_disable_plane, 1190 - .destroy = drm_plane_cleanup, 1191 1253 .reset = atmel_hlcdc_plane_reset, 1192 1254 .atomic_duplicate_state = atmel_hlcdc_plane_atomic_duplicate_state, 1193 1255 .atomic_destroy_state = atmel_hlcdc_plane_atomic_destroy_state, ··· 1225 1239 enum drm_plane_type type; 1226 1240 int ret; 1227 1241 1228 - plane = devm_kzalloc(dev->dev, sizeof(*plane), GFP_KERNEL); 1229 - if (!plane) 1230 - return -ENOMEM; 1231 - 1232 - atmel_hlcdc_layer_init(&plane->layer, desc, dc->hlcdc->regmap); 1233 - 1234 1242 if (desc->type == ATMEL_HLCDC_BASE_LAYER) 1235 1243 type = DRM_PLANE_TYPE_PRIMARY; 1236 1244 else if (desc->type == ATMEL_HLCDC_CURSOR_LAYER) ··· 1232 1252 else 1233 1253 type = DRM_PLANE_TYPE_OVERLAY; 1234 1254 1235 - ret = drm_universal_plane_init(dev, &plane->base, 0, 1236 - &layer_plane_funcs, 1237 - desc->formats->formats, 1238 - desc->formats->nformats, 1239 - NULL, type, NULL); 1240 - if (ret) 1241 - return ret; 1255 + plane = drmm_universal_plane_alloc(dev, struct atmel_hlcdc_plane, base, 0, 1256 + &layer_plane_funcs, desc->formats->formats, 1257 + desc->formats->nformats, NULL, type, NULL); 1258 + if (IS_ERR(plane)) 1259 + return PTR_ERR(plane); 1260 + 1261 + atmel_hlcdc_layer_init(&plane->layer, desc, dc->hlcdc->regmap); 1242 1262 1243 1263 drm_plane_helper_add(&plane->base, 1244 1264 &atmel_hlcdc_layer_plane_helper_funcs);
+98 -68
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
··· 887 887 return adv7511_edid_read(adv, connector); 888 888 } 889 889 890 - static int adv7511_bridge_hdmi_clear_infoframe(struct drm_bridge *bridge, 891 - enum hdmi_infoframe_type type) 890 + static int adv7511_bridge_hdmi_clear_audio_infoframe(struct drm_bridge *bridge) 892 891 { 893 892 struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 894 893 895 - switch (type) { 896 - case HDMI_INFOFRAME_TYPE_AUDIO: 897 - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); 898 - break; 899 - case HDMI_INFOFRAME_TYPE_AVI: 900 - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME); 901 - break; 902 - case HDMI_INFOFRAME_TYPE_SPD: 903 - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPD); 904 - break; 905 - case HDMI_INFOFRAME_TYPE_VENDOR: 906 - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); 907 - break; 908 - default: 909 - drm_dbg_driver(adv7511->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type); 910 - break; 911 - } 894 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); 912 895 913 896 return 0; 914 897 } 915 898 916 - static int adv7511_bridge_hdmi_write_infoframe(struct drm_bridge *bridge, 917 - enum hdmi_infoframe_type type, 918 - const u8 *buffer, size_t len) 899 + static int adv7511_bridge_hdmi_clear_avi_infoframe(struct drm_bridge *bridge) 919 900 { 920 901 struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 921 902 922 - switch (type) { 923 - case HDMI_INFOFRAME_TYPE_AUDIO: 924 - /* send current Audio infoframe values while updating */ 925 - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 926 - BIT(5), BIT(5)); 903 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME); 927 904 928 - /* The Audio infoframe id is not configurable */ 929 - regmap_bulk_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME_VERSION, 930 - buffer + 1, len - 1); 905 + return 0; 906 + } 931 907 932 - /* use Audio infoframe updated info */ 933 - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 934 - BIT(5), 0); 908 + static int adv7511_bridge_hdmi_clear_spd_infoframe(struct drm_bridge *bridge) 909 + { 910 + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 935 911 936 - adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); 937 - break; 938 - case HDMI_INFOFRAME_TYPE_AVI: 939 - /* send current AVI infoframe values while updating */ 940 - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 941 - BIT(6), BIT(6)); 912 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPD); 942 913 943 - /* The AVI infoframe id is not configurable */ 944 - regmap_bulk_write(adv7511->regmap, ADV7511_REG_AVI_INFOFRAME_VERSION, 945 - buffer + 1, len - 1); 914 + return 0; 915 + } 946 916 947 - regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME_LENGTH, 0x2); 948 - regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME(1), 0x1); 917 + static int adv7511_bridge_hdmi_clear_hdmi_infoframe(struct drm_bridge *bridge) 918 + { 919 + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 949 920 950 - /* use AVI infoframe updated info */ 951 - regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 952 - BIT(6), 0); 921 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); 953 922 954 - adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME); 955 - break; 956 - case HDMI_INFOFRAME_TYPE_SPD: 957 - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPD); 958 - regmap_bulk_write(adv7511->regmap_packet, ADV7511_PACKET_SPD(0), 959 - buffer, len); 960 - adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_SPD); 961 - break; 962 - case HDMI_INFOFRAME_TYPE_VENDOR: 963 - adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); 964 - regmap_bulk_write(adv7511->regmap_packet, ADV7511_PACKET_SPARE1(0), 965 - buffer, len); 966 - adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); 967 - break; 968 - default: 969 - drm_dbg_driver(adv7511->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type); 970 - break; 971 - } 923 + return 0; 924 + } 925 + 926 + static int adv7511_bridge_hdmi_write_audio_infoframe(struct drm_bridge *bridge, 927 + const u8 *buffer, size_t len) 928 + { 929 + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 930 + 931 + /* send current Audio infoframe values while updating */ 932 + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 933 + BIT(5), BIT(5)); 934 + 935 + /* The Audio infoframe id is not configurable */ 936 + regmap_bulk_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME_VERSION, 937 + buffer + 1, len - 1); 938 + 939 + /* use Audio infoframe updated info */ 940 + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 941 + BIT(5), 0); 942 + 943 + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AUDIO_INFOFRAME); 944 + 945 + return 0; 946 + } 947 + 948 + static int adv7511_bridge_hdmi_write_avi_infoframe(struct drm_bridge *bridge, 949 + const u8 *buffer, size_t len) 950 + { 951 + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 952 + 953 + /* send current AVI infoframe values while updating */ 954 + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 955 + BIT(6), BIT(6)); 956 + 957 + /* The AVI infoframe id is not configurable */ 958 + regmap_bulk_write(adv7511->regmap, ADV7511_REG_AVI_INFOFRAME_VERSION, 959 + buffer + 1, len - 1); 960 + 961 + regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME_LENGTH, 0x2); 962 + regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME(1), 0x1); 963 + 964 + /* use AVI infoframe updated info */ 965 + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 966 + BIT(6), 0); 967 + 968 + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_AVI_INFOFRAME); 969 + 970 + return 0; 971 + } 972 + 973 + static int adv7511_bridge_hdmi_write_spd_infoframe(struct drm_bridge *bridge, 974 + const u8 *buffer, size_t len) 975 + { 976 + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 977 + 978 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPD); 979 + regmap_bulk_write(adv7511->regmap_packet, ADV7511_PACKET_SPD(0), 980 + buffer, len); 981 + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_SPD); 982 + 983 + return 0; 984 + } 985 + 986 + static int adv7511_bridge_hdmi_write_hdmi_infoframe(struct drm_bridge *bridge, 987 + const u8 *buffer, size_t len) 988 + { 989 + struct adv7511 *adv7511 = bridge_to_adv7511(bridge); 990 + 991 + adv7511_packet_disable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); 992 + regmap_bulk_write(adv7511->regmap_packet, ADV7511_PACKET_SPARE1(0), 993 + buffer, len); 994 + adv7511_packet_enable(adv7511, ADV7511_PACKET_ENABLE_SPARE1); 972 995 973 996 return 0; 974 997 } ··· 1009 986 .atomic_reset = drm_atomic_helper_bridge_reset, 1010 987 1011 988 .hdmi_tmds_char_rate_valid = adv7511_bridge_hdmi_tmds_char_rate_valid, 1012 - .hdmi_clear_infoframe = adv7511_bridge_hdmi_clear_infoframe, 1013 - .hdmi_write_infoframe = adv7511_bridge_hdmi_write_infoframe, 989 + .hdmi_clear_audio_infoframe = adv7511_bridge_hdmi_clear_audio_infoframe, 990 + .hdmi_write_audio_infoframe = adv7511_bridge_hdmi_write_audio_infoframe, 991 + .hdmi_clear_avi_infoframe = adv7511_bridge_hdmi_clear_avi_infoframe, 992 + .hdmi_write_avi_infoframe = adv7511_bridge_hdmi_write_avi_infoframe, 993 + .hdmi_clear_spd_infoframe = adv7511_bridge_hdmi_clear_spd_infoframe, 994 + .hdmi_write_spd_infoframe = adv7511_bridge_hdmi_write_spd_infoframe, 995 + .hdmi_clear_hdmi_infoframe = adv7511_bridge_hdmi_clear_hdmi_infoframe, 996 + .hdmi_write_hdmi_infoframe = adv7511_bridge_hdmi_write_hdmi_infoframe, 1014 997 1015 998 .hdmi_audio_startup = adv7511_hdmi_audio_startup, 1016 999 .hdmi_audio_prepare = adv7511_hdmi_audio_prepare, ··· 1351 1322 1352 1323 adv7511->bridge.ops = DRM_BRIDGE_OP_DETECT | 1353 1324 DRM_BRIDGE_OP_EDID | 1354 - DRM_BRIDGE_OP_HDMI; 1325 + DRM_BRIDGE_OP_HDMI | 1326 + DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME; 1355 1327 if (adv7511->i2c_main->irq) 1356 1328 adv7511->bridge.ops |= DRM_BRIDGE_OP_HPD; 1357 1329
+1 -1
drivers/gpu/drm/bridge/analogix/anx7625.c
··· 1801 1801 return NULL; 1802 1802 } 1803 1803 1804 - ctx->cached_drm_edid = drm_edid_alloc(edid_buf, FOUR_BLOCK_SIZE); 1804 + ctx->cached_drm_edid = drm_edid_alloc(edid_buf, edid_num * ONE_BLOCK_SIZE); 1805 1805 kfree(edid_buf); 1806 1806 1807 1807 out:
+7 -8
drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
··· 29 29 struct imx8mp_hdmi_pvi { 30 30 struct drm_bridge bridge; 31 31 struct device *dev; 32 - struct drm_bridge *next_bridge; 33 32 void __iomem *regs; 34 33 }; 35 34 ··· 44 45 { 45 46 struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge); 46 47 47 - return drm_bridge_attach(encoder, pvi->next_bridge, 48 + return drm_bridge_attach(encoder, pvi->bridge.next_bridge, 48 49 bridge, flags); 49 50 } 50 51 ··· 77 78 if (mode->flags & DRM_MODE_FLAG_PHSYNC) 78 79 val |= PVI_CTRL_OP_HSYNC_POL | PVI_CTRL_INP_HSYNC_POL; 79 80 80 - if (pvi->next_bridge->timings) 81 - bus_flags = pvi->next_bridge->timings->input_bus_flags; 81 + if (pvi->bridge.next_bridge->timings) 82 + bus_flags = pvi->bridge.next_bridge->timings->input_bus_flags; 82 83 else if (bridge_state) 83 84 bus_flags = bridge_state->input_bus_cfg.flags; 84 85 ··· 107 108 unsigned int *num_input_fmts) 108 109 { 109 110 struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge); 110 - struct drm_bridge *next_bridge = pvi->next_bridge; 111 + struct drm_bridge *next_bridge = pvi->bridge.next_bridge; 111 112 struct drm_bridge_state *next_state; 112 113 113 114 if (!next_bridge->funcs->atomic_get_input_bus_fmts) ··· 156 157 if (!remote) 157 158 return -EINVAL; 158 159 159 - pvi->next_bridge = of_drm_find_bridge(remote); 160 + pvi->bridge.next_bridge = of_drm_find_and_get_bridge(remote); 160 161 of_node_put(remote); 161 162 162 - if (!pvi->next_bridge) 163 + if (!pvi->bridge.next_bridge) 163 164 return dev_err_probe(&pdev->dev, -EPROBE_DEFER, 164 165 "could not find next bridge\n"); 165 166 ··· 167 168 168 169 /* Register the bridge. */ 169 170 pvi->bridge.of_node = pdev->dev.of_node; 170 - pvi->bridge.timings = pvi->next_bridge->timings; 171 + pvi->bridge.timings = pvi->bridge.next_bridge->timings; 171 172 172 173 drm_bridge_add(&pvi->bridge); 173 174
+11 -1
drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c
··· 62 62 return container_of(base, struct imx8qxp_ldb, base); 63 63 } 64 64 65 + static void imx8qxp_ldb_bridge_destroy(struct drm_bridge *bridge) 66 + { 67 + struct ldb_channel *ldb_ch = bridge->driver_private; 68 + struct ldb *ldb = ldb_ch->ldb; 69 + struct imx8qxp_ldb *imx8qxp_ldb = base_to_imx8qxp_ldb(ldb); 70 + 71 + drm_bridge_put(imx8qxp_ldb->companion); 72 + } 73 + 65 74 static void imx8qxp_ldb_set_phy_cfg(struct imx8qxp_ldb *imx8qxp_ldb, 66 75 unsigned long di_clk, bool is_split, 67 76 struct phy_configure_opts_lvds *phy_cfg) ··· 400 391 } 401 392 402 393 static const struct drm_bridge_funcs imx8qxp_ldb_bridge_funcs = { 394 + .destroy = imx8qxp_ldb_bridge_destroy, 403 395 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, 404 396 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, 405 397 .atomic_reset = drm_atomic_helper_bridge_reset, ··· 562 552 goto out; 563 553 } 564 554 565 - imx8qxp_ldb->companion = of_drm_find_bridge(companion_port); 555 + imx8qxp_ldb->companion = of_drm_find_and_get_bridge(companion_port); 566 556 if (!imx8qxp_ldb->companion) { 567 557 ret = -EPROBE_DEFER; 568 558 DRM_DEV_DEBUG_DRIVER(dev,
+23 -18
drivers/gpu/drm/bridge/inno-hdmi.c
··· 584 584 hdmi_modb(hdmi, HDMI_STATUS, m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1)); 585 585 } 586 586 587 - static int inno_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge, 588 - enum hdmi_infoframe_type type) 587 + static int inno_hdmi_bridge_clear_avi_infoframe(struct drm_bridge *bridge) 589 588 { 590 589 struct inno_hdmi *hdmi = bridge_to_inno_hdmi(bridge); 591 - 592 - if (type != HDMI_INFOFRAME_TYPE_AVI) { 593 - drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type); 594 - return 0; 595 - } 596 590 597 591 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); 598 592 599 593 return 0; 600 594 } 601 595 602 - static int inno_hdmi_bridge_write_infoframe(struct drm_bridge *bridge, 603 - enum hdmi_infoframe_type type, 604 - const u8 *buffer, size_t len) 596 + static int inno_hdmi_bridge_write_avi_infoframe(struct drm_bridge *bridge, 597 + const u8 *buffer, size_t len) 605 598 { 606 599 struct inno_hdmi *hdmi = bridge_to_inno_hdmi(bridge); 607 600 ssize_t i; 608 601 609 - if (type != HDMI_INFOFRAME_TYPE_AVI) { 610 - drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type); 611 - return 0; 612 - } 613 - 614 - inno_hdmi_bridge_clear_infoframe(bridge, type); 602 + inno_hdmi_bridge_clear_avi_infoframe(bridge); 615 603 616 604 for (i = 0; i < len; i++) 617 605 hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i, buffer[i]); 606 + 607 + return 0; 608 + } 609 + 610 + static int inno_hdmi_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge) 611 + { 612 + drm_warn_once(bridge->encoder->dev, "HDMI VSI not implemented\n"); 613 + 614 + return 0; 615 + } 616 + 617 + static int inno_hdmi_bridge_write_hdmi_infoframe(struct drm_bridge *bridge, 618 + const u8 *buffer, size_t len) 619 + { 620 + drm_warn_once(bridge->encoder->dev, "HDMI VSI not implemented\n"); 618 621 619 622 return 0; 620 623 } ··· 886 883 .atomic_disable = inno_hdmi_bridge_atomic_disable, 887 884 .detect = inno_hdmi_bridge_detect, 888 885 .edid_read = inno_hdmi_bridge_edid_read, 889 - .hdmi_clear_infoframe = inno_hdmi_bridge_clear_infoframe, 890 - .hdmi_write_infoframe = inno_hdmi_bridge_write_infoframe, 886 + .hdmi_clear_avi_infoframe = inno_hdmi_bridge_clear_avi_infoframe, 887 + .hdmi_write_avi_infoframe = inno_hdmi_bridge_write_avi_infoframe, 888 + .hdmi_clear_hdmi_infoframe = inno_hdmi_bridge_clear_hdmi_infoframe, 889 + .hdmi_write_hdmi_infoframe = inno_hdmi_bridge_write_hdmi_infoframe, 891 890 .mode_valid = inno_hdmi_bridge_mode_valid, 892 891 }; 893 892
+45 -42
drivers/gpu/drm/bridge/ite-it6263.c
··· 759 759 return MODE_OK; 760 760 } 761 761 762 - static int it6263_hdmi_clear_infoframe(struct drm_bridge *bridge, 763 - enum hdmi_infoframe_type type) 762 + static int it6263_hdmi_clear_avi_infoframe(struct drm_bridge *bridge) 764 763 { 765 764 struct it6263 *it = bridge_to_it6263(bridge); 766 765 767 - switch (type) { 768 - case HDMI_INFOFRAME_TYPE_AVI: 769 - regmap_write(it->hdmi_regmap, HDMI_REG_AVI_INFOFRM_CTRL, 0); 770 - break; 771 - case HDMI_INFOFRAME_TYPE_VENDOR: 772 - regmap_write(it->hdmi_regmap, HDMI_REG_PKT_NULL_CTRL, 0); 773 - break; 774 - default: 775 - dev_dbg(it->dev, "unsupported HDMI infoframe 0x%x\n", type); 776 - } 766 + regmap_write(it->hdmi_regmap, HDMI_REG_AVI_INFOFRM_CTRL, 0); 777 767 778 768 return 0; 779 769 } 780 770 781 - static int it6263_hdmi_write_infoframe(struct drm_bridge *bridge, 782 - enum hdmi_infoframe_type type, 783 - const u8 *buffer, size_t len) 771 + static int it6263_hdmi_clear_hdmi_infoframe(struct drm_bridge *bridge) 772 + { 773 + struct it6263 *it = bridge_to_it6263(bridge); 774 + 775 + regmap_write(it->hdmi_regmap, HDMI_REG_PKT_NULL_CTRL, 0); 776 + 777 + return 0; 778 + } 779 + 780 + static int it6263_hdmi_write_avi_infoframe(struct drm_bridge *bridge, 781 + const u8 *buffer, size_t len) 784 782 { 785 783 struct it6263 *it = bridge_to_it6263(bridge); 786 784 struct regmap *regmap = it->hdmi_regmap; 787 785 788 - switch (type) { 789 - case HDMI_INFOFRAME_TYPE_AVI: 790 - /* write the first AVI infoframe data byte chunk(DB1-DB5) */ 791 - regmap_bulk_write(regmap, HDMI_REG_AVI_DB1, 792 - &buffer[HDMI_INFOFRAME_HEADER_SIZE], 793 - HDMI_AVI_DB_CHUNK1_SIZE); 786 + /* write the first AVI infoframe data byte chunk(DB1-DB5) */ 787 + regmap_bulk_write(regmap, HDMI_REG_AVI_DB1, 788 + &buffer[HDMI_INFOFRAME_HEADER_SIZE], 789 + HDMI_AVI_DB_CHUNK1_SIZE); 794 790 795 - /* write the second AVI infoframe data byte chunk(DB6-DB13) */ 796 - regmap_bulk_write(regmap, HDMI_REG_AVI_DB6, 797 - &buffer[HDMI_INFOFRAME_HEADER_SIZE + 798 - HDMI_AVI_DB_CHUNK1_SIZE], 799 - HDMI_AVI_DB_CHUNK2_SIZE); 791 + /* write the second AVI infoframe data byte chunk(DB6-DB13) */ 792 + regmap_bulk_write(regmap, HDMI_REG_AVI_DB6, 793 + &buffer[HDMI_INFOFRAME_HEADER_SIZE + 794 + HDMI_AVI_DB_CHUNK1_SIZE], 795 + HDMI_AVI_DB_CHUNK2_SIZE); 800 796 801 - /* write checksum */ 802 - regmap_write(regmap, HDMI_REG_AVI_CSUM, buffer[3]); 797 + /* write checksum */ 798 + regmap_write(regmap, HDMI_REG_AVI_CSUM, buffer[3]); 803 799 804 - regmap_write(regmap, HDMI_REG_AVI_INFOFRM_CTRL, 805 - ENABLE_PKT | REPEAT_PKT); 806 - break; 807 - case HDMI_INFOFRAME_TYPE_VENDOR: 808 - /* write header and payload */ 809 - regmap_bulk_write(regmap, HDMI_REG_PKT_HB(0), buffer, len); 800 + regmap_write(regmap, HDMI_REG_AVI_INFOFRM_CTRL, 801 + ENABLE_PKT | REPEAT_PKT); 810 802 811 - regmap_write(regmap, HDMI_REG_PKT_NULL_CTRL, 812 - ENABLE_PKT | REPEAT_PKT); 813 - break; 814 - default: 815 - dev_dbg(it->dev, "unsupported HDMI infoframe 0x%x\n", type); 816 - } 803 + return 0; 804 + } 805 + 806 + static int it6263_hdmi_write_hdmi_infoframe(struct drm_bridge *bridge, 807 + const u8 *buffer, size_t len) 808 + { 809 + struct it6263 *it = bridge_to_it6263(bridge); 810 + struct regmap *regmap = it->hdmi_regmap; 811 + 812 + /* write header and payload */ 813 + regmap_bulk_write(regmap, HDMI_REG_PKT_HB(0), buffer, len); 814 + 815 + regmap_write(regmap, HDMI_REG_PKT_NULL_CTRL, 816 + ENABLE_PKT | REPEAT_PKT); 817 + 817 818 818 819 return 0; 819 820 } ··· 831 830 .edid_read = it6263_bridge_edid_read, 832 831 .atomic_get_input_bus_fmts = it6263_bridge_atomic_get_input_bus_fmts, 833 832 .hdmi_tmds_char_rate_valid = it6263_hdmi_tmds_char_rate_valid, 834 - .hdmi_clear_infoframe = it6263_hdmi_clear_infoframe, 835 - .hdmi_write_infoframe = it6263_hdmi_write_infoframe, 833 + .hdmi_clear_avi_infoframe = it6263_hdmi_clear_avi_infoframe, 834 + .hdmi_write_avi_infoframe = it6263_hdmi_write_avi_infoframe, 835 + .hdmi_clear_hdmi_infoframe = it6263_hdmi_clear_hdmi_infoframe, 836 + .hdmi_write_hdmi_infoframe = it6263_hdmi_write_hdmi_infoframe, 836 837 }; 837 838 838 839 static int it6263_probe(struct i2c_client *client)
+15 -16
drivers/gpu/drm/bridge/lontium-lt8912b.c
··· 35 35 struct regmap *regmap[I2C_MAX_IDX]; 36 36 37 37 struct device_node *host_node; 38 - struct drm_bridge *hdmi_port; 39 38 40 39 struct mipi_dsi_device *dsi; 41 40 ··· 406 407 { 407 408 struct lt8912 *lt = connector_to_lt8912(connector); 408 409 409 - if (lt->hdmi_port->ops & DRM_BRIDGE_OP_DETECT) 410 - return drm_bridge_detect(lt->hdmi_port, connector); 410 + if (lt->bridge.next_bridge->ops & DRM_BRIDGE_OP_DETECT) 411 + return drm_bridge_detect(lt->bridge.next_bridge, connector); 411 412 412 413 return lt8912_check_cable_status(lt); 413 414 } ··· 428 429 u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24; 429 430 int ret, num; 430 431 431 - drm_edid = drm_bridge_edid_read(lt->hdmi_port, connector); 432 + drm_edid = drm_bridge_edid_read(lt->bridge.next_bridge, connector); 432 433 drm_edid_connector_update(connector, drm_edid); 433 434 if (!drm_edid) 434 435 return 0; ··· 518 519 struct lt8912 *lt = bridge_to_lt8912(bridge); 519 520 struct drm_connector *connector = &lt->connector; 520 521 521 - if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD) { 522 - drm_bridge_hpd_enable(lt->hdmi_port, lt8912_bridge_hpd_cb, lt); 522 + if (lt->bridge.next_bridge->ops & DRM_BRIDGE_OP_HPD) { 523 + drm_bridge_hpd_enable(lt->bridge.next_bridge, lt8912_bridge_hpd_cb, lt); 523 524 connector->polled = DRM_CONNECTOR_POLL_HPD; 524 525 } else { 525 526 connector->polled = DRM_CONNECTOR_POLL_CONNECT | ··· 528 529 529 530 ret = drm_connector_init(bridge->dev, connector, 530 531 &lt8912_connector_funcs, 531 - lt->hdmi_port->type); 532 + lt->bridge.next_bridge->type); 532 533 if (ret) 533 534 goto exit; 534 535 ··· 548 549 struct lt8912 *lt = bridge_to_lt8912(bridge); 549 550 int ret; 550 551 551 - ret = drm_bridge_attach(encoder, lt->hdmi_port, bridge, 552 + ret = drm_bridge_attach(encoder, lt->bridge.next_bridge, bridge, 552 553 DRM_BRIDGE_ATTACH_NO_CONNECTOR); 553 554 if (ret < 0) { 554 555 dev_err(lt->dev, "Failed to attach next bridge (%d)\n", ret); ··· 584 585 585 586 lt8912_hard_power_off(lt); 586 587 587 - if (lt->connector.dev && lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD) 588 - drm_bridge_hpd_disable(lt->hdmi_port); 588 + if (lt->connector.dev && lt->bridge.next_bridge->ops & DRM_BRIDGE_OP_HPD) 589 + drm_bridge_hpd_disable(lt->bridge.next_bridge); 589 590 } 590 591 591 592 static enum drm_mode_status ··· 610 611 { 611 612 struct lt8912 *lt = bridge_to_lt8912(bridge); 612 613 613 - if (lt->hdmi_port->ops & DRM_BRIDGE_OP_DETECT) 614 - return drm_bridge_detect(lt->hdmi_port, connector); 614 + if (lt->bridge.next_bridge->ops & DRM_BRIDGE_OP_DETECT) 615 + return drm_bridge_detect(lt->bridge.next_bridge, connector); 615 616 616 617 return lt8912_check_cable_status(lt); 617 618 } ··· 625 626 * edid must be read through the ddc bus but it must be 626 627 * given to the hdmi connector node. 627 628 */ 628 - if (lt->hdmi_port->ops & DRM_BRIDGE_OP_EDID) 629 - return drm_bridge_edid_read(lt->hdmi_port, connector); 629 + if (lt->bridge.next_bridge->ops & DRM_BRIDGE_OP_EDID) 630 + return drm_bridge_edid_read(lt->bridge.next_bridge, connector); 630 631 631 632 dev_warn(lt->dev, "The connected bridge does not supports DRM_BRIDGE_OP_EDID\n"); 632 633 return NULL; ··· 722 723 goto err_free_host_node; 723 724 } 724 725 725 - lt->hdmi_port = of_drm_find_bridge(port_node); 726 - if (!lt->hdmi_port) { 726 + lt->bridge.next_bridge = of_drm_find_and_get_bridge(port_node); 727 + if (!lt->bridge.next_bridge) { 727 728 ret = -EPROBE_DEFER; 728 729 dev_err_probe(lt->dev, ret, "%s: Failed to get hdmi port\n", __func__); 729 730 goto err_free_host_node;
+82 -63
drivers/gpu/drm/bridge/lontium-lt9611.c
··· 843 843 #define LT9611_INFOFRAME_AUDIO 0x02 844 844 #define LT9611_INFOFRAME_AVI 0x08 845 845 #define LT9611_INFOFRAME_SPD 0x10 846 - #define LT9611_INFOFRAME_VENDOR 0x20 846 + #define LT9611_INFOFRAME_HDMI 0x20 847 847 848 - static int lt9611_hdmi_clear_infoframe(struct drm_bridge *bridge, 849 - enum hdmi_infoframe_type type) 848 + static int lt9611_hdmi_clear_audio_infoframe(struct drm_bridge *bridge) 850 849 { 851 850 struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 852 - unsigned int mask; 853 851 854 - switch (type) { 855 - case HDMI_INFOFRAME_TYPE_AUDIO: 856 - mask = LT9611_INFOFRAME_AUDIO; 857 - break; 858 - 859 - case HDMI_INFOFRAME_TYPE_AVI: 860 - mask = LT9611_INFOFRAME_AVI; 861 - break; 862 - 863 - case HDMI_INFOFRAME_TYPE_SPD: 864 - mask = LT9611_INFOFRAME_SPD; 865 - break; 866 - 867 - case HDMI_INFOFRAME_TYPE_VENDOR: 868 - mask = LT9611_INFOFRAME_VENDOR; 869 - break; 870 - 871 - default: 872 - drm_dbg_driver(lt9611->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type); 873 - mask = 0; 874 - break; 875 - } 876 - 877 - if (mask) 878 - regmap_update_bits(lt9611->regmap, 0x843d, mask, 0); 852 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AUDIO, 0); 879 853 880 854 return 0; 881 855 } 882 856 883 - static int lt9611_hdmi_write_infoframe(struct drm_bridge *bridge, 884 - enum hdmi_infoframe_type type, 885 - const u8 *buffer, size_t len) 857 + static int lt9611_hdmi_clear_avi_infoframe(struct drm_bridge *bridge) 886 858 { 887 859 struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 888 - unsigned int mask, addr; 860 + 861 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AVI, 0); 862 + 863 + return 0; 864 + } 865 + 866 + static int lt9611_hdmi_clear_spd_infoframe(struct drm_bridge *bridge) 867 + { 868 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 869 + 870 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_SPD, 0); 871 + 872 + return 0; 873 + } 874 + 875 + static int lt9611_hdmi_clear_hdmi_infoframe(struct drm_bridge *bridge) 876 + { 877 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 878 + 879 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_HDMI, 0); 880 + 881 + return 0; 882 + } 883 + 884 + static int lt9611_hdmi_write_audio_infoframe(struct drm_bridge *bridge, 885 + const u8 *buffer, size_t len) 886 + { 887 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 889 888 int i; 890 889 891 - switch (type) { 892 - case HDMI_INFOFRAME_TYPE_AUDIO: 893 - mask = LT9611_INFOFRAME_AUDIO; 894 - addr = 0x84b2; 895 - break; 890 + for (i = 0; i < len; i++) 891 + regmap_write(lt9611->regmap, 0x84b2 + i, buffer[i]); 896 892 897 - case HDMI_INFOFRAME_TYPE_AVI: 898 - mask = LT9611_INFOFRAME_AVI; 899 - addr = 0x8440; 900 - break; 893 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AUDIO, LT9611_INFOFRAME_AUDIO); 901 894 902 - case HDMI_INFOFRAME_TYPE_SPD: 903 - mask = LT9611_INFOFRAME_SPD; 904 - addr = 0x8493; 905 - break; 895 + return 0; 896 + } 906 897 907 - case HDMI_INFOFRAME_TYPE_VENDOR: 908 - mask = LT9611_INFOFRAME_VENDOR; 909 - addr = 0x8474; 910 - break; 898 + static int lt9611_hdmi_write_avi_infoframe(struct drm_bridge *bridge, 899 + const u8 *buffer, size_t len) 900 + { 901 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 902 + int i; 911 903 912 - default: 913 - drm_dbg_driver(lt9611->bridge.dev, "Unsupported HDMI InfoFrame %x\n", type); 914 - mask = 0; 915 - break; 916 - } 904 + for (i = 0; i < len; i++) 905 + regmap_write(lt9611->regmap, 0x8440 + i, buffer[i]); 917 906 918 - if (mask) { 919 - for (i = 0; i < len; i++) 920 - regmap_write(lt9611->regmap, addr + i, buffer[i]); 907 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_AVI, LT9611_INFOFRAME_AVI); 921 908 922 - regmap_update_bits(lt9611->regmap, 0x843d, mask, mask); 923 - } 909 + return 0; 910 + } 911 + 912 + static int lt9611_hdmi_write_spd_infoframe(struct drm_bridge *bridge, 913 + const u8 *buffer, size_t len) 914 + { 915 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 916 + int i; 917 + 918 + for (i = 0; i < len; i++) 919 + regmap_write(lt9611->regmap, 0x8493 + i, buffer[i]); 920 + 921 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_SPD, LT9611_INFOFRAME_SPD); 922 + 923 + return 0; 924 + } 925 + 926 + static int lt9611_hdmi_write_hdmi_infoframe(struct drm_bridge *bridge, 927 + const u8 *buffer, size_t len) 928 + { 929 + struct lt9611 *lt9611 = bridge_to_lt9611(bridge); 930 + int i; 931 + 932 + for (i = 0; i < len; i++) 933 + regmap_write(lt9611->regmap, 0x8474 + i, buffer[i]); 934 + 935 + regmap_update_bits(lt9611->regmap, 0x843d, LT9611_INFOFRAME_HDMI, LT9611_INFOFRAME_HDMI); 924 936 925 937 return 0; 926 938 } ··· 1015 1003 .atomic_get_input_bus_fmts = lt9611_atomic_get_input_bus_fmts, 1016 1004 1017 1005 .hdmi_tmds_char_rate_valid = lt9611_hdmi_tmds_char_rate_valid, 1018 - .hdmi_write_infoframe = lt9611_hdmi_write_infoframe, 1019 - .hdmi_clear_infoframe = lt9611_hdmi_clear_infoframe, 1006 + .hdmi_write_audio_infoframe = lt9611_hdmi_write_audio_infoframe, 1007 + .hdmi_clear_audio_infoframe = lt9611_hdmi_clear_audio_infoframe, 1008 + .hdmi_write_avi_infoframe = lt9611_hdmi_write_avi_infoframe, 1009 + .hdmi_clear_avi_infoframe = lt9611_hdmi_clear_avi_infoframe, 1010 + .hdmi_write_spd_infoframe = lt9611_hdmi_write_spd_infoframe, 1011 + .hdmi_clear_spd_infoframe = lt9611_hdmi_clear_spd_infoframe, 1012 + .hdmi_write_hdmi_infoframe = lt9611_hdmi_write_hdmi_infoframe, 1013 + .hdmi_clear_hdmi_infoframe = lt9611_hdmi_clear_hdmi_infoframe, 1020 1014 1021 1015 .hdmi_audio_startup = lt9611_hdmi_audio_startup, 1022 1016 .hdmi_audio_prepare = lt9611_hdmi_audio_prepare, ··· 1150 1132 lt9611->bridge.of_node = client->dev.of_node; 1151 1133 lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | 1152 1134 DRM_BRIDGE_OP_HPD | DRM_BRIDGE_OP_MODES | 1153 - DRM_BRIDGE_OP_HDMI | DRM_BRIDGE_OP_HDMI_AUDIO; 1135 + DRM_BRIDGE_OP_HDMI | DRM_BRIDGE_OP_HDMI_AUDIO | 1136 + DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME; 1154 1137 lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA; 1155 1138 lt9611->bridge.vendor = "Lontium"; 1156 1139 lt9611->bridge.product = "LT9611";
+26 -11
drivers/gpu/drm/bridge/samsung-dsim.c
··· 1828 1828 { 1829 1829 struct samsung_dsim *dsi = bridge_to_dsi(bridge); 1830 1830 1831 - return drm_bridge_attach(encoder, dsi->out_bridge, bridge, 1831 + return drm_bridge_attach(encoder, dsi->bridge.next_bridge, bridge, 1832 1832 flags); 1833 1833 } 1834 1834 ··· 1886 1886 { 1887 1887 struct samsung_dsim *dsi = host_to_dsi(host); 1888 1888 const struct samsung_dsim_plat_data *pdata = dsi->plat_data; 1889 + struct drm_bridge *next_bridge __free(drm_bridge_put) = NULL; 1889 1890 struct device *dev = dsi->dev; 1890 1891 struct device_node *np = dev->of_node; 1891 1892 struct device_node *remote; 1892 1893 struct drm_panel *panel; 1893 - int ret; 1894 + int ret = 0; 1894 1895 1895 1896 /* 1896 1897 * Devices can also be child nodes when we also control that device ··· 1925 1924 1926 1925 panel = of_drm_find_panel(remote); 1927 1926 if (!IS_ERR(panel)) { 1928 - dsi->out_bridge = devm_drm_panel_bridge_add(dev, panel); 1927 + next_bridge = devm_drm_panel_bridge_add(dev, panel); 1928 + if (IS_ERR(next_bridge)) { 1929 + ret = PTR_ERR(next_bridge); 1930 + next_bridge = NULL; // Inhibit the cleanup action on an ERR_PTR 1931 + } else { 1932 + drm_bridge_get(next_bridge); 1933 + } 1929 1934 } else { 1930 - dsi->out_bridge = of_drm_find_bridge(remote); 1931 - if (!dsi->out_bridge) 1932 - dsi->out_bridge = ERR_PTR(-EINVAL); 1935 + next_bridge = of_drm_find_and_get_bridge(remote); 1936 + if (!next_bridge) 1937 + ret = -EINVAL; 1933 1938 } 1934 1939 1935 1940 of_node_put(remote); 1936 1941 1937 - if (IS_ERR(dsi->out_bridge)) { 1938 - ret = PTR_ERR(dsi->out_bridge); 1942 + if (ret) { 1939 1943 DRM_DEV_ERROR(dev, "failed to find the bridge: %d\n", ret); 1940 1944 return ret; 1941 1945 } ··· 1964 1958 return ret; 1965 1959 } 1966 1960 1961 + // The next bridge can be used by host_ops->attach 1962 + dsi->bridge.next_bridge = drm_bridge_get(next_bridge); 1963 + 1967 1964 if (pdata->host_ops && pdata->host_ops->attach) { 1968 1965 ret = pdata->host_ops->attach(dsi, device); 1969 1966 if (ret) 1970 - return ret; 1967 + goto err_release_next_bridge; 1971 1968 } 1972 1969 1973 1970 dsi->lanes = device->lanes; ··· 1978 1969 dsi->mode_flags = device->mode_flags; 1979 1970 1980 1971 return 0; 1972 + 1973 + err_release_next_bridge: 1974 + drm_bridge_put(dsi->bridge.next_bridge); 1975 + dsi->bridge.next_bridge = NULL; 1976 + return ret; 1981 1977 } 1982 1978 1983 1979 static void samsung_dsim_unregister_te_irq(struct samsung_dsim *dsi) ··· 1999 1985 struct samsung_dsim *dsi = host_to_dsi(host); 2000 1986 const struct samsung_dsim_plat_data *pdata = dsi->plat_data; 2001 1987 2002 - dsi->out_bridge = NULL; 2003 - 2004 1988 if (pdata->host_ops && pdata->host_ops->detach) 2005 1989 pdata->host_ops->detach(dsi, device); 1990 + 1991 + drm_bridge_put(dsi->bridge.next_bridge); 1992 + dsi->bridge.next_bridge = NULL; 2006 1993 2007 1994 samsung_dsim_unregister_te_irq(dsi); 2008 1995
+3 -4
drivers/gpu/drm/bridge/sii902x.c
··· 175 175 struct i2c_client *i2c; 176 176 struct regmap *regmap; 177 177 struct drm_bridge bridge; 178 - struct drm_bridge *next_bridge; 179 178 struct drm_connector connector; 180 179 struct gpio_desc *reset_gpio; 181 180 struct i2c_mux_core *i2cmux; ··· 420 421 int ret; 421 422 422 423 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) 423 - return drm_bridge_attach(encoder, sii902x->next_bridge, 424 + return drm_bridge_attach(encoder, sii902x->bridge.next_bridge, 424 425 bridge, flags); 425 426 426 427 drm_connector_helper_add(&sii902x->connector, ··· 1203 1204 return -ENODEV; 1204 1205 } 1205 1206 1206 - sii902x->next_bridge = of_drm_find_bridge(remote); 1207 + sii902x->bridge.next_bridge = of_drm_find_and_get_bridge(remote); 1207 1208 of_node_put(remote); 1208 - if (!sii902x->next_bridge) 1209 + if (!sii902x->bridge.next_bridge) 1209 1210 return dev_err_probe(dev, -EPROBE_DEFER, 1210 1211 "Failed to find remote bridge\n"); 1211 1212 }
+5
drivers/gpu/drm/bridge/simple-bridge.c
··· 261 261 .connector_type = DRM_MODE_CONNECTOR_VGA, 262 262 }, 263 263 }, { 264 + .compatible = "algoltek,ag6311", 265 + .data = &(const struct simple_bridge_info) { 266 + .connector_type = DRM_MODE_CONNECTOR_HDMIA, 267 + }, 268 + }, { 264 269 .compatible = "asl-tek,cs5263", 265 270 .data = &(const struct simple_bridge_info) { 266 271 .connector_type = DRM_MODE_CONNECTOR_HDMIA,
+76 -40
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
··· 26 26 #include <drm/drm_connector.h> 27 27 #include <drm/drm_edid.h> 28 28 #include <drm/drm_modes.h> 29 + #include <drm/drm_print.h> 29 30 30 31 #include <media/cec.h> 31 32 ··· 957 956 return MODE_OK; 958 957 } 959 958 960 - static int dw_hdmi_qp_bridge_clear_infoframe(struct drm_bridge *bridge, 961 - enum hdmi_infoframe_type type) 959 + static int dw_hdmi_qp_bridge_clear_avi_infoframe(struct drm_bridge *bridge) 962 960 { 963 961 struct dw_hdmi_qp *hdmi = bridge->driver_private; 964 962 965 - switch (type) { 966 - case HDMI_INFOFRAME_TYPE_AVI: 967 - dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, 968 - PKTSCHED_PKT_EN); 969 - break; 970 - 971 - case HDMI_INFOFRAME_TYPE_DRM: 972 - dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN); 973 - break; 974 - 975 - case HDMI_INFOFRAME_TYPE_AUDIO: 976 - dw_hdmi_qp_mod(hdmi, 0, 977 - PKTSCHED_ACR_TX_EN | 978 - PKTSCHED_AUDS_TX_EN | 979 - PKTSCHED_AUDI_TX_EN, 980 - PKTSCHED_PKT_EN); 981 - break; 982 - default: 983 - dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type); 984 - } 963 + dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, 964 + PKTSCHED_PKT_EN); 985 965 986 966 return 0; 987 967 } 988 968 989 - static int dw_hdmi_qp_bridge_write_infoframe(struct drm_bridge *bridge, 990 - enum hdmi_infoframe_type type, 991 - const u8 *buffer, size_t len) 969 + static int dw_hdmi_qp_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge) 970 + { 971 + /* FIXME: add support for this InfoFrame */ 972 + 973 + drm_warn_once(bridge->encoder->dev, "HDMI VSI not supported\n"); 974 + 975 + return 0; 976 + } 977 + 978 + static int dw_hdmi_qp_bridge_clear_hdr_drm_infoframe(struct drm_bridge *bridge) 992 979 { 993 980 struct dw_hdmi_qp *hdmi = bridge->driver_private; 994 981 995 - dw_hdmi_qp_bridge_clear_infoframe(bridge, type); 982 + dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN); 996 983 997 - switch (type) { 998 - case HDMI_INFOFRAME_TYPE_AVI: 999 - return dw_hdmi_qp_config_avi_infoframe(hdmi, buffer, len); 984 + return 0; 985 + } 1000 986 1001 - case HDMI_INFOFRAME_TYPE_DRM: 1002 - return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len); 987 + static int dw_hdmi_qp_bridge_clear_audio_infoframe(struct drm_bridge *bridge) 988 + { 989 + struct dw_hdmi_qp *hdmi = bridge->driver_private; 1003 990 1004 - case HDMI_INFOFRAME_TYPE_AUDIO: 1005 - return dw_hdmi_qp_config_audio_infoframe(hdmi, buffer, len); 991 + dw_hdmi_qp_mod(hdmi, 0, 992 + PKTSCHED_ACR_TX_EN | 993 + PKTSCHED_AUDS_TX_EN | 994 + PKTSCHED_AUDI_TX_EN, 995 + PKTSCHED_PKT_EN); 1006 996 1007 - default: 1008 - dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type); 1009 - return 0; 1010 - } 997 + return 0; 998 + } 999 + 1000 + static int dw_hdmi_qp_bridge_write_avi_infoframe(struct drm_bridge *bridge, 1001 + const u8 *buffer, size_t len) 1002 + { 1003 + struct dw_hdmi_qp *hdmi = bridge->driver_private; 1004 + 1005 + dw_hdmi_qp_bridge_clear_avi_infoframe(bridge); 1006 + 1007 + return dw_hdmi_qp_config_avi_infoframe(hdmi, buffer, len); 1008 + } 1009 + 1010 + static int dw_hdmi_qp_bridge_write_hdmi_infoframe(struct drm_bridge *bridge, 1011 + const u8 *buffer, size_t len) 1012 + { 1013 + dw_hdmi_qp_bridge_clear_hdmi_infoframe(bridge); 1014 + 1015 + /* FIXME: add support for the HDMI VSI */ 1016 + 1017 + return 0; 1018 + } 1019 + 1020 + static int dw_hdmi_qp_bridge_write_hdr_drm_infoframe(struct drm_bridge *bridge, 1021 + const u8 *buffer, size_t len) 1022 + { 1023 + struct dw_hdmi_qp *hdmi = bridge->driver_private; 1024 + 1025 + dw_hdmi_qp_bridge_clear_hdr_drm_infoframe(bridge); 1026 + 1027 + return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len); 1028 + } 1029 + 1030 + static int dw_hdmi_qp_bridge_write_audio_infoframe(struct drm_bridge *bridge, 1031 + const u8 *buffer, size_t len) 1032 + { 1033 + struct dw_hdmi_qp *hdmi = bridge->driver_private; 1034 + 1035 + dw_hdmi_qp_bridge_clear_audio_infoframe(bridge); 1036 + 1037 + return dw_hdmi_qp_config_audio_infoframe(hdmi, buffer, len); 1011 1038 } 1012 1039 1013 1040 #ifdef CONFIG_DRM_DW_HDMI_QP_CEC ··· 1220 1191 .detect = dw_hdmi_qp_bridge_detect, 1221 1192 .edid_read = dw_hdmi_qp_bridge_edid_read, 1222 1193 .hdmi_tmds_char_rate_valid = dw_hdmi_qp_bridge_tmds_char_rate_valid, 1223 - .hdmi_clear_infoframe = dw_hdmi_qp_bridge_clear_infoframe, 1224 - .hdmi_write_infoframe = dw_hdmi_qp_bridge_write_infoframe, 1194 + .hdmi_clear_avi_infoframe = dw_hdmi_qp_bridge_clear_avi_infoframe, 1195 + .hdmi_write_avi_infoframe = dw_hdmi_qp_bridge_write_avi_infoframe, 1196 + .hdmi_clear_hdmi_infoframe = dw_hdmi_qp_bridge_clear_hdmi_infoframe, 1197 + .hdmi_write_hdmi_infoframe = dw_hdmi_qp_bridge_write_hdmi_infoframe, 1198 + .hdmi_clear_hdr_drm_infoframe = dw_hdmi_qp_bridge_clear_hdr_drm_infoframe, 1199 + .hdmi_write_hdr_drm_infoframe = dw_hdmi_qp_bridge_write_hdr_drm_infoframe, 1200 + .hdmi_clear_audio_infoframe = dw_hdmi_qp_bridge_clear_audio_infoframe, 1201 + .hdmi_write_audio_infoframe = dw_hdmi_qp_bridge_write_audio_infoframe, 1225 1202 .hdmi_audio_startup = dw_hdmi_qp_audio_enable, 1226 1203 .hdmi_audio_shutdown = dw_hdmi_qp_audio_disable, 1227 1204 .hdmi_audio_prepare = dw_hdmi_qp_audio_prepare, ··· 1341 1306 hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | 1342 1307 DRM_BRIDGE_OP_EDID | 1343 1308 DRM_BRIDGE_OP_HDMI | 1344 - DRM_BRIDGE_OP_HDMI_AUDIO; 1309 + DRM_BRIDGE_OP_HDMI_AUDIO | 1310 + DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME; 1345 1311 if (!hdmi->no_hpd) 1346 1312 hdmi->bridge.ops |= DRM_BRIDGE_OP_HPD; 1347 1313 hdmi->bridge.of_node = pdev->dev.of_node;
+3 -4
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
··· 132 132 struct dw_hdmi { 133 133 struct drm_connector connector; 134 134 struct drm_bridge bridge; 135 - struct drm_bridge *next_bridge; 136 135 137 136 unsigned int version; 138 137 ··· 2911 2912 struct dw_hdmi *hdmi = bridge->driver_private; 2912 2913 2913 2914 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) 2914 - return drm_bridge_attach(encoder, hdmi->next_bridge, 2915 + return drm_bridge_attach(encoder, hdmi->bridge.next_bridge, 2915 2916 bridge, flags); 2916 2917 2917 2918 return dw_hdmi_connector_create(hdmi); ··· 3317 3318 if (!remote) 3318 3319 return -ENODEV; 3319 3320 3320 - hdmi->next_bridge = of_drm_find_bridge(remote); 3321 + hdmi->bridge.next_bridge = of_drm_find_and_get_bridge(remote); 3321 3322 of_node_put(remote); 3322 - if (!hdmi->next_bridge) 3323 + if (!hdmi->bridge.next_bridge) 3323 3324 return -EPROBE_DEFER; 3324 3325 3325 3326 return 0;
+3 -4
drivers/gpu/drm/bridge/thc63lvd1024.c
··· 32 32 struct gpio_desc *oe; 33 33 34 34 struct drm_bridge bridge; 35 - struct drm_bridge *next; 36 35 37 36 struct drm_bridge_timings timings; 38 37 }; ··· 47 48 { 48 49 struct thc63_dev *thc63 = to_thc63(bridge); 49 50 50 - return drm_bridge_attach(encoder, thc63->next, bridge, flags); 51 + return drm_bridge_attach(encoder, thc63->bridge.next_bridge, bridge, flags); 51 52 } 52 53 53 54 static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge, ··· 131 132 return -ENODEV; 132 133 } 133 134 134 - thc63->next = of_drm_find_bridge(remote); 135 + thc63->bridge.next_bridge = of_drm_find_and_get_bridge(remote); 135 136 of_node_put(remote); 136 - if (!thc63->next) 137 + if (!thc63->bridge.next_bridge) 137 138 return -EPROBE_DEFER; 138 139 139 140 endpoint = of_graph_get_endpoint_by_regs(thc63->dev->of_node,
+13 -14
drivers/gpu/drm/bridge/ti-tfp410.c
··· 30 30 struct gpio_desc *powerdown; 31 31 32 32 struct drm_bridge_timings timings; 33 - struct drm_bridge *next_bridge; 34 33 35 34 struct device *dev; 36 35 }; ··· 52 53 const struct drm_edid *drm_edid; 53 54 int ret; 54 55 55 - if (dvi->next_bridge->ops & DRM_BRIDGE_OP_EDID) { 56 - drm_edid = drm_bridge_edid_read(dvi->next_bridge, connector); 56 + if (dvi->bridge.next_bridge->ops & DRM_BRIDGE_OP_EDID) { 57 + drm_edid = drm_bridge_edid_read(dvi->bridge.next_bridge, connector); 57 58 if (!drm_edid) 58 59 DRM_INFO("EDID read failed. Fallback to standard modes\n"); 59 60 } else { ··· 88 89 { 89 90 struct tfp410 *dvi = drm_connector_to_tfp410(connector); 90 91 91 - return drm_bridge_detect(dvi->next_bridge, connector); 92 + return drm_bridge_detect(dvi->bridge.next_bridge, connector); 92 93 } 93 94 94 95 static const struct drm_connector_funcs tfp410_con_funcs = { ··· 125 126 struct tfp410 *dvi = drm_bridge_to_tfp410(bridge); 126 127 int ret; 127 128 128 - ret = drm_bridge_attach(encoder, dvi->next_bridge, bridge, 129 + ret = drm_bridge_attach(encoder, dvi->bridge.next_bridge, bridge, 129 130 DRM_BRIDGE_ATTACH_NO_CONNECTOR); 130 131 if (ret < 0) 131 132 return ret; ··· 133 134 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) 134 135 return 0; 135 136 136 - if (dvi->next_bridge->ops & DRM_BRIDGE_OP_DETECT) 137 + if (dvi->bridge.next_bridge->ops & DRM_BRIDGE_OP_DETECT) 137 138 dvi->connector.polled = DRM_CONNECTOR_POLL_HPD; 138 139 else 139 140 dvi->connector.polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; 140 141 141 - if (dvi->next_bridge->ops & DRM_BRIDGE_OP_HPD) { 142 + if (dvi->bridge.next_bridge->ops & DRM_BRIDGE_OP_HPD) { 142 143 INIT_DELAYED_WORK(&dvi->hpd_work, tfp410_hpd_work_func); 143 - drm_bridge_hpd_enable(dvi->next_bridge, tfp410_hpd_callback, 144 + drm_bridge_hpd_enable(dvi->bridge.next_bridge, tfp410_hpd_callback, 144 145 dvi); 145 146 } 146 147 ··· 148 149 &tfp410_con_helper_funcs); 149 150 ret = drm_connector_init_with_ddc(bridge->dev, &dvi->connector, 150 151 &tfp410_con_funcs, 151 - dvi->next_bridge->type, 152 - dvi->next_bridge->ddc); 152 + dvi->bridge.next_bridge->type, 153 + dvi->bridge.next_bridge->ddc); 153 154 if (ret) { 154 155 dev_err(dvi->dev, "drm_connector_init_with_ddc() failed: %d\n", 155 156 ret); ··· 168 169 { 169 170 struct tfp410 *dvi = drm_bridge_to_tfp410(bridge); 170 171 171 - if (dvi->connector.dev && dvi->next_bridge->ops & DRM_BRIDGE_OP_HPD) { 172 - drm_bridge_hpd_disable(dvi->next_bridge); 172 + if (dvi->connector.dev && dvi->bridge.next_bridge->ops & DRM_BRIDGE_OP_HPD) { 173 + drm_bridge_hpd_disable(dvi->bridge.next_bridge); 173 174 cancel_delayed_work_sync(&dvi->hpd_work); 174 175 } 175 176 } ··· 361 362 if (!node) 362 363 return -ENODEV; 363 364 364 - dvi->next_bridge = of_drm_find_bridge(node); 365 + dvi->bridge.next_bridge = of_drm_find_and_get_bridge(node); 365 366 of_node_put(node); 366 367 367 - if (!dvi->next_bridge) 368 + if (!dvi->bridge.next_bridge) 368 369 return -EPROBE_DEFER; 369 370 370 371 /* Get the powerdown GPIO. */
+3 -5
drivers/gpu/drm/bridge/ti-tpd12s015.c
··· 28 28 struct gpio_desc *ls_oe_gpio; 29 29 struct gpio_desc *hpd_gpio; 30 30 int hpd_irq; 31 - 32 - struct drm_bridge *next_bridge; 33 31 }; 34 32 35 33 static inline struct tpd12s015_device *to_tpd12s015(struct drm_bridge *bridge) ··· 45 47 if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) 46 48 return -EINVAL; 47 49 48 - ret = drm_bridge_attach(encoder, tpd->next_bridge, 50 + ret = drm_bridge_attach(encoder, tpd->bridge.next_bridge, 49 51 bridge, flags); 50 52 if (ret < 0) 51 53 return ret; ··· 136 138 if (!node) 137 139 return -ENODEV; 138 140 139 - tpd->next_bridge = of_drm_find_bridge(node); 141 + tpd->bridge.next_bridge = of_drm_find_and_get_bridge(node); 140 142 of_node_put(node); 141 143 142 - if (!tpd->next_bridge) 144 + if (!tpd->bridge.next_bridge) 143 145 return -EPROBE_DEFER; 144 146 145 147 /* Get the control and HPD GPIOs. */
+177 -13
drivers/gpu/drm/display/drm_bridge_connector.c
··· 123 123 * DRM_BRIDGE_OP_HDMI_CEC_NOTIFIER). 124 124 */ 125 125 struct drm_bridge *bridge_hdmi_cec; 126 + 127 + /** 128 + * @hdmi_funcs: 129 + * 130 + * The particular &drm_connector_hdmi_funcs implementation for this 131 + * bridge connector. 132 + */ 133 + struct drm_connector_hdmi_funcs hdmi_funcs; 126 134 }; 127 135 128 136 #define to_drm_bridge_connector(x) \ ··· 409 401 return MODE_OK; 410 402 } 411 403 412 - static int drm_bridge_connector_clear_infoframe(struct drm_connector *connector, 413 - enum hdmi_infoframe_type type) 404 + static int drm_bridge_connector_clear_avi_infoframe(struct drm_connector *connector) 414 405 { 415 406 struct drm_bridge_connector *bridge_connector = 416 407 to_drm_bridge_connector(connector); ··· 419 412 if (!bridge) 420 413 return -EINVAL; 421 414 422 - return bridge->funcs->hdmi_clear_infoframe(bridge, type); 415 + return bridge->funcs->hdmi_clear_avi_infoframe(bridge); 423 416 } 424 417 425 - static int drm_bridge_connector_write_infoframe(struct drm_connector *connector, 426 - enum hdmi_infoframe_type type, 427 - const u8 *buffer, size_t len) 418 + static int drm_bridge_connector_write_avi_infoframe(struct drm_connector *connector, 419 + const u8 *buffer, size_t len) 428 420 { 429 421 struct drm_bridge_connector *bridge_connector = 430 422 to_drm_bridge_connector(connector); ··· 433 427 if (!bridge) 434 428 return -EINVAL; 435 429 436 - return bridge->funcs->hdmi_write_infoframe(bridge, type, buffer, len); 430 + return bridge->funcs->hdmi_write_avi_infoframe(bridge, buffer, len); 431 + } 432 + 433 + static int drm_bridge_connector_clear_hdmi_infoframe(struct drm_connector *connector) 434 + { 435 + struct drm_bridge_connector *bridge_connector = 436 + to_drm_bridge_connector(connector); 437 + struct drm_bridge *bridge; 438 + 439 + bridge = bridge_connector->bridge_hdmi; 440 + if (!bridge) 441 + return -EINVAL; 442 + 443 + return bridge->funcs->hdmi_clear_hdmi_infoframe(bridge); 444 + } 445 + 446 + static int drm_bridge_connector_write_hdmi_infoframe(struct drm_connector *connector, 447 + const u8 *buffer, size_t len) 448 + { 449 + struct drm_bridge_connector *bridge_connector = 450 + to_drm_bridge_connector(connector); 451 + struct drm_bridge *bridge; 452 + 453 + bridge = bridge_connector->bridge_hdmi; 454 + if (!bridge) 455 + return -EINVAL; 456 + 457 + return bridge->funcs->hdmi_write_hdmi_infoframe(bridge, buffer, len); 458 + } 459 + 460 + static int drm_bridge_connector_clear_audio_infoframe(struct drm_connector *connector) 461 + { 462 + struct drm_bridge_connector *bridge_connector = 463 + to_drm_bridge_connector(connector); 464 + struct drm_bridge *bridge; 465 + 466 + bridge = bridge_connector->bridge_hdmi; 467 + if (!bridge) 468 + return -EINVAL; 469 + 470 + return bridge->funcs->hdmi_clear_audio_infoframe(bridge); 471 + } 472 + 473 + static int drm_bridge_connector_write_audio_infoframe(struct drm_connector *connector, 474 + const u8 *buffer, size_t len) 475 + { 476 + struct drm_bridge_connector *bridge_connector = 477 + to_drm_bridge_connector(connector); 478 + struct drm_bridge *bridge; 479 + 480 + bridge = bridge_connector->bridge_hdmi; 481 + if (!bridge) 482 + return -EINVAL; 483 + 484 + return bridge->funcs->hdmi_write_audio_infoframe(bridge, buffer, len); 485 + } 486 + 487 + static int drm_bridge_connector_clear_hdr_drm_infoframe(struct drm_connector *connector) 488 + { 489 + struct drm_bridge_connector *bridge_connector = 490 + to_drm_bridge_connector(connector); 491 + struct drm_bridge *bridge; 492 + 493 + bridge = bridge_connector->bridge_hdmi; 494 + if (!bridge) 495 + return -EINVAL; 496 + 497 + return bridge->funcs->hdmi_clear_hdr_drm_infoframe(bridge); 498 + } 499 + 500 + static int drm_bridge_connector_write_hdr_drm_infoframe(struct drm_connector *connector, 501 + const u8 *buffer, size_t len) 502 + { 503 + struct drm_bridge_connector *bridge_connector = 504 + to_drm_bridge_connector(connector); 505 + struct drm_bridge *bridge; 506 + 507 + bridge = bridge_connector->bridge_hdmi; 508 + if (!bridge) 509 + return -EINVAL; 510 + 511 + return bridge->funcs->hdmi_write_hdr_drm_infoframe(bridge, buffer, len); 512 + } 513 + 514 + static int drm_bridge_connector_clear_spd_infoframe(struct drm_connector *connector) 515 + { 516 + struct drm_bridge_connector *bridge_connector = 517 + to_drm_bridge_connector(connector); 518 + struct drm_bridge *bridge; 519 + 520 + bridge = bridge_connector->bridge_hdmi; 521 + if (!bridge) 522 + return -EINVAL; 523 + 524 + return bridge->funcs->hdmi_clear_spd_infoframe(bridge); 525 + } 526 + 527 + static int drm_bridge_connector_write_spd_infoframe(struct drm_connector *connector, 528 + const u8 *buffer, size_t len) 529 + { 530 + struct drm_bridge_connector *bridge_connector = 531 + to_drm_bridge_connector(connector); 532 + struct drm_bridge *bridge; 533 + 534 + bridge = bridge_connector->bridge_hdmi; 535 + if (!bridge) 536 + return -EINVAL; 537 + 538 + return bridge->funcs->hdmi_write_spd_infoframe(bridge, buffer, len); 437 539 } 438 540 439 541 static const struct drm_edid * ··· 560 446 561 447 static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = { 562 448 .tmds_char_rate_valid = drm_bridge_connector_tmds_char_rate_valid, 563 - .clear_infoframe = drm_bridge_connector_clear_infoframe, 564 - .write_infoframe = drm_bridge_connector_write_infoframe, 565 449 .read_edid = drm_bridge_connector_read_edid, 450 + .avi = { 451 + .clear_infoframe = drm_bridge_connector_clear_avi_infoframe, 452 + .write_infoframe = drm_bridge_connector_write_avi_infoframe, 453 + }, 454 + .hdmi = { 455 + .clear_infoframe = drm_bridge_connector_clear_hdmi_infoframe, 456 + .write_infoframe = drm_bridge_connector_write_hdmi_infoframe, 457 + }, 458 + /* audio, hdr_drm and spd are set dynamically during init */ 459 + }; 460 + 461 + static const struct drm_connector_infoframe_funcs drm_bridge_connector_hdmi_audio_infoframe = { 462 + .clear_infoframe = drm_bridge_connector_clear_audio_infoframe, 463 + .write_infoframe = drm_bridge_connector_write_audio_infoframe, 464 + }; 465 + 466 + static const struct drm_connector_infoframe_funcs drm_bridge_connector_hdmi_hdr_drm_infoframe = { 467 + .clear_infoframe = drm_bridge_connector_clear_hdr_drm_infoframe, 468 + .write_infoframe = drm_bridge_connector_write_hdr_drm_infoframe, 469 + }; 470 + 471 + static const struct drm_connector_infoframe_funcs drm_bridge_connector_hdmi_spd_infoframe = { 472 + .clear_infoframe = drm_bridge_connector_clear_spd_infoframe, 473 + .write_infoframe = drm_bridge_connector_write_spd_infoframe, 566 474 }; 567 475 568 476 static int drm_bridge_connector_audio_startup(struct drm_connector *connector) ··· 845 709 if (bridge->ops & DRM_BRIDGE_OP_HDMI) { 846 710 if (bridge_connector->bridge_hdmi) 847 711 return ERR_PTR(-EBUSY); 848 - if (!bridge->funcs->hdmi_write_infoframe || 849 - !bridge->funcs->hdmi_clear_infoframe) 712 + if (!bridge->funcs->hdmi_write_avi_infoframe || 713 + !bridge->funcs->hdmi_clear_avi_infoframe || 714 + !bridge->funcs->hdmi_write_hdmi_infoframe || 715 + !bridge->funcs->hdmi_clear_hdmi_infoframe) 716 + return ERR_PTR(-EINVAL); 717 + 718 + if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME && 719 + (!bridge->funcs->hdmi_write_hdr_drm_infoframe || 720 + !bridge->funcs->hdmi_clear_hdr_drm_infoframe)) 721 + return ERR_PTR(-EINVAL); 722 + 723 + if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME && 724 + (!bridge->funcs->hdmi_write_spd_infoframe || 725 + !bridge->funcs->hdmi_clear_spd_infoframe)) 850 726 return ERR_PTR(-EINVAL); 851 727 852 728 bridge_connector->bridge_hdmi = drm_bridge_get(bridge); ··· 880 732 !bridge->hdmi_audio_spdif_playback) 881 733 return ERR_PTR(-EINVAL); 882 734 883 - if (!bridge->funcs->hdmi_audio_prepare || 735 + if (!bridge->funcs->hdmi_write_audio_infoframe || 736 + !bridge->funcs->hdmi_clear_audio_infoframe || 737 + !bridge->funcs->hdmi_audio_prepare || 884 738 !bridge->funcs->hdmi_audio_shutdown) 885 739 return ERR_PTR(-EINVAL); 886 740 ··· 953 803 if (!connector->ycbcr_420_allowed) 954 804 supported_formats &= ~BIT(HDMI_COLORSPACE_YUV420); 955 805 806 + bridge_connector->hdmi_funcs = drm_bridge_connector_hdmi_funcs; 807 + 808 + if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_AUDIO) 809 + bridge_connector->hdmi_funcs.audio = 810 + drm_bridge_connector_hdmi_audio_infoframe; 811 + 812 + if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME) 813 + bridge_connector->hdmi_funcs.hdr_drm = 814 + drm_bridge_connector_hdmi_hdr_drm_infoframe; 815 + 816 + if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME) 817 + bridge_connector->hdmi_funcs.spd = 818 + drm_bridge_connector_hdmi_spd_infoframe; 819 + 956 820 ret = drmm_connector_hdmi_init(drm, connector, 957 821 bridge_connector->bridge_hdmi->vendor, 958 822 bridge_connector->bridge_hdmi->product, 959 823 &drm_bridge_connector_funcs, 960 - &drm_bridge_connector_hdmi_funcs, 824 + &bridge_connector->hdmi_funcs, 961 825 connector_type, ddc, 962 826 supported_formats, 963 827 max_bpc);
+61 -53
drivers/gpu/drm/display/drm_hdmi_state_helper.c
··· 718 718 719 719 infoframe->set = false; 720 720 721 + if (!connector->hdmi.funcs->spd.write_infoframe) 722 + return 0; 723 + 721 724 ret = hdmi_spd_infoframe_init(frame, 722 725 connector->hdmi.vendor, 723 726 connector->hdmi.product); ··· 744 741 int ret; 745 742 746 743 infoframe->set = false; 744 + 745 + if (!connector->hdmi.funcs->hdr_drm.write_infoframe) 746 + return 0; 747 747 748 748 if (connector->max_bpc < 10) 749 749 return 0; ··· 897 891 } 898 892 EXPORT_SYMBOL(drm_hdmi_connector_mode_valid); 899 893 900 - static int clear_device_infoframe(struct drm_connector *connector, 901 - enum hdmi_infoframe_type type) 902 - { 903 - const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; 904 - struct drm_device *dev = connector->dev; 905 - int ret; 906 - 907 - drm_dbg_kms(dev, "Clearing infoframe type 0x%x\n", type); 908 - 909 - if (!funcs || !funcs->clear_infoframe) { 910 - drm_dbg_kms(dev, "Function not implemented, bailing.\n"); 911 - return 0; 912 - } 913 - 914 - ret = funcs->clear_infoframe(connector, type); 915 - if (ret) { 916 - drm_dbg_kms(dev, "Call failed: %d\n", ret); 917 - return ret; 918 - } 919 - 920 - return 0; 921 - } 922 - 923 894 static int clear_infoframe(struct drm_connector *connector, 924 - struct drm_connector_hdmi_infoframe *old_frame) 895 + const struct drm_connector_infoframe_funcs *funcs, 896 + const char *type) 925 897 { 926 - int ret; 927 - 928 - ret = clear_device_infoframe(connector, old_frame->data.any.type); 929 - if (ret) 930 - return ret; 931 - 932 - return 0; 933 - } 934 - 935 - static int write_device_infoframe(struct drm_connector *connector, 936 - union hdmi_infoframe *frame) 937 - { 938 - const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; 939 898 struct drm_device *dev = connector->dev; 940 - u8 buffer[HDMI_INFOFRAME_SIZE(MAX)]; 941 899 int ret; 942 - int len; 943 900 944 - drm_dbg_kms(dev, "Writing infoframe type %x\n", frame->any.type); 901 + drm_dbg_kms(dev, "Clearing %s InfoFrame\n", type); 945 902 946 - if (!funcs || !funcs->write_infoframe) { 903 + if (!funcs->clear_infoframe) { 947 904 drm_dbg_kms(dev, "Function not implemented, bailing.\n"); 948 - return -EINVAL; 905 + return -EOPNOTSUPP; 949 906 } 950 907 951 - len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer)); 952 - if (len < 0) 953 - return len; 954 - 955 - ret = funcs->write_infoframe(connector, frame->any.type, buffer, len); 908 + ret = funcs->clear_infoframe(connector); 956 909 if (ret) { 957 910 drm_dbg_kms(dev, "Call failed: %d\n", ret); 958 911 return ret; ··· 921 956 } 922 957 923 958 static int write_infoframe(struct drm_connector *connector, 959 + const struct drm_connector_infoframe_funcs *funcs, 960 + const char *type, 924 961 struct drm_connector_hdmi_infoframe *new_frame) 925 962 { 963 + struct drm_device *dev = connector->dev; 964 + u8 buffer[HDMI_INFOFRAME_SIZE(MAX)]; 926 965 int ret; 966 + int len; 927 967 928 - ret = write_device_infoframe(connector, &new_frame->data); 929 - if (ret) 968 + drm_dbg_kms(dev, "Writing %s InfoFrame\n", type); 969 + 970 + if (!funcs->write_infoframe) { 971 + drm_dbg_kms(dev, "Function not implemented, bailing.\n"); 972 + return -EOPNOTSUPP; 973 + } 974 + 975 + len = hdmi_infoframe_pack(&new_frame->data, buffer, sizeof(buffer)); 976 + if (len < 0) 977 + return len; 978 + 979 + ret = funcs->write_infoframe(connector, buffer, len); 980 + if (ret) { 981 + drm_dbg_kms(dev, "Call failed: %d\n", ret); 930 982 return ret; 983 + } 931 984 932 985 return 0; 933 986 } 934 987 935 988 static int write_or_clear_infoframe(struct drm_connector *connector, 989 + const struct drm_connector_infoframe_funcs *funcs, 990 + const char *type, 936 991 struct drm_connector_hdmi_infoframe *old_frame, 937 992 struct drm_connector_hdmi_infoframe *new_frame) 938 993 { 939 994 if (new_frame->set) 940 - return write_infoframe(connector, new_frame); 995 + return write_infoframe(connector, funcs, type, new_frame); 941 996 942 997 if (old_frame->set && !new_frame->set) 943 - return clear_infoframe(connector, old_frame); 998 + return clear_infoframe(connector, funcs, type); 944 999 945 1000 return 0; 946 1001 } ··· 980 995 int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector, 981 996 struct drm_atomic_state *state) 982 997 { 998 + const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; 983 999 struct drm_connector_state *old_conn_state = 984 1000 drm_atomic_get_old_connector_state(state, connector); 985 1001 struct drm_connector_state *new_conn_state = ··· 991 1005 if (!info->is_hdmi) 992 1006 return 0; 993 1007 1008 + if (!funcs) { 1009 + drm_dbg_kms(connector->dev, "Function not implemented, bailing.\n"); 1010 + return -EINVAL; 1011 + } 1012 + 994 1013 mutex_lock(&connector->hdmi.infoframes.lock); 995 1014 996 1015 ret = write_or_clear_infoframe(connector, 1016 + &funcs->avi, "AVI", 997 1017 &old_conn_state->hdmi.infoframes.avi, 998 1018 &new_conn_state->hdmi.infoframes.avi); 999 1019 if (ret) ··· 1007 1015 1008 1016 if (connector->hdmi.infoframes.audio.set) { 1009 1017 ret = write_infoframe(connector, 1018 + &funcs->audio, "Audio", 1010 1019 &connector->hdmi.infoframes.audio); 1011 1020 if (ret) 1012 1021 goto out; 1013 1022 } 1014 1023 1015 1024 ret = write_or_clear_infoframe(connector, 1025 + &funcs->hdr_drm, "HDR DRM", 1016 1026 &old_conn_state->hdmi.infoframes.hdr_drm, 1017 1027 &new_conn_state->hdmi.infoframes.hdr_drm); 1018 1028 if (ret) 1019 1029 goto out; 1020 1030 1021 1031 ret = write_or_clear_infoframe(connector, 1032 + &funcs->spd, "SPD", 1022 1033 &old_conn_state->hdmi.infoframes.spd, 1023 1034 &new_conn_state->hdmi.infoframes.spd); 1024 1035 if (ret) ··· 1029 1034 1030 1035 if (info->has_hdmi_infoframe) { 1031 1036 ret = write_or_clear_infoframe(connector, 1037 + &funcs->hdmi, "HDMI-VS", 1032 1038 &old_conn_state->hdmi.infoframes.hdmi, 1033 1039 &new_conn_state->hdmi.infoframes.hdmi); 1034 1040 if (ret) ··· 1058 1062 drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector, 1059 1063 struct hdmi_audio_infoframe *frame) 1060 1064 { 1065 + const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; 1061 1066 struct drm_connector_hdmi_infoframe *infoframe = 1062 1067 &connector->hdmi.infoframes.audio; 1063 1068 struct drm_display_info *info = &connector->display_info; ··· 1067 1070 if (!info->is_hdmi) 1068 1071 return 0; 1069 1072 1073 + if (!funcs || !funcs->audio.write_infoframe) { 1074 + drm_dbg_kms(connector->dev, "Function not implemented, bailing.\n"); 1075 + return -EINVAL; 1076 + } 1077 + 1070 1078 mutex_lock(&connector->hdmi.infoframes.lock); 1071 1079 1072 1080 memcpy(&infoframe->data, frame, sizeof(infoframe->data)); 1073 1081 infoframe->set = true; 1074 1082 1075 - ret = write_infoframe(connector, infoframe); 1083 + ret = write_infoframe(connector, &funcs->audio, "Audio", infoframe); 1076 1084 1077 1085 mutex_unlock(&connector->hdmi.infoframes.lock); 1078 1086 ··· 1099 1097 int 1100 1098 drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *connector) 1101 1099 { 1100 + const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; 1102 1101 struct drm_connector_hdmi_infoframe *infoframe = 1103 1102 &connector->hdmi.infoframes.audio; 1104 1103 struct drm_display_info *info = &connector->display_info; ··· 1108 1105 if (!info->is_hdmi) 1109 1106 return 0; 1110 1107 1108 + if (!funcs || !funcs->audio.write_infoframe) { 1109 + drm_dbg_kms(connector->dev, "Function not implemented, bailing.\n"); 1110 + return -EINVAL; 1111 + } 1112 + 1111 1113 mutex_lock(&connector->hdmi.infoframes.lock); 1112 1114 1113 1115 infoframe->set = false; 1114 1116 1115 - ret = clear_infoframe(connector, infoframe); 1117 + ret = clear_infoframe(connector, &funcs->audio, "Audio"); 1116 1118 1117 1119 memset(&infoframe->data, 0, sizeof(infoframe->data)); 1118 1120
+3
drivers/gpu/drm/drm_bridge.c
··· 1518 1518 * The bridge returned by this function is not refcounted. This is 1519 1519 * dangerous because the bridge might be deallocated even before the caller 1520 1520 * has a chance to use it. To use this function you have to do one of: 1521 + * 1521 1522 * - get a reference with drm_bridge_get() as soon as possible to 1522 1523 * minimize the race window, and then drm_bridge_put() when no longer 1523 1524 * using the pointer 1525 + * 1524 1526 * - not call drm_bridge_get() or drm_bridge_put() at all, which used to 1525 1527 * be the correct practice before dynamic bridge lifetime was introduced 1528 + * 1526 1529 * - again, convert to of_drm_find_and_get_bridge(), which is the only safe 1527 1530 * thing to do 1528 1531 *
+10
drivers/gpu/drm/drm_buddy.c
··· 420 420 421 421 for_each_free_tree(i) 422 422 kfree(mm->free_trees[i]); 423 + kfree(mm->free_trees); 423 424 kfree(mm->roots); 424 425 } 425 426 EXPORT_SYMBOL(drm_buddy_fini); ··· 1155 1154 pages = size >> ilog2(mm->chunk_size); 1156 1155 order = fls(pages) - 1; 1157 1156 min_order = ilog2(min_block_size) - ilog2(mm->chunk_size); 1157 + 1158 + if (order > mm->max_order || size > mm->size) { 1159 + if ((flags & DRM_BUDDY_CONTIGUOUS_ALLOCATION) && 1160 + !(flags & DRM_BUDDY_RANGE_ALLOCATION)) 1161 + return __alloc_contig_try_harder(mm, original_size, 1162 + original_min_size, blocks); 1163 + 1164 + return -EINVAL; 1165 + } 1158 1166 1159 1167 do { 1160 1168 order = min(order, (unsigned int)fls(pages) - 1);
+6
drivers/gpu/drm/drm_connector.c
··· 600 600 if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12)) 601 601 return -EINVAL; 602 602 603 + if (!hdmi_funcs->avi.clear_infoframe || 604 + !hdmi_funcs->avi.write_infoframe || 605 + !hdmi_funcs->hdmi.clear_infoframe || 606 + !hdmi_funcs->hdmi.write_infoframe) 607 + return -EINVAL; 608 + 603 609 ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc); 604 610 if (ret) 605 611 return ret;
+7
drivers/gpu/drm/drm_debugfs.c
··· 672 672 { 673 673 struct dentry *file; 674 674 675 + if (!connector->hdmi.funcs || 676 + !connector->hdmi.funcs->audio.write_infoframe) 677 + return 0; 678 + 675 679 file = debugfs_create_file("audio", 0400, parent, connector, &audio_infoframe_fops); 676 680 if (IS_ERR(file)) 677 681 return PTR_ERR(file); ··· 730 726 { \ 731 727 struct dentry *file; \ 732 728 \ 729 + if (!connector->hdmi.funcs || \ 730 + !connector->hdmi.funcs->_f.write_infoframe) \ 731 + return 0; \ 733 732 file = debugfs_create_file(#_f, 0400, parent, connector, &_f ## _infoframe_fops); \ 734 733 if (IS_ERR(file)) \ 735 734 return PTR_ERR(file); \
+1 -1
drivers/gpu/drm/drm_property.c
··· 562 562 if (!length || length > INT_MAX - sizeof(struct drm_property_blob)) 563 563 return ERR_PTR(-EINVAL); 564 564 565 - blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL); 565 + blob = kvzalloc(sizeof(struct drm_property_blob) + length, GFP_KERNEL_ACCOUNT); 566 566 if (!blob) 567 567 return ERR_PTR(-ENOMEM); 568 568
+3 -1
drivers/gpu/drm/exynos/exynos_hdmi.c
··· 1779 1779 return -EINVAL; 1780 1780 } 1781 1781 1782 - hdata->bridge = of_drm_find_bridge(np); 1782 + hdata->bridge = of_drm_find_and_get_bridge(np); 1783 1783 of_node_put(np); 1784 1784 1785 1785 if (!hdata->bridge) ··· 2095 2095 iounmap(hdata->regs_hdmiphy); 2096 2096 2097 2097 put_device(&hdata->ddc_adpt->dev); 2098 + 2099 + drm_bridge_put(hdata->bridge); 2098 2100 2099 2101 mutex_destroy(&hdata->mutex); 2100 2102 }
+4
drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h
··· 40 40 struct mutex lock; /* protects concurrent RW in hibmc_dp_reg_write_field() */ 41 41 struct hibmc_dp_link link; 42 42 u8 dpcd[DP_RECEIVER_CAP_SIZE]; 43 + u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS]; 44 + struct drm_dp_desc desc; 45 + bool is_branch; 46 + int hpd_status; 43 47 void __iomem *serdes_base; 44 48 }; 45 49
+2
drivers/gpu/drm/hisilicon/hibmc/dp/dp_config.h
··· 17 17 #define HIBMC_DP_LINK_RATE_CAL 27 18 18 #define HIBMC_DP_SYNC_DELAY(lanes) ((lanes) == 0x2 ? 86 : 46) 19 19 #define HIBMC_DP_INT_ENABLE 0xc 20 + /* HIBMC_DP_LINK_RATE_CAL * 10000 * 80% = 216000 */ 21 + #define DP_MODE_VALI_CAL 216000 20 22 21 23 #endif
+36 -2
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.c
··· 2 2 // Copyright (c) 2024 Hisilicon Limited. 3 3 4 4 #include <linux/io.h> 5 + #include <linux/iopoll.h> 5 6 #include <linux/delay.h> 6 7 #include "dp_config.h" 7 8 #include "dp_comm.h" ··· 177 176 dp_dev->link.cap.lanes = 0x2; 178 177 dp_dev->link.cap.link_rate = DP_LINK_BW_8_1; 179 178 180 - /* hdcp data */ 181 - writel(HIBMC_DP_HDCP, dp_dev->base + HIBMC_DP_HDCP_CFG); 182 179 /* int init */ 183 180 writel(0, dp_dev->base + HIBMC_DP_INTR_ENABLE); 184 181 writel(HIBMC_DP_INT_RST, dp_dev->base + HIBMC_DP_INTR_ORIGINAL_STATUS); 182 + /* clr colorbar */ 183 + writel(0, dp_dev->base + HIBMC_DP_COLOR_BAR_CTRL); 185 184 /* rst */ 185 + writel(0, dp_dev->base + HIBMC_DP_DPTX_RST_CTRL); 186 + usleep_range(30, 50); 187 + /* de-rst */ 186 188 writel(HIBMC_DP_DPTX_RST, dp_dev->base + HIBMC_DP_DPTX_RST_CTRL); 189 + /* hdcp data */ 190 + writel(HIBMC_DP_HDCP, dp_dev->base + HIBMC_DP_HDCP_CFG); 187 191 /* clock enable */ 188 192 writel(HIBMC_DP_CLK_EN, dp_dev->base + HIBMC_DP_DPTX_CLK_CTRL); 189 193 ··· 269 263 dp->dp_dev->link.status.channel_equalized = false; 270 264 } 271 265 266 + u8 hibmc_dp_get_link_rate(struct hibmc_dp *dp) 267 + { 268 + return dp->dp_dev->link.cap.link_rate; 269 + } 270 + 271 + u8 hibmc_dp_get_lanes(struct hibmc_dp *dp) 272 + { 273 + return dp->dp_dev->link.cap.lanes; 274 + } 275 + 272 276 static const struct hibmc_dp_color_raw g_rgb_raw[] = { 273 277 {CBAR_COLOR_BAR, 0x000, 0x000, 0x000}, 274 278 {CBAR_WHITE, 0xfff, 0xfff, 0xfff}, ··· 320 304 321 305 hibmc_dp_reg_write_field(dp_dev, HIBMC_DP_COLOR_BAR_CTRL, BIT(0), cfg->enable); 322 306 writel(HIBMC_DP_SYNC_EN_MASK, dp_dev->base + HIBMC_DP_TIMING_SYNC_CTRL); 307 + } 308 + 309 + bool hibmc_dp_check_hpd_status(struct hibmc_dp *dp, int exp_status) 310 + { 311 + u32 status; 312 + int ret; 313 + 314 + ret = readl_poll_timeout(dp->dp_dev->base + HIBMC_DP_HPD_STATUS, status, 315 + FIELD_GET(HIBMC_DP_HPD_CUR_STATE, status) == exp_status, 316 + 1000, 100000); /* DP spec says 100ms */ 317 + if (ret) { 318 + drm_dbg_dp(dp->drm_dev, "wait hpd status timeout"); 319 + return false; 320 + } 321 + 322 + dp->dp_dev->hpd_status = exp_status; 323 + 324 + return true; 323 325 }
+8
drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h
··· 14 14 15 15 struct hibmc_dp_dev; 16 16 17 + enum hibmc_hpd_status { 18 + HIBMC_HPD_OUT, 19 + HIBMC_HPD_IN, 20 + }; 21 + 17 22 enum hibmc_dp_cbar_pattern { 18 23 CBAR_COLOR_BAR, 19 24 CBAR_WHITE, ··· 65 60 void hibmc_dp_hpd_cfg(struct hibmc_dp *dp); 66 61 void hibmc_dp_enable_int(struct hibmc_dp *dp); 67 62 void hibmc_dp_disable_int(struct hibmc_dp *dp); 63 + bool hibmc_dp_check_hpd_status(struct hibmc_dp *dp, int exp_status); 64 + u8 hibmc_dp_get_link_rate(struct hibmc_dp *dp); 65 + u8 hibmc_dp_get_lanes(struct hibmc_dp *dp); 68 66 69 67 #endif
+3
drivers/gpu/drm/hisilicon/hibmc/dp/dp_reg.h
··· 24 24 #define HIBMC_DP_CFG_AUX_READY_DATA_BYTE GENMASK(16, 12) 25 25 #define HIBMC_DP_CFG_AUX GENMASK(24, 17) 26 26 27 + #define HIBMC_DP_HPD_STATUS 0x98 28 + #define HIBMC_DP_HPD_CUR_STATE GENMASK(7, 4) 29 + 27 30 #define HIBMC_DP_PHYIF_CTRL0 0xa0 28 31 #define HIBMC_DP_CFG_SCRAMBLE_EN BIT(0) 29 32 #define HIBMC_DP_CFG_PAT_SEL GENMASK(7, 4)
+67 -4
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
··· 12 12 13 13 #include "hibmc_drm_drv.h" 14 14 #include "dp/dp_hw.h" 15 + #include "dp/dp_comm.h" 16 + #include "dp/dp_config.h" 15 17 16 18 #define DP_MASKED_SINK_HPD_PLUG_INT BIT(2) 17 19 ··· 33 31 return count; 34 32 } 35 33 34 + static bool hibmc_dp_get_dpcd(struct hibmc_dp_dev *dp_dev) 35 + { 36 + int ret; 37 + 38 + ret = drm_dp_read_dpcd_caps(dp_dev->aux, dp_dev->dpcd); 39 + if (ret) 40 + return false; 41 + 42 + dp_dev->is_branch = drm_dp_is_branch(dp_dev->dpcd); 43 + 44 + ret = drm_dp_read_desc(dp_dev->aux, &dp_dev->desc, dp_dev->is_branch); 45 + if (ret) 46 + return false; 47 + 48 + ret = drm_dp_read_downstream_info(dp_dev->aux, dp_dev->dpcd, dp_dev->downstream_ports); 49 + if (ret) 50 + return false; 51 + 52 + return true; 53 + } 54 + 36 55 static int hibmc_dp_detect(struct drm_connector *connector, 37 56 struct drm_modeset_acquire_ctx *ctx, bool force) 38 57 { 39 - mdelay(200); 58 + struct hibmc_dp *dp = to_hibmc_dp(connector); 59 + struct hibmc_dp_dev *dp_dev = dp->dp_dev; 60 + int ret; 40 61 41 - return drm_connector_helper_detect_from_ddc(connector, ctx, force); 62 + if (dp->irq_status) { 63 + if (dp_dev->hpd_status != HIBMC_HPD_IN) 64 + return connector_status_disconnected; 65 + } 66 + 67 + if (!hibmc_dp_get_dpcd(dp_dev)) 68 + return connector_status_disconnected; 69 + 70 + if (!dp_dev->is_branch) 71 + return connector_status_connected; 72 + 73 + if (drm_dp_read_sink_count_cap(connector, dp_dev->dpcd, &dp_dev->desc) && 74 + dp_dev->downstream_ports[0] & DP_DS_PORT_HPD) { 75 + ret = drm_dp_read_sink_count(dp_dev->aux); 76 + if (ret > 0) 77 + return connector_status_connected; 78 + } 79 + 80 + return connector_status_disconnected; 81 + } 82 + 83 + static int hibmc_dp_mode_valid(struct drm_connector *connector, 84 + const struct drm_display_mode *mode, 85 + struct drm_modeset_acquire_ctx *ctx, 86 + enum drm_mode_status *status) 87 + { 88 + struct hibmc_dp *dp = to_hibmc_dp(connector); 89 + u64 cur_val, max_val; 90 + 91 + /* check DP link BW */ 92 + cur_val = (u64)mode->clock * HIBMC_DP_BPP; 93 + max_val = (u64)hibmc_dp_get_link_rate(dp) * DP_MODE_VALI_CAL * hibmc_dp_get_lanes(dp); 94 + 95 + *status = cur_val > max_val ? MODE_CLOCK_HIGH : MODE_OK; 96 + 97 + return 0; 42 98 } 43 99 44 100 static const struct drm_connector_helper_funcs hibmc_dp_conn_helper_funcs = { 45 101 .get_modes = hibmc_dp_connector_get_modes, 46 102 .detect_ctx = hibmc_dp_detect, 103 + .mode_valid_ctx = hibmc_dp_mode_valid, 47 104 }; 48 105 49 106 static int hibmc_dp_late_register(struct drm_connector *connector) ··· 176 115 { 177 116 struct drm_device *dev = (struct drm_device *)arg; 178 117 struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); 179 - int idx; 118 + int idx, exp_status; 180 119 181 120 if (!drm_dev_enter(dev, &idx)) 182 121 return -ENODEV; ··· 184 123 if (priv->dp.irq_status & DP_MASKED_SINK_HPD_PLUG_INT) { 185 124 drm_dbg_dp(&priv->dev, "HPD IN isr occur!\n"); 186 125 hibmc_dp_hpd_cfg(&priv->dp); 126 + exp_status = HIBMC_HPD_IN; 187 127 } else { 188 128 drm_dbg_dp(&priv->dev, "HPD OUT isr occur!\n"); 189 129 hibmc_dp_reset_link(&priv->dp); 130 + exp_status = HIBMC_HPD_OUT; 190 131 } 191 132 192 - if (dev->registered) 133 + if (hibmc_dp_check_hpd_status(&priv->dp, exp_status)) 193 134 drm_connector_helper_hpd_irq_event(&priv->dp.connector); 194 135 195 136 drm_dev_exit(idx);
+12
drivers/gpu/drm/imagination/Kconfig
··· 18 18 Technologies PowerVR (Series 6 or later) or IMG GPU. 19 19 20 20 If "M" is selected, the module will be called powervr. 21 + 22 + config DRM_POWERVR_KUNIT_TEST 23 + tristate "KUnit tests for the drm powervr driver" if !KUNIT_ALL_TESTS 24 + depends on DRM_POWERVR && KUNIT 25 + default KUNIT_ALL_TESTS 26 + help 27 + Choose this option to allow the driver to perform selftests under 28 + the kunit framework 29 + 30 + Recommended for driver developers only. 31 + 32 + If in doubt, say "N".
+2 -1
drivers/gpu/drm/imagination/Makefile
··· 20 20 pvr_hwrt.o \ 21 21 pvr_job.o \ 22 22 pvr_mmu.o \ 23 - pvr_params.o \ 24 23 pvr_power.o \ 25 24 pvr_queue.o \ 26 25 pvr_stream.o \ ··· 32 33 pvr_debugfs.o 33 34 34 35 obj-$(CONFIG_DRM_POWERVR) += powervr.o 36 + 37 + obj-$(CONFIG_DRM_POWERVR_KUNIT_TEST) += pvr_test.o
-2
drivers/gpu/drm/imagination/pvr_debugfs.c
··· 5 5 6 6 #include "pvr_device.h" 7 7 #include "pvr_fw_trace.h" 8 - #include "pvr_params.h" 9 8 10 9 #include <linux/dcache.h> 11 10 #include <linux/debugfs.h> ··· 17 18 #include <drm/drm_print.h> 18 19 19 20 static const struct pvr_debugfs_entry pvr_debugfs_entries[] = { 20 - {"pvr_params", pvr_params_debugfs_init}, 21 21 {"pvr_fw", pvr_fw_trace_debugfs_init}, 22 22 }; 23 23
+183 -17
drivers/gpu/drm/imagination/pvr_device.c
··· 5 5 #include "pvr_device_info.h" 6 6 7 7 #include "pvr_fw.h" 8 - #include "pvr_params.h" 9 8 #include "pvr_power.h" 10 9 #include "pvr_queue.h" 11 10 #include "pvr_rogue_cr_defs.h" ··· 30 31 #include <linux/stddef.h> 31 32 #include <linux/types.h> 32 33 #include <linux/workqueue.h> 34 + 35 + #include <kunit/visibility.h> 33 36 34 37 /* Major number for the supported version of the firmware. */ 35 38 #define PVR_FW_VERSION_MAJOR 1 ··· 423 422 } 424 423 425 424 /** 426 - * pvr_load_gpu_id() - Load a PowerVR device's GPU ID (BVNC) from control registers. 425 + * pvr_gpuid_decode_reg() - Decode the GPU ID from GPU register 427 426 * 428 - * Sets struct pvr_dev.gpu_id. 427 + * Sets the b, v, n, c fields of struct pvr_dev.gpu_id. 429 428 * 430 429 * @pvr_dev: Target PowerVR device. 430 + * @gpu_id: Output to be updated with the GPU ID. 431 431 */ 432 432 static void 433 - pvr_load_gpu_id(struct pvr_device *pvr_dev) 433 + pvr_gpuid_decode_reg(const struct pvr_device *pvr_dev, struct pvr_gpu_id *gpu_id) 434 434 { 435 - struct pvr_gpu_id *gpu_id = &pvr_dev->gpu_id; 436 - u64 bvnc; 437 - 438 435 /* 439 436 * Try reading the BVNC using the newer (cleaner) method first. If the 440 437 * B value is zero, fall back to the older method. 441 438 */ 442 - bvnc = pvr_cr_read64(pvr_dev, ROGUE_CR_CORE_ID__PBVNC); 439 + u64 bvnc = pvr_cr_read64(pvr_dev, ROGUE_CR_CORE_ID__PBVNC); 443 440 444 441 gpu_id->b = PVR_CR_FIELD_GET(bvnc, CORE_ID__PBVNC__BRANCH_ID); 445 442 if (gpu_id->b != 0) { ··· 454 455 gpu_id->n = FIELD_GET(0xFF00, core_id_config); 455 456 gpu_id->c = FIELD_GET(0x00FF, core_id_config); 456 457 } 458 + } 459 + 460 + /** 461 + * pvr_gpuid_decode_string() - Decode the GPU ID from a module input string 462 + * 463 + * Sets the b, v, n, c fields of struct pvr_dev.gpu_id. 464 + * 465 + * @pvr_dev: Target PowerVR device. 466 + * @param_bvnc: GPU ID (BVNC) module parameter. 467 + * @gpu_id: Output to be updated with the GPU ID. 468 + */ 469 + VISIBLE_IF_KUNIT int 470 + pvr_gpuid_decode_string(const struct pvr_device *pvr_dev, 471 + const char *param_bvnc, struct pvr_gpu_id *gpu_id) 472 + { 473 + const struct drm_device *drm_dev = &pvr_dev->base; 474 + char str_cpy[PVR_GPUID_STRING_MAX_LENGTH]; 475 + char *pos, *tkn; 476 + int ret, idx = 0; 477 + u16 user_bvnc_u16[4]; 478 + u8 dot_cnt = 0; 479 + 480 + ret = strscpy(str_cpy, param_bvnc); 481 + 482 + /* 483 + * strscpy() should return at least a size 7 for the input to be valid. 484 + * Returns -E2BIG for the case when the string is empty or too long. 485 + */ 486 + if (ret < PVR_GPUID_STRING_MIN_LENGTH) { 487 + drm_info(drm_dev, 488 + "Invalid size of the input GPU ID (BVNC): %s", 489 + str_cpy); 490 + return -EINVAL; 491 + } 492 + 493 + while (*param_bvnc) { 494 + if (*param_bvnc == '.') 495 + dot_cnt++; 496 + param_bvnc++; 497 + } 498 + 499 + if (dot_cnt != 3) { 500 + drm_info(drm_dev, 501 + "Invalid format of the input GPU ID (BVNC): %s", 502 + str_cpy); 503 + return -EINVAL; 504 + } 505 + 506 + pos = str_cpy; 507 + 508 + while ((tkn = strsep(&pos, ".")) != NULL && idx < 4) { 509 + /* kstrtou16() will also handle the case of consecutive dots */ 510 + ret = kstrtou16(tkn, 10, &user_bvnc_u16[idx]); 511 + if (ret) { 512 + drm_info(drm_dev, 513 + "Invalid format of the input GPU ID (BVNC): %s", 514 + str_cpy); 515 + return -EINVAL; 516 + } 517 + idx++; 518 + } 519 + 520 + gpu_id->b = user_bvnc_u16[0]; 521 + gpu_id->v = user_bvnc_u16[1]; 522 + gpu_id->n = user_bvnc_u16[2]; 523 + gpu_id->c = user_bvnc_u16[3]; 524 + 525 + return 0; 526 + } 527 + EXPORT_SYMBOL_IF_KUNIT(pvr_gpuid_decode_string); 528 + 529 + static bool pvr_exp_hw_support; 530 + module_param_named(exp_hw_support, pvr_exp_hw_support, bool, 0600); 531 + MODULE_PARM_DESC(exp_hw_support, "Bypass runtime checks for fully supported GPU cores. WARNING: enabling this option may result in a buggy, insecure, or otherwise unusable driver."); 532 + 533 + /** 534 + * enum pvr_gpu_support_level - The level of support for a gpu_id in the current 535 + * version of the driver. 536 + * 537 + * @PVR_GPU_UNKNOWN: Cores that are unknown to the driver. These may not even exist. 538 + * @PVR_GPU_EXPERIMENTAL: Cores that have experimental support. 539 + * @PVR_GPU_SUPPORTED: Cores that are supported and maintained. 540 + */ 541 + enum pvr_gpu_support_level { 542 + PVR_GPU_UNKNOWN, 543 + PVR_GPU_EXPERIMENTAL, 544 + PVR_GPU_SUPPORTED, 545 + }; 546 + 547 + static enum pvr_gpu_support_level 548 + pvr_gpu_support_level(const struct pvr_gpu_id *gpu_id) 549 + { 550 + switch (pvr_gpu_id_to_packed_bvnc(gpu_id)) { 551 + case PVR_PACKED_BVNC(33, 15, 11, 3): 552 + case PVR_PACKED_BVNC(36, 53, 104, 796): 553 + return PVR_GPU_SUPPORTED; 554 + 555 + case PVR_PACKED_BVNC(36, 52, 104, 182): 556 + return PVR_GPU_EXPERIMENTAL; 557 + 558 + default: 559 + return PVR_GPU_UNKNOWN; 560 + } 561 + } 562 + 563 + static int 564 + pvr_check_gpu_supported(struct pvr_device *pvr_dev, 565 + const struct pvr_gpu_id *gpu_id) 566 + { 567 + struct drm_device *drm_dev = from_pvr_device(pvr_dev); 568 + 569 + switch (pvr_gpu_support_level(gpu_id)) { 570 + case PVR_GPU_SUPPORTED: 571 + if (pvr_exp_hw_support) 572 + drm_info(drm_dev, "Module parameter 'exp_hw_support' was set, but this hardware is fully supported by the current driver."); 573 + 574 + break; 575 + 576 + case PVR_GPU_EXPERIMENTAL: 577 + if (!pvr_exp_hw_support) { 578 + drm_err(drm_dev, "Unsupported GPU! Set 'exp_hw_support' to bypass this check."); 579 + return -ENODEV; 580 + } 581 + 582 + drm_warn(drm_dev, "Running on unsupported hardware; you may encounter bugs!"); 583 + break; 584 + 585 + /* NOTE: This code path may indicate misbehaving hardware. */ 586 + case PVR_GPU_UNKNOWN: 587 + default: 588 + if (!pvr_exp_hw_support) { 589 + drm_err(drm_dev, "Unknown GPU! Set 'exp_hw_support' to bypass this check."); 590 + return -ENODEV; 591 + } 592 + 593 + drm_warn(drm_dev, "Running on unknown hardware; expect issues."); 594 + break; 595 + } 596 + 597 + return 0; 598 + } 599 + 600 + static char *pvr_gpuid_override; 601 + module_param_named(gpuid, pvr_gpuid_override, charp, 0400); 602 + MODULE_PARM_DESC(gpuid, "GPU ID (BVNC) to be used instead of the value read from hardware."); 603 + 604 + /** 605 + * pvr_load_gpu_id() - Load a PowerVR device's GPU ID (BVNC) from control 606 + * registers or input parameter. The input parameter is processed instead 607 + * of the GPU register if provided. 608 + * 609 + * Sets the arch field of struct pvr_dev.gpu_id. 610 + * 611 + * @pvr_dev: Target PowerVR device. 612 + */ 613 + static int 614 + pvr_load_gpu_id(struct pvr_device *pvr_dev) 615 + { 616 + struct pvr_gpu_id *gpu_id = &pvr_dev->gpu_id; 617 + 618 + if (!pvr_gpuid_override || !pvr_gpuid_override[0]) { 619 + pvr_gpuid_decode_reg(pvr_dev, gpu_id); 620 + } else { 621 + drm_warn(from_pvr_device(pvr_dev), 622 + "Using custom GPU ID (BVNC) provided by the user!"); 623 + 624 + int err = pvr_gpuid_decode_string(pvr_dev, pvr_gpuid_override, 625 + gpu_id); 626 + if (err) 627 + return err; 628 + } 629 + 630 + return pvr_check_gpu_supported(pvr_dev, gpu_id); 457 631 } 458 632 459 633 /** ··· 689 517 { 690 518 int err; 691 519 692 - pvr_load_gpu_id(pvr_dev); 520 + err = pvr_load_gpu_id(pvr_dev); 521 + if (err) 522 + return err; 693 523 694 524 err = pvr_request_firmware(pvr_dev); 695 525 if (err) ··· 780 606 781 607 /* Get the platform-specific data based on the compatible string. */ 782 608 pvr_dev->device_data = of_device_get_match_data(dev); 783 - 784 - /* 785 - * Setup device parameters. We do this first in case other steps 786 - * depend on them. 787 - */ 788 - err = pvr_device_params_init(&pvr_dev->params); 789 - if (err) 790 - return err; 791 609 792 610 /* Enable and initialize clocks required for the device to operate. */ 793 611 err = pvr_device_clk_init(pvr_dev);
+11 -13
drivers/gpu/drm/imagination/pvr_device.h
··· 7 7 #include "pvr_ccb.h" 8 8 #include "pvr_device_info.h" 9 9 #include "pvr_fw.h" 10 - #include "pvr_params.h" 11 10 #include "pvr_rogue_fwif_stream.h" 12 11 #include "pvr_stream.h" 13 12 ··· 38 39 39 40 /* Forward declaration from <linux/pwrseq/consumer.h> */ 40 41 struct pwrseq_desc; 42 + 43 + #define PVR_GPUID_STRING_MIN_LENGTH 7U 44 + #define PVR_GPUID_STRING_MAX_LENGTH 32U 41 45 42 46 /** 43 47 * struct pvr_gpu_id - Hardware GPU ID information for a PowerVR device ··· 193 191 194 192 /** @fw_dev: Firmware related data. */ 195 193 struct pvr_fw_device fw_dev; 196 - 197 - /** 198 - * @params: Device-specific parameters. 199 - * 200 - * The values of these parameters are initialized from the 201 - * defaults specified as module parameters. They may be 202 - * modified at runtime via debugfs (if enabled). 203 - */ 204 - struct pvr_device_params params; 205 194 206 195 /** @stream_musthave_quirks: Bit array of "must-have" quirks for stream commands. */ 207 196 u32 stream_musthave_quirks[PVR_STREAM_TYPE_MAX][PVR_STREAM_EXTHDR_TYPE_MAX]; ··· 519 526 * Return: Packed BVNC. 520 527 */ 521 528 static __always_inline u64 522 - pvr_gpu_id_to_packed_bvnc(struct pvr_gpu_id *gpu_id) 529 + pvr_gpu_id_to_packed_bvnc(const struct pvr_gpu_id *gpu_id) 523 530 { 524 531 return PVR_PACKED_BVNC(gpu_id->b, gpu_id->v, gpu_id->n, gpu_id->c); 525 532 } ··· 544 551 bool 545 552 pvr_device_has_feature(struct pvr_device *pvr_dev, u32 feature); 546 553 554 + #if IS_ENABLED(CONFIG_KUNIT) 555 + int pvr_gpuid_decode_string(const struct pvr_device *pvr_dev, 556 + const char *param_bvnc, struct pvr_gpu_id *gpu_id); 557 + #endif 558 + 547 559 /** 548 560 * PVR_CR_FIELD_GET() - Extract a single field from a PowerVR control register 549 561 * @val: Value of the target register. ··· 566 568 * Return: The value of the requested register. 567 569 */ 568 570 static __always_inline u32 569 - pvr_cr_read32(struct pvr_device *pvr_dev, u32 reg) 571 + pvr_cr_read32(const struct pvr_device *pvr_dev, u32 reg) 570 572 { 571 573 return ioread32(pvr_dev->regs + reg); 572 574 } ··· 579 581 * Return: The value of the requested register. 580 582 */ 581 583 static __always_inline u64 582 - pvr_cr_read64(struct pvr_device *pvr_dev, u32 reg) 584 + pvr_cr_read64(const struct pvr_device *pvr_dev, u32 reg) 583 585 { 584 586 return ioread64(pvr_dev->regs + reg); 585 587 }
+108 -17
drivers/gpu/drm/imagination/pvr_fw_trace.c
··· 12 12 #include <drm/drm_print.h> 13 13 14 14 #include <linux/build_bug.h> 15 + #include <linux/compiler_attributes.h> 15 16 #include <linux/dcache.h> 16 17 #include <linux/debugfs.h> 18 + #include <linux/moduleparam.h> 17 19 #include <linux/sysfs.h> 18 20 #include <linux/types.h> 21 + 22 + static int 23 + validate_group_mask(struct pvr_device *pvr_dev, const u32 group_mask) 24 + { 25 + if (group_mask & ~ROGUE_FWIF_LOG_TYPE_GROUP_MASK) { 26 + drm_warn(from_pvr_device(pvr_dev), 27 + "Invalid fw_trace group mask 0x%08x (must be a subset of 0x%08x)", 28 + group_mask, ROGUE_FWIF_LOG_TYPE_GROUP_MASK); 29 + return -EINVAL; 30 + } 31 + 32 + return 0; 33 + } 34 + 35 + static inline u32 36 + build_log_type(const u32 group_mask) 37 + { 38 + if (!group_mask) 39 + return ROGUE_FWIF_LOG_TYPE_NONE; 40 + 41 + return group_mask | ROGUE_FWIF_LOG_TYPE_TRACE; 42 + } 43 + 44 + /* 45 + * Don't gate this behind CONFIG_DEBUG_FS so that it can be used as an initial 46 + * value without further conditional code... 47 + */ 48 + static u32 pvr_fw_trace_init_mask; 49 + 50 + /* 51 + * ...but do only expose the module parameter if debugfs is enabled, since 52 + * there's no reason to turn on fw_trace without it. 53 + */ 54 + #if IS_ENABLED(CONFIG_DEBUG_FS) 55 + static int 56 + pvr_fw_trace_init_mask_set(const char *val, const struct kernel_param *kp) 57 + { 58 + u32 mask = 0; 59 + int err; 60 + 61 + err = kstrtouint(val, 0, &mask); 62 + if (err) 63 + return err; 64 + 65 + err = validate_group_mask(NULL, mask); 66 + if (err) 67 + return err; 68 + 69 + *(unsigned int *)kp->arg = mask; 70 + 71 + return 0; 72 + } 73 + 74 + const struct kernel_param_ops pvr_fw_trace_init_mask_ops = { 75 + .set = pvr_fw_trace_init_mask_set, 76 + .get = param_get_hexint, 77 + }; 78 + 79 + param_check_hexint(init_fw_trace_mask, &pvr_fw_trace_init_mask); 80 + module_param_cb(init_fw_trace_mask, &pvr_fw_trace_init_mask_ops, &pvr_fw_trace_init_mask, 0600); 81 + __MODULE_PARM_TYPE(init_fw_trace_mask, "hexint"); 82 + MODULE_PARM_DESC(init_fw_trace_mask, 83 + "Enable FW trace for the specified groups at device init time"); 84 + #endif 19 85 20 86 static void 21 87 tracebuf_ctrl_init(void *cpu_ptr, void *priv) ··· 91 25 92 26 tracebuf_ctrl->tracebuf_size_in_dwords = ROGUE_FW_TRACE_BUF_DEFAULT_SIZE_IN_DWORDS; 93 27 tracebuf_ctrl->tracebuf_flags = 0; 94 - 95 - if (fw_trace->group_mask) 96 - tracebuf_ctrl->log_type = fw_trace->group_mask | ROGUE_FWIF_LOG_TYPE_TRACE; 97 - else 98 - tracebuf_ctrl->log_type = ROGUE_FWIF_LOG_TYPE_NONE; 28 + tracebuf_ctrl->log_type = build_log_type(fw_trace->group_mask); 99 29 100 30 for (u32 thread_nr = 0; thread_nr < ARRAY_SIZE(fw_trace->buffers); thread_nr++) { 101 31 struct rogue_fwif_tracebuf_space *tracebuf_space = ··· 130 68 } 131 69 } 132 70 133 - /* TODO: Provide control of group mask. */ 134 - fw_trace->group_mask = 0; 71 + /* 72 + * Load the initial group_mask from the init_fw_trace_mask module 73 + * parameter. This allows early tracing before the user can write to 74 + * debugfs. Unlike update_logtype(), we don't set log_type here as that 75 + * is initialised by tracebuf_ctrl_init(). 76 + */ 77 + fw_trace->group_mask = pvr_fw_trace_init_mask; 135 78 136 79 fw_trace->tracebuf_ctrl = 137 80 pvr_fw_object_create_and_map(pvr_dev, ··· 190 123 /** 191 124 * update_logtype() - Send KCCB command to trigger FW to update logtype 192 125 * @pvr_dev: Target PowerVR device 193 - * @group_mask: New log group mask. 126 + * @group_mask: New log group mask; must pass validate_group_mask(). 194 127 * 195 128 * Returns: 129 + * * 0 if the provided @group_mask is the same as the current value (this is a 130 + * short-circuit evaluation), 196 131 * * 0 on success, 197 132 * * Any error returned by pvr_kccb_send_cmd(), or 198 133 * * -%EIO if the device is lost. ··· 203 134 update_logtype(struct pvr_device *pvr_dev, u32 group_mask) 204 135 { 205 136 struct pvr_fw_trace *fw_trace = &pvr_dev->fw_dev.fw_trace; 137 + struct drm_device *drm_dev = from_pvr_device(pvr_dev); 206 138 struct rogue_fwif_kccb_cmd cmd; 207 139 int idx; 208 140 int err; 209 141 210 - if (group_mask) 211 - fw_trace->tracebuf_ctrl->log_type = ROGUE_FWIF_LOG_TYPE_TRACE | group_mask; 212 - else 213 - fw_trace->tracebuf_ctrl->log_type = ROGUE_FWIF_LOG_TYPE_NONE; 142 + /* No change in group_mask => nothing to update. */ 143 + if (fw_trace->group_mask == group_mask) 144 + return 0; 214 145 215 146 fw_trace->group_mask = group_mask; 147 + fw_trace->tracebuf_ctrl->log_type = build_log_type(group_mask); 216 148 217 149 down_read(&pvr_dev->reset_sem); 218 - if (!drm_dev_enter(from_pvr_device(pvr_dev), &idx)) { 150 + if (!drm_dev_enter(drm_dev, &idx)) { 219 151 err = -EIO; 220 152 goto err_up_read; 221 153 } ··· 507 437 .release = fw_trace_release, 508 438 }; 509 439 510 - void 511 - pvr_fw_trace_mask_update(struct pvr_device *pvr_dev, u32 old_mask, u32 new_mask) 440 + static int pvr_fw_trace_mask_get(void *data, u64 *value) 512 441 { 513 - if (IS_ENABLED(CONFIG_DEBUG_FS) && old_mask != new_mask) 514 - update_logtype(pvr_dev, new_mask); 442 + struct pvr_device *pvr_dev = data; 443 + 444 + *value = pvr_dev->fw_dev.fw_trace.group_mask; 445 + 446 + return 0; 515 447 } 448 + 449 + static int pvr_fw_trace_mask_set(void *data, u64 value) 450 + { 451 + struct pvr_device *pvr_dev = data; 452 + const u32 group_mask = (u32)value; 453 + int err; 454 + 455 + err = validate_group_mask(pvr_dev, group_mask); 456 + if (err) 457 + return err; 458 + 459 + return update_logtype(pvr_dev, group_mask); 460 + } 461 + 462 + DEFINE_DEBUGFS_ATTRIBUTE(pvr_fw_trace_mask_fops, pvr_fw_trace_mask_get, 463 + pvr_fw_trace_mask_set, "0x%08llx\n"); 516 464 517 465 void 518 466 pvr_fw_trace_debugfs_init(struct pvr_device *pvr_dev, struct dentry *dir) ··· 551 463 &fw_trace->buffers[thread_nr], 552 464 &pvr_fw_trace_fops); 553 465 } 466 + 467 + debugfs_create_file("trace_mask", 0600, dir, fw_trace, 468 + &pvr_fw_trace_mask_fops); 554 469 }
-3
drivers/gpu/drm/imagination/pvr_fw_trace.h
··· 68 68 /* Forward declaration from <linux/dcache.h>. */ 69 69 struct dentry; 70 70 71 - void pvr_fw_trace_mask_update(struct pvr_device *pvr_dev, u32 old_mask, 72 - u32 new_mask); 73 - 74 71 void pvr_fw_trace_debugfs_init(struct pvr_device *pvr_dev, struct dentry *dir); 75 72 76 73 #endif /* PVR_FW_TRACE_H */
-147
drivers/gpu/drm/imagination/pvr_params.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 - /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 - 4 - #include "pvr_params.h" 5 - 6 - #include <linux/cache.h> 7 - #include <linux/moduleparam.h> 8 - 9 - static struct pvr_device_params pvr_device_param_defaults __read_mostly = { 10 - #define X(type_, name_, value_, desc_, ...) .name_ = (value_), 11 - PVR_DEVICE_PARAMS 12 - #undef X 13 - }; 14 - 15 - #define PVR_DEVICE_PARAM_NAMED(name_, type_, desc_) \ 16 - module_param_named(name_, pvr_device_param_defaults.name_, type_, \ 17 - 0400); \ 18 - MODULE_PARM_DESC(name_, desc_); 19 - 20 - /* 21 - * This list of defines must contain every type specified in "pvr_params.h" as 22 - * ``PVR_PARAM_TYPE_*_C``. 23 - */ 24 - #define PVR_PARAM_TYPE_X32_MODPARAM uint 25 - 26 - #define X(type_, name_, value_, desc_, ...) \ 27 - PVR_DEVICE_PARAM_NAMED(name_, PVR_PARAM_TYPE_##type_##_MODPARAM, desc_); 28 - PVR_DEVICE_PARAMS 29 - #undef X 30 - 31 - int 32 - pvr_device_params_init(struct pvr_device_params *params) 33 - { 34 - /* 35 - * If heap-allocated parameters are added in the future (e.g. 36 - * modparam's charp type), they must be handled specially here (via 37 - * kstrdup() in the case of charp). Since that's not necessary yet, 38 - * a straight copy will do for now. This change will also require a 39 - * pvr_device_params_fini() function to free any heap-allocated copies. 40 - */ 41 - 42 - *params = pvr_device_param_defaults; 43 - 44 - return 0; 45 - } 46 - 47 - #if defined(CONFIG_DEBUG_FS) 48 - #include "pvr_device.h" 49 - 50 - #include <linux/dcache.h> 51 - #include <linux/debugfs.h> 52 - #include <linux/export.h> 53 - #include <linux/fs.h> 54 - #include <linux/stddef.h> 55 - 56 - /* 57 - * This list of defines must contain every type specified in "pvr_params.h" as 58 - * ``PVR_PARAM_TYPE_*_C``. 59 - */ 60 - #define PVR_PARAM_TYPE_X32_FMT "0x%08llx" 61 - 62 - #define X_SET(name_, mode_) X_SET_##mode_(name_) 63 - #define X_SET_DEF(name_, update_, mode_) X_SET_DEF_##mode_(name_, update_) 64 - 65 - #define X_SET_RO(name_) NULL 66 - #define X_SET_RW(name_) __pvr_device_param_##name_##set 67 - 68 - #define X_SET_DEF_RO(name_, update_) 69 - #define X_SET_DEF_RW(name_, update_) \ 70 - static int \ 71 - X_SET_RW(name_)(void *data, u64 val) \ 72 - { \ 73 - struct pvr_device *pvr_dev = data; \ 74 - /* This is not just (update_) to suppress -Waddress. */ \ 75 - if ((void *)(update_) != NULL) \ 76 - (update_)(pvr_dev, pvr_dev->params.name_, val); \ 77 - pvr_dev->params.name_ = val; \ 78 - return 0; \ 79 - } 80 - 81 - #define X(type_, name_, value_, desc_, mode_, update_) \ 82 - static int \ 83 - __pvr_device_param_##name_##_get(void *data, u64 *val) \ 84 - { \ 85 - struct pvr_device *pvr_dev = data; \ 86 - *val = pvr_dev->params.name_; \ 87 - return 0; \ 88 - } \ 89 - X_SET_DEF(name_, update_, mode_) \ 90 - static int \ 91 - __pvr_device_param_##name_##_open(struct inode *inode, \ 92 - struct file *file) \ 93 - { \ 94 - __simple_attr_check_format(PVR_PARAM_TYPE_##type_##_FMT, \ 95 - 0ull); \ 96 - return simple_attr_open(inode, file, \ 97 - __pvr_device_param_##name_##_get, \ 98 - X_SET(name_, mode_), \ 99 - PVR_PARAM_TYPE_##type_##_FMT); \ 100 - } 101 - PVR_DEVICE_PARAMS 102 - #undef X 103 - 104 - #undef X_SET 105 - #undef X_SET_RO 106 - #undef X_SET_RW 107 - #undef X_SET_DEF 108 - #undef X_SET_DEF_RO 109 - #undef X_SET_DEF_RW 110 - 111 - static struct { 112 - #define X(type_, name_, value_, desc_, mode_, update_) \ 113 - const struct file_operations name_; 114 - PVR_DEVICE_PARAMS 115 - #undef X 116 - } pvr_device_param_debugfs_fops = { 117 - #define X(type_, name_, value_, desc_, mode_, update_) \ 118 - .name_ = { \ 119 - .owner = THIS_MODULE, \ 120 - .open = __pvr_device_param_##name_##_open, \ 121 - .release = simple_attr_release, \ 122 - .read = simple_attr_read, \ 123 - .write = simple_attr_write, \ 124 - .llseek = generic_file_llseek, \ 125 - }, 126 - PVR_DEVICE_PARAMS 127 - #undef X 128 - }; 129 - 130 - void 131 - pvr_params_debugfs_init(struct pvr_device *pvr_dev, struct dentry *dir) 132 - { 133 - #define X_MODE(mode_) X_MODE_##mode_ 134 - #define X_MODE_RO 0400 135 - #define X_MODE_RW 0600 136 - 137 - #define X(type_, name_, value_, desc_, mode_, update_) \ 138 - debugfs_create_file(#name_, X_MODE(mode_), dir, pvr_dev, \ 139 - &pvr_device_param_debugfs_fops.name_); 140 - PVR_DEVICE_PARAMS 141 - #undef X 142 - 143 - #undef X_MODE 144 - #undef X_MODE_RO 145 - #undef X_MODE_RW 146 - } 147 - #endif
-72
drivers/gpu/drm/imagination/pvr_params.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only OR MIT */ 2 - /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 - 4 - #ifndef PVR_PARAMS_H 5 - #define PVR_PARAMS_H 6 - 7 - #include "pvr_rogue_fwif.h" 8 - 9 - #include <linux/cache.h> 10 - #include <linux/compiler_attributes.h> 11 - 12 - /* 13 - * This is the definitive list of types allowed in the definition of 14 - * %PVR_DEVICE_PARAMS. 15 - */ 16 - #define PVR_PARAM_TYPE_X32_C u32 17 - 18 - /* 19 - * This macro defines all device-specific parameters; that is parameters which 20 - * are set independently per device. 21 - * 22 - * The X-macro accepts the following arguments. Arguments marked with [debugfs] 23 - * are ignored when debugfs is disabled; values used for these arguments may 24 - * safely be gated behind CONFIG_DEBUG_FS. 25 - * 26 - * @type_: The definitive list of allowed values is PVR_PARAM_TYPE_*_C. 27 - * @name_: Name of the parameter. This is used both as the field name in C and 28 - * stringified as the parameter name. 29 - * @value_: Initial/default value. 30 - * @desc_: String literal used as help text to describe the usage of this 31 - * parameter. 32 - * @mode_: [debugfs] One of {RO,RW}. The access mode of the debugfs entry for 33 - * this parameter. 34 - * @update_: [debugfs] When debugfs support is enabled, parameters may be 35 - * updated at runtime. When this happens, this function will be 36 - * called to allow changes to propagate. The signature of this 37 - * function is: 38 - * 39 - * void (*)(struct pvr_device *pvr_dev, T old_val, T new_val) 40 - * 41 - * Where T is the C type associated with @type_. 42 - * 43 - * If @mode_ does not allow write access, this function will never be 44 - * called. In this case, or if no update callback is required, you 45 - * should specify NULL for this argument. 46 - */ 47 - #define PVR_DEVICE_PARAMS \ 48 - X(X32, fw_trace_mask, ROGUE_FWIF_LOG_TYPE_NONE, \ 49 - "Enable FW trace for the specified groups. Specifying 0 disables " \ 50 - "all FW tracing.", \ 51 - RW, pvr_fw_trace_mask_update) 52 - 53 - struct pvr_device_params { 54 - #define X(type_, name_, value_, desc_, ...) \ 55 - PVR_PARAM_TYPE_##type_##_C name_; 56 - PVR_DEVICE_PARAMS 57 - #undef X 58 - }; 59 - 60 - int pvr_device_params_init(struct pvr_device_params *params); 61 - 62 - #if defined(CONFIG_DEBUG_FS) 63 - /* Forward declaration from "pvr_device.h". */ 64 - struct pvr_device; 65 - 66 - /* Forward declaration from <linux/dcache.h>. */ 67 - struct dentry; 68 - 69 - void pvr_params_debugfs_init(struct pvr_device *pvr_dev, struct dentry *dir); 70 - #endif /* defined(CONFIG_DEBUG_FS) */ 71 - 72 - #endif /* PVR_PARAMS_H */
+73
drivers/gpu/drm/imagination/pvr_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 + /* Copyright (c) 2025 Imagination Technologies Ltd. */ 3 + 4 + #include "pvr_device.h" 5 + 6 + #include <linux/errno.h> 7 + #include <linux/stddef.h> 8 + #include <linux/string.h> 9 + #include <linux/types.h> 10 + 11 + #include <kunit/test.h> 12 + #include <kunit/visibility.h> 13 + 14 + static void decode_gpuid_string(struct kunit *test) 15 + { 16 + const struct pvr_gpu_id bad_gpuid = { 0xdead, 0xbeef, 0xcafe, 0xface }; 17 + const u64 packed_bad_gpuid = pvr_gpu_id_to_packed_bvnc(&bad_gpuid); 18 + 19 + #define GPUID_TEST_CASE(str_, err_, value_) \ 20 + do { \ 21 + struct pvr_gpu_id _gpuid_out = bad_gpuid; \ 22 + int _err; \ 23 + _err = pvr_gpuid_decode_string(NULL, str_, &_gpuid_out); \ 24 + KUNIT_EXPECT_EQ(test, _err, err_); \ 25 + KUNIT_EXPECT_EQ(test, \ 26 + pvr_gpu_id_to_packed_bvnc(&_gpuid_out), \ 27 + value_); \ 28 + } while (0) 29 + 30 + #define GPUID_TEST_CASE_OK(str_, b_, v_, n_, c_) \ 31 + GPUID_TEST_CASE(str_, 0, PVR_PACKED_BVNC(b_, v_, n_, c_)) 32 + 33 + #define GPUID_TEST_CASE_INVAL(str_) \ 34 + GPUID_TEST_CASE(str_, -EINVAL, packed_bad_gpuid) 35 + 36 + GPUID_TEST_CASE_OK("12.34.56.78", 12, 34, 56, 78); 37 + GPUID_TEST_CASE_OK("0.0.0.0", 0, 0, 0, 0); 38 + 39 + GPUID_TEST_CASE_INVAL(""); 40 + GPUID_TEST_CASE_INVAL("42.foobar-invalid.gpuid.bvnc"); 41 + 42 + /* String longer than PVR_GPUID_STRING_MAX_LENGTH. */ 43 + GPUID_TEST_CASE_INVAL("12.34.56.789012345678901234567890123456"); 44 + 45 + /* Single value overflowing u16. */ 46 + GPUID_TEST_CASE_INVAL("12.34.56.999999"); 47 + 48 + /* Wrong number of parts and/or dots. */ 49 + GPUID_TEST_CASE_INVAL("12.34.56.78.90"); 50 + GPUID_TEST_CASE_INVAL("12.34.56..78"); 51 + GPUID_TEST_CASE_INVAL("12.34..56"); 52 + GPUID_TEST_CASE_INVAL("12.34.56"); 53 + 54 + #undef GPUID_TEST_CASE_INVAL 55 + #undef GPUID_TEST_CASE_OK 56 + #undef GPUID_TEST_CASE 57 + } 58 + 59 + static struct kunit_case pvr_tests_cases[] = { 60 + KUNIT_CASE(decode_gpuid_string), 61 + {}, 62 + }; 63 + 64 + static struct kunit_suite pvr_tests_suite = { 65 + .name = "pvr_tests", 66 + .test_cases = pvr_tests_cases, 67 + }; 68 + kunit_test_suite(pvr_tests_suite); 69 + 70 + MODULE_AUTHOR("Imagination Technologies Ltd."); 71 + MODULE_LICENSE("Dual MIT/GPL"); 72 + MODULE_DESCRIPTION("pvr kunit tests"); 73 + MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
+5 -2
drivers/gpu/drm/imx/ipuv3/dw_hdmi-imx.c
··· 241 241 if (IS_ERR(hdmi->hdmi)) 242 242 return PTR_ERR(hdmi->hdmi); 243 243 244 - hdmi->bridge = of_drm_find_bridge(np); 244 + hdmi->bridge = of_drm_find_and_get_bridge(np); 245 245 if (!hdmi->bridge) { 246 246 dev_err(hdmi->dev, "Unable to find bridge\n"); 247 247 dw_hdmi_remove(hdmi->hdmi); ··· 249 249 } 250 250 251 251 ret = component_add(&pdev->dev, &dw_hdmi_imx_ops); 252 - if (ret) 252 + if (ret) { 253 + drm_bridge_put(hdmi->bridge); 253 254 dw_hdmi_remove(hdmi->hdmi); 255 + } 254 256 255 257 return ret; 256 258 } ··· 262 260 struct imx_hdmi *hdmi = platform_get_drvdata(pdev); 263 261 264 262 component_del(&pdev->dev, &dw_hdmi_imx_ops); 263 + drm_bridge_put(hdmi->bridge); 265 264 dw_hdmi_remove(hdmi->hdmi); 266 265 } 267 266
+2 -2
drivers/gpu/drm/mediatek/mtk_hdmi.c
··· 986 986 return -EINVAL; 987 987 } 988 988 989 - if (hdmi->next_bridge) { 990 - ret = drm_bridge_attach(encoder, hdmi->next_bridge, 989 + if (hdmi->bridge.next_bridge) { 990 + ret = drm_bridge_attach(encoder, hdmi->bridge.next_bridge, 991 991 bridge, flags); 992 992 if (ret) 993 993 return ret;
+7 -5
drivers/gpu/drm/mediatek/mtk_hdmi_common.c
··· 315 315 return -EINVAL; 316 316 317 317 if (!of_device_is_compatible(remote, "hdmi-connector")) { 318 - hdmi->next_bridge = of_drm_find_bridge(remote); 319 - if (!hdmi->next_bridge) { 318 + hdmi->bridge.next_bridge = of_drm_find_and_get_bridge(remote); 319 + if (!hdmi->bridge.next_bridge) { 320 320 dev_err(dev, "Waiting for external bridge\n"); 321 321 of_node_put(remote); 322 322 return -EPROBE_DEFER; ··· 433 433 hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID 434 434 | DRM_BRIDGE_OP_HPD; 435 435 436 - if (ver_conf->bridge_funcs->hdmi_write_infoframe && 437 - ver_conf->bridge_funcs->hdmi_clear_infoframe) 438 - hdmi->bridge.ops |= DRM_BRIDGE_OP_HDMI; 436 + /* Only v2 support OP_HDMI now and it we know that it also support SPD */ 437 + if (ver_conf->bridge_funcs->hdmi_write_avi_infoframe && 438 + ver_conf->bridge_funcs->hdmi_clear_avi_infoframe) 439 + hdmi->bridge.ops |= DRM_BRIDGE_OP_HDMI | 440 + DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME; 439 441 440 442 hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; 441 443 hdmi->bridge.ddc = hdmi->ddc_adpt;
-1
drivers/gpu/drm/mediatek/mtk_hdmi_common.h
··· 150 150 151 151 struct mtk_hdmi { 152 152 struct drm_bridge bridge; 153 - struct drm_bridge *next_bridge; 154 153 struct drm_connector *curr_conn;/* current connector (only valid when 'enabled') */ 155 154 struct device *dev; 156 155 const struct mtk_hdmi_conf *conf;
+61 -53
drivers/gpu/drm/mediatek/mtk_hdmi_v2.c
··· 145 145 return val; 146 146 } 147 147 148 - static void mtk_hdmi_v2_hw_write_audio_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer) 148 + static int mtk_hdmi_v2_hdmi_write_audio_infoframe(struct drm_bridge *bridge, 149 + const u8 *buffer, size_t len) 149 150 { 151 + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 152 + 150 153 regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR); 151 154 regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN); 152 155 ··· 161 158 162 159 regmap_set_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN); 163 160 regmap_set_bits(hdmi->regs, TOP_INFO_EN, AUD_EN | AUD_EN_WR); 161 + 162 + return 0; 164 163 } 165 164 166 - static void mtk_hdmi_v2_hw_write_avi_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer) 165 + static int mtk_hdmi_v2_hdmi_write_avi_infoframe(struct drm_bridge *bridge, 166 + const u8 *buffer, size_t len) 167 167 { 168 + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 169 + 168 170 regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN); 169 171 regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN); 170 172 ··· 183 175 184 176 regmap_set_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN); 185 177 regmap_set_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN); 178 + 179 + return 0; 186 180 } 187 181 188 - static void mtk_hdmi_v2_hw_write_spd_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer) 182 + static int mtk_hdmi_v2_hdmi_write_spd_infoframe(struct drm_bridge *bridge, 183 + const u8 *buffer, size_t len) 189 184 { 185 + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 186 + 190 187 regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN); 191 188 regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN); 192 189 ··· 207 194 208 195 regmap_set_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN); 209 196 regmap_set_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN); 197 + 198 + return 0; 210 199 } 211 200 212 - static void mtk_hdmi_v2_hw_write_vendor_infoframe(struct mtk_hdmi *hdmi, const u8 *buffer) 201 + static int mtk_hdmi_v2_hdmi_write_hdmi_infoframe(struct drm_bridge *bridge, 202 + const u8 *buffer, size_t len) 213 203 { 204 + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 205 + 214 206 regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN); 215 207 regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN); 216 208 ··· 231 213 232 214 regmap_set_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN); 233 215 regmap_set_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN); 216 + 217 + return 0; 234 218 } 235 219 236 220 static void mtk_hdmi_yuv420_downsampling(struct mtk_hdmi *hdmi, bool enable) ··· 275 255 if (ret < 0) 276 256 return ret; 277 257 278 - mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer); 258 + mtk_hdmi_v2_hdmi_write_audio_infoframe(&hdmi->bridge, buffer, sizeof(buffer)); 279 259 280 260 return 0; 281 261 } ··· 960 940 DRM_ERROR("The flag DRM_BRIDGE_ATTACH_NO_CONNECTOR must be supplied\n"); 961 941 return -EINVAL; 962 942 } 963 - if (hdmi->next_bridge) { 964 - ret = drm_bridge_attach(encoder, hdmi->next_bridge, bridge, flags); 943 + if (hdmi->bridge.next_bridge) { 944 + ret = drm_bridge_attach(encoder, hdmi->bridge.next_bridge, bridge, flags); 965 945 if (ret) 966 946 return ret; 967 947 } ··· 1152 1132 return MODE_OK; 1153 1133 } 1154 1134 1155 - static int mtk_hdmi_v2_hdmi_clear_infoframe(struct drm_bridge *bridge, 1156 - enum hdmi_infoframe_type type) 1135 + static int mtk_hdmi_v2_hdmi_clear_audio_infoframe(struct drm_bridge *bridge) 1157 1136 { 1158 1137 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 1159 1138 1160 - switch (type) { 1161 - case HDMI_INFOFRAME_TYPE_AUDIO: 1162 - regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN_WR | AUD_EN); 1163 - regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN); 1164 - break; 1165 - case HDMI_INFOFRAME_TYPE_AVI: 1166 - regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN); 1167 - regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN); 1168 - break; 1169 - case HDMI_INFOFRAME_TYPE_SPD: 1170 - regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN); 1171 - regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN); 1172 - break; 1173 - case HDMI_INFOFRAME_TYPE_VENDOR: 1174 - regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN); 1175 - regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN); 1176 - break; 1177 - case HDMI_INFOFRAME_TYPE_DRM: 1178 - default: 1179 - break; 1180 - } 1139 + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AUD_EN_WR | AUD_EN); 1140 + regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AUD_RPT_EN); 1181 1141 1182 1142 return 0; 1183 1143 } 1184 1144 1185 - static int mtk_hdmi_v2_hdmi_write_infoframe(struct drm_bridge *bridge, 1186 - enum hdmi_infoframe_type type, 1187 - const u8 *buffer, size_t len) 1145 + static int mtk_hdmi_v2_hdmi_clear_avi_infoframe(struct drm_bridge *bridge) 1188 1146 { 1189 1147 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 1190 1148 1191 - switch (type) { 1192 - case HDMI_INFOFRAME_TYPE_AUDIO: 1193 - mtk_hdmi_v2_hw_write_audio_infoframe(hdmi, buffer); 1194 - break; 1195 - case HDMI_INFOFRAME_TYPE_AVI: 1196 - mtk_hdmi_v2_hw_write_avi_infoframe(hdmi, buffer); 1197 - break; 1198 - case HDMI_INFOFRAME_TYPE_SPD: 1199 - mtk_hdmi_v2_hw_write_spd_infoframe(hdmi, buffer); 1200 - break; 1201 - case HDMI_INFOFRAME_TYPE_VENDOR: 1202 - mtk_hdmi_v2_hw_write_vendor_infoframe(hdmi, buffer); 1203 - break; 1204 - case HDMI_INFOFRAME_TYPE_DRM: 1205 - default: 1206 - dev_err(hdmi->dev, "Unsupported HDMI infoframe type %u\n", type); 1207 - break; 1208 - } 1149 + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, AVI_EN_WR | AVI_EN); 1150 + regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, AVI_RPT_EN); 1151 + 1152 + return 0; 1153 + } 1154 + 1155 + static int mtk_hdmi_v2_hdmi_clear_spd_infoframe(struct drm_bridge *bridge) 1156 + { 1157 + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 1158 + 1159 + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, SPD_EN_WR | SPD_EN); 1160 + regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, SPD_RPT_EN); 1161 + 1162 + return 0; 1163 + } 1164 + 1165 + static int mtk_hdmi_v2_hdmi_clear_hdmi_infoframe(struct drm_bridge *bridge) 1166 + { 1167 + struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); 1168 + 1169 + regmap_clear_bits(hdmi->regs, TOP_INFO_EN, VSIF_EN_WR | VSIF_EN); 1170 + regmap_clear_bits(hdmi->regs, TOP_INFO_RPT, VSIF_RPT_EN); 1209 1171 1210 1172 return 0; 1211 1173 } ··· 1331 1329 .hpd_enable = mtk_hdmi_v2_hpd_enable, 1332 1330 .hpd_disable = mtk_hdmi_v2_hpd_disable, 1333 1331 .hdmi_tmds_char_rate_valid = mtk_hdmi_v2_hdmi_tmds_char_rate_valid, 1334 - .hdmi_clear_infoframe = mtk_hdmi_v2_hdmi_clear_infoframe, 1335 - .hdmi_write_infoframe = mtk_hdmi_v2_hdmi_write_infoframe, 1332 + .hdmi_clear_audio_infoframe = mtk_hdmi_v2_hdmi_clear_audio_infoframe, 1333 + .hdmi_write_audio_infoframe = mtk_hdmi_v2_hdmi_write_audio_infoframe, 1334 + .hdmi_clear_avi_infoframe = mtk_hdmi_v2_hdmi_clear_avi_infoframe, 1335 + .hdmi_write_avi_infoframe = mtk_hdmi_v2_hdmi_write_avi_infoframe, 1336 + .hdmi_clear_spd_infoframe = mtk_hdmi_v2_hdmi_clear_spd_infoframe, 1337 + .hdmi_write_spd_infoframe = mtk_hdmi_v2_hdmi_write_spd_infoframe, 1338 + .hdmi_clear_hdmi_infoframe = mtk_hdmi_v2_hdmi_clear_hdmi_infoframe, 1339 + .hdmi_write_hdmi_infoframe = mtk_hdmi_v2_hdmi_write_hdmi_infoframe, 1336 1340 .debugfs_init = mtk_hdmi_v2_debugfs_init, 1337 1341 }; 1338 1342
+5 -1
drivers/gpu/drm/meson/meson_dw_hdmi.c
··· 778 778 if (IS_ERR(meson_dw_hdmi->hdmi)) 779 779 return PTR_ERR(meson_dw_hdmi->hdmi); 780 780 781 - meson_dw_hdmi->bridge = of_drm_find_bridge(pdev->dev.of_node); 781 + meson_dw_hdmi->bridge = of_drm_find_and_get_bridge(pdev->dev.of_node); 782 782 783 783 DRM_DEBUG_DRIVER("HDMI controller initialized\n"); 784 784 ··· 789 789 void *data) 790 790 { 791 791 struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev); 792 + struct platform_device *pdev = to_platform_device(dev); 793 + int irq = platform_get_irq(pdev, 0); 792 794 795 + devm_free_irq(dev, irq, meson_dw_hdmi); 793 796 dw_hdmi_unbind(meson_dw_hdmi->hdmi); 797 + drm_bridge_put(meson_dw_hdmi->bridge); 794 798 } 795 799 796 800 static const struct component_ops meson_dw_hdmi_ops = {
+101 -94
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
··· 54 54 #define SPD_IFRAME_LINE_NUMBER 1 55 55 #define VENSPEC_IFRAME_LINE_NUMBER 3 56 56 57 - static int msm_hdmi_config_avi_infoframe(struct hdmi *hdmi, 58 - const u8 *buffer, size_t len) 57 + static int msm_hdmi_bridge_clear_avi_infoframe(struct drm_bridge *bridge) 59 58 { 59 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 60 + struct hdmi *hdmi = hdmi_bridge->hdmi; 61 + u32 val; 62 + 63 + val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0); 64 + val &= ~(HDMI_INFOFRAME_CTRL0_AVI_SEND | 65 + HDMI_INFOFRAME_CTRL0_AVI_CONT); 66 + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); 67 + 68 + val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); 69 + val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK; 70 + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); 71 + 72 + return 0; 73 + } 74 + 75 + static int msm_hdmi_bridge_clear_audio_infoframe(struct drm_bridge *bridge) 76 + { 77 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 78 + struct hdmi *hdmi = hdmi_bridge->hdmi; 79 + u32 val; 80 + 81 + val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0); 82 + val &= ~(HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND | 83 + HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT | 84 + HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE | 85 + HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE); 86 + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); 87 + 88 + val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); 89 + val &= ~HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK; 90 + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); 91 + 92 + return 0; 93 + } 94 + 95 + static int msm_hdmi_bridge_clear_spd_infoframe(struct drm_bridge *bridge) 96 + { 97 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 98 + struct hdmi *hdmi = hdmi_bridge->hdmi; 99 + u32 val; 100 + 101 + val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); 102 + val &= ~(HDMI_GEN_PKT_CTRL_GENERIC1_SEND | 103 + HDMI_GEN_PKT_CTRL_GENERIC1_CONT | 104 + HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK); 105 + hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); 106 + 107 + return 0; 108 + } 109 + 110 + static int msm_hdmi_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge) 111 + { 112 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 113 + struct hdmi *hdmi = hdmi_bridge->hdmi; 114 + u32 val; 115 + 116 + val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); 117 + val &= ~(HDMI_GEN_PKT_CTRL_GENERIC0_SEND | 118 + HDMI_GEN_PKT_CTRL_GENERIC0_CONT | 119 + HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE | 120 + HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK); 121 + hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); 122 + 123 + return 0; 124 + } 125 + 126 + static int msm_hdmi_bridge_write_avi_infoframe(struct drm_bridge *bridge, 127 + const u8 *buffer, size_t len) 128 + { 129 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 130 + struct hdmi *hdmi = hdmi_bridge->hdmi; 60 131 u32 buf[4] = {}; 61 132 u32 val; 62 133 int i; ··· 137 66 "failed to configure avi infoframe\n"); 138 67 return -EINVAL; 139 68 } 69 + 70 + msm_hdmi_bridge_clear_avi_infoframe(bridge); 140 71 141 72 /* 142 73 * the AVI_INFOx registers don't map exactly to how the AVI infoframes ··· 166 93 return 0; 167 94 } 168 95 169 - static int msm_hdmi_config_audio_infoframe(struct hdmi *hdmi, 170 - const u8 *buffer, size_t len) 96 + static int msm_hdmi_bridge_write_audio_infoframe(struct drm_bridge *bridge, 97 + const u8 *buffer, size_t len) 171 98 { 99 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 100 + struct hdmi *hdmi = hdmi_bridge->hdmi; 172 101 u32 val; 173 102 174 103 if (len != HDMI_INFOFRAME_SIZE(AUDIO)) { ··· 178 103 "failed to configure audio infoframe\n"); 179 104 return -EINVAL; 180 105 } 106 + 107 + msm_hdmi_bridge_clear_audio_infoframe(bridge); 181 108 182 109 hdmi_write(hdmi, REG_HDMI_AUDIO_INFO0, 183 110 buffer[3] | ··· 203 126 return 0; 204 127 } 205 128 206 - static int msm_hdmi_config_spd_infoframe(struct hdmi *hdmi, 207 - const u8 *buffer, size_t len) 129 + static int msm_hdmi_bridge_write_spd_infoframe(struct drm_bridge *bridge, 130 + const u8 *buffer, size_t len) 208 131 { 132 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 133 + struct hdmi *hdmi = hdmi_bridge->hdmi; 209 134 u32 buf[7] = {}; 210 135 u32 val; 211 136 int i; ··· 217 138 "failed to configure SPD infoframe\n"); 218 139 return -EINVAL; 219 140 } 141 + 142 + msm_hdmi_bridge_clear_spd_infoframe(bridge); 220 143 221 144 /* checksum gets written together with the body of the frame */ 222 145 hdmi_write(hdmi, REG_HDMI_GENERIC1_HDR, ··· 240 159 return 0; 241 160 } 242 161 243 - static int msm_hdmi_config_hdmi_infoframe(struct hdmi *hdmi, 244 - const u8 *buffer, size_t len) 162 + static int msm_hdmi_bridge_write_hdmi_infoframe(struct drm_bridge *bridge, 163 + const u8 *buffer, size_t len) 245 164 { 165 + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 166 + struct hdmi *hdmi = hdmi_bridge->hdmi; 246 167 u32 buf[7] = {}; 247 168 u32 val; 248 169 int i; ··· 255 172 "failed to configure HDMI infoframe\n"); 256 173 return -EINVAL; 257 174 } 175 + 176 + msm_hdmi_bridge_clear_hdmi_infoframe(bridge); 258 177 259 178 /* checksum gets written together with the body of the frame */ 260 179 hdmi_write(hdmi, REG_HDMI_GENERIC0_HDR, ··· 277 192 hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); 278 193 279 194 return 0; 280 - } 281 - 282 - static int msm_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge, 283 - enum hdmi_infoframe_type type) 284 - { 285 - struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 286 - struct hdmi *hdmi = hdmi_bridge->hdmi; 287 - u32 val; 288 - 289 - switch (type) { 290 - case HDMI_INFOFRAME_TYPE_AVI: 291 - val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0); 292 - val &= ~(HDMI_INFOFRAME_CTRL0_AVI_SEND | 293 - HDMI_INFOFRAME_CTRL0_AVI_CONT); 294 - hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); 295 - 296 - val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); 297 - val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK; 298 - hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); 299 - 300 - break; 301 - 302 - case HDMI_INFOFRAME_TYPE_AUDIO: 303 - val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0); 304 - val &= ~(HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND | 305 - HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT | 306 - HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE | 307 - HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE); 308 - hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val); 309 - 310 - val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); 311 - val &= ~HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK; 312 - hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); 313 - 314 - break; 315 - 316 - case HDMI_INFOFRAME_TYPE_SPD: 317 - val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); 318 - val &= ~(HDMI_GEN_PKT_CTRL_GENERIC1_SEND | 319 - HDMI_GEN_PKT_CTRL_GENERIC1_CONT | 320 - HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK); 321 - hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); 322 - 323 - break; 324 - 325 - case HDMI_INFOFRAME_TYPE_VENDOR: 326 - val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL); 327 - val &= ~(HDMI_GEN_PKT_CTRL_GENERIC0_SEND | 328 - HDMI_GEN_PKT_CTRL_GENERIC0_CONT | 329 - HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE | 330 - HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK); 331 - hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val); 332 - 333 - break; 334 - 335 - default: 336 - drm_dbg_driver(hdmi_bridge->base.dev, "Unsupported infoframe type %x\n", type); 337 - } 338 - 339 - return 0; 340 - } 341 - 342 - static int msm_hdmi_bridge_write_infoframe(struct drm_bridge *bridge, 343 - enum hdmi_infoframe_type type, 344 - const u8 *buffer, size_t len) 345 - { 346 - struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); 347 - struct hdmi *hdmi = hdmi_bridge->hdmi; 348 - 349 - msm_hdmi_bridge_clear_infoframe(bridge, type); 350 - 351 - switch (type) { 352 - case HDMI_INFOFRAME_TYPE_AVI: 353 - return msm_hdmi_config_avi_infoframe(hdmi, buffer, len); 354 - case HDMI_INFOFRAME_TYPE_AUDIO: 355 - return msm_hdmi_config_audio_infoframe(hdmi, buffer, len); 356 - case HDMI_INFOFRAME_TYPE_SPD: 357 - return msm_hdmi_config_spd_infoframe(hdmi, buffer, len); 358 - case HDMI_INFOFRAME_TYPE_VENDOR: 359 - return msm_hdmi_config_hdmi_infoframe(hdmi, buffer, len); 360 - default: 361 - drm_dbg_driver(hdmi_bridge->base.dev, "Unsupported infoframe type %x\n", type); 362 - return 0; 363 - } 364 195 } 365 196 366 197 static void msm_hdmi_set_timings(struct hdmi *hdmi, ··· 463 462 .hpd_enable = msm_hdmi_hpd_enable, 464 463 .hpd_disable = msm_hdmi_hpd_disable, 465 464 .hdmi_tmds_char_rate_valid = msm_hdmi_bridge_tmds_char_rate_valid, 466 - .hdmi_clear_infoframe = msm_hdmi_bridge_clear_infoframe, 467 - .hdmi_write_infoframe = msm_hdmi_bridge_write_infoframe, 465 + .hdmi_clear_audio_infoframe = msm_hdmi_bridge_clear_audio_infoframe, 466 + .hdmi_write_audio_infoframe = msm_hdmi_bridge_write_audio_infoframe, 467 + .hdmi_clear_avi_infoframe = msm_hdmi_bridge_clear_avi_infoframe, 468 + .hdmi_write_avi_infoframe = msm_hdmi_bridge_write_avi_infoframe, 469 + .hdmi_clear_spd_infoframe = msm_hdmi_bridge_clear_spd_infoframe, 470 + .hdmi_write_spd_infoframe = msm_hdmi_bridge_write_spd_infoframe, 471 + .hdmi_clear_hdmi_infoframe = msm_hdmi_bridge_clear_hdmi_infoframe, 472 + .hdmi_write_hdmi_infoframe = msm_hdmi_bridge_write_hdmi_infoframe, 468 473 .hdmi_audio_prepare = msm_hdmi_bridge_audio_prepare, 469 474 .hdmi_audio_shutdown = msm_hdmi_bridge_audio_shutdown, 470 475 };
+274 -7
drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
··· 33 33 unsigned int backlight_off_to_display_off_delay_ms; 34 34 unsigned int display_off_to_enter_sleep_delay_ms; 35 35 unsigned int enter_sleep_to_reset_down_delay_ms; 36 + unsigned long mode_flags; 36 37 }; 37 38 38 39 struct jadard { ··· 110 109 if (jadard->desc->lp11_to_reset_delay_ms) 111 110 msleep(jadard->desc->lp11_to_reset_delay_ms); 112 111 113 - gpiod_set_value(jadard->reset, 0); 112 + gpiod_set_value_cansleep(jadard->reset, 0); 114 113 msleep(5); 115 114 116 - gpiod_set_value(jadard->reset, 1); 115 + gpiod_set_value_cansleep(jadard->reset, 1); 117 116 msleep(10); 118 117 119 - gpiod_set_value(jadard->reset, 0); 118 + gpiod_set_value_cansleep(jadard->reset, 0); 120 119 msleep(130); 121 120 122 121 ret = jadard->desc->init(jadard); ··· 130 129 { 131 130 struct jadard *jadard = panel_to_jadard(panel); 132 131 133 - gpiod_set_value(jadard->reset, 0); 132 + gpiod_set_value_cansleep(jadard->reset, 0); 134 133 msleep(120); 135 134 136 135 if (jadard->desc->reset_before_power_off_vcioo) { 137 - gpiod_set_value(jadard->reset, 1); 136 + gpiod_set_value_cansleep(jadard->reset, 1); 138 137 139 138 usleep_range(1000, 2000); 140 139 } ··· 1114 1113 .enter_sleep_to_reset_down_delay_ms = 100, 1115 1114 }; 1116 1115 1116 + static int anbernic_rgds_init_cmds(struct jadard *jadard) 1117 + { 1118 + struct mipi_dsi_multi_context dsi_ctx = { .dsi = jadard->dsi }; 1119 + struct drm_panel *panel = &jadard->panel; 1120 + 1121 + jd9365da_switch_page(&dsi_ctx, 0x0); 1122 + 1123 + jadard_enable_standard_cmds(&dsi_ctx); 1124 + 1125 + jd9365da_switch_page(&dsi_ctx, 0x01); 1126 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x00); 1127 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x6a); 1128 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x10); 1129 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x6a); 1130 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0c, 0x74); 1131 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x00); 1132 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0xbf); 1133 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x01); 1134 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x00); 1135 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0xbf); 1136 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x01); 1137 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0xfe); 1138 + 1139 + if (of_device_is_compatible(panel->dev->of_node, 1140 + "anbernic,rg-ds-display-top")) 1141 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x05); 1142 + else 1143 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x09); 1144 + 1145 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x02); 1146 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x08); 1147 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3a, 0x1f); 1148 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3c, 0xf7); 1149 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3d, 0xff); 1150 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3e, 0xff); 1151 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3f, 0xff); 1152 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x03); 1153 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0x3c); 1154 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0xff); 1155 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x0a); 1156 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x11); 1157 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x78); 1158 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x02); 1159 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x6d); 1160 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x0a); 1161 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x0a); 1162 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x1f); 1163 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x1f); 1164 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x7f); 1165 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x56); 1166 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x43); 1167 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x34); 1168 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x2f); 1169 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x20); 1170 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x22); 1171 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0x0c); 1172 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x24); 1173 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x24); 1174 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x25); 1175 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x43); 1176 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x33); 1177 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0x3a); 1178 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x2d); 1179 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6c, 0x28); 1180 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6d, 0x1b); 1181 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6e, 0x0b); 1182 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x00); 1183 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x70, 0x7f); 1184 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x71, 0x56); 1185 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x72, 0x43); 1186 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x73, 0x34); 1187 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x74, 0x2f); 1188 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0x20); 1189 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x22); 1190 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x0c); 1191 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0x24); 1192 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x79, 0x24); 1193 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7a, 0x25); 1194 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7b, 0x43); 1195 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7c, 0x33); 1196 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7d, 0x3a); 1197 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7e, 0x2d); 1198 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x7f, 0x28); 1199 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x80, 0x1b); 1200 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x0b); 1201 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x82, 0x00); 1202 + 1203 + jd9365da_switch_page(&dsi_ctx, 0x02); 1204 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x5f); 1205 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x01, 0x5f); 1206 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0x5f); 1207 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x03, 0x5e); 1208 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x04, 0x50); 1209 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x05, 0x40); 1210 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x06, 0x5f); 1211 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x07, 0x57); 1212 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x08, 0x77); 1213 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x48); 1214 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0a, 0x48); 1215 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0b, 0x4a); 1216 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0c, 0x4a); 1217 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0d, 0x44); 1218 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0e, 0x44); 1219 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0f, 0x46); 1220 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x10, 0x46); 1221 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x11, 0x5f); 1222 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x12, 0x5f); 1223 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x13, 0x5f); 1224 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x14, 0x5f); 1225 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x15, 0x5f); 1226 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x16, 0x5f); 1227 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x17, 0x5f); 1228 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x18, 0x5f); 1229 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x19, 0x5e); 1230 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1a, 0x50); 1231 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1b, 0x41); 1232 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1c, 0x5f); 1233 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1d, 0x57); 1234 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1e, 0x77); 1235 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1f, 0x49); 1236 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x20, 0x49); 1237 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x21, 0x4b); 1238 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x22, 0x4b); 1239 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x23, 0x45); 1240 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x24, 0x45); 1241 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x25, 0x47); 1242 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x26, 0x47); 1243 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x27, 0x5f); 1244 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x28, 0x5f); 1245 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x29, 0x5f); 1246 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2a, 0x5f); 1247 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2b, 0x5f); 1248 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2c, 0x1f); 1249 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2d, 0x1f); 1250 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2e, 0x1e); 1251 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2f, 0x1f); 1252 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x30, 0x10); 1253 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x31, 0x01); 1254 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x32, 0x1f); 1255 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x33, 0x17); 1256 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x34, 0x17); 1257 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x35, 0x07); 1258 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x36, 0x07); 1259 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x05); 1260 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x38, 0x05); 1261 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x39, 0x0b); 1262 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3a, 0x0b); 1263 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3b, 0x09); 1264 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3c, 0x09); 1265 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3d, 0x1f); 1266 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3e, 0x1f); 1267 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3f, 0x1f); 1268 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x40, 0x1f); 1269 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x41, 0x1f); 1270 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x42, 0x1f); 1271 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x43, 0x1f); 1272 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x44, 0x1e); 1273 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x45, 0x1f); 1274 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x46, 0x10); 1275 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x47, 0x00); 1276 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x48, 0x1f); 1277 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x49, 0x17); 1278 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4a, 0x17); 1279 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4b, 0x06); 1280 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4c, 0x06); 1281 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4d, 0x04); 1282 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4e, 0x04); 1283 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x4f, 0x0a); 1284 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x50, 0x0a); 1285 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x51, 0x08); 1286 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x52, 0x08); 1287 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x53, 0x1f); 1288 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x54, 0x1f); 1289 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x55, 0x1f); 1290 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x56, 0x1f); 1291 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x57, 0x1f); 1292 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x58, 0x40); 1293 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x59, 0x00); 1294 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x00); 1295 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5b, 0x10); 1296 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5c, 0x07); 1297 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5d, 0x30); 1298 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5e, 0x01); 1299 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x02); 1300 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x60, 0x30); 1301 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x61, 0x01); 1302 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x62, 0x02); 1303 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x06); 1304 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x64, 0xe9); 1305 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x65, 0x40); 1306 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x66, 0x02); 1307 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x67, 0x73); 1308 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x68, 0x0b); 1309 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x69, 0x06); 1310 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6a, 0xe9); 1311 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6b, 0x08); 1312 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x75, 0xda); 1313 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x76, 0x00); 1314 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x77, 0x01); 1315 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x78, 0xfc); 1316 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x81, 0x08); 1317 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x83, 0xf4); 1318 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x87, 0x10); 1319 + 1320 + jd9365da_switch_page(&dsi_ctx, 0x04); 1321 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x00, 0x0e); 1322 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x02, 0xb3); 1323 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x09, 0x60); 1324 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x0e, 0x48); 1325 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x1e, 0x00); 1326 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x37, 0x58); 1327 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2b, 0x0f); 1328 + 1329 + jd9365da_switch_page(&dsi_ctx, 0x05); 1330 + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x15, 0x1d); 1331 + 1332 + jd9365da_switch_page(&dsi_ctx, 0x00); 1333 + mipi_dsi_msleep(&dsi_ctx, 120); 1334 + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); 1335 + mipi_dsi_msleep(&dsi_ctx, 120); 1336 + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); 1337 + mipi_dsi_msleep(&dsi_ctx, 10); 1338 + 1339 + return dsi_ctx.accum_err; 1340 + }; 1341 + 1342 + static const struct jadard_panel_desc anbernic_rgds_display_desc = { 1343 + .mode = { 1344 + .clock = (640 + 260 + 220 + 260) * (480 + 10 + 2 + 16) * 60 / 1000, 1345 + 1346 + .hdisplay = 640, 1347 + .hsync_start = 640 + 260, 1348 + .hsync_end = 640 + 260 + 220, 1349 + .htotal = 640 + 260 + 220 + 260, 1350 + 1351 + .vdisplay = 480, 1352 + .vsync_start = 480 + 10, 1353 + .vsync_end = 480 + 10 + 2, 1354 + .vtotal = 480 + 10 + 2 + 16, 1355 + 1356 + .width_mm = 68, 1357 + .height_mm = 87, 1358 + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 1359 + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 1360 + }, 1361 + .lanes = 4, 1362 + .format = MIPI_DSI_FMT_RGB888, 1363 + .init = anbernic_rgds_init_cmds, 1364 + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | 1365 + MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM, 1366 + }; 1367 + 1117 1368 static int jadard_dsi_probe(struct mipi_dsi_device *dsi) 1118 1369 { 1119 1370 struct device *dev = &dsi->dev; ··· 1379 1126 return PTR_ERR(jadard); 1380 1127 1381 1128 desc = of_device_get_match_data(dev); 1382 - dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | 1383 - MIPI_DSI_MODE_NO_EOT_PACKET; 1129 + 1130 + if (desc->mode_flags) 1131 + dsi->mode_flags = desc->mode_flags; 1132 + else 1133 + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | 1134 + MIPI_DSI_MODE_VIDEO_BURST | 1135 + MIPI_DSI_MODE_NO_EOT_PACKET; 1136 + 1384 1137 dsi->format = desc->format; 1385 1138 dsi->lanes = desc->lanes; 1386 1139 ··· 1435 1176 } 1436 1177 1437 1178 static const struct of_device_id jadard_of_match[] = { 1179 + { 1180 + .compatible = "anbernic,rg-ds-display-bottom", 1181 + .data = &anbernic_rgds_display_desc 1182 + }, 1183 + { 1184 + .compatible = "anbernic,rg-ds-display-top", 1185 + .data = &anbernic_rgds_display_desc 1186 + }, 1438 1187 { 1439 1188 .compatible = "chongzhou,cz101b4001", 1440 1189 .data = &cz101b4001_desc
+9 -1
drivers/gpu/drm/renesas/rcar-du/rcar_lvds.c
··· 633 633 return true; 634 634 } 635 635 636 + static void rcar_lvds_destroy(struct drm_bridge *bridge) 637 + { 638 + struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); 639 + 640 + drm_bridge_put(lvds->companion); 641 + } 642 + 636 643 static int rcar_lvds_attach(struct drm_bridge *bridge, 637 644 struct drm_encoder *encoder, 638 645 enum drm_bridge_attach_flags flags) ··· 655 648 656 649 static const struct drm_bridge_funcs rcar_lvds_bridge_ops = { 657 650 .attach = rcar_lvds_attach, 651 + .destroy = rcar_lvds_destroy, 658 652 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, 659 653 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, 660 654 .atomic_reset = drm_atomic_helper_bridge_reset, ··· 748 740 goto done; 749 741 } 750 742 751 - lvds->companion = of_drm_find_bridge(companion); 743 + lvds->companion = of_drm_find_and_get_bridge(companion); 752 744 if (!lvds->companion) { 753 745 ret = -EPROBE_DEFER; 754 746 goto done;
+8
drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
··· 1068 1068 1069 1069 rzg2l_mipi_dsi_stop_video(dsi); 1070 1070 rzg2l_mipi_dsi_stop_hs_clock(dsi); 1071 + } 1072 + 1073 + static void rzg2l_mipi_dsi_atomic_post_disable(struct drm_bridge *bridge, 1074 + struct drm_atomic_state *state) 1075 + { 1076 + struct rzg2l_mipi_dsi *dsi = bridge_to_rzg2l_mipi_dsi(bridge); 1077 + 1071 1078 rzg2l_mipi_dsi_stop(dsi); 1072 1079 } 1073 1080 ··· 1110 1103 .atomic_pre_enable = rzg2l_mipi_dsi_atomic_pre_enable, 1111 1104 .atomic_enable = rzg2l_mipi_dsi_atomic_enable, 1112 1105 .atomic_disable = rzg2l_mipi_dsi_atomic_disable, 1106 + .atomic_post_disable = rzg2l_mipi_dsi_atomic_post_disable, 1113 1107 .mode_valid = rzg2l_mipi_dsi_bridge_mode_valid, 1114 1108 }; 1115 1109
+2 -11
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
··· 280 280 static irqreturn_t dw_hdmi_qp_rk3576_irq(int irq, void *dev_id) 281 281 { 282 282 struct rockchip_hdmi_qp *hdmi = dev_id; 283 - u32 intr_stat, val; 284 - 285 - regmap_read(hdmi->regmap, RK3576_IOC_HDMI_HPD_STATUS, &intr_stat); 286 - 287 - if (!intr_stat) 288 - return IRQ_NONE; 283 + u32 val; 289 284 290 285 val = FIELD_PREP_WM16(RK3576_HDMI_HPD_INT_CLR, 1); 291 286 regmap_write(hdmi->regmap, RK3576_IOC_MISC_CON0, val); ··· 315 320 static irqreturn_t dw_hdmi_qp_rk3588_irq(int irq, void *dev_id) 316 321 { 317 322 struct rockchip_hdmi_qp *hdmi = dev_id; 318 - u32 intr_stat, val; 319 - 320 - regmap_read(hdmi->regmap, RK3588_GRF_SOC_STATUS1, &intr_stat); 321 - if (!intr_stat) 322 - return IRQ_NONE; 323 + u32 val; 323 324 324 325 if (hdmi->port_id) 325 326 val = FIELD_PREP_WM16(RK3588_HDMI1_HPD_INT_CLR, 1);
+29 -18
drivers/gpu/drm/rockchip/rk3066_hdmi.c
··· 158 158 hdmi->tmdsclk = DEFAULT_PLLA_RATE; 159 159 } 160 160 161 - static int rk3066_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge, 162 - enum hdmi_infoframe_type type) 161 + static int rk3066_hdmi_bridge_clear_avi_infoframe(struct drm_bridge *bridge) 163 162 { 164 163 struct rk3066_hdmi *hdmi = bridge_to_rk3066_hdmi(bridge); 165 - 166 - if (type != HDMI_INFOFRAME_TYPE_AVI) { 167 - drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type); 168 - return 0; 169 - } 170 164 171 165 hdmi_writeb(hdmi, HDMI_CP_BUF_INDEX, HDMI_INFOFRAME_AVI); 172 166 ··· 168 174 } 169 175 170 176 static int 171 - rk3066_hdmi_bridge_write_infoframe(struct drm_bridge *bridge, 172 - enum hdmi_infoframe_type type, 173 - const u8 *buffer, size_t len) 177 + rk3066_hdmi_bridge_clear_hdmi_infoframe(struct drm_bridge *bridge) 178 + { 179 + /* FIXME: add support for this InfoFrame */ 180 + 181 + drm_warn_once(bridge->encoder->dev, "HDMI VSI not supported\n"); 182 + 183 + return 0; 184 + } 185 + 186 + static int 187 + rk3066_hdmi_bridge_write_avi_infoframe(struct drm_bridge *bridge, 188 + const u8 *buffer, size_t len) 174 189 { 175 190 struct rk3066_hdmi *hdmi = bridge_to_rk3066_hdmi(bridge); 176 191 ssize_t i; 177 192 178 - if (type != HDMI_INFOFRAME_TYPE_AVI) { 179 - drm_err(bridge->dev, "Unsupported infoframe type: %u\n", type); 180 - return 0; 181 - } 182 - 183 - rk3066_hdmi_bridge_clear_infoframe(bridge, type); 193 + rk3066_hdmi_bridge_clear_avi_infoframe(bridge); 184 194 185 195 for (i = 0; i < len; i++) 186 196 hdmi_writeb(hdmi, HDMI_CP_BUF_ACC_HB0 + i * 4, buffer[i]); 197 + 198 + return 0; 199 + } 200 + 201 + static int 202 + rk3066_hdmi_bridge_write_hdmi_infoframe(struct drm_bridge *bridge, 203 + const u8 *buffer, size_t len) 204 + { 205 + rk3066_hdmi_bridge_clear_hdmi_infoframe(bridge); 206 + 207 + /* FIXME: add support for this InfoFrame */ 187 208 188 209 return 0; 189 210 } ··· 502 493 .atomic_disable = rk3066_hdmi_bridge_atomic_disable, 503 494 .detect = rk3066_hdmi_bridge_detect, 504 495 .edid_read = rk3066_hdmi_bridge_edid_read, 505 - .hdmi_clear_infoframe = rk3066_hdmi_bridge_clear_infoframe, 506 - .hdmi_write_infoframe = rk3066_hdmi_bridge_write_infoframe, 496 + .hdmi_clear_avi_infoframe = rk3066_hdmi_bridge_clear_avi_infoframe, 497 + .hdmi_write_avi_infoframe = rk3066_hdmi_bridge_write_avi_infoframe, 498 + .hdmi_clear_hdmi_infoframe = rk3066_hdmi_bridge_clear_hdmi_infoframe, 499 + .hdmi_write_hdmi_infoframe = rk3066_hdmi_bridge_write_hdmi_infoframe, 507 500 .mode_valid = rk3066_hdmi_bridge_mode_valid, 508 501 }; 509 502
+12
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
··· 1426 1426 vop2_crtc_disable_irq(vp, VP_INT_FS_FIELD); 1427 1427 } 1428 1428 1429 + static enum drm_mode_status vop2_crtc_mode_valid(struct drm_crtc *crtc, 1430 + const struct drm_display_mode *mode) 1431 + { 1432 + struct vop2_video_port *vp = to_vop2_video_port(crtc); 1433 + 1434 + if (mode->hdisplay > vp->data->max_output.width) 1435 + return MODE_BAD_HVALUE; 1436 + 1437 + return MODE_OK; 1438 + } 1439 + 1429 1440 static bool vop2_crtc_mode_fixup(struct drm_crtc *crtc, 1430 1441 const struct drm_display_mode *mode, 1431 1442 struct drm_display_mode *adj_mode) ··· 1882 1871 1883 1872 static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = { 1884 1873 .mode_fixup = vop2_crtc_mode_fixup, 1874 + .mode_valid = vop2_crtc_mode_valid, 1885 1875 .atomic_check = vop2_crtc_atomic_check, 1886 1876 .atomic_begin = vop2_crtc_atomic_begin, 1887 1877 .atomic_flush = vop2_crtc_atomic_flush,
+32 -10
drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
··· 40 40 #define drm_connector_to_sun4i_hdmi(c) \ 41 41 container_of_const(c, struct sun4i_hdmi, connector) 42 42 43 - static int sun4i_hdmi_write_infoframe(struct drm_connector *connector, 44 - enum hdmi_infoframe_type type, 45 - const u8 *buffer, size_t len) 43 + static int sun4i_hdmi_clear_avi_infoframe(struct drm_connector *connector) 44 + { 45 + drm_warn_once(connector->dev, "clearing of AVI infoframe is not implemented\n"); 46 + 47 + return 0; 48 + } 49 + 50 + static int sun4i_hdmi_write_avi_infoframe(struct drm_connector *connector, 51 + const u8 *buffer, size_t len) 46 52 { 47 53 struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector); 48 54 int i; 49 - 50 - if (type != HDMI_INFOFRAME_TYPE_AVI) { 51 - drm_err(connector->dev, 52 - "Unsupported infoframe type: %u\n", type); 53 - return 0; 54 - } 55 55 56 56 for (i = 0; i < len; i++) 57 57 writeb(buffer[i], hdmi->base + SUN4I_HDMI_AVI_INFOFRAME_REG(i)); 58 58 59 59 return 0; 60 60 61 + } 62 + 63 + static int sun4i_hdmi_clear_hdmi_infoframe(struct drm_connector *connector) 64 + { 65 + drm_warn_once(connector->dev, "HDMI VSI not implemented\n"); 66 + 67 + return 0; 68 + } 69 + 70 + static int sun4i_hdmi_write_hdmi_infoframe(struct drm_connector *connector, 71 + const u8 *buffer, size_t len) 72 + { 73 + drm_warn_once(connector->dev, "HDMI VSI not implemented\n"); 74 + 75 + return 0; 61 76 } 62 77 63 78 static void sun4i_hdmi_disable(struct drm_encoder *encoder, ··· 251 236 252 237 static const struct drm_connector_hdmi_funcs sun4i_hdmi_hdmi_connector_funcs = { 253 238 .tmds_char_rate_valid = sun4i_hdmi_connector_clock_valid, 254 - .write_infoframe = sun4i_hdmi_write_infoframe, 239 + .avi = { 240 + .clear_infoframe = sun4i_hdmi_clear_avi_infoframe, 241 + .write_infoframe = sun4i_hdmi_write_avi_infoframe, 242 + }, 243 + .hdmi = { 244 + .clear_infoframe = sun4i_hdmi_clear_hdmi_infoframe, 245 + .write_infoframe = sun4i_hdmi_write_hdmi_infoframe, 246 + }, 255 247 }; 256 248 257 249 static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = {
+35
drivers/gpu/drm/tests/drm_buddy_test.c
··· 857 857 drm_buddy_fini(&mm); 858 858 } 859 859 860 + static void drm_test_buddy_alloc_exceeds_max_order(struct kunit *test) 861 + { 862 + u64 mm_size = SZ_8G + SZ_2G, size = SZ_8G + SZ_1G, min_block_size = SZ_8G; 863 + struct drm_buddy mm; 864 + LIST_HEAD(blocks); 865 + int err; 866 + 867 + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, SZ_4K), 868 + "buddy_init failed\n"); 869 + 870 + /* CONTIGUOUS allocation should succeed via try_harder fallback */ 871 + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size, size, 872 + SZ_4K, &blocks, 873 + DRM_BUDDY_CONTIGUOUS_ALLOCATION), 874 + "buddy_alloc hit an error size=%llu\n", size); 875 + drm_buddy_free_list(&mm, &blocks, 0); 876 + 877 + /* Non-CONTIGUOUS with large min_block_size should return -EINVAL */ 878 + err = drm_buddy_alloc_blocks(&mm, 0, mm_size, size, min_block_size, &blocks, 0); 879 + KUNIT_EXPECT_EQ(test, err, -EINVAL); 880 + 881 + /* Non-CONTIGUOUS + RANGE with large min_block_size should return -EINVAL */ 882 + err = drm_buddy_alloc_blocks(&mm, 0, mm_size, size, min_block_size, &blocks, 883 + DRM_BUDDY_RANGE_ALLOCATION); 884 + KUNIT_EXPECT_EQ(test, err, -EINVAL); 885 + 886 + /* CONTIGUOUS + RANGE should return -EINVAL (no try_harder for RANGE) */ 887 + err = drm_buddy_alloc_blocks(&mm, 0, mm_size, size, SZ_4K, &blocks, 888 + DRM_BUDDY_CONTIGUOUS_ALLOCATION | DRM_BUDDY_RANGE_ALLOCATION); 889 + KUNIT_EXPECT_EQ(test, err, -EINVAL); 890 + 891 + drm_buddy_fini(&mm); 892 + } 893 + 860 894 static int drm_buddy_suite_init(struct kunit_suite *suite) 861 895 { 862 896 while (!random_seed) ··· 911 877 KUNIT_CASE(drm_test_buddy_alloc_clear), 912 878 KUNIT_CASE(drm_test_buddy_alloc_range_bias), 913 879 KUNIT_CASE(drm_test_buddy_fragmentation_performance), 880 + KUNIT_CASE(drm_test_buddy_alloc_exceeds_max_order), 914 881 {} 915 882 }; 916 883
+3
drivers/gpu/drm/tests/drm_client_modeset_test.c
··· 5 5 6 6 #include <kunit/test.h> 7 7 8 + #include <drm/drm_atomic_state_helper.h> 8 9 #include <drm/drm_connector.h> 9 10 #include <drm/drm_edid.h> 10 11 #include <drm/drm_drv.h> ··· 49 48 }; 50 49 51 50 static const struct drm_connector_funcs drm_client_modeset_connector_funcs = { 51 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 52 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state 52 53 }; 53 54 54 55 static int drm_client_modeset_test_init(struct kunit *test)
+19
drivers/gpu/drm/tests/drm_connector_test.c
··· 25 25 struct i2c_adapter ddc; 26 26 }; 27 27 28 + static int accept_infoframe_clear_infoframe(struct drm_connector *connector) 29 + { 30 + return 0; 31 + } 32 + 33 + static int accept_infoframe_write_infoframe(struct drm_connector *connector, 34 + const u8 *buffer, size_t len) 35 + { 36 + return 0; 37 + } 38 + 28 39 static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = { 40 + .avi = { 41 + .clear_infoframe = accept_infoframe_clear_infoframe, 42 + .write_infoframe = accept_infoframe_write_infoframe, 43 + }, 44 + .hdmi = { 45 + .clear_infoframe = accept_infoframe_clear_infoframe, 46 + .write_infoframe = accept_infoframe_write_infoframe, 47 + }, 29 48 }; 30 49 31 50 static const struct drm_connector_funcs dummy_funcs = {
+667
drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
··· 35 35 36 36 const void *current_edid; 37 37 size_t current_edid_len; 38 + 39 + int hdmi_update_failures; 38 40 }; 39 41 40 42 #define connector_to_priv(c) \ 41 43 container_of_const(c, struct drm_atomic_helper_connector_hdmi_priv, connector) 44 + 45 + #define encoder_to_priv(e) \ 46 + container_of_const(e, struct drm_atomic_helper_connector_hdmi_priv, encoder) 42 47 43 48 static struct drm_display_mode *find_preferred_mode(struct drm_connector *connector) 44 49 { ··· 78 73 return ret; 79 74 } 80 75 76 + static int accept_infoframe_clear_infoframe(struct drm_connector *connector) 77 + { 78 + return 0; 79 + } 80 + 81 + static int accept_infoframe_write_infoframe(struct drm_connector *connector, 82 + const u8 *buffer, size_t len) 83 + { 84 + return 0; 85 + } 86 + 81 87 static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = { 88 + .avi = { 89 + .clear_infoframe = accept_infoframe_clear_infoframe, 90 + .write_infoframe = accept_infoframe_write_infoframe, 91 + }, 92 + .hdmi = { 93 + .clear_infoframe = accept_infoframe_clear_infoframe, 94 + .write_infoframe = accept_infoframe_write_infoframe, 95 + }, 82 96 }; 83 97 84 98 static enum drm_mode_status ··· 110 86 111 87 static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = { 112 88 .tmds_char_rate_valid = reject_connector_tmds_char_rate_valid, 89 + .avi = { 90 + .clear_infoframe = accept_infoframe_clear_infoframe, 91 + .write_infoframe = accept_infoframe_write_infoframe, 92 + }, 93 + .hdmi = { 94 + .clear_infoframe = accept_infoframe_clear_infoframe, 95 + .write_infoframe = accept_infoframe_write_infoframe, 96 + }, 113 97 }; 114 98 115 99 static enum drm_mode_status ··· 130 98 131 99 static const struct drm_connector_hdmi_funcs reject_100mhz_connector_hdmi_funcs = { 132 100 .tmds_char_rate_valid = reject_100mhz_connector_tmds_char_rate_valid, 101 + .avi = { 102 + .clear_infoframe = accept_infoframe_clear_infoframe, 103 + .write_infoframe = accept_infoframe_write_infoframe, 104 + }, 105 + .hdmi = { 106 + .clear_infoframe = accept_infoframe_clear_infoframe, 107 + .write_infoframe = accept_infoframe_write_infoframe, 108 + }, 133 109 }; 134 110 135 111 static int dummy_connector_get_modes(struct drm_connector *connector) ··· 176 136 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 177 137 .fill_modes = drm_helper_probe_single_connector_modes, 178 138 .reset = dummy_hdmi_connector_reset, 139 + }; 140 + 141 + static void test_encoder_atomic_enable(struct drm_encoder *encoder, 142 + struct drm_atomic_state *state) 143 + { 144 + struct drm_atomic_helper_connector_hdmi_priv *priv = 145 + encoder_to_priv(encoder); 146 + int ret; 147 + 148 + ret = drm_atomic_helper_connector_hdmi_update_infoframes(&priv->connector, state); 149 + if (ret) 150 + priv->hdmi_update_failures++; 151 + } 152 + 153 + static const struct drm_encoder_helper_funcs test_encoder_helper_funcs = { 154 + .atomic_enable = test_encoder_atomic_enable, 179 155 }; 180 156 181 157 static ··· 2522 2466 .test_cases = drm_atomic_helper_connector_hdmi_mode_valid_tests, 2523 2467 }; 2524 2468 2469 + /* 2470 + * Test that the default behaviour works without errors. We expect that 2471 + * infoframe-related hooks are called and there are no errors raised. 2472 + */ 2473 + static void drm_test_check_infoframes(struct kunit *test) 2474 + { 2475 + struct drm_atomic_helper_connector_hdmi_priv *priv; 2476 + struct drm_modeset_acquire_ctx ctx; 2477 + struct drm_crtc_state *crtc_state; 2478 + struct drm_atomic_state *state; 2479 + struct drm_display_mode *preferred; 2480 + struct drm_connector *conn; 2481 + struct drm_device *drm; 2482 + struct drm_crtc *crtc; 2483 + int old_hdmi_update_failures; 2484 + int ret; 2485 + 2486 + priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, 2487 + BIT(HDMI_COLORSPACE_RGB), 2488 + 8, 2489 + &dummy_connector_hdmi_funcs, 2490 + test_edid_hdmi_1080p_rgb_max_200mhz); 2491 + KUNIT_ASSERT_NOT_NULL(test, priv); 2492 + 2493 + drm = &priv->drm; 2494 + crtc = priv->crtc; 2495 + conn = &priv->connector; 2496 + 2497 + preferred = find_preferred_mode(conn); 2498 + KUNIT_ASSERT_NOT_NULL(test, preferred); 2499 + 2500 + drm_modeset_acquire_init(&ctx, 0); 2501 + 2502 + retry_conn_enable: 2503 + ret = drm_kunit_helper_enable_crtc_connector(test, drm, 2504 + crtc, conn, 2505 + preferred, 2506 + &ctx); 2507 + if (ret == -EDEADLK) { 2508 + ret = drm_modeset_backoff(&ctx); 2509 + if (!ret) 2510 + goto retry_conn_enable; 2511 + } 2512 + KUNIT_ASSERT_EQ(test, ret, 0); 2513 + 2514 + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 2515 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 2516 + 2517 + retry_crtc_state: 2518 + crtc_state = drm_atomic_get_crtc_state(state, crtc); 2519 + if (PTR_ERR(crtc_state) == -EDEADLK) { 2520 + drm_atomic_state_clear(state); 2521 + ret = drm_modeset_backoff(&ctx); 2522 + if (!ret) 2523 + goto retry_crtc_state; 2524 + } 2525 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); 2526 + 2527 + crtc_state->mode_changed = true; 2528 + 2529 + old_hdmi_update_failures = priv->hdmi_update_failures; 2530 + 2531 + ret = drm_atomic_check_only(state); 2532 + if (ret == -EDEADLK) { 2533 + drm_atomic_state_clear(state); 2534 + ret = drm_modeset_backoff(&ctx); 2535 + if (!ret) 2536 + goto retry_crtc_state; 2537 + } 2538 + KUNIT_ASSERT_EQ(test, ret, 0); 2539 + 2540 + ret = drm_atomic_commit(state); 2541 + if (ret == -EDEADLK) { 2542 + drm_atomic_state_clear(state); 2543 + ret = drm_modeset_backoff(&ctx); 2544 + if (!ret) 2545 + goto retry_crtc_state; 2546 + } 2547 + KUNIT_ASSERT_EQ(test, ret, 0); 2548 + 2549 + KUNIT_EXPECT_GE(test, old_hdmi_update_failures, priv->hdmi_update_failures); 2550 + 2551 + drm_modeset_drop_locks(&ctx); 2552 + drm_modeset_acquire_fini(&ctx); 2553 + } 2554 + 2555 + static int reject_infoframe_write_infoframe(struct drm_connector *connector, 2556 + const u8 *buffer, size_t len) 2557 + { 2558 + return -EOPNOTSUPP; 2559 + } 2560 + 2561 + static const struct drm_connector_hdmi_funcs reject_avi_infoframe_hdmi_funcs = { 2562 + .avi = { 2563 + .clear_infoframe = accept_infoframe_clear_infoframe, 2564 + .write_infoframe = reject_infoframe_write_infoframe, 2565 + }, 2566 + .hdmi = { 2567 + .clear_infoframe = accept_infoframe_clear_infoframe, 2568 + .write_infoframe = accept_infoframe_write_infoframe, 2569 + }, 2570 + }; 2571 + 2572 + /* 2573 + * Test that the rejection of AVI InfoFrame results in the failure of 2574 + * drm_atomic_helper_connector_hdmi_update_infoframes(). 2575 + */ 2576 + static void drm_test_check_reject_avi_infoframe(struct kunit *test) 2577 + { 2578 + struct drm_atomic_helper_connector_hdmi_priv *priv; 2579 + struct drm_modeset_acquire_ctx ctx; 2580 + struct drm_atomic_state *state; 2581 + struct drm_crtc_state *crtc_state; 2582 + struct drm_display_mode *preferred; 2583 + struct drm_connector *conn; 2584 + struct drm_device *drm; 2585 + struct drm_crtc *crtc; 2586 + int old_hdmi_update_failures; 2587 + int ret; 2588 + 2589 + priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, 2590 + BIT(HDMI_COLORSPACE_RGB), 2591 + 8, 2592 + &reject_avi_infoframe_hdmi_funcs, 2593 + test_edid_hdmi_1080p_rgb_max_200mhz); 2594 + KUNIT_ASSERT_NOT_NULL(test, priv); 2595 + 2596 + drm = &priv->drm; 2597 + crtc = priv->crtc; 2598 + conn = &priv->connector; 2599 + 2600 + preferred = find_preferred_mode(conn); 2601 + KUNIT_ASSERT_NOT_NULL(test, preferred); 2602 + 2603 + drm_modeset_acquire_init(&ctx, 0); 2604 + 2605 + retry_conn_enable: 2606 + ret = drm_kunit_helper_enable_crtc_connector(test, drm, 2607 + crtc, conn, 2608 + preferred, 2609 + &ctx); 2610 + if (ret == -EDEADLK) { 2611 + ret = drm_modeset_backoff(&ctx); 2612 + if (!ret) 2613 + goto retry_conn_enable; 2614 + } 2615 + KUNIT_ASSERT_EQ(test, ret, 0); 2616 + 2617 + drm_encoder_helper_add(&priv->encoder, &test_encoder_helper_funcs); 2618 + 2619 + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 2620 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 2621 + 2622 + retry_crtc_state: 2623 + crtc_state = drm_atomic_get_crtc_state(state, crtc); 2624 + if (PTR_ERR(crtc_state) == -EDEADLK) { 2625 + drm_atomic_state_clear(state); 2626 + ret = drm_modeset_backoff(&ctx); 2627 + if (!ret) 2628 + goto retry_crtc_state; 2629 + } 2630 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); 2631 + 2632 + crtc_state->mode_changed = true; 2633 + 2634 + old_hdmi_update_failures = priv->hdmi_update_failures; 2635 + 2636 + ret = drm_atomic_check_only(state); 2637 + if (ret == -EDEADLK) { 2638 + drm_atomic_state_clear(state); 2639 + ret = drm_modeset_backoff(&ctx); 2640 + if (!ret) 2641 + goto retry_crtc_state; 2642 + } 2643 + KUNIT_ASSERT_EQ(test, ret, 0); 2644 + 2645 + ret = drm_atomic_commit(state); 2646 + if (ret == -EDEADLK) { 2647 + drm_atomic_state_clear(state); 2648 + ret = drm_modeset_backoff(&ctx); 2649 + if (!ret) 2650 + goto retry_crtc_state; 2651 + } 2652 + KUNIT_ASSERT_EQ(test, ret, 0); 2653 + 2654 + KUNIT_EXPECT_NE(test, old_hdmi_update_failures, priv->hdmi_update_failures); 2655 + 2656 + drm_modeset_drop_locks(&ctx); 2657 + drm_modeset_acquire_fini(&ctx); 2658 + } 2659 + 2660 + static const struct drm_connector_hdmi_funcs reject_hdr_infoframe_hdmi_funcs = { 2661 + .avi = { 2662 + .clear_infoframe = accept_infoframe_clear_infoframe, 2663 + .write_infoframe = accept_infoframe_write_infoframe, 2664 + }, 2665 + .hdmi = { 2666 + .clear_infoframe = accept_infoframe_clear_infoframe, 2667 + .write_infoframe = accept_infoframe_write_infoframe, 2668 + }, 2669 + .hdr_drm = { 2670 + .clear_infoframe = accept_infoframe_clear_infoframe, 2671 + .write_infoframe = reject_infoframe_write_infoframe, 2672 + }, 2673 + }; 2674 + 2675 + /* 2676 + * Test that the HDR InfoFrame isn't programmed in 2677 + * drm_atomic_helper_connector_hdmi_update_infoframes() if the max_bpc is 8. 2678 + */ 2679 + static void drm_test_check_reject_hdr_infoframe_bpc_8(struct kunit *test) 2680 + { 2681 + struct drm_atomic_helper_connector_hdmi_priv *priv; 2682 + struct drm_modeset_acquire_ctx ctx; 2683 + struct drm_atomic_state *state; 2684 + struct drm_connector_state *new_conn_state; 2685 + struct drm_crtc_state *crtc_state; 2686 + struct drm_display_mode *preferred; 2687 + struct drm_connector *conn; 2688 + struct drm_device *drm; 2689 + struct drm_crtc *crtc; 2690 + int old_hdmi_update_failures; 2691 + int ret; 2692 + 2693 + priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, 2694 + BIT(HDMI_COLORSPACE_RGB), 2695 + 8, 2696 + &reject_hdr_infoframe_hdmi_funcs, 2697 + test_edid_hdmi_1080p_rgb_max_200mhz_hdr); 2698 + KUNIT_ASSERT_NOT_NULL(test, priv); 2699 + 2700 + drm = &priv->drm; 2701 + crtc = priv->crtc; 2702 + conn = &priv->connector; 2703 + 2704 + preferred = find_preferred_mode(conn); 2705 + KUNIT_ASSERT_NOT_NULL(test, preferred); 2706 + 2707 + drm_modeset_acquire_init(&ctx, 0); 2708 + 2709 + retry_conn_enable: 2710 + ret = drm_kunit_helper_enable_crtc_connector(test, drm, 2711 + crtc, conn, 2712 + preferred, 2713 + &ctx); 2714 + if (ret == -EDEADLK) { 2715 + ret = drm_modeset_backoff(&ctx); 2716 + if (!ret) 2717 + goto retry_conn_enable; 2718 + } 2719 + KUNIT_ASSERT_EQ(test, ret, 0); 2720 + 2721 + drm_encoder_helper_add(&priv->encoder, &test_encoder_helper_funcs); 2722 + 2723 + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 2724 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 2725 + 2726 + retry_conn_state: 2727 + new_conn_state = drm_atomic_get_connector_state(state, conn); 2728 + if (PTR_ERR(new_conn_state) == -EDEADLK) { 2729 + drm_atomic_state_clear(state); 2730 + ret = drm_modeset_backoff(&ctx); 2731 + if (!ret) 2732 + goto retry_conn_state; 2733 + } 2734 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); 2735 + 2736 + crtc_state = drm_atomic_get_crtc_state(state, crtc); 2737 + if (PTR_ERR(crtc_state) == -EDEADLK) { 2738 + drm_atomic_state_clear(state); 2739 + ret = drm_modeset_backoff(&ctx); 2740 + if (!ret) 2741 + goto retry_conn_state; 2742 + } 2743 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); 2744 + 2745 + /* Verify that there is no HDR property, so "userspace" can't set it. */ 2746 + for (int i = 0; i < conn->base.properties->count; i++) 2747 + KUNIT_ASSERT_PTR_NE(test, 2748 + drm->mode_config.hdr_output_metadata_property, 2749 + conn->base.properties->properties[i]); 2750 + 2751 + crtc_state->mode_changed = true; 2752 + 2753 + old_hdmi_update_failures = priv->hdmi_update_failures; 2754 + 2755 + ret = drm_atomic_check_only(state); 2756 + if (ret == -EDEADLK) { 2757 + drm_atomic_state_clear(state); 2758 + ret = drm_modeset_backoff(&ctx); 2759 + if (!ret) 2760 + goto retry_conn_state; 2761 + } 2762 + KUNIT_ASSERT_EQ(test, ret, 0); 2763 + 2764 + ret = drm_atomic_commit(state); 2765 + if (ret == -EDEADLK) { 2766 + drm_atomic_state_clear(state); 2767 + ret = drm_modeset_backoff(&ctx); 2768 + if (!ret) 2769 + goto retry_conn_state; 2770 + } 2771 + KUNIT_ASSERT_EQ(test, ret, 0); 2772 + 2773 + KUNIT_EXPECT_EQ(test, old_hdmi_update_failures, priv->hdmi_update_failures); 2774 + 2775 + new_conn_state = conn->state; 2776 + KUNIT_ASSERT_NOT_NULL(test, new_conn_state); 2777 + 2778 + KUNIT_ASSERT_EQ(test, new_conn_state->hdmi.output_bpc, 8); 2779 + KUNIT_ASSERT_EQ(test, new_conn_state->hdmi.infoframes.hdr_drm.set, false); 2780 + 2781 + drm_modeset_drop_locks(&ctx); 2782 + drm_modeset_acquire_fini(&ctx); 2783 + } 2784 + 2785 + /* 2786 + * Test that the rejection of HDR InfoFrame results in the failure of 2787 + * drm_atomic_helper_connector_hdmi_update_infoframes() in the high bpc is 2788 + * supported. 2789 + */ 2790 + static void drm_test_check_reject_hdr_infoframe_bpc_10(struct kunit *test) 2791 + { 2792 + struct drm_atomic_helper_connector_hdmi_priv *priv; 2793 + struct drm_modeset_acquire_ctx ctx; 2794 + struct drm_atomic_state *state; 2795 + struct drm_connector_state *new_conn_state; 2796 + struct drm_crtc_state *crtc_state; 2797 + struct drm_display_mode *preferred; 2798 + struct drm_connector *conn; 2799 + struct drm_device *drm; 2800 + struct drm_crtc *crtc; 2801 + int old_hdmi_update_failures; 2802 + struct hdr_output_metadata hdr_data; 2803 + struct drm_property_blob *hdr_blob; 2804 + bool replaced; 2805 + int ret; 2806 + 2807 + priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, 2808 + BIT(HDMI_COLORSPACE_RGB), 2809 + 10, 2810 + &reject_hdr_infoframe_hdmi_funcs, 2811 + test_edid_hdmi_1080p_rgb_max_200mhz_hdr); 2812 + KUNIT_ASSERT_NOT_NULL(test, priv); 2813 + 2814 + drm = &priv->drm; 2815 + crtc = priv->crtc; 2816 + conn = &priv->connector; 2817 + 2818 + preferred = find_preferred_mode(conn); 2819 + KUNIT_ASSERT_NOT_NULL(test, preferred); 2820 + 2821 + drm_modeset_acquire_init(&ctx, 0); 2822 + 2823 + retry_conn_enable: 2824 + ret = drm_kunit_helper_enable_crtc_connector(test, drm, 2825 + crtc, conn, 2826 + preferred, 2827 + &ctx); 2828 + if (ret == -EDEADLK) { 2829 + ret = drm_modeset_backoff(&ctx); 2830 + if (!ret) 2831 + goto retry_conn_enable; 2832 + } 2833 + KUNIT_ASSERT_EQ(test, ret, 0); 2834 + 2835 + drm_encoder_helper_add(&priv->encoder, &test_encoder_helper_funcs); 2836 + 2837 + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 2838 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 2839 + 2840 + retry_conn_state: 2841 + new_conn_state = drm_atomic_get_connector_state(state, conn); 2842 + if (PTR_ERR(new_conn_state) == -EDEADLK) { 2843 + drm_atomic_state_clear(state); 2844 + ret = drm_modeset_backoff(&ctx); 2845 + if (!ret) 2846 + goto retry_conn_state; 2847 + } 2848 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); 2849 + 2850 + crtc_state = drm_atomic_get_crtc_state(state, crtc); 2851 + if (PTR_ERR(crtc_state) == -EDEADLK) { 2852 + drm_atomic_state_clear(state); 2853 + ret = drm_modeset_backoff(&ctx); 2854 + if (!ret) 2855 + goto retry_conn_state; 2856 + } 2857 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); 2858 + 2859 + hdr_data.metadata_type = HDMI_STATIC_METADATA_TYPE1; 2860 + hdr_data.hdmi_metadata_type1.eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR; 2861 + hdr_data.hdmi_metadata_type1.metadata_type = HDMI_STATIC_METADATA_TYPE1; 2862 + 2863 + hdr_blob = drm_property_create_blob(drm, sizeof(hdr_data), &hdr_data); 2864 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hdr_blob); 2865 + 2866 + ret = drm_property_replace_blob_from_id(drm, 2867 + &new_conn_state->hdr_output_metadata, 2868 + hdr_blob->base.id, 2869 + -1, sizeof(struct hdr_output_metadata), -1, 2870 + &replaced); 2871 + KUNIT_ASSERT_EQ(test, ret, 0); 2872 + KUNIT_ASSERT_EQ(test, replaced, true); 2873 + 2874 + crtc_state->mode_changed = true; 2875 + 2876 + old_hdmi_update_failures = priv->hdmi_update_failures; 2877 + 2878 + ret = drm_atomic_check_only(state); 2879 + if (ret == -EDEADLK) { 2880 + drm_atomic_state_clear(state); 2881 + ret = drm_modeset_backoff(&ctx); 2882 + if (!ret) 2883 + goto retry_conn_state; 2884 + } 2885 + KUNIT_ASSERT_EQ(test, ret, 0); 2886 + 2887 + ret = drm_atomic_commit(state); 2888 + if (ret == -EDEADLK) { 2889 + drm_atomic_state_clear(state); 2890 + ret = drm_modeset_backoff(&ctx); 2891 + if (!ret) 2892 + goto retry_conn_state; 2893 + } 2894 + KUNIT_ASSERT_EQ(test, ret, 0); 2895 + 2896 + KUNIT_EXPECT_LE(test, old_hdmi_update_failures, priv->hdmi_update_failures); 2897 + 2898 + new_conn_state = conn->state; 2899 + KUNIT_ASSERT_NOT_NULL(test, new_conn_state); 2900 + 2901 + KUNIT_ASSERT_EQ(test, new_conn_state->hdmi.output_bpc, 10); 2902 + KUNIT_ASSERT_EQ(test, new_conn_state->hdmi.infoframes.hdr_drm.set, true); 2903 + 2904 + drm_modeset_drop_locks(&ctx); 2905 + drm_modeset_acquire_fini(&ctx); 2906 + } 2907 + 2908 + static const struct drm_connector_hdmi_funcs reject_audio_infoframe_hdmi_funcs = { 2909 + .avi = { 2910 + .clear_infoframe = accept_infoframe_clear_infoframe, 2911 + .write_infoframe = accept_infoframe_write_infoframe, 2912 + }, 2913 + .hdmi = { 2914 + .clear_infoframe = accept_infoframe_clear_infoframe, 2915 + .write_infoframe = accept_infoframe_write_infoframe, 2916 + }, 2917 + .audio = { 2918 + .clear_infoframe = accept_infoframe_clear_infoframe, 2919 + .write_infoframe = reject_infoframe_write_infoframe, 2920 + }, 2921 + }; 2922 + 2923 + /* 2924 + * Test that Audio InfoFrame is only programmed if we call a corresponding API, 2925 + * thus the drivers can safely assume that they won't get Audio InfoFrames if 2926 + * they don't call it. 2927 + */ 2928 + static void drm_test_check_reject_audio_infoframe(struct kunit *test) 2929 + { 2930 + struct drm_atomic_helper_connector_hdmi_priv *priv; 2931 + struct drm_modeset_acquire_ctx ctx; 2932 + struct drm_atomic_state *state; 2933 + struct drm_crtc_state *crtc_state; 2934 + struct drm_display_mode *preferred; 2935 + struct drm_connector *conn; 2936 + struct drm_device *drm; 2937 + struct drm_crtc *crtc; 2938 + int old_hdmi_update_failures; 2939 + struct hdmi_audio_infoframe cea; 2940 + int ret; 2941 + 2942 + priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, 2943 + BIT(HDMI_COLORSPACE_RGB), 2944 + 8, 2945 + &reject_audio_infoframe_hdmi_funcs, 2946 + test_edid_hdmi_1080p_rgb_max_200mhz); 2947 + KUNIT_ASSERT_NOT_NULL(test, priv); 2948 + 2949 + drm = &priv->drm; 2950 + crtc = priv->crtc; 2951 + conn = &priv->connector; 2952 + 2953 + preferred = find_preferred_mode(conn); 2954 + KUNIT_ASSERT_NOT_NULL(test, preferred); 2955 + 2956 + drm_modeset_acquire_init(&ctx, 0); 2957 + 2958 + retry_conn_enable: 2959 + ret = drm_kunit_helper_enable_crtc_connector(test, drm, 2960 + crtc, conn, 2961 + preferred, 2962 + &ctx); 2963 + if (ret == -EDEADLK) { 2964 + ret = drm_modeset_backoff(&ctx); 2965 + if (!ret) 2966 + goto retry_conn_enable; 2967 + } 2968 + KUNIT_ASSERT_EQ(test, ret, 0); 2969 + 2970 + drm_encoder_helper_add(&priv->encoder, &test_encoder_helper_funcs); 2971 + 2972 + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 2973 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 2974 + 2975 + retry_crtc_state: 2976 + crtc_state = drm_atomic_get_crtc_state(state, crtc); 2977 + if (PTR_ERR(crtc_state) == -EDEADLK) { 2978 + drm_atomic_state_clear(state); 2979 + ret = drm_modeset_backoff(&ctx); 2980 + if (!ret) 2981 + goto retry_crtc_state; 2982 + } 2983 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); 2984 + 2985 + crtc_state->mode_changed = true; 2986 + 2987 + old_hdmi_update_failures = priv->hdmi_update_failures; 2988 + 2989 + ret = drm_atomic_check_only(state); 2990 + if (ret == -EDEADLK) { 2991 + drm_atomic_state_clear(state); 2992 + ret = drm_modeset_backoff(&ctx); 2993 + if (!ret) 2994 + goto retry_crtc_state; 2995 + } 2996 + KUNIT_ASSERT_EQ(test, ret, 0); 2997 + 2998 + ret = drm_atomic_commit(state); 2999 + if (ret == -EDEADLK) { 3000 + drm_atomic_state_clear(state); 3001 + ret = drm_modeset_backoff(&ctx); 3002 + if (!ret) 3003 + goto retry_crtc_state; 3004 + } 3005 + KUNIT_ASSERT_EQ(test, ret, 0); 3006 + 3007 + KUNIT_EXPECT_EQ(test, old_hdmi_update_failures, priv->hdmi_update_failures); 3008 + 3009 + /* 3010 + * So, it works without Audio InfoFrame, let's fail with it in place, 3011 + * checking that writing the infofraem actually gets triggered. 3012 + */ 3013 + 3014 + hdmi_audio_infoframe_init(&cea); 3015 + cea.channels = 2; 3016 + cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; 3017 + cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; 3018 + cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; 3019 + 3020 + ret = drm_atomic_helper_connector_hdmi_update_audio_infoframe(conn, &cea); 3021 + KUNIT_ASSERT_EQ(test, ret, -EOPNOTSUPP); 3022 + 3023 + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 3024 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 3025 + 3026 + retry_crtc_state_2: 3027 + crtc_state = drm_atomic_get_crtc_state(state, crtc); 3028 + if (PTR_ERR(crtc_state) == -EDEADLK) { 3029 + drm_atomic_state_clear(state); 3030 + ret = drm_modeset_backoff(&ctx); 3031 + if (!ret) 3032 + goto retry_crtc_state_2; 3033 + } 3034 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); 3035 + 3036 + crtc_state->mode_changed = true; 3037 + 3038 + old_hdmi_update_failures = priv->hdmi_update_failures; 3039 + 3040 + ret = drm_atomic_check_only(state); 3041 + if (ret == -EDEADLK) { 3042 + drm_atomic_state_clear(state); 3043 + ret = drm_modeset_backoff(&ctx); 3044 + if (!ret) 3045 + goto retry_crtc_state_2; 3046 + } 3047 + KUNIT_ASSERT_EQ(test, ret, 0); 3048 + 3049 + ret = drm_atomic_commit(state); 3050 + if (ret == -EDEADLK) { 3051 + drm_atomic_state_clear(state); 3052 + ret = drm_modeset_backoff(&ctx); 3053 + if (!ret) 3054 + goto retry_crtc_state_2; 3055 + } 3056 + KUNIT_ASSERT_EQ(test, ret, 0); 3057 + 3058 + KUNIT_EXPECT_LE(test, old_hdmi_update_failures, priv->hdmi_update_failures); 3059 + 3060 + drm_modeset_drop_locks(&ctx); 3061 + drm_modeset_acquire_fini(&ctx); 3062 + } 3063 + 3064 + 3065 + static struct kunit_case drm_atomic_helper_connector_hdmi_infoframes_tests[] = { 3066 + KUNIT_CASE(drm_test_check_infoframes), 3067 + KUNIT_CASE(drm_test_check_reject_avi_infoframe), 3068 + KUNIT_CASE(drm_test_check_reject_hdr_infoframe_bpc_8), 3069 + KUNIT_CASE(drm_test_check_reject_hdr_infoframe_bpc_10), 3070 + KUNIT_CASE(drm_test_check_reject_audio_infoframe), 3071 + { } 3072 + }; 3073 + 3074 + static struct kunit_suite drm_atomic_helper_connector_hdmi_infoframes_test_suite = { 3075 + .name = "drm_atomic_helper_connector_hdmi_infoframes", 3076 + .test_cases = drm_atomic_helper_connector_hdmi_infoframes_tests, 3077 + }; 3078 + 2525 3079 kunit_test_suites( 2526 3080 &drm_atomic_helper_connector_hdmi_check_test_suite, 2527 3081 &drm_atomic_helper_connector_hdmi_reset_test_suite, 2528 3082 &drm_atomic_helper_connector_hdmi_mode_valid_test_suite, 3083 + &drm_atomic_helper_connector_hdmi_infoframes_test_suite, 2529 3084 ); 2530 3085 2531 3086 MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>");
+119
drivers/gpu/drm/tests/drm_kunit_edid.h
··· 305 305 * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10 306 306 * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92 307 307 * 308 + * 02 03 1c 81 e3 05 c0 20 41 10 e2 00 4a 67 03 0c 309 + * 00 12 34 00 28 e6 06 05 01 52 52 51 00 00 00 00 310 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 311 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 312 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 313 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 314 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 315 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4e 316 + * 317 + * ---------------- 318 + * 319 + * Block 0, Base EDID: 320 + * EDID Structure Version & Revision: 1.3 321 + * Vendor & Product Identification: 322 + * Manufacturer: LNX 323 + * Model: 42 324 + * Made in: 2023 325 + * Basic Display Parameters & Features: 326 + * Digital display 327 + * DFP 1.x compatible TMDS 328 + * Maximum image size: 160 cm x 90 cm 329 + * Gamma: 2.20 330 + * Monochrome or grayscale display 331 + * First detailed timing is the preferred timing 332 + * Color Characteristics: 333 + * Red : 0.0000, 0.0000 334 + * Green: 0.0000, 0.0000 335 + * Blue : 0.0000, 0.0000 336 + * White: 0.0000, 0.0000 337 + * Established Timings I & II: 338 + * DMT 0x04: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz 339 + * Standard Timings: none 340 + * Detailed Timing Descriptors: 341 + * DTD 1: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (1600 mm x 900 mm) 342 + * Hfront 88 Hsync 44 Hback 148 Hpol P 343 + * Vfront 4 Vsync 5 Vback 36 Vpol P 344 + * Display Product Name: 'Test EDID' 345 + * Display Range Limits: 346 + * Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz 347 + * Dummy Descriptor: 348 + * Extension blocks: 1 349 + * Checksum: 0x92 350 + * 351 + * ---------------- 352 + * 353 + * Block 1, CTA-861 Extension Block: 354 + * Revision: 3 355 + * Underscans IT Video Formats by default 356 + * Native detailed modes: 1 357 + * Colorimetry Data Block: 358 + * BT2020YCC 359 + * BT2020RGB 360 + * sRGB 361 + * Video Data Block: 362 + * VIC 16: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz 363 + * Video Capability Data Block: 364 + * YCbCr quantization: No Data 365 + * RGB quantization: Selectable (via AVI Q) 366 + * PT scan behavior: No Data 367 + * IT scan behavior: Always Underscanned 368 + * CE scan behavior: Always Underscanned 369 + * Vendor-Specific Data Block (HDMI), OUI 00-0C-03: 370 + * Source physical address: 1.2.3.4 371 + * Maximum TMDS clock: 200 MHz 372 + * HDR Static Metadata Data Block: 373 + * Electro optical transfer functions: 374 + * Traditional gamma - SDR luminance range 375 + * SMPTE ST2084 376 + * Supported static metadata descriptors: 377 + * Static metadata type 1 378 + * Desired content max luminance: 82 (295.365 cd/m^2) 379 + * Desired content max frame-average luminance: 82 (295.365 cd/m^2) 380 + * Desired content min luminance: 81 (0.298 cd/m^2) 381 + * Checksum: 0x4e Unused space in Extension Block: 99 bytes 382 + * 383 + * ---------------- 384 + * 385 + * edid-decode 1.31.0-5387 386 + * edid-decode SHA: 5508bc4301ac 2025-08-25 08:14:22 387 + * 388 + * EDID conformity: PASS 389 + */ 390 + static const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz_hdr[] = { 391 + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00, 392 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78, 393 + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 394 + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 395 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 396 + 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e, 397 + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44, 398 + 0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32, 399 + 0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 400 + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 401 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x92, 0x02, 0x03, 0x1c, 0x81, 402 + 0xe3, 0x05, 0xc0, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x67, 0x03, 0x0c, 403 + 0x00, 0x12, 0x34, 0x78, 0x28, 0xe6, 0x06, 0x05, 0x01, 0x52, 0x52, 0x51, 404 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 405 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 406 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 407 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 408 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 409 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 410 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 411 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 412 + 0x00, 0x00, 0x00, 0xd6, 413 + }; 414 + 415 + /* 416 + * edid-decode (hex): 417 + * 418 + * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00 419 + * 00 21 01 03 81 a0 5a 78 02 00 00 00 00 00 00 00 420 + * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01 421 + * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c 422 + * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73 423 + * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32 424 + * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10 425 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92 426 + * 308 427 * 02 03 15 81 e3 05 00 20 41 10 e2 00 4a 67 03 0c 309 428 * 00 12 34 00 44 00 00 00 00 00 00 00 00 00 00 00 310 429 * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+3 -2
drivers/gpu/drm/tyr/gpu.rs
··· 8 8 use kernel::prelude::*; 9 9 use kernel::time; 10 10 use kernel::transmute::AsBytes; 11 + use kernel::uapi; 11 12 12 13 use crate::driver::IoMem; 13 14 use crate::regs; ··· 35 34 pub(crate) coherency_features: u32, 36 35 pub(crate) texture_features: [u32; 4], 37 36 pub(crate) as_present: u32, 38 - pub(crate) pad0: u32, 37 + pub(crate) selected_coherency: u32, 39 38 pub(crate) shader_present: u64, 40 39 pub(crate) l2_present: u64, 41 40 pub(crate) tiler_present: u64, ··· 90 89 // TODO: Add texture_features_{1,2,3}. 91 90 texture_features: [texture_features, 0, 0, 0], 92 91 as_present, 93 - pad0: 0, 92 + selected_coherency: uapi::drm_panthor_gpu_coherency_DRM_PANTHOR_GPU_COHERENCY_NONE, 94 93 shader_present, 95 94 l2_present, 96 95 tiler_present,
+4 -4
drivers/gpu/drm/v3d/v3d_bo.c
··· 213 213 int ret; 214 214 215 215 if (args->flags != 0) { 216 - DRM_INFO("unknown create_bo flags: %d\n", args->flags); 216 + drm_dbg(dev, "unknown create_bo flags: %d\n", args->flags); 217 217 return -EINVAL; 218 218 } 219 219 ··· 236 236 struct drm_gem_object *gem_obj; 237 237 238 238 if (args->flags != 0) { 239 - DRM_INFO("unknown mmap_bo flags: %d\n", args->flags); 239 + drm_dbg(dev, "unknown mmap_bo flags: %d\n", args->flags); 240 240 return -EINVAL; 241 241 } 242 242 243 243 gem_obj = drm_gem_object_lookup(file_priv, args->handle); 244 244 if (!gem_obj) { 245 - DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle); 245 + drm_dbg(dev, "Failed to look up GEM BO %d\n", args->handle); 246 246 return -ENOENT; 247 247 } 248 248 ··· 261 261 262 262 gem_obj = drm_gem_object_lookup(file_priv, args->handle); 263 263 if (!gem_obj) { 264 - DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle); 264 + drm_dbg(dev, "Failed to look up GEM BO %d\n", args->handle); 265 265 return -ENOENT; 266 266 } 267 267 bo = to_v3d_bo(gem_obj);
+3 -3
drivers/gpu/drm/v3d/v3d_drv.c
··· 120 120 mutex_unlock(&v3d->reset_lock); 121 121 return 0; 122 122 default: 123 - DRM_DEBUG("Unknown parameter %d\n", args->param); 123 + drm_dbg(dev, "Unknown parameter %d\n", args->param); 124 124 return -EINVAL; 125 125 } 126 126 } ··· 297 297 298 298 if (wait_for((V3D_GET_FIELD(V3D_SMS_READ(V3D_SMS_TEE_CS), 299 299 V3D_SMS_STATE) == V3D_SMS_IDLE), 100)) { 300 - DRM_ERROR("Failed to power up SMS\n"); 300 + drm_err(&v3d->drm, "Failed to power up SMS\n"); 301 301 } 302 302 303 303 v3d_reset_sms(v3d); ··· 313 313 314 314 if (wait_for((V3D_GET_FIELD(V3D_SMS_READ(V3D_SMS_TEE_CS), 315 315 V3D_SMS_STATE) == V3D_SMS_POWER_OFF_STATE), 100)) { 316 - DRM_ERROR("Failed to power off SMS\n"); 316 + drm_err(&v3d->drm, "Failed to power off SMS\n"); 317 317 } 318 318 } 319 319
+8 -8
drivers/gpu/drm/v3d/v3d_gem.c
··· 52 52 (V3D_GMP_STATUS_RD_COUNT_MASK | 53 53 V3D_GMP_STATUS_WR_COUNT_MASK | 54 54 V3D_GMP_STATUS_CFG_BUSY)) == 0, 100)) { 55 - DRM_ERROR("Failed to wait for safe GMP shutdown\n"); 55 + drm_err(&v3d->drm, "Failed to wait for safe GMP shutdown\n"); 56 56 } 57 57 } 58 58 ··· 67 67 if (wait_for((V3D_GCA_READ(V3D_GCA_SAFE_SHUTDOWN_ACK) & 68 68 V3D_GCA_SAFE_SHUTDOWN_ACK_ACKED) == 69 69 V3D_GCA_SAFE_SHUTDOWN_ACK_ACKED, 100)) { 70 - DRM_ERROR("Failed to wait for safe GCA shutdown\n"); 70 + drm_err(&v3d->drm, "Failed to wait for safe GCA shutdown\n"); 71 71 } 72 72 } 73 73 ··· 117 117 V3D_SMS_STATE) == V3D_SMS_ISOLATING_FOR_RESET) && 118 118 !(V3D_GET_FIELD(V3D_SMS_READ(V3D_SMS_REE_CS), 119 119 V3D_SMS_STATE) == V3D_SMS_RESETTING), 100)) { 120 - DRM_ERROR("Failed to wait for SMS reset\n"); 120 + drm_err(&v3d->drm, "Failed to wait for SMS reset\n"); 121 121 } 122 122 } 123 123 ··· 126 126 { 127 127 struct drm_device *dev = &v3d->drm; 128 128 129 - DRM_DEV_ERROR(dev->dev, "Resetting GPU for hang.\n"); 130 - DRM_DEV_ERROR(dev->dev, "V3D_ERR_STAT: 0x%08x\n", 131 - V3D_CORE_READ(0, V3D_ERR_STAT)); 129 + drm_err(dev, "Resetting GPU for hang.\n"); 130 + drm_err(dev, "V3D_ERR_STAT: 0x%08x\n", V3D_CORE_READ(0, V3D_ERR_STAT)); 131 + 132 132 trace_v3d_reset_begin(dev); 133 133 134 134 /* XXX: only needed for safe powerdown, not reset. */ ··· 216 216 V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_TMUWCF); 217 217 if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & 218 218 V3D_L2TCACTL_TMUWCF), 100)) { 219 - DRM_ERROR("Timeout waiting for TMU write combiner flush\n"); 219 + drm_err(dev, "Timeout waiting for TMU write combiner flush\n"); 220 220 } 221 221 222 222 mutex_lock(&v3d->cache_clean_lock); ··· 226 226 227 227 if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & 228 228 V3D_L2TCACTL_L2TFLS), 100)) { 229 - DRM_ERROR("Timeout waiting for L2T clean\n"); 229 + drm_err(dev, "Timeout waiting for L2T clean\n"); 230 230 } 231 231 232 232 mutex_unlock(&v3d->cache_clean_lock);
+4 -4
drivers/gpu/drm/v3d/v3d_irq.c
··· 50 50 unsigned long irqflags; 51 51 52 52 if (IS_ERR(bo)) { 53 - DRM_ERROR("Couldn't allocate binner overflow mem\n"); 53 + drm_err(dev, "Couldn't allocate binner overflow mem\n"); 54 54 return; 55 55 } 56 56 obj = &bo->base.base; ··· 140 140 * always-allowed mode. 141 141 */ 142 142 if (v3d->ver < V3D_GEN_71 && (intsts & V3D_INT_GMPV)) 143 - dev_err(v3d->drm.dev, "GMP violation\n"); 143 + drm_err(&v3d->drm, "GMP violation\n"); 144 144 145 145 /* V3D 4.2 wires the hub and core IRQs together, so if we & 146 146 * didn't see the common one then check hub for MMU IRQs. ··· 226 226 } 227 227 } 228 228 229 - dev_err(v3d->drm.dev, "MMU error from client %s (0x%x) at 0x%llx%s%s%s\n", 229 + drm_dbg(&v3d->drm, "MMU error from client %s (0x%x) at 0x%llx%s%s%s\n", 230 230 client, axi_id, (long long)vio_addr, 231 231 ((intsts & V3D_HUB_INT_MMU_WRV) ? 232 232 ", write violation" : ""), ··· 238 238 } 239 239 240 240 if (v3d->ver >= V3D_GEN_71 && (intsts & V3D_V7_HUB_INT_GMPV)) { 241 - dev_err(v3d->drm.dev, "GMP Violation\n"); 241 + drm_err(&v3d->drm, "GMP Violation\n"); 242 242 status = IRQ_HANDLED; 243 243 } 244 244
+4 -2
drivers/gpu/drm/v3d/v3d_mmu.c
··· 18 18 * each client. This is not yet implemented. 19 19 */ 20 20 21 + #include <drm/drm_print.h> 22 + 21 23 #include "v3d_drv.h" 22 24 #include "v3d_regs.h" 23 25 ··· 127 125 shmem_obj->base.size >> V3D_MMU_PAGE_SHIFT); 128 126 129 127 if (v3d_mmu_flush_all(v3d)) 130 - dev_err(v3d->drm.dev, "MMU flush timeout\n"); 128 + drm_err(&v3d->drm, "MMU flush timeout\n"); 131 129 } 132 130 133 131 void v3d_mmu_remove_ptes(struct v3d_bo *bo) ··· 140 138 v3d->pt[page] = 0; 141 139 142 140 if (v3d_mmu_flush_all(v3d)) 143 - dev_err(v3d->drm.dev, "MMU flush timeout\n"); 141 + drm_err(&v3d->drm, "MMU flush timeout\n"); 144 142 }
+3 -3
drivers/gpu/drm/v3d/v3d_sched.c
··· 585 585 perfmon = v3d_perfmon_find(v3d_priv, 586 586 performance_query->queries[i].kperfmon_ids[j]); 587 587 if (!perfmon) { 588 - DRM_DEBUG("Failed to find perfmon."); 588 + drm_dbg(&v3d->drm, "Failed to find perfmon."); 589 589 continue; 590 590 } 591 591 ··· 620 620 perfmon = v3d_perfmon_find(v3d_priv, 621 621 perf_query->kperfmon_ids[i]); 622 622 if (!perfmon) { 623 - DRM_DEBUG("Failed to find perfmon."); 623 + drm_dbg(&v3d->drm, "Failed to find perfmon."); 624 624 continue; 625 625 } 626 626 ··· 690 690 struct v3d_dev *v3d = job->base.v3d; 691 691 692 692 if (job->job_type >= ARRAY_SIZE(cpu_job_function)) { 693 - DRM_DEBUG_DRIVER("Unknown CPU job: %d\n", job->job_type); 693 + drm_dbg(&v3d->drm, "Unknown CPU job: %d\n", job->job_type); 694 694 return NULL; 695 695 } 696 696
+62 -78
drivers/gpu/drm/v3d/v3d_submit.c
··· 76 76 /* See comment on bo_index for why we have to check 77 77 * this. 78 78 */ 79 - DRM_DEBUG("Rendering requires BOs\n"); 79 + drm_warn(dev, "Rendering requires BOs\n"); 80 80 return -EINVAL; 81 81 } 82 82 ··· 138 138 } 139 139 140 140 static int 141 - v3d_job_allocate(void **container, size_t size) 141 + v3d_job_allocate(struct v3d_dev *v3d, void **container, size_t size) 142 142 { 143 143 *container = kcalloc(1, size, GFP_KERNEL); 144 144 if (!*container) { 145 - DRM_ERROR("Cannot allocate memory for V3D job.\n"); 145 + drm_err(&v3d->drm, "Cannot allocate memory for V3D job.\n"); 146 146 return -ENOMEM; 147 147 } 148 148 ··· 183 183 184 184 if (copy_from_user(&in, handle++, sizeof(in))) { 185 185 ret = -EFAULT; 186 - DRM_DEBUG("Failed to copy wait dep handle.\n"); 186 + drm_dbg(&v3d->drm, "Failed to copy wait dep handle.\n"); 187 187 goto fail_deps; 188 188 } 189 189 ret = drm_sched_job_add_syncobj_dependency(&job->base, file_priv, in.handle, 0); ··· 276 276 { 277 277 int ret; 278 278 279 - ret = v3d_job_allocate((void *)job, sizeof(**job)); 279 + ret = v3d_job_allocate(v3d, (void *)job, sizeof(**job)); 280 280 if (ret) 281 281 return ret; 282 282 ··· 287 287 return ret; 288 288 } 289 289 290 - ret = v3d_job_allocate((void *)clean_job, sizeof(**clean_job)); 290 + ret = v3d_job_allocate(v3d, (void *)clean_job, sizeof(**clean_job)); 291 291 if (ret) 292 292 return ret; 293 293 ··· 326 326 struct v3d_submit_ext *se, 327 327 u32 count, u64 handles) 328 328 { 329 + struct v3d_file_priv *v3d_priv = file_priv->driver_priv; 330 + struct v3d_dev *v3d = v3d_priv->v3d; 329 331 struct drm_v3d_sem __user *post_deps; 330 332 int i, ret; 331 333 ··· 348 346 349 347 if (copy_from_user(&out, post_deps++, sizeof(out))) { 350 348 ret = -EFAULT; 351 - DRM_DEBUG("Failed to copy post dep handles\n"); 349 + drm_dbg(&v3d->drm, "Failed to copy post dep handles\n"); 352 350 goto fail; 353 351 } 354 352 ··· 379 377 struct drm_v3d_extension __user *ext, 380 378 struct v3d_submit_ext *se) 381 379 { 380 + struct v3d_file_priv *v3d_priv = file_priv->driver_priv; 381 + struct v3d_dev *v3d = v3d_priv->v3d; 382 382 struct drm_v3d_multi_sync multisync; 383 383 int ret; 384 384 385 385 if (se->in_sync_count || se->out_sync_count) { 386 - DRM_DEBUG("Two multisync extensions were added to the same job."); 386 + drm_dbg(&v3d->drm, "Two multisync extensions were added to the same job."); 387 387 return -EINVAL; 388 388 } 389 389 ··· 408 404 return 0; 409 405 } 410 406 407 + /* Returns false if the CPU job has an invalid configuration. */ 408 + static bool 409 + v3d_validate_cpu_job(struct drm_file *file_priv, struct v3d_cpu_job *job) 410 + { 411 + struct v3d_file_priv *v3d_priv = file_priv->driver_priv; 412 + struct v3d_dev *v3d = v3d_priv->v3d; 413 + 414 + if (!job) { 415 + drm_dbg(&v3d->drm, "CPU job extension was attached to a GPU job.\n"); 416 + return false; 417 + } 418 + 419 + if (job->job_type) { 420 + drm_dbg(&v3d->drm, "Two CPU job extensions were added to the same CPU job.\n"); 421 + return false; 422 + } 423 + 424 + return true; 425 + } 426 + 411 427 /* Get data for the indirect CSD job submission. */ 412 428 static int 413 429 v3d_get_cpu_indirect_csd_params(struct drm_file *file_priv, ··· 439 415 struct drm_v3d_indirect_csd indirect_csd; 440 416 struct v3d_indirect_csd_info *info = &job->indirect_csd; 441 417 442 - if (!job) { 443 - DRM_DEBUG("CPU job extension was attached to a GPU job.\n"); 418 + if (!v3d_validate_cpu_job(file_priv, job)) 444 419 return -EINVAL; 445 - } 446 - 447 - if (job->job_type) { 448 - DRM_DEBUG("Two CPU job extensions were added to the same CPU job.\n"); 449 - return -EINVAL; 450 - } 451 420 452 421 if (copy_from_user(&indirect_csd, ext, sizeof(indirect_csd))) 453 422 return -EFAULT; 454 423 455 424 if (!v3d_has_csd(v3d)) { 456 - DRM_DEBUG("Attempting CSD submit on non-CSD hardware.\n"); 425 + drm_warn(&v3d->drm, "Attempting CSD submit on non-CSD hardware.\n"); 457 426 return -EINVAL; 458 427 } 459 428 ··· 475 458 unsigned int i; 476 459 int err; 477 460 478 - if (!job) { 479 - DRM_DEBUG("CPU job extension was attached to a GPU job.\n"); 461 + if (!v3d_validate_cpu_job(file_priv, job)) 480 462 return -EINVAL; 481 - } 482 - 483 - if (job->job_type) { 484 - DRM_DEBUG("Two CPU job extensions were added to the same CPU job.\n"); 485 - return -EINVAL; 486 - } 487 463 488 464 if (copy_from_user(&timestamp, ext, sizeof(timestamp))) 489 465 return -EFAULT; ··· 537 527 unsigned int i; 538 528 int err; 539 529 540 - if (!job) { 541 - DRM_DEBUG("CPU job extension was attached to a GPU job.\n"); 530 + if (!v3d_validate_cpu_job(file_priv, job)) 542 531 return -EINVAL; 543 - } 544 - 545 - if (job->job_type) { 546 - DRM_DEBUG("Two CPU job extensions were added to the same CPU job.\n"); 547 - return -EINVAL; 548 - } 549 532 550 533 if (copy_from_user(&reset, ext, sizeof(reset))) 551 534 return -EFAULT; ··· 591 588 unsigned int i; 592 589 int err; 593 590 594 - if (!job) { 595 - DRM_DEBUG("CPU job extension was attached to a GPU job.\n"); 591 + if (!v3d_validate_cpu_job(file_priv, job)) 596 592 return -EINVAL; 597 - } 598 - 599 - if (job->job_type) { 600 - DRM_DEBUG("Two CPU job extensions were added to the same CPU job.\n"); 601 - return -EINVAL; 602 - } 603 593 604 594 if (copy_from_user(&copy, ext, sizeof(copy))) 605 595 return -EFAULT; ··· 720 724 struct drm_v3d_reset_performance_query reset; 721 725 int err; 722 726 723 - if (!job) { 724 - DRM_DEBUG("CPU job extension was attached to a GPU job.\n"); 727 + if (!v3d_validate_cpu_job(file_priv, job)) 725 728 return -EINVAL; 726 - } 727 - 728 - if (job->job_type) { 729 - DRM_DEBUG("Two CPU job extensions were added to the same CPU job.\n"); 730 - return -EINVAL; 731 - } 732 729 733 730 if (copy_from_user(&reset, ext, sizeof(reset))) 734 731 return -EFAULT; ··· 759 770 struct drm_v3d_copy_performance_query copy; 760 771 int err; 761 772 762 - if (!job) { 763 - DRM_DEBUG("CPU job extension was attached to a GPU job.\n"); 773 + if (!v3d_validate_cpu_job(file_priv, job)) 764 774 return -EINVAL; 765 - } 766 - 767 - if (job->job_type) { 768 - DRM_DEBUG("Two CPU job extensions were added to the same CPU job.\n"); 769 - return -EINVAL; 770 - } 771 775 772 776 if (copy_from_user(&copy, ext, sizeof(copy))) 773 777 return -EFAULT; ··· 808 826 struct v3d_submit_ext *se, 809 827 struct v3d_cpu_job *job) 810 828 { 829 + struct v3d_file_priv *v3d_priv = file_priv->driver_priv; 830 + struct v3d_dev *v3d = v3d_priv->v3d; 811 831 struct drm_v3d_extension __user *user_ext; 812 832 int ret; 813 833 ··· 818 834 struct drm_v3d_extension ext; 819 835 820 836 if (copy_from_user(&ext, user_ext, sizeof(ext))) { 821 - DRM_DEBUG("Failed to copy submit extension\n"); 837 + drm_dbg(&v3d->drm, "Failed to copy submit extension\n"); 822 838 return -EFAULT; 823 839 } 824 840 ··· 845 861 ret = v3d_get_cpu_copy_performance_query_params(file_priv, user_ext, job); 846 862 break; 847 863 default: 848 - DRM_DEBUG_DRIVER("Unknown extension id: %d\n", ext.id); 864 + drm_dbg(&v3d->drm, "Unknown V3D extension ID: %d\n", ext.id); 849 865 return -EINVAL; 850 866 } 851 867 ··· 893 909 if (args->flags && 894 910 args->flags & ~(DRM_V3D_SUBMIT_CL_FLUSH_CACHE | 895 911 DRM_V3D_SUBMIT_EXTENSION)) { 896 - DRM_INFO("invalid flags: %d\n", args->flags); 912 + drm_dbg(dev, "invalid flags: %d\n", args->flags); 897 913 return -EINVAL; 898 914 } 899 915 900 916 if (args->flags & DRM_V3D_SUBMIT_EXTENSION) { 901 917 ret = v3d_get_extensions(file_priv, args->extensions, &se, NULL); 902 918 if (ret) { 903 - DRM_DEBUG("Failed to get extensions.\n"); 919 + drm_dbg(dev, "Failed to get extensions.\n"); 904 920 return ret; 905 921 } 906 922 } 907 923 908 - ret = v3d_job_allocate((void *)&render, sizeof(*render)); 924 + ret = v3d_job_allocate(v3d, (void *)&render, sizeof(*render)); 909 925 if (ret) 910 926 return ret; 911 927 ··· 921 937 INIT_LIST_HEAD(&render->unref_list); 922 938 923 939 if (args->bcl_start != args->bcl_end) { 924 - ret = v3d_job_allocate((void *)&bin, sizeof(*bin)); 940 + ret = v3d_job_allocate(v3d, (void *)&bin, sizeof(*bin)); 925 941 if (ret) 926 942 goto fail; 927 943 ··· 941 957 } 942 958 943 959 if (args->flags & DRM_V3D_SUBMIT_CL_FLUSH_CACHE) { 944 - ret = v3d_job_allocate((void *)&clean_job, sizeof(*clean_job)); 960 + ret = v3d_job_allocate(v3d, (void *)&clean_job, sizeof(*clean_job)); 945 961 if (ret) 946 962 goto fail; 947 963 ··· 1059 1075 trace_v3d_submit_tfu_ioctl(&v3d->drm, args->iia); 1060 1076 1061 1077 if (args->flags && !(args->flags & DRM_V3D_SUBMIT_EXTENSION)) { 1062 - DRM_DEBUG("invalid flags: %d\n", args->flags); 1078 + drm_dbg(dev, "invalid flags: %d\n", args->flags); 1063 1079 return -EINVAL; 1064 1080 } 1065 1081 1066 1082 if (args->flags & DRM_V3D_SUBMIT_EXTENSION) { 1067 1083 ret = v3d_get_extensions(file_priv, args->extensions, &se, NULL); 1068 1084 if (ret) { 1069 - DRM_DEBUG("Failed to get extensions.\n"); 1085 + drm_dbg(dev, "Failed to get extensions.\n"); 1070 1086 return ret; 1071 1087 } 1072 1088 } 1073 1089 1074 - ret = v3d_job_allocate((void *)&job, sizeof(*job)); 1090 + ret = v3d_job_allocate(v3d, (void *)&job, sizeof(*job)); 1075 1091 if (ret) 1076 1092 return ret; 1077 1093 ··· 1101 1117 1102 1118 bo = drm_gem_object_lookup(file_priv, args->bo_handles[job->base.bo_count]); 1103 1119 if (!bo) { 1104 - DRM_DEBUG("Failed to look up GEM BO %d: %d\n", 1105 - job->base.bo_count, 1106 - args->bo_handles[job->base.bo_count]); 1120 + drm_dbg(dev, "Failed to look up GEM BO %d: %d\n", 1121 + job->base.bo_count, 1122 + args->bo_handles[job->base.bo_count]); 1107 1123 ret = -ENOENT; 1108 1124 goto fail; 1109 1125 } ··· 1163 1179 return -EINVAL; 1164 1180 1165 1181 if (!v3d_has_csd(v3d)) { 1166 - DRM_DEBUG("Attempting CSD submit on non-CSD hardware\n"); 1182 + drm_warn(dev, "Attempting CSD submit on non-CSD hardware\n"); 1167 1183 return -EINVAL; 1168 1184 } 1169 1185 1170 1186 if (args->flags && !(args->flags & DRM_V3D_SUBMIT_EXTENSION)) { 1171 - DRM_INFO("invalid flags: %d\n", args->flags); 1187 + drm_dbg(dev, "invalid flags: %d\n", args->flags); 1172 1188 return -EINVAL; 1173 1189 } 1174 1190 1175 1191 if (args->flags & DRM_V3D_SUBMIT_EXTENSION) { 1176 1192 ret = v3d_get_extensions(file_priv, args->extensions, &se, NULL); 1177 1193 if (ret) { 1178 - DRM_DEBUG("Failed to get extensions.\n"); 1194 + drm_dbg(dev, "Failed to get extensions.\n"); 1179 1195 return ret; 1180 1196 } 1181 1197 } ··· 1269 1285 int ret; 1270 1286 1271 1287 if (args->flags && !(args->flags & DRM_V3D_SUBMIT_EXTENSION)) { 1272 - DRM_INFO("Invalid flags: %d\n", args->flags); 1288 + drm_dbg(dev, "Invalid flags: %d\n", args->flags); 1273 1289 return -EINVAL; 1274 1290 } 1275 1291 1276 - ret = v3d_job_allocate((void *)&cpu_job, sizeof(*cpu_job)); 1292 + ret = v3d_job_allocate(v3d, (void *)&cpu_job, sizeof(*cpu_job)); 1277 1293 if (ret) 1278 1294 return ret; 1279 1295 1280 1296 if (args->flags & DRM_V3D_SUBMIT_EXTENSION) { 1281 1297 ret = v3d_get_extensions(file_priv, args->extensions, &se, cpu_job); 1282 1298 if (ret) { 1283 - DRM_DEBUG("Failed to get extensions.\n"); 1299 + drm_dbg(dev, "Failed to get extensions.\n"); 1284 1300 goto fail; 1285 1301 } 1286 1302 } 1287 1303 1288 1304 /* Every CPU job must have a CPU job user extension */ 1289 1305 if (!cpu_job->job_type) { 1290 - DRM_DEBUG("CPU job must have a CPU job user extension.\n"); 1306 + drm_dbg(dev, "CPU job must have a CPU job user extension.\n"); 1291 1307 ret = -EINVAL; 1292 1308 goto fail; 1293 1309 } 1294 1310 1295 1311 if (args->bo_handle_count != cpu_job_bo_handle_count[cpu_job->job_type]) { 1296 - DRM_DEBUG("This CPU job was not submitted with the proper number of BOs.\n"); 1312 + drm_dbg(dev, "This CPU job was not submitted with the proper number of BOs.\n"); 1297 1313 ret = -EINVAL; 1298 1314 goto fail; 1299 1315 }
+104 -1
drivers/gpu/drm/vc4/vc4_hdmi.c
··· 624 624 return ret; 625 625 } 626 626 627 + static int vc4_hdmi_clear_infoframe(struct drm_connector *connector, 628 + enum hdmi_infoframe_type type) 629 + { 630 + struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); 631 + struct drm_device *drm = connector->dev; 632 + int ret; 633 + int idx; 634 + 635 + if (!drm_dev_enter(drm, &idx)) 636 + return 0; 637 + 638 + WARN_ONCE(!(HDMI_READ(HDMI_RAM_PACKET_CONFIG) & 639 + VC4_HDMI_RAM_PACKET_ENABLE), 640 + "Packet RAM has to be on to store the packet."); 641 + 642 + ret = vc4_hdmi_stop_packet(vc4_hdmi, type, true); 643 + if (ret) 644 + drm_err(drm, "Failed to wait for infoframe to go idle: %d\n", ret); 645 + 646 + drm_dev_exit(idx); 647 + 648 + return ret; 649 + } 650 + 627 651 static int vc4_hdmi_write_infoframe(struct drm_connector *connector, 628 652 enum hdmi_infoframe_type type, 629 653 const u8 *infoframe, size_t len) ··· 725 701 out: 726 702 drm_dev_exit(idx); 727 703 return ret; 704 + } 705 + 706 + static int vc4_hdmi_clear_avi_infoframe(struct drm_connector *connector) 707 + { 708 + return vc4_hdmi_clear_infoframe(connector, HDMI_INFOFRAME_TYPE_AVI); 709 + } 710 + 711 + static int vc4_hdmi_clear_hdmi_infoframe(struct drm_connector *connector) 712 + { 713 + return vc4_hdmi_clear_infoframe(connector, HDMI_INFOFRAME_TYPE_VENDOR); 714 + } 715 + 716 + static int vc4_hdmi_clear_audio_infoframe(struct drm_connector *connector) 717 + { 718 + return vc4_hdmi_clear_infoframe(connector, HDMI_INFOFRAME_TYPE_AUDIO); 719 + } 720 + 721 + static int vc4_hdmi_clear_hdr_drm_infoframe(struct drm_connector *connector) 722 + { 723 + return vc4_hdmi_clear_infoframe(connector, HDMI_INFOFRAME_TYPE_DRM); 724 + } 725 + 726 + static int vc4_hdmi_clear_spd_infoframe(struct drm_connector *connector) 727 + { 728 + return vc4_hdmi_clear_infoframe(connector, HDMI_INFOFRAME_TYPE_SPD); 729 + } 730 + 731 + static int vc4_hdmi_write_avi_infoframe(struct drm_connector *connector, 732 + const u8 *buffer, size_t len) 733 + { 734 + return vc4_hdmi_write_infoframe(connector, HDMI_INFOFRAME_TYPE_AVI, 735 + buffer, len); 736 + } 737 + 738 + static int vc4_hdmi_write_hdmi_infoframe(struct drm_connector *connector, 739 + const u8 *buffer, size_t len) 740 + { 741 + return vc4_hdmi_write_infoframe(connector, HDMI_INFOFRAME_TYPE_VENDOR, 742 + buffer, len); 743 + } 744 + 745 + static int vc4_hdmi_write_audio_infoframe(struct drm_connector *connector, 746 + const u8 *buffer, size_t len) 747 + { 748 + return vc4_hdmi_write_infoframe(connector, HDMI_INFOFRAME_TYPE_AUDIO, 749 + buffer, len); 750 + } 751 + 752 + static int vc4_hdmi_write_hdr_drm_infoframe(struct drm_connector *connector, 753 + const u8 *buffer, size_t len) 754 + { 755 + return vc4_hdmi_write_infoframe(connector, HDMI_INFOFRAME_TYPE_DRM, 756 + buffer, len); 757 + } 758 + 759 + static int vc4_hdmi_write_spd_infoframe(struct drm_connector *connector, 760 + const u8 *buffer, size_t len) 761 + { 762 + return vc4_hdmi_write_infoframe(connector, HDMI_INFOFRAME_TYPE_SPD, 763 + buffer, len); 728 764 } 729 765 730 766 #define SCRAMBLING_POLLING_DELAY_MS 1000 ··· 1744 1660 1745 1661 static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs = { 1746 1662 .tmds_char_rate_valid = vc4_hdmi_connector_clock_valid, 1747 - .write_infoframe = vc4_hdmi_write_infoframe, 1663 + .avi = { 1664 + .clear_infoframe = vc4_hdmi_clear_avi_infoframe, 1665 + .write_infoframe = vc4_hdmi_write_avi_infoframe, 1666 + }, 1667 + .hdmi = { 1668 + .clear_infoframe = vc4_hdmi_clear_hdmi_infoframe, 1669 + .write_infoframe = vc4_hdmi_write_hdmi_infoframe, 1670 + }, 1671 + .audio = { 1672 + .clear_infoframe = vc4_hdmi_clear_audio_infoframe, 1673 + .write_infoframe = vc4_hdmi_write_audio_infoframe, 1674 + }, 1675 + .hdr_drm = { 1676 + .clear_infoframe = vc4_hdmi_clear_hdr_drm_infoframe, 1677 + .write_infoframe = vc4_hdmi_write_hdr_drm_infoframe, 1678 + }, 1679 + .spd = { 1680 + .clear_infoframe = vc4_hdmi_clear_spd_infoframe, 1681 + .write_infoframe = vc4_hdmi_write_spd_infoframe, 1682 + }, 1748 1683 }; 1749 1684 1750 1685 #define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL
+2
include/drm/bridge/inno_hdmi.h
··· 6 6 #ifndef __INNO_HDMI__ 7 7 #define __INNO_HDMI__ 8 8 9 + #include <linux/types.h> 10 + 9 11 struct device; 10 12 struct drm_encoder; 11 13 struct drm_display_mode;
-1
include/drm/bridge/samsung-dsim.h
··· 100 100 struct samsung_dsim { 101 101 struct mipi_dsi_host dsi_host; 102 102 struct drm_bridge bridge; 103 - struct drm_bridge *out_bridge; 104 103 struct device *dev; 105 104 struct drm_display_mode mode; 106 105
+115 -12
include/drm/drm_bridge.h
··· 785 785 unsigned long long tmds_rate); 786 786 787 787 /** 788 - * @hdmi_clear_infoframe: 788 + * @hdmi_clear_avi_infoframe: 789 789 * 790 790 * This callback clears the infoframes in the hardware during commit. 791 - * It will be called multiple times, once for every disabled infoframe 792 - * type. 793 791 * 794 792 * This callback is optional but it must be implemented by bridges that 795 793 * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops. 796 794 */ 797 - int (*hdmi_clear_infoframe)(struct drm_bridge *bridge, 798 - enum hdmi_infoframe_type type); 795 + int (*hdmi_clear_avi_infoframe)(struct drm_bridge *bridge); 796 + 799 797 /** 800 - * @hdmi_write_infoframe: 798 + * @hdmi_write_avi_infoframe: 801 799 * 802 - * Program the infoframe into the hardware. It will be called multiple 803 - * times, once for every updated infoframe type. 800 + * Program the infoframe into the hardware. 804 801 * 805 802 * This callback is optional but it must be implemented by bridges that 806 803 * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops. 807 804 */ 808 - int (*hdmi_write_infoframe)(struct drm_bridge *bridge, 809 - enum hdmi_infoframe_type type, 810 - const u8 *buffer, size_t len); 805 + int (*hdmi_write_avi_infoframe)(struct drm_bridge *bridge, 806 + const u8 *buffer, size_t len); 807 + 808 + /** 809 + * @hdmi_clear_hdmi_infoframe: 810 + * 811 + * This callback clears the infoframes in the hardware during commit. 812 + * 813 + * This callback is optional but it must be implemented by bridges that 814 + * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops. 815 + */ 816 + int (*hdmi_clear_hdmi_infoframe)(struct drm_bridge *bridge); 817 + 818 + /** 819 + * @hdmi_write_hdmi_infoframe: 820 + * 821 + * Program the infoframe into the hardware. 822 + * 823 + * This callback is optional but it must be implemented by bridges that 824 + * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops. 825 + */ 826 + int (*hdmi_write_hdmi_infoframe)(struct drm_bridge *bridge, 827 + const u8 *buffer, size_t len); 828 + 829 + /** 830 + * @hdmi_clear_hdr_drm_infoframe: 831 + * 832 + * This callback clears the infoframes in the hardware during commit. 833 + * 834 + * This callback is optional but it must be implemented by bridges that 835 + * set the DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME flag in their 836 + * &drm_bridge->ops. 837 + */ 838 + int (*hdmi_clear_hdr_drm_infoframe)(struct drm_bridge *bridge); 839 + 840 + /** 841 + * @hdmi_write_hdr_drm_infoframe: 842 + * 843 + * Program the infoframe into the hardware. 844 + * 845 + * This callback is optional but it must be implemented by bridges that 846 + * set the DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME flag in their 847 + * &drm_bridge->ops. 848 + */ 849 + int (*hdmi_write_hdr_drm_infoframe)(struct drm_bridge *bridge, 850 + const u8 *buffer, size_t len); 851 + 852 + /** 853 + * @hdmi_clear_spd_infoframe: 854 + * 855 + * This callback clears the infoframes in the hardware during commit. 856 + * 857 + * This callback is optional but it must be implemented by bridges that 858 + * set the DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME flag in their 859 + * &drm_bridge->ops. 860 + */ 861 + int (*hdmi_clear_spd_infoframe)(struct drm_bridge *bridge); 862 + 863 + /** 864 + * @hdmi_write_spd_infoframe: 865 + * 866 + * Program the infoframe into the hardware. 867 + * 868 + * This callback is optional but it must be implemented by bridges that 869 + * set the DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME flag in their 870 + * &drm_bridge->ops. 871 + */ 872 + int (*hdmi_write_spd_infoframe)(struct drm_bridge *bridge, 873 + const u8 *buffer, size_t len); 874 + 875 + /** 876 + * @hdmi_clear_audio_infoframe: 877 + * 878 + * This callback clears the infoframes in the hardware during commit. 879 + * 880 + * This callback is optional but it must be implemented by bridges that 881 + * set the DRM_BRIDGE_OP_HDMI_AUDIO flag in their &drm_bridge->ops. 882 + */ 883 + int (*hdmi_clear_audio_infoframe)(struct drm_bridge *bridge); 884 + 885 + /** 886 + * @hdmi_write_audio_infoframe: 887 + * 888 + * Program the infoframe into the hardware. 889 + * 890 + * This callback is optional but it must be implemented by bridges that 891 + * set the DRM_BRIDGE_OP_HDMI_AUDIO flag in their &drm_bridge->ops. 892 + */ 893 + int (*hdmi_write_audio_infoframe)(struct drm_bridge *bridge, 894 + const u8 *buffer, size_t len); 811 895 812 896 /** 813 897 * @hdmi_audio_startup: ··· 1147 1063 /** 1148 1064 * @DRM_BRIDGE_OP_HDMI: The bridge provides HDMI connector operations, 1149 1065 * including infoframes support. Bridges that set this flag must 1150 - * implement the &drm_bridge_funcs->write_infoframe callback. 1066 + * provide HDMI-related information and implement the 1067 + * &drm_bridge_funcs->clear_avi_infoframe, 1068 + * &drm_bridge_funcs->write_avi_infoframe, 1069 + * &drm_bridge_funcs->clear_hdmi_infoframe and 1070 + * &drm_bridge_funcs->write_hdmi_infoframe callbacks. 1151 1071 * 1152 1072 * Note: currently there can be at most one bridge in a chain that sets 1153 1073 * this bit. This is to simplify corresponding glue code in connector ··· 1163 1075 * Bridges that set this flag must implement the 1164 1076 * &drm_bridge_funcs->hdmi_audio_prepare and 1165 1077 * &drm_bridge_funcs->hdmi_audio_shutdown callbacks. 1078 + * If the bridge implements @DRM_BRIDGE_OP_HDMI, it also must implement 1079 + * &drm_bridge_funcs->hdmi_write_audio_infoframe and 1080 + * &drm_bridge_funcs->hdmi_cleaer_audio_infoframe callbacks. 1166 1081 * 1167 1082 * Note: currently there can be at most one bridge in a chain that sets 1168 1083 * this bit. This is to simplify corresponding glue code in connector ··· 1197 1106 * to be present. 1198 1107 */ 1199 1108 DRM_BRIDGE_OP_HDMI_CEC_ADAPTER = BIT(8), 1109 + /** 1110 + * @DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME: The bridge supports 1111 + * &drm_bridge_funcs->hdmi_write_hdr_drm_infoframe and 1112 + * &drm_bridge_funcs->hdmi_clear_hdr_drm_infoframe callbacks. 1113 + */ 1114 + DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME = BIT(9), 1115 + /** 1116 + * @DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME: The bridge supports 1117 + * &drm_bridge_funcs->hdmi_write_spd_infoframe and 1118 + * &drm_bridge_funcs->hdmi_clear_spd_infoframe callbacks. 1119 + */ 1120 + DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME = BIT(10), 1200 1121 }; 1201 1122 1202 1123 /**
+80 -35
include/drm/drm_connector.h
··· 1222 1222 }; 1223 1223 1224 1224 /** 1225 + * struct drm_connector_infoframe_funcs - InfoFrame-related functions 1226 + */ 1227 + struct drm_connector_infoframe_funcs { 1228 + /** 1229 + * @clear_infoframe: 1230 + * 1231 + * This callback is invoked through 1232 + * @drm_atomic_helper_connector_hdmi_update_infoframes during a 1233 + * commit to clear the infoframes into the hardware. It will be 1234 + * called once for each frame type to be disabled. 1235 + * 1236 + * The @clear_infoframe callback is mandatory for AVI and HDMI-VS 1237 + * InfoFrame types. 1238 + * 1239 + * Returns: 1240 + * 0 on success, a negative error code otherwise 1241 + */ 1242 + int (*clear_infoframe)(struct drm_connector *connector); 1243 + 1244 + /** 1245 + * @write_infoframe: 1246 + * 1247 + * This callback is invoked through 1248 + * @drm_atomic_helper_connector_hdmi_update_infoframes during a 1249 + * commit to program the infoframes into the hardware. It will 1250 + * be called for every updated infoframe type. 1251 + * 1252 + * The @write_infoframe callback is mandatory for AVI and HDMI-VS 1253 + * InfoFrame types. 1254 + * 1255 + * Returns: 1256 + * 0 on success, a negative error code otherwise 1257 + */ 1258 + int (*write_infoframe)(struct drm_connector *connector, 1259 + const u8 *buffer, size_t len); 1260 + 1261 + }; 1262 + 1263 + /** 1225 1264 * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions 1226 1265 */ 1227 1266 struct drm_connector_hdmi_funcs { ··· 1284 1245 unsigned long long tmds_rate); 1285 1246 1286 1247 /** 1287 - * @clear_infoframe: 1288 - * 1289 - * This callback is invoked through 1290 - * @drm_atomic_helper_connector_hdmi_update_infoframes during a 1291 - * commit to clear the infoframes into the hardware. It will be 1292 - * called multiple times, once for every disabled infoframe 1293 - * type. 1294 - * 1295 - * The @clear_infoframe callback is optional. 1296 - * 1297 - * Returns: 1298 - * 0 on success, a negative error code otherwise 1299 - */ 1300 - int (*clear_infoframe)(struct drm_connector *connector, 1301 - enum hdmi_infoframe_type type); 1302 - 1303 - /** 1304 - * @write_infoframe: 1305 - * 1306 - * This callback is invoked through 1307 - * @drm_atomic_helper_connector_hdmi_update_infoframes during a 1308 - * commit to program the infoframes into the hardware. It will 1309 - * be called multiple times, once for every updated infoframe 1310 - * type. 1311 - * 1312 - * The @write_infoframe callback is mandatory. 1313 - * 1314 - * Returns: 1315 - * 0 on success, a negative error code otherwise 1316 - */ 1317 - int (*write_infoframe)(struct drm_connector *connector, 1318 - enum hdmi_infoframe_type type, 1319 - const u8 *buffer, size_t len); 1320 - 1321 - /** 1322 1248 * @read_edid: 1323 1249 * 1324 1250 * This callback is used by the framework as a replacement for reading ··· 1297 1293 * Valid EDID on success, NULL in case of failure. 1298 1294 */ 1299 1295 const struct drm_edid *(*read_edid)(struct drm_connector *connector); 1296 + 1297 + /** 1298 + * @avi: 1299 + * 1300 + * Set of callbacks for handling the AVI InfoFrame. These callbacks are 1301 + * mandatory. 1302 + */ 1303 + struct drm_connector_infoframe_funcs avi; 1304 + 1305 + /** 1306 + * @hdmi: 1307 + * 1308 + * Set of callbacks for handling the HDMI Vendor-Specific InfoFrame. 1309 + * These callbacks are mandatory. 1310 + */ 1311 + struct drm_connector_infoframe_funcs hdmi; 1312 + 1313 + /** 1314 + * @audio: 1315 + * 1316 + * Set of callbacks for handling the Audio InfoFrame. These callbacks 1317 + * are optional, but they are required for drivers which use 1318 + * drm_atomic_helper_connector_hdmi_update_audio_infoframe(). 1319 + */ 1320 + struct drm_connector_infoframe_funcs audio; 1321 + 1322 + /** 1323 + * @hdr_drm: 1324 + * 1325 + * Set of callbacks for handling the HDR DRM InfoFrame. These callbacks 1326 + * are mandatory if HDR output is to be supported. 1327 + */ 1328 + struct drm_connector_infoframe_funcs hdr_drm; 1329 + 1330 + /** 1331 + * @spd: 1332 + * 1333 + * Set of callbacks for handling the SPD InfoFrame. These callbacks are 1334 + * optional. 1335 + */ 1336 + struct drm_connector_infoframe_funcs spd; 1300 1337 }; 1301 1338 1302 1339 /**
+5 -1
include/drm/drm_of.h
··· 5 5 #include <linux/err.h> 6 6 #include <linux/of_graph.h> 7 7 #if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE) 8 + #include <linux/of.h> 8 9 #include <drm/drm_bridge.h> 9 10 #endif 10 11 ··· 171 170 if (!remote) 172 171 return -ENODEV; 173 172 174 - bridge = of_drm_find_bridge(remote); 173 + bridge = of_drm_find_and_get_bridge(remote); 175 174 drm_panel_bridge_remove(bridge); 175 + 176 + drm_bridge_put(bridge); 177 + of_node_put(remote); 176 178 177 179 return 0; 178 180 #else
-12
include/linux/dma-buf.h
··· 429 429 430 430 __poll_t active; 431 431 } cb_in, cb_out; 432 - #ifdef CONFIG_DMABUF_SYSFS_STATS 433 - /** 434 - * @sysfs_entry: 435 - * 436 - * For exposing information about this buffer in sysfs. See also 437 - * `DMA-BUF statistics`_ for the uapi this enables. 438 - */ 439 - struct dma_buf_sysfs_entry { 440 - struct kobject kobj; 441 - struct dma_buf *dmabuf; 442 - } *sysfs_entry; 443 - #endif 444 432 }; 445 433 446 434 /**
+2
include/linux/dma-heap.h
··· 46 46 47 47 struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info); 48 48 49 + extern bool mem_accounting; 50 + 49 51 #endif /* _DMA_HEAPS_H */
+26 -24
include/trace/events/dma_buf.h
··· 15 15 TP_ARGS(dmabuf), 16 16 17 17 TP_STRUCT__entry( 18 - __string(exp_name, dmabuf->exp_name) 19 - __field(size_t, size) 20 - __field(ino_t, ino) 18 + __string( exp_name, dmabuf->exp_name) 19 + __field( size_t, size) 20 + __field( ino_t, ino) 21 21 ), 22 22 23 23 TP_fast_assign( 24 24 __assign_str(exp_name); 25 - __entry->size = dmabuf->size; 26 - __entry->ino = dmabuf->file->f_inode->i_ino; 25 + __entry->size = dmabuf->size; 26 + __entry->ino = dmabuf->file->f_inode->i_ino; 27 27 ), 28 28 29 29 TP_printk("exp_name=%s size=%zu ino=%lu", ··· 40 40 TP_ARGS(dmabuf, attach, is_dynamic, dev), 41 41 42 42 TP_STRUCT__entry( 43 - __string(dev_name, dev_name(dev)) 44 - __string(exp_name, dmabuf->exp_name) 45 - __field(size_t, size) 46 - __field(ino_t, ino) 47 - __field(struct dma_buf_attachment *, attach) 48 - __field(bool, is_dynamic) 43 + __string( dev_name, dev_name(dev)) 44 + __string( exp_name, dmabuf->exp_name) 45 + __field( size_t, size) 46 + __field( ino_t, ino) 47 + __field( struct dma_buf_attachment *, attach) 48 + __field( bool, is_dynamic) 49 49 ), 50 50 51 51 TP_fast_assign( 52 52 __assign_str(dev_name); 53 53 __assign_str(exp_name); 54 - __entry->size = dmabuf->size; 55 - __entry->ino = dmabuf->file->f_inode->i_ino; 56 - __entry->is_dynamic = is_dynamic; 57 - __entry->attach = attach; 54 + __entry->size = dmabuf->size; 55 + __entry->ino = dmabuf->file->f_inode->i_ino; 56 + __entry->is_dynamic = is_dynamic; 57 + __entry->attach = attach; 58 58 ), 59 59 60 60 TP_printk("exp_name=%s size=%zu ino=%lu attachment:%p is_dynamic=%d dev_name=%s", ··· 73 73 TP_ARGS(dmabuf, fd), 74 74 75 75 TP_STRUCT__entry( 76 - __string(exp_name, dmabuf->exp_name) 77 - __field(size_t, size) 78 - __field(ino_t, ino) 79 - __field(int, fd) 76 + __string( exp_name, dmabuf->exp_name) 77 + __field( size_t, size) 78 + __field( ino_t, ino) 79 + __field( int, fd) 80 80 ), 81 81 82 82 TP_fast_assign( 83 83 __assign_str(exp_name); 84 - __entry->size = dmabuf->size; 85 - __entry->ino = dmabuf->file->f_inode->i_ino; 86 - __entry->fd = fd; 84 + __entry->size = dmabuf->size; 85 + __entry->ino = dmabuf->file->f_inode->i_ino; 86 + __entry->fd = fd; 87 87 ), 88 88 89 89 TP_printk("exp_name=%s size=%zu ino=%lu fd=%d", ··· 137 137 TP_ARGS(dmabuf, attach, is_dynamic, dev) 138 138 ); 139 139 140 - DEFINE_EVENT(dma_buf_fd, dma_buf_fd, 140 + DEFINE_EVENT_CONDITION(dma_buf_fd, dma_buf_fd, 141 141 142 142 TP_PROTO(struct dma_buf *dmabuf, int fd), 143 143 144 - TP_ARGS(dmabuf, fd) 144 + TP_ARGS(dmabuf, fd), 145 + 146 + TP_CONDITION(fd >= 0) 145 147 ); 146 148 147 149 DEFINE_EVENT(dma_buf_fd, dma_buf_get,